00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "global.h"
00017 #include "transform.h"
00018
00019
00020 static int tmp[64];
00021
00022 void forward4x4(int **block, int **tblock, int pos_y, int pos_x)
00023 {
00024 int i, ii;
00025 int *pTmp = tmp, *pblock;
00026 static int p0,p1,p2,p3;
00027 static int t0,t1,t2,t3;
00028
00029
00030 for (i=pos_y; i < pos_y + BLOCK_SIZE; i++)
00031 {
00032 pblock = &block[i][pos_x];
00033 p0 = *(pblock++);
00034 p1 = *(pblock++);
00035 p2 = *(pblock++);
00036 p3 = *(pblock );
00037
00038 t0 = p0 + p3;
00039 t1 = p1 + p2;
00040 t2 = p1 - p2;
00041 t3 = p0 - p3;
00042
00043 *(pTmp++) = t0 + t1;
00044 *(pTmp++) = (t3 << 1) + t2;
00045 *(pTmp++) = t0 - t1;
00046 *(pTmp++) = t3 - (t2 << 1);
00047 }
00048
00049
00050 for (i=0; i < BLOCK_SIZE; i++)
00051 {
00052 pTmp = tmp + i;
00053 p0 = *pTmp;
00054 p1 = *(pTmp += BLOCK_SIZE);
00055 p2 = *(pTmp += BLOCK_SIZE);
00056 p3 = *(pTmp += BLOCK_SIZE);
00057
00058 t0 = p0 + p3;
00059 t1 = p1 + p2;
00060 t2 = p1 - p2;
00061 t3 = p0 - p3;
00062
00063 ii = pos_x + i;
00064 tblock[pos_y ][ii] = t0 + t1;
00065 tblock[pos_y + 1][ii] = t2 + (t3 << 1);
00066 tblock[pos_y + 2][ii] = t0 - t1;
00067 tblock[pos_y + 3][ii] = t3 - (t2 << 1);
00068 }
00069 }
00070
00071
00072 void inverse4x4(int **tblock, int **block, int pos_y, int pos_x)
00073 {
00074 int i, ii;
00075 int *pTmp = tmp, *pblock;
00076 static int p0,p1,p2,p3;
00077 static int t0,t1,t2,t3;
00078
00079
00080 for (i = pos_y; i < pos_y + BLOCK_SIZE; i++)
00081 {
00082 pblock = &tblock[i][pos_x];
00083 t0 = *(pblock++);
00084 t1 = *(pblock++);
00085 t2 = *(pblock++);
00086 t3 = *(pblock );
00087
00088 p0 = t0 + t2;
00089 p1 = t0 - t2;
00090 p2 = (t1 >> 1) - t3;
00091 p3 = t1 + (t3 >> 1);
00092
00093 *(pTmp++) = p0 + p3;
00094 *(pTmp++) = p1 + p2;
00095 *(pTmp++) = p1 - p2;
00096 *(pTmp++) = p0 - p3;
00097 }
00098
00099
00100 for (i = 0; i < BLOCK_SIZE; i++)
00101 {
00102 pTmp = tmp + i;
00103 t0 = *pTmp;
00104 t1 = *(pTmp += BLOCK_SIZE);
00105 t2 = *(pTmp += BLOCK_SIZE);
00106 t3 = *(pTmp += BLOCK_SIZE);
00107
00108 p0 = t0 + t2;
00109 p1 = t0 - t2;
00110 p2 =(t1 >> 1) - t3;
00111 p3 = t1 + (t3 >> 1);
00112
00113 ii = i + pos_x;
00114 block[pos_y ][ii] = p0 + p3;
00115 block[pos_y + 1][ii] = p1 + p2;
00116 block[pos_y + 2][ii] = p1 - p2;
00117 block[pos_y + 3][ii] = p0 - p3;
00118 }
00119 }
00120
00121
00122 void hadamard4x4(int **block, int **tblock)
00123 {
00124 int i;
00125 int *pTmp = tmp, *pblock;
00126 static int p0,p1,p2,p3;
00127 static int t0,t1,t2,t3;
00128
00129
00130 for (i = 0; i < BLOCK_SIZE; i++)
00131 {
00132 pblock = block[i];
00133 p0 = *(pblock++);
00134 p1 = *(pblock++);
00135 p2 = *(pblock++);
00136 p3 = *(pblock );
00137
00138 t0 = p0 + p3;
00139 t1 = p1 + p2;
00140 t2 = p1 - p2;
00141 t3 = p0 - p3;
00142
00143 *(pTmp++) = t0 + t1;
00144 *(pTmp++) = t3 + t2;
00145 *(pTmp++) = t0 - t1;
00146 *(pTmp++) = t3 - t2;
00147 }
00148
00149
00150 for (i = 0; i < BLOCK_SIZE; i++)
00151 {
00152 pTmp = tmp + i;
00153 p0 = *pTmp;
00154 p1 = *(pTmp += BLOCK_SIZE);
00155 p2 = *(pTmp += BLOCK_SIZE);
00156 p3 = *(pTmp += BLOCK_SIZE);
00157
00158 t0 = p0 + p3;
00159 t1 = p1 + p2;
00160 t2 = p1 - p2;
00161 t3 = p0 - p3;
00162
00163 tblock[0][i] = (t0 + t1) >> 1;
00164 tblock[1][i] = (t2 + t3) >> 1;
00165 tblock[2][i] = (t0 - t1) >> 1;
00166 tblock[3][i] = (t3 - t2) >> 1;
00167 }
00168 }
00169
00170
00171 void ihadamard4x4(int **tblock, int **block)
00172 {
00173 int i;
00174 int *pTmp = tmp, *pblock;
00175 static int p0,p1,p2,p3;
00176 static int t0,t1,t2,t3;
00177
00178
00179 for (i = 0; i < BLOCK_SIZE; i++)
00180 {
00181 pblock = tblock[i];
00182 t0 = *(pblock++);
00183 t1 = *(pblock++);
00184 t2 = *(pblock++);
00185 t3 = *(pblock );
00186
00187 p0 = t0 + t2;
00188 p1 = t0 - t2;
00189 p2 = t1 - t3;
00190 p3 = t1 + t3;
00191
00192 *(pTmp++) = p0 + p3;
00193 *(pTmp++) = p1 + p2;
00194 *(pTmp++) = p1 - p2;
00195 *(pTmp++) = p0 - p3;
00196 }
00197
00198
00199 for (i = 0; i < BLOCK_SIZE; i++)
00200 {
00201 pTmp = tmp + i;
00202 t0 = *pTmp;
00203 t1 = *(pTmp += BLOCK_SIZE);
00204 t2 = *(pTmp += BLOCK_SIZE);
00205 t3 = *(pTmp += BLOCK_SIZE);
00206
00207 p0 = t0 + t2;
00208 p1 = t0 - t2;
00209 p2 = t1 - t3;
00210 p3 = t1 + t3;
00211
00212 block[0][i] = p0 + p3;
00213 block[1][i] = p1 + p2;
00214 block[2][i] = p1 - p2;
00215 block[3][i] = p0 - p3;
00216 }
00217 }
00218
00219 void hadamard4x2(int **block, int **tblock)
00220 {
00221 int i;
00222 int *pTmp = tmp;
00223 static int p0,p1,p2,p3;
00224 static int t0,t1,t2,t3;
00225
00226
00227 *(pTmp++) = block[0][0] + block[1][0];
00228 *(pTmp++) = block[0][1] + block[1][1];
00229 *(pTmp++) = block[0][2] + block[1][2];
00230 *(pTmp++) = block[0][3] + block[1][3];
00231
00232 *(pTmp++) = block[0][0] - block[1][0];
00233 *(pTmp++) = block[0][1] - block[1][1];
00234 *(pTmp++) = block[0][2] - block[1][2];
00235 *(pTmp ) = block[0][3] - block[1][3];
00236
00237
00238 pTmp = tmp;
00239 for (i=0;i<2;i++)
00240 {
00241 p0 = *(pTmp++);
00242 p1 = *(pTmp++);
00243 p2 = *(pTmp++);
00244 p3 = *(pTmp++);
00245
00246 t0 = p0 + p3;
00247 t1 = p1 + p2;
00248 t2 = p1 - p2;
00249 t3 = p0 - p3;
00250
00251 tblock[i][0] = (t0 + t1);
00252 tblock[i][1] = (t3 + t2);
00253 tblock[i][2] = (t0 - t1);
00254 tblock[i][3] = (t3 - t2);
00255 }
00256 }
00257
00258 void ihadamard4x2(int **tblock, int **block)
00259 {
00260 int i;
00261 int *pTmp = tmp;
00262 static int p0,p1,p2,p3;
00263 static int t0,t1,t2,t3;
00264
00265
00266 *(pTmp++) = tblock[0][0] + tblock[1][0];
00267 *(pTmp++) = tblock[0][1] + tblock[1][1];
00268 *(pTmp++) = tblock[0][2] + tblock[1][2];
00269 *(pTmp++) = tblock[0][3] + tblock[1][3];
00270
00271 *(pTmp++) = tblock[0][0] - tblock[1][0];
00272 *(pTmp++) = tblock[0][1] - tblock[1][1];
00273 *(pTmp++) = tblock[0][2] - tblock[1][2];
00274 *(pTmp ) = tblock[0][3] - tblock[1][3];
00275
00276
00277 pTmp = tmp;
00278 for (i = 0; i < 2; i++)
00279 {
00280 p0 = *(pTmp++);
00281 p1 = *(pTmp++);
00282 p2 = *(pTmp++);
00283 p3 = *(pTmp++);
00284
00285 t0 = p0 + p2;
00286 t1 = p0 - p2;
00287 t2 = p1 - p3;
00288 t3 = p1 + p3;
00289
00290
00291 block[0][i] = t0 + t3;
00292 block[1][i] = t1 + t2;
00293 block[2][i] = t1 - t2;
00294 block[3][i] = t0 - t3;
00295 }
00296 }
00297
00298
00299 void hadamard2x2(int **block, int tblock[4])
00300 {
00301 static int p0,p1,p2,p3;
00302
00303 p0 = block[0][0] + block[0][4];
00304 p1 = block[0][0] - block[0][4];
00305 p2 = block[4][0] + block[4][4];
00306 p3 = block[4][0] - block[4][4];
00307
00308 tblock[0] = (p0 + p2);
00309 tblock[1] = (p1 + p3);
00310 tblock[2] = (p0 - p2);
00311 tblock[3] = (p1 - p3);
00312 }
00313
00314 void ihadamard2x2(int tblock[4], int block[4])
00315 {
00316 static int t0,t1,t2,t3;
00317
00318 t0 = tblock[0] + tblock[1];
00319 t1 = tblock[0] - tblock[1];
00320 t2 = tblock[2] + tblock[3];
00321 t3 = tblock[2] - tblock[3];
00322
00323 block[0] = (t0 + t2);
00324 block[1] = (t1 + t3);
00325 block[2] = (t0 - t2);
00326 block[3] = (t1 - t3);
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 void forward8x8(int **block, int **tblock, int pos_y, int pos_x)
00351 {
00352 int i, ii;
00353 int *pTmp = tmp, *pblock;
00354 static int a0, a1, a2, a3;
00355 static int p0, p1, p2, p3, p4, p5 ,p6, p7;
00356 static int b0, b1, b2, b3, b4, b5, b6, b7;
00357
00358
00359 for (i=pos_y; i < pos_y + BLOCK_SIZE_8x8; i++)
00360 {
00361 pblock = &block[i][pos_x];
00362 p0 = *(pblock++);
00363 p1 = *(pblock++);
00364 p2 = *(pblock++);
00365 p3 = *(pblock++);
00366 p4 = *(pblock++);
00367 p5 = *(pblock++);
00368 p6 = *(pblock++);
00369 p7 = *(pblock );
00370
00371 a0 = p0 + p7;
00372 a1 = p1 + p6;
00373 a2 = p2 + p5;
00374 a3 = p3 + p4;
00375
00376 b0 = a0 + a3;
00377 b1 = a1 + a2;
00378 b2 = a0 - a3;
00379 b3 = a1 - a2;
00380
00381 a0 = p0 - p7;
00382 a1 = p1 - p6;
00383 a2 = p2 - p5;
00384 a3 = p3 - p4;
00385
00386 b4 = a1 + a2 + ((a0 >> 1) + a0);
00387 b5 = a0 - a3 - ((a2 >> 1) + a2);
00388 b6 = a0 + a3 - ((a1 >> 1) + a1);
00389 b7 = a1 - a2 + ((a3 >> 1) + a3);
00390
00391 *(pTmp++) = b0 + b1;
00392 *(pTmp++) = b4 + (b7 >> 2);
00393 *(pTmp++) = b2 + (b3 >> 1);
00394 *(pTmp++) = b5 + (b6 >> 2);
00395 *(pTmp++) = b0 - b1;
00396 *(pTmp++) = b6 - (b5 >> 2);
00397 *(pTmp++) = (b2 >> 1) - b3;
00398 *(pTmp++) = (b4 >> 2) - b7;
00399 }
00400
00401
00402 for (i=0; i < BLOCK_SIZE_8x8; i++)
00403 {
00404 pTmp = tmp + i;
00405 p0 = *pTmp;
00406 p1 = *(pTmp += BLOCK_SIZE_8x8);
00407 p2 = *(pTmp += BLOCK_SIZE_8x8);
00408 p3 = *(pTmp += BLOCK_SIZE_8x8);
00409 p4 = *(pTmp += BLOCK_SIZE_8x8);
00410 p5 = *(pTmp += BLOCK_SIZE_8x8);
00411 p6 = *(pTmp += BLOCK_SIZE_8x8);
00412 p7 = *(pTmp += BLOCK_SIZE_8x8);
00413
00414 a0 = p0 + p7;
00415 a1 = p1 + p6;
00416 a2 = p2 + p5;
00417 a3 = p3 + p4;
00418
00419 b0 = a0 + a3;
00420 b1 = a1 + a2;
00421 b2 = a0 - a3;
00422 b3 = a1 - a2;
00423
00424 a0 = p0 - p7;
00425 a1 = p1 - p6;
00426 a2 = p2 - p5;
00427 a3 = p3 - p4;
00428
00429 b4 = a1 + a2 + ((a0 >> 1) + a0);
00430 b5 = a0 - a3 - ((a2 >> 1) + a2);
00431 b6 = a0 + a3 - ((a1 >> 1) + a1);
00432 b7 = a1 - a2 + ((a3 >> 1) + a3);
00433
00434 ii = pos_x + i;
00435 tblock[pos_y ][ii] = b0 + b1;
00436 tblock[pos_y + 1][ii] = b4 + (b7 >> 2);
00437 tblock[pos_y + 2][ii] = b2 + (b3 >> 1);
00438 tblock[pos_y + 3][ii] = b5 + (b6 >> 2);
00439 tblock[pos_y + 4][ii] = b0 - b1;
00440 tblock[pos_y + 5][ii] = b6 - (b5 >> 2);
00441 tblock[pos_y + 6][ii] = (b2 >> 1) - b3;
00442 tblock[pos_y + 7][ii] = (b4 >> 2) - b7;
00443 }
00444 }
00445
00446 void inverse8x8(int **tblock, int **block, int pos_y, int pos_x)
00447 {
00448 int i, ii;
00449 int *pTmp = tmp, *pblock;
00450 static int a0, a1, a2, a3;
00451 static int p0, p1, p2, p3, p4, p5 ,p6, p7;
00452 static int b0, b1, b2, b3, b4, b5, b6, b7;
00453
00454
00455 for (i=pos_y; i < pos_y + BLOCK_SIZE_8x8; i++)
00456 {
00457 pblock = &tblock[i][pos_x];
00458 p0 = *(pblock++);
00459 p1 = *(pblock++);
00460 p2 = *(pblock++);
00461 p3 = *(pblock++);
00462 p4 = *(pblock++);
00463 p5 = *(pblock++);
00464 p6 = *(pblock++);
00465 p7 = *(pblock );
00466
00467 a0 = p0 + p4;
00468 a1 = p0 - p4;
00469 a2 = p6 - (p2 >> 1);
00470 a3 = p2 + (p6 >> 1);
00471
00472 b0 = a0 + a3;
00473 b2 = a1 - a2;
00474 b4 = a1 + a2;
00475 b6 = a0 - a3;
00476
00477 a0 = -p3 + p5 - p7 - (p7 >> 1);
00478 a1 = p1 + p7 - p3 - (p3 >> 1);
00479 a2 = -p1 + p7 + p5 + (p5 >> 1);
00480 a3 = p3 + p5 + p1 + (p1 >> 1);
00481
00482
00483 b1 = a0 + (a3>>2);
00484 b3 = a1 + (a2>>2);
00485 b5 = a2 - (a1>>2);
00486 b7 = a3 - (a0>>2);
00487
00488 *(pTmp++) = b0 + b7;
00489 *(pTmp++) = b2 - b5;
00490 *(pTmp++) = b4 + b3;
00491 *(pTmp++) = b6 + b1;
00492 *(pTmp++) = b6 - b1;
00493 *(pTmp++) = b4 - b3;
00494 *(pTmp++) = b2 + b5;
00495 *(pTmp++) = b0 - b7;
00496 }
00497
00498
00499 for (i=0; i < BLOCK_SIZE_8x8; i++)
00500 {
00501 pTmp = tmp + i;
00502 p0 = *pTmp;
00503 p1 = *(pTmp += BLOCK_SIZE_8x8);
00504 p2 = *(pTmp += BLOCK_SIZE_8x8);
00505 p3 = *(pTmp += BLOCK_SIZE_8x8);
00506 p4 = *(pTmp += BLOCK_SIZE_8x8);
00507 p5 = *(pTmp += BLOCK_SIZE_8x8);
00508 p6 = *(pTmp += BLOCK_SIZE_8x8);
00509 p7 = *(pTmp += BLOCK_SIZE_8x8);
00510
00511 a0 = p0 + p4;
00512 a1 = p0 - p4;
00513 a2 = p6 - (p2>>1);
00514 a3 = p2 + (p6>>1);
00515
00516 b0 = a0 + a3;
00517 b2 = a1 - a2;
00518 b4 = a1 + a2;
00519 b6 = a0 - a3;
00520
00521 a0 = -p3 + p5 - p7 - (p7 >> 1);
00522 a1 = p1 + p7 - p3 - (p3 >> 1);
00523 a2 = -p1 + p7 + p5 + (p5 >> 1);
00524 a3 = p3 + p5 + p1 + (p1 >> 1);
00525
00526
00527 b1 = a0 + (a3 >> 2);
00528 b7 = a3 - (a0 >> 2);
00529 b3 = a1 + (a2 >> 2);
00530 b5 = a2 - (a1 >> 2);
00531
00532 ii = i + pos_x;
00533 block[pos_y ][ii] = b0 + b7;
00534 block[pos_y + 1][ii] = b2 - b5;
00535 block[pos_y + 2][ii] = b4 + b3;
00536 block[pos_y + 3][ii] = b6 + b1;
00537 block[pos_y + 4][ii] = b6 - b1;
00538 block[pos_y + 5][ii] = b4 - b3;
00539 block[pos_y + 6][ii] = b2 + b5;
00540 block[pos_y + 7][ii] = b0 - b7;
00541 }
00542 }
00543