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