00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef IMAGE_C_INTEGER_MATH_OPS_C_DEFINED
00039 #define IMAGE_C_INTEGER_MATH_OPS_C_DEFINED
00040
00041 #include "Image/c_integer_math_ops.h"
00042
00043 #include "Util/Assert.H"
00044
00045
00046 void c_intg_low_pass_5_x_dec_x_manybits(const int* src,
00047 const int w, const int h,
00048 int* dst,
00049 const int w2)
00050 {
00051 if (w == 2)
00052 for (int j = 0; j < h; ++j)
00053 {
00054
00055 *dst++ = (src[0] / 10) * 6 + (src[1] / 10) * 4;
00056
00057 src += 2;
00058 }
00059 else if (w == 3)
00060 for (int j = 0; j < h; ++j)
00061 {
00062
00063
00064 *dst++ =
00065 (src[0] / 11) * 6 +
00066 (src[1] / 11) * 4 +
00067 (src[2] / 11) * 1;
00068
00069 src += 3;
00070 }
00071 else
00072
00073
00074
00075
00076 for (int j = 0; j < h; ++j)
00077 {
00078 int i1 = 0, i2 = 0;
00079 const int* src2 = src;
00080
00081
00082 *dst++ =
00083 (src2[0] / 11) * 6 +
00084 (src2[1] / 11) * 4 +
00085 (src2[2] / 11) * 1;
00086 ++i2;
00087 i1 += 2;
00088
00089
00090
00091
00092 while ((i1 < (w-2)) && (i2 < w2))
00093 {
00094 *dst++ =
00095 ((src2[0] >> 4) + (src2[4] >> 4)) * 1 +
00096 ((src2[1] >> 4) + (src2[3] >> 4)) * 4 +
00097 (src2[2] >> 4) * 6;
00098 i1 += 2; src2 += 2;
00099 ++i2;
00100 }
00101
00102
00103 if ((i2 < w2) && (i1 == (w-2)))
00104 {
00105 src2 = src + w - 4;
00106
00107 *dst++ =
00108 (src2[0] / 15) * 1 +
00109 (src2[1] / 15 + src2[3] / 15) * 4 +
00110 (src2[2] / 15) * 6;
00111 i1 += 2;
00112 ++i2;
00113 }
00114
00115
00116 if ((i2 < w2) && (i1 == (w-1)))
00117 {
00118 src2 = src + w - 3;
00119
00120 *dst++ =
00121 (src2[0] / 11) * 1 +
00122 (src2[1] / 11) * 4 +
00123 (src2[2] / 11) * 6;
00124 ++i2;
00125 }
00126 src += w;
00127 }
00128 }
00129
00130
00131 void c_intg_low_pass_5_y_dec_y_manybits(const int* src,
00132 const int w, const int h,
00133 int* dst,
00134 const int h2)
00135 {
00136 const int* const src_end = src + w*h;
00137
00138
00139 const int w2 = w * 2, w3 = w * 3, w4 = w * 4;
00140
00141 if (h == 2)
00142 {
00143
00144 for (int i = 0; i < w; ++i)
00145 {
00146 *dst++ =
00147 (src[0] / 10) * 6 +
00148 (src[w] / 10) * 4;
00149 src++;
00150 }
00151 src -= w;
00152 }
00153 else if (h == 3)
00154 {
00155
00156 for (int i = 0; i < w; ++i)
00157 {
00158 *dst++ =
00159 (src[ 0] / 11) * 6 +
00160 (src[ w] / 11) * 4 +
00161 (src[w2] / 11) * 1;
00162 src++;
00163 }
00164 src -= w;
00165 }
00166 else
00167 {
00168 int i1 = 0, i2 = 0;
00169
00170
00171 for (int i = 0; i < w; ++i)
00172 {
00173 *dst++ =
00174 (src[ 0] / 11) * 6 +
00175 (src[ w] / 11) * 4 +
00176 (src[w2] / 11) * 1;
00177 src++;
00178 }
00179 src -= w;
00180 ++i2;
00181 i1 += 2;
00182
00183
00184
00185
00186 while ((i1 < (h-2)) && (i2 < h2))
00187 {
00188 for (int i = 0; i < w; ++i)
00189 {
00190 *dst++ =
00191 ((src[ 0] >> 4) + (src[w4] >> 4)) * 1 +
00192 ((src[ w] >> 4) + (src[w3] >> 4)) * 4 +
00193 (src[w2] >> 4) * 6;
00194 src++;
00195 }
00196 src += w;
00197 i1 += 2;
00198 ++ i2;
00199 }
00200
00201
00202 if ((i2 < h2) && (i1 == (h-2)))
00203 {
00204 src = src_end - w4;
00205
00206 for (int i = 0; i < w; ++i)
00207 {
00208 *dst++ =
00209 (src[ 0] / 15) * 1 +
00210 (src[ w] / 15 + src[w3] / 15) * 4 +
00211 (src[w2] / 15) * 6;
00212 src++;
00213 }
00214 i1 += 2;
00215 ++i2;
00216 }
00217
00218
00219 if ((i2 < h2) && (i1 == (h-1)))
00220 {
00221 src = src_end - w3;
00222
00223 for (int i = 0; i < w; ++i)
00224 {
00225 *dst++ =
00226 (src[ 0] / 11) * 1 +
00227 (src[ w] / 11) * 4 +
00228 (src[w2] / 11) * 6;
00229 src++;
00230 }
00231 }
00232 }
00233 }
00234
00235
00236 void c_intg_low_pass_5_x_dec_x_fewbits(const int* src,
00237 const int w, const int h,
00238 int* dst,
00239 const int w2)
00240 {
00241 if (w == 2)
00242 for (int j = 0; j < h; ++j)
00243 {
00244
00245 *dst++ =
00246 (src[0] * 6 +
00247 src[1] * 4
00248 ) / 10;
00249
00250 src += 2;
00251 }
00252 else if (w == 3)
00253 for (int j = 0; j < h; ++j)
00254 {
00255
00256
00257 *dst++ =
00258 (src[0] * 6 +
00259 src[1] * 4 +
00260 src[2] * 1
00261 ) / 11;
00262
00263 src += 3;
00264 }
00265 else
00266
00267
00268
00269
00270 for (int j = 0; j < h; ++j)
00271 {
00272 int i1 = 0, i2 = 0;
00273 const int* src2 = src;
00274
00275
00276 *dst++ =
00277 (src2[0] * 6 +
00278 src2[1] * 4 +
00279 src2[2] * 1
00280 ) / 11;
00281 ++i2;
00282 i1 += 2;
00283
00284
00285
00286
00287 while ((i1 < (w-2)) && (i2 < w2))
00288 {
00289 *dst++ =
00290 ((src2[0] + src2[4]) * 1 +
00291 (src2[1] + src2[3]) * 4 +
00292 src2[2] * 6
00293 ) >> 4;
00294 i1 += 2; src2 += 2;
00295 ++i2;
00296 }
00297
00298
00299 if ((i2 < w2) && (i1 == (w-2)))
00300 {
00301 src2 = src + w - 4;
00302
00303 *dst++ =
00304 (src2[0] * 1 +
00305 (src2[1] + src2[3]) * 4 +
00306 src2[2] * 6
00307 ) / 15;
00308 i1 += 2;
00309 ++i2;
00310 }
00311
00312
00313 if ((i2 < w2) && (i1 == (w-1)))
00314 {
00315 src2 = src + w - 3;
00316
00317 *dst++ =
00318 (src2[0] * 1 +
00319 src2[1] * 4 +
00320 src2[2] * 6
00321 ) / 11;
00322 ++i2;
00323 }
00324 src += w;
00325 }
00326 }
00327
00328
00329 void c_intg_low_pass_5_y_dec_y_fewbits(const int* src,
00330 const int w, const int h,
00331 int* dst,
00332 const int h2)
00333 {
00334 const int* const src_end = src + w*h;
00335
00336
00337 const int w2 = w * 2, w3 = w * 3, w4 = w * 4;
00338
00339 if (h == 2)
00340 {
00341
00342 for (int i = 0; i < w; ++i)
00343 {
00344 *dst++ =
00345 (src[0] * 6 +
00346 src[w] * 4
00347 ) / 10;
00348 src++;
00349 }
00350 src -= w;
00351 }
00352 else if (h == 3)
00353 {
00354
00355 for (int i = 0; i < w; ++i)
00356 {
00357 *dst++ =
00358 (src[ 0] * 6 +
00359 src[ w] * 4 +
00360 src[w2] * 1
00361 ) / 11;
00362 src++;
00363 }
00364 src -= w;
00365 }
00366 else
00367 {
00368 int i1 = 0, i2 = 0;
00369
00370
00371 for (int i = 0; i < w; ++i)
00372 {
00373 *dst++ =
00374 (src[ 0] * 6 +
00375 src[ w] * 4 +
00376 src[w2] * 1
00377 ) / 11;
00378 src++;
00379 }
00380 src -= w;
00381 ++i2;
00382 i1 += 2;
00383
00384
00385
00386
00387 while ((i1 < (h-2)) && (i2 < h2))
00388 {
00389 for (int i = 0; i < w; ++i)
00390 {
00391 *dst++ =
00392 ((src[ 0] + src[w4]) * 1 +
00393 (src[ w] + src[w3]) * 4 +
00394 src[w2] * 6
00395 ) >> 4;
00396 src++;
00397 }
00398 src += w;
00399 i1 += 2;
00400 ++ i2;
00401 }
00402
00403
00404 if ((i2 < h2) && (i1 == (h-2)))
00405 {
00406 src = src_end - w4;
00407
00408 for (int i = 0; i < w; ++i)
00409 {
00410 *dst++ =
00411 (src[ 0] * 1 +
00412 (src[ w] + src[w3]) * 4 +
00413 src[w2] * 6
00414 ) / 15;
00415 src++;
00416 }
00417 i1 += 2;
00418 ++i2;
00419 }
00420
00421
00422 if ((i2 < h2) && (i1 == (h-1)))
00423 {
00424 src = src_end - w3;
00425
00426 for (int i = 0; i < w; ++i)
00427 {
00428 *dst++ =
00429 (src[ 0] * 1 +
00430 src[ w] * 4 +
00431 src[w2] * 6
00432 ) / 11;
00433 src++;
00434 }
00435 }
00436 }
00437 }
00438
00439 #define LP5_APPROX_LEVEL 0
00440
00441 #if LP5_APPROX_LEVEL == 0
00442
00443 # define LP5_APPROX_2_3 2
00444 # define LP5_APPROX_1_3 1
00445 # define LP5_DIV_3 / 3
00446
00447 #elif LP5_APPROX_LEVEL == 1
00448
00449 # define LP5_APPROX_2_3 1
00450 # define LP5_APPROX_1_3 1
00451 # define LP5_DIV_3 / 2
00452
00453 #else
00454 #error bogus LP5_APPROX_LEVEL (must be 0 or 1)
00455 #endif
00456
00457
00458 void c_intg_low_pass_5_x_dec_x_fewbits_optim(const int* src,
00459 const int w, const int h,
00460 int* dst,
00461 const int w2)
00462 {
00463 ASSERT(w2 == w/2);
00464
00465 if (w == 2)
00466 for (int j = 0; j < h; ++j)
00467 {
00468
00469 *dst++ =
00470 (src[0] * 3 +
00471 src[1] * 2
00472 ) / 5;
00473
00474 src += 2;
00475 }
00476 else if (w == 3)
00477 for (int j = 0; j < h; ++j)
00478 {
00479
00480
00481 *dst++ =
00482 (src[0] * 6 +
00483 src[1] * 4 +
00484 src[2] * 1
00485 ) / 11;
00486
00487 src += 3;
00488 }
00489 else
00490
00491
00492
00493
00494 for (int j = 0; j < h; ++j)
00495 {
00496 const int* src2 = src;
00497
00498
00499 *dst++ =
00500 (src2[0] * LP5_APPROX_2_3 +
00501 src2[1] * LP5_APPROX_1_3
00502 ) LP5_DIV_3;
00503
00504
00505
00506
00507 for (int i = 0; i < w-3; i += 2)
00508 {
00509 *dst++ =
00510 ((src2[1] + src2[3]) +
00511 src2[2] * 2
00512 ) >> 2;
00513 src2 += 2;
00514 }
00515
00516 src += w;
00517 }
00518 }
00519
00520
00521 void c_intg_low_pass_5_y_dec_y_fewbits_optim(const int* src,
00522 const int w, const int h,
00523 int* dst,
00524 const int h2)
00525 {
00526 ASSERT(h2 == h/2);
00527
00528
00529 const int w2 = w * 2, w3 = w * 3;
00530
00531 if (h == 2)
00532 {
00533
00534 for (int i = 0; i < w; ++i)
00535 {
00536 *dst++ =
00537 (src[0] * 3 +
00538 src[w] * 2
00539 ) / 5;
00540 src++;
00541 }
00542 src -= w;
00543 }
00544 else if (h == 3)
00545 {
00546
00547 for (int i = 0; i < w; ++i)
00548 {
00549 *dst++ =
00550 (src[ 0] * 6 +
00551 src[ w] * 4 +
00552 src[w2] * 1
00553 ) / 11;
00554 src++;
00555 }
00556 src -= w;
00557 }
00558 else
00559 {
00560
00561 for (int k = 0; k < w; ++k)
00562 {
00563 *dst++ =
00564 (src[ 0] * LP5_APPROX_2_3 +
00565 src[ w] * LP5_APPROX_1_3
00566 ) LP5_DIV_3;
00567 src++;
00568 }
00569 src -= w;
00570
00571
00572
00573
00574 for (int i = 0; i < h-3; i += 2)
00575 {
00576 for (int k = 0; k < w; ++k)
00577 {
00578 *dst++ =
00579 ((src[ w] + src[w3]) +
00580 src[w2] * 2
00581 ) >> 2;
00582 src++;
00583 }
00584 src += w;
00585 }
00586 }
00587 }
00588
00589
00590 void c_intg_low_pass_9_x_manybits(const int* src,
00591 const int w, const int h,
00592 int* dst)
00593 {
00594 ASSERT(w >= 9);
00595
00596
00597 for (int j = 0; j < h; ++j)
00598 {
00599
00600 *dst++ =
00601 (src[0] / 163) * 70 +
00602 (src[1] / 163) * 56 +
00603 (src[2] / 163) * 28 +
00604 (src[3] / 163) * 8 +
00605 (src[4] / 163) * 1;
00606 *dst++ =
00607 (src[0] / 219 + src[2] / 219) * 56 +
00608 (src[1] / 219) * 70 +
00609 (src[3] / 219) * 28 +
00610 (src[4] / 219) * 8 +
00611 (src[5] / 219) * 1;
00612 *dst++ =
00613 (src[0] / 247 + src[4] / 247) * 28 +
00614 (src[1] / 247 + src[3] / 247) * 56 +
00615 (src[2] / 247) * 70 +
00616 (src[5] / 247) * 8 +
00617 (src[6] / 247) * 1;
00618 *dst++ =
00619 (src[0] / 255 + src[6] / 255) * 8 +
00620 (src[1] / 255 + src[5] / 255) * 28 +
00621 (src[2] / 255 + src[4] / 255) * 56 +
00622 (src[3] / 255) * 70 +
00623 (src[7] / 255) * 1;
00624
00625
00626 for (int i = 0; i < w - 8; ++i)
00627 {
00628 *dst++ =
00629 ((src[0] >> 8) + (src[8] >> 8)) * 1 +
00630 ((src[1] >> 8) + (src[7] >> 8)) * 8 +
00631 ((src[2] >> 8) + (src[6] >> 8)) * 28 +
00632 ((src[3] >> 8) + (src[5] >> 8)) * 56 +
00633 (src[4] >> 8) * 70;
00634 ++src;
00635 }
00636
00637
00638 *dst++ =
00639 (src[0] / 255) * 1 +
00640 (src[1] / 255 + src[7] / 255) * 8 +
00641 (src[2] / 255 + src[6] / 255) * 28 +
00642 (src[3] / 255 + src[5] / 255) * 56 +
00643 (src[4] / 255) * 70;
00644 ++src;
00645 *dst++ =
00646 (src[0] / 247) * 1 +
00647 (src[1] / 247) * 8 +
00648 (src[2] / 247 + src[6] / 247) * 28 +
00649 (src[3] / 247 + src[5] / 247) * 56 +
00650 (src[4] / 247) * 70;
00651 ++src;
00652 *dst++ =
00653 (src[0] / 219) * 1 +
00654 (src[1] / 219) * 8 +
00655 (src[2] / 219) * 28 +
00656 (src[3] / 219 + src[5] / 219) * 56 +
00657 (src[4] / 219) * 70;
00658 ++src;
00659 *dst++ =
00660 (src[0] / 163) * 1 +
00661 (src[1] / 163) * 8 +
00662 (src[2] / 163) * 28 +
00663 (src[3] / 163) * 56 +
00664 (src[4] / 163) * 70;
00665 src += 5;
00666 }
00667 }
00668
00669
00670 void c_intg_low_pass_9_y_manybits(const int* src,
00671 const int w, const int h,
00672 int* dst)
00673 {
00674 ASSERT(h >= 9);
00675
00676
00677 const int w2 = w + w, w3 = w2 + w, w4 = w3 + w, w5 = w4 + w, w6 = w5 + w,
00678 w7 = w6 + w, w8 = w7 + w;
00679 for (int i = 0; i < w; ++i)
00680 {
00681 *dst++ =
00682 (src[ 0] / 163) * 70 +
00683 (src[ w] / 163) * 56 +
00684 (src[w2] / 163) * 28 +
00685 (src[w3] / 163) * 8 +
00686 (src[w4] / 163) * 1;
00687 ++src;
00688 }
00689 src -= w;
00690 for (int i = 0; i < w; ++i)
00691 {
00692 *dst++ =
00693 (src[ 0] / 219 + src[w2] / 219) * 56 +
00694 (src[ w] / 219) * 70 +
00695 (src[w3] / 219) * 28 +
00696 (src[w4] / 219) * 8 +
00697 (src[w5] / 219) * 1;
00698 ++src;
00699 }
00700 src -= w;
00701 for (int i = 0; i < w; ++i)
00702 {
00703 *dst++ =
00704 (src[ 0] / 247 + src[w4] / 247) * 28 +
00705 (src[ w] / 247 + src[w3] / 247) * 56 +
00706 (src[w2] / 247) * 70 +
00707 (src[w5] / 247) * 8 +
00708 (src[w6] / 247) * 1;
00709 ++src;
00710 }
00711 src -= w;
00712 for (int i = 0; i < w; ++i)
00713 {
00714 *dst++ =
00715 (src[ 0] / 255 + src[w6] / 255) * 8 +
00716 (src[ w] / 255 + src[w5] / 255) * 28 +
00717 (src[w2] / 255 + src[w4] / 255) * 56 +
00718 (src[w3] / 255) * 70 +
00719 (src[w7] / 255) * 1;
00720 ++src;
00721 }
00722 src -= w;
00723 for (int j = 0; j < h - 8; j ++)
00724 for (int i = 0; i < w; ++i)
00725 {
00726 *dst++ =
00727 ((src[ 0] >> 8) + (src[w8] >> 8)) * 1 +
00728 ((src[ w] >> 8) + (src[w7] >> 8)) * 8 +
00729 ((src[w2] >> 8) + (src[w6] >> 8)) * 28 +
00730 ((src[w3] >> 8) + (src[w5] >> 8)) * 56 +
00731 (src[w4] >> 8) * 70;
00732 ++src;
00733 }
00734 for (int i = 0; i < w; ++i)
00735 {
00736 *dst++ =
00737 (src[ 0] / 255) * 1 +
00738 (src[ w] / 255 + src[w7] / 255) * 8 +
00739 (src[w2] / 255 + src[w6] / 255) * 28 +
00740 (src[w3] / 255 + src[w5] / 255) * 56 +
00741 (src[w4] / 255) * 70;
00742 ++src;
00743 }
00744 for (int i = 0; i < w; ++i)
00745 {
00746 *dst++ =
00747 (src[ 0] / 247) * 1 +
00748 (src[ w] / 247) * 8 +
00749 (src[w2] / 247 + src[w6] / 247) * 28 +
00750 (src[w3] / 247 + src[w5] / 247) * 56 +
00751 (src[w4] / 247) * 70;
00752 ++src;
00753 }
00754 for (int i = 0; i < w; ++i)
00755 {
00756 *dst++ =
00757 (src[ 0] / 219) * 1 +
00758 (src[ w] / 219) * 8 +
00759 (src[w2] / 219) * 28 +
00760 (src[w3] / 219 + src[w5] / 219) * 56 +
00761 (src[w4] / 219) * 70;
00762 ++src;
00763 }
00764 for (int i = 0; i < w; ++i)
00765 {
00766 *dst++ =
00767 (src[ 0] / 163) * 1 +
00768 (src[ w] / 163) * 8 +
00769 (src[w2] / 163) * 28 +
00770 (src[w3] / 163) * 56 +
00771 (src[w4] / 163) * 70;
00772 ++src;
00773 }
00774 }
00775
00776
00777 void c_intg_low_pass_9_x_fewbits(const int* src,
00778 const int w, const int h,
00779 int* dst)
00780 {
00781 ASSERT(w >= 9);
00782
00783
00784 for (int j = 0; j < h; ++j)
00785 {
00786
00787 *dst++ =
00788 (src[0] * 70 +
00789 src[1] * 56 +
00790 src[2] * 28 +
00791 src[3] * 8 +
00792 src[4] * 1
00793 ) / 163;
00794 *dst++ =
00795 ((src[0] + src[2]) * 56 +
00796 src[1] * 70 +
00797 src[3] * 28 +
00798 src[4] * 8 +
00799 src[5] * 1
00800 ) / 219;
00801 *dst++ =
00802 ((src[0] + src[4]) * 28 +
00803 (src[1] + src[3]) * 56 +
00804 src[2] * 70 +
00805 src[5] * 8 +
00806 src[6] * 1
00807 ) / 247;
00808 *dst++ =
00809 ((src[0] + src[6]) * 8 +
00810 (src[1] + src[5]) * 28 +
00811 (src[2] + src[4]) * 56 +
00812 src[3] * 70 +
00813 src[7] * 1
00814 ) / 255;
00815
00816
00817 for (int i = 0; i < w - 8; ++i)
00818 {
00819 *dst++ =
00820 ((src[0] + src[8]) * 1 +
00821 (src[1] + src[7]) * 8 +
00822 (src[2] + src[6]) * 28 +
00823 (src[3] + src[5]) * 56 +
00824 src[4] * 70
00825 ) >> 8;
00826 ++src;
00827 }
00828
00829
00830 *dst++ =
00831 (src[0] * 1 +
00832 (src[1] + src[7]) * 8 +
00833 (src[2] + src[6]) * 28 +
00834 (src[3] + src[5]) * 56 +
00835 src[4] * 70
00836 ) / 255;
00837 ++src;
00838 *dst++ =
00839 (src[0] * 1 +
00840 src[1] * 8 +
00841 (src[2] + src[6]) * 28 +
00842 (src[3] + src[5]) * 56 +
00843 src[4] * 70
00844 ) / 247;
00845 ++src;
00846 *dst++ =
00847 (src[0] * 1 +
00848 src[1] * 8 +
00849 src[2] * 28 +
00850 (src[3] + src[5]) * 56 +
00851 src[4] * 70
00852 ) / 219;
00853 ++src;
00854 *dst++ =
00855 (src[0] * 1 +
00856 src[1] * 8 +
00857 src[2] * 28 +
00858 src[3] * 56 +
00859 src[4] * 70
00860 ) / 163;
00861 src += 5;
00862 }
00863 }
00864
00865
00866 void c_intg_low_pass_9_y_fewbits(const int* src,
00867 const int w, const int h,
00868 int* dst)
00869 {
00870 ASSERT(h >= 9);
00871
00872
00873 const int w2 = w + w, w3 = w2 + w, w4 = w3 + w, w5 = w4 + w, w6 = w5 + w,
00874 w7 = w6 + w, w8 = w7 + w;
00875 for (int i = 0; i < w; ++i)
00876 {
00877 *dst++ =
00878 (src[ 0] * 70 +
00879 src[ w] * 56 +
00880 src[w2] * 28 +
00881 src[w3] * 8 +
00882 src[w4] * 1
00883 ) / 163;
00884 ++src;
00885 }
00886 src -= w;
00887 for (int i = 0; i < w; ++i)
00888 {
00889 *dst++ =
00890 ((src[ 0] + src[w2]) * 56 +
00891 src[ w] * 70 +
00892 src[w3] * 28 +
00893 src[w4] * 8 +
00894 src[w5] * 1
00895 ) / 219;
00896 ++src;
00897 }
00898 src -= w;
00899 for (int i = 0; i < w; ++i)
00900 {
00901 *dst++ =
00902 ((src[ 0] + src[w4]) * 28 +
00903 (src[ w] + src[w3]) * 56 +
00904 src[w2] * 70 +
00905 src[w5] * 8 +
00906 src[w6] * 1
00907 ) / 247;
00908 ++src;
00909 }
00910 src -= w;
00911 for (int i = 0; i < w; ++i)
00912 {
00913 *dst++ =
00914 ((src[ 0] + src[w6]) * 8 +
00915 (src[ w] + src[w5]) * 28 +
00916 (src[w2] + src[w4]) * 56 +
00917 src[w3] * 70 +
00918 src[w7] * 1
00919 ) / 255;
00920 ++src;
00921 }
00922 src -= w;
00923 for (int j = 0; j < h - 8; j ++)
00924 for (int i = 0; i < w; ++i)
00925 {
00926 *dst++ =
00927 ((src[ 0] + src[w8]) * 1 +
00928 (src[ w] + src[w7]) * 8 +
00929 (src[w2] + src[w6]) * 28 +
00930 (src[w3] + src[w5]) * 56 +
00931 src[w4] * 70
00932 ) >> 8;
00933 ++src;
00934 }
00935 for (int i = 0; i < w; ++i)
00936 {
00937 *dst++ =
00938 (src[ 0] * 1 +
00939 (src[ w] + src[w7]) * 8 +
00940 (src[w2] + src[w6]) * 28 +
00941 (src[w3] + src[w5]) * 56 +
00942 src[w4] * 70
00943 ) / 255;
00944 ++src;
00945 }
00946 for (int i = 0; i < w; ++i)
00947 {
00948 *dst++ =
00949 (src[ 0] * 1 +
00950 src[ w] * 8 +
00951 (src[w2] + src[w6]) * 28 +
00952 (src[w3] + src[w5]) * 56 +
00953 src[w4] * 70
00954 ) / 247;
00955 ++src;
00956 }
00957 for (int i = 0; i < w; ++i)
00958 {
00959 *dst++ =
00960 (src[ 0] * 1 +
00961 src[ w] * 8 +
00962 src[w2] * 28 +
00963 (src[w3] + src[w5]) * 56 +
00964 src[w4] * 70
00965 ) / 219;
00966 ++src;
00967 }
00968 for (int i = 0; i < w; ++i)
00969 {
00970 *dst++ =
00971 (src[ 0] * 1 +
00972 src[ w] * 8 +
00973 src[w2] * 28 +
00974 src[w3] * 56 +
00975 src[w4] * 70
00976 ) / 163;
00977 ++src;
00978 }
00979 }
00980
00981 #define LP9_APPROX_LEVEL 0
00982
00983 #if LP9_APPROX_LEVEL == 0
00984
00985 # define LP9_APPROX_72_164 72
00986 # define LP9_APPROX_56_164 56
00987 # define LP9_APPROX_28_164 28
00988 # define LP9_APPROX_8_164 8
00989 # define LP9_DIV_164 / 164
00990
00991 # define LP9_APPROX_72_220 72
00992 # define LP9_APPROX_56_220 56
00993 # define LP9_APPROX_28_220 28
00994 # define LP9_APPROX_8_220 8
00995 # define LP9_DIV_220 / 220
00996
00997 # define LP9_APPROX_72_248 72
00998 # define LP9_APPROX_56_248 56
00999 # define LP9_APPROX_28_248 28
01000 # define LP9_APPROX_8_248 8
01001 # define LP9_DIV_248 / 248
01002
01003 #elif LP9_APPROX_LEVEL == 1
01004
01005 # define LP9_APPROX_72_164 28
01006 # define LP9_APPROX_56_164 22
01007 # define LP9_APPROX_28_164 11
01008 # define LP9_APPROX_8_164 3
01009 # define LP9_DIV_164 >> 6
01010
01011 # define LP9_APPROX_72_220 22
01012 # define LP9_APPROX_56_220 16
01013 # define LP9_APPROX_28_220 8
01014 # define LP9_APPROX_8_220 2
01015 # define LP9_DIV_220 >> 6
01016
01017 # define LP9_APPROX_72_248 20
01018 # define LP9_APPROX_56_248 14
01019 # define LP9_APPROX_28_248 7
01020 # define LP9_APPROX_8_248 2
01021 # define LP9_DIV_248 >> 6
01022
01023 #elif LP9_APPROX_LEVEL == 2
01024
01025 # define LP9_APPROX_72_164 8
01026 # define LP9_APPROX_56_164 (4+1)
01027 # define LP9_APPROX_28_164 2
01028 # define LP9_APPROX_8_164 1
01029 # define LP9_DIV_164 >> 4
01030
01031 # define LP9_APPROX_72_220 (4+1)
01032 # define LP9_APPROX_56_220 4
01033 # define LP9_APPROX_28_220 2
01034 # define LP9_APPROX_8_220 1
01035 # define LP9_DIV_220 >> 4
01036
01037 # define LP9_APPROX_72_248 (4+1)
01038 # define LP9_APPROX_56_248 3
01039 # define LP9_APPROX_28_248 2
01040 # define LP9_APPROX_8_248 1
01041 # define LP9_DIV_248 >> 4
01042
01043 #elif LP9_APPROX_LEVEL == 3
01044
01045 # define LP9_APPROX_72_164 0
01046 # define LP9_APPROX_56_164 0
01047 # define LP9_APPROX_28_164 0
01048 # define LP9_APPROX_8_164 0
01049 # define LP9_DIV_164
01050
01051 # define LP9_APPROX_72_220 0
01052 # define LP9_APPROX_56_220 0
01053 # define LP9_APPROX_28_220 0
01054 # define LP9_APPROX_8_220 0
01055 # define LP9_DIV_220
01056
01057 # define LP9_APPROX_72_248 0
01058 # define LP9_APPROX_56_248 0
01059 # define LP9_APPROX_28_248 0
01060 # define LP9_APPROX_8_248 0
01061 # define LP9_DIV_248
01062
01063 # define LP9_APPROX_SHIFTR 0
01064
01065 #else
01066 #error bogus LP9_APPROX_LEVEL (must be 0, 1, 2, or 3)
01067 #endif
01068
01069
01070 void c_intg_low_pass_9_x_fewbits_optim(const int* src,
01071 const int w, const int h,
01072 int* dst)
01073 {
01074 ASSERT(w >= 9);
01075
01076
01077 for (int j = 0; j < h; ++j)
01078 {
01079
01080 *dst++ =
01081 (src[0] * LP9_APPROX_72_164 +
01082 src[1] * LP9_APPROX_56_164 +
01083 src[2] * LP9_APPROX_28_164 +
01084 src[3] * LP9_APPROX_8_164
01085 ) LP9_DIV_164;
01086 *dst++ =
01087 ((src[0] + src[2]) * LP9_APPROX_56_220 +
01088 src[1] * LP9_APPROX_72_220 +
01089 src[3] * LP9_APPROX_28_220 +
01090 src[4] * LP9_APPROX_8_220
01091 ) LP9_DIV_220;
01092 *dst++ =
01093 ((src[0] + src[4]) * LP9_APPROX_28_248 +
01094 (src[1] + src[3]) * LP9_APPROX_56_248 +
01095 src[2] * LP9_APPROX_72_248 +
01096 src[5] * LP9_APPROX_8_248
01097 ) LP9_DIV_248;
01098
01099
01100 for (int i = 0; i < w - 6; ++i)
01101 {
01102 *dst++ =
01103 ((src[0] + src[6]) * 8 +
01104 (src[1] + src[5]) * 28 +
01105 (src[2] + src[4]) * 56 +
01106 src[3] * 72
01107 ) >> 8;
01108 ++src;
01109 }
01110
01111
01112 *dst++ =
01113 (src[0] * LP9_APPROX_8_248 +
01114 (src[1] + src[5]) * LP9_APPROX_28_248 +
01115 (src[2] + src[4]) * LP9_APPROX_56_248 +
01116 src[3] * LP9_APPROX_72_248
01117 ) LP9_DIV_248;
01118 ++src;
01119 *dst++ =
01120 (src[0] * LP9_APPROX_8_220 +
01121 src[1] * LP9_APPROX_28_220 +
01122 (src[2] + src[4]) * LP9_APPROX_56_220 +
01123 src[3] * LP9_APPROX_72_220
01124 ) LP9_DIV_220;
01125 ++src;
01126 *dst++ =
01127 (src[0] * LP9_APPROX_8_164 +
01128 src[1] * LP9_APPROX_28_164 +
01129 src[2] * LP9_APPROX_56_164 +
01130 src[3] * LP9_APPROX_72_164
01131 ) LP9_DIV_164;
01132 src += 4;
01133 }
01134 }
01135
01136
01137 void c_intg_low_pass_9_y_fewbits_optim(const int* src,
01138 const int w, const int h,
01139 int* dst)
01140 {
01141 ASSERT(h >= 9);
01142
01143
01144 const int w2 = w + w, w3 = w2 + w, w4 = w3 + w, w5 = w4 + w, w6 = w5 + w;
01145
01146
01147 for (int i = 0; i < w; ++i)
01148 {
01149 *dst++ =
01150 (src[ 0] * LP9_APPROX_72_164 +
01151 src[ w] * LP9_APPROX_56_164 +
01152 src[w2] * LP9_APPROX_28_164 +
01153 src[w3] * LP9_APPROX_8_164
01154 ) LP9_DIV_164;
01155 ++src;
01156 }
01157 src -= w;
01158 for (int i = 0; i < w; ++i)
01159 {
01160 *dst++ =
01161 ((src[ 0] + src[w2]) * LP9_APPROX_56_220 +
01162 src[ w] * LP9_APPROX_72_220 +
01163 src[w3] * LP9_APPROX_28_220 +
01164 src[w4] * LP9_APPROX_8_220
01165 ) LP9_DIV_220;
01166 ++src;
01167 }
01168 src -= w;
01169 for (int i = 0; i < w; ++i)
01170 {
01171 *dst++ =
01172 ((src[ 0] + src[w4]) * LP9_APPROX_28_248 +
01173 (src[ w] + src[w3]) * LP9_APPROX_56_248 +
01174 src[w2] * LP9_APPROX_72_248 +
01175 src[w5] * LP9_APPROX_8_248
01176 ) LP9_DIV_248;
01177 ++src;
01178 }
01179 src -= w;
01180
01181 for (int j = 0; j < h - 6; j ++)
01182 for (int i = 0; i < w; ++i)
01183 {
01184 *dst++ =
01185 ((src[ 0] + src[w6]) * 8 +
01186 (src[ w] + src[w5]) * 28 +
01187 (src[w2] + src[w4]) * 56 +
01188 src[w3] * 72
01189 ) >> 8;
01190 ++src;
01191 }
01192
01193 for (int i = 0; i < w; ++i)
01194 {
01195 *dst++ =
01196 (src[ 0] * LP9_APPROX_8_248 +
01197 (src[ w] + src[w5]) * LP9_APPROX_28_248 +
01198 (src[w2] + src[w4]) * LP9_APPROX_56_248 +
01199 src[w3] * LP9_APPROX_72_248
01200 ) LP9_DIV_248;
01201 ++src;
01202 }
01203 for (int i = 0; i < w; ++i)
01204 {
01205 *dst++ =
01206 (src[ 0] * LP9_APPROX_8_220 +
01207 src[ w] * LP9_APPROX_28_220 +
01208 (src[w2] + src[w4]) * LP9_APPROX_56_220 +
01209 src[w3] * LP9_APPROX_72_220
01210 ) LP9_DIV_220;
01211 ++src;
01212 }
01213 for (int i = 0; i < w; ++i)
01214 {
01215 *dst++ =
01216 (src[ 0] * LP9_APPROX_8_164 +
01217 src[ w] * LP9_APPROX_28_164 +
01218 src[w2] * LP9_APPROX_56_164 +
01219 src[w3] * LP9_APPROX_72_164
01220 ) LP9_DIV_164;
01221 ++src;
01222 }
01223 }
01224
01225
01226 void c_intg_x_filter_clean_manybits(const int* src,
01227 const int w, const int h,
01228 const int* hf_flipped, const int hfs,
01229 const int shiftbits,
01230 int* dst)
01231 {
01232 ASSERT(w >= hfs);
01233 ASSERT(hfs > 0);
01234
01235 ASSERT(hfs & 1);
01236 const int hfs2 = (hfs - 1) / 2;
01237
01238 for (int jj = 0; jj < h; ++jj)
01239 {
01240
01241 for (int j = hfs2; j < hfs - 1; ++j)
01242 {
01243 const int fp = hfs - 1 - j;
01244 int sum = 0;
01245 for (int k = 0; k <= j; k ++)
01246 sum += hf_flipped[fp + k];
01247
01248 int val = 0;
01249 for (int k = 0; k <= j; k ++)
01250 val += (src[k] / sum) * hf_flipped[fp + k];
01251
01252 *dst++ = val;
01253 }
01254
01255
01256 for (int i = 0; i < w - hfs + 1; ++i)
01257 {
01258 int val = 0;
01259 for (int k = 0; k < hfs; k ++)
01260 val += (src[k] >> shiftbits) * hf_flipped[k];
01261 *dst++ = val;
01262 src++;
01263 }
01264
01265
01266 for (int j = hfs - 2; j >= hfs2; j --)
01267 {
01268 int sum = 0;
01269 for (int k = 0; k <= j; k ++)
01270 sum += hf_flipped[k];
01271
01272 int val = 0;
01273 for (int k = 0; k <= j; k ++)
01274 val += (src[k] / sum) * hf_flipped[k];
01275
01276 *dst++ = val;
01277 src++;
01278 }
01279 src += hfs2;
01280 }
01281 }
01282
01283
01284 void c_intg_x_filter_clean_fewbits(const int* src,
01285 const int w, const int h,
01286 const int* hf_flipped, const int hfs,
01287 const int shiftbits,
01288 int* dst)
01289 {
01290 ASSERT(w >= hfs);
01291 ASSERT(hfs > 0);
01292
01293 ASSERT(hfs & 1);
01294 const int hfs2 = (hfs - 1) / 2;
01295
01296 for (int jj = 0; jj < h; ++jj)
01297 {
01298
01299 for (int j = hfs2; j < hfs - 1; ++j)
01300 {
01301 const int fp = hfs - 1 - j;
01302 int sum = 0;
01303 int val = 0;
01304 for (int k = 0; k <= j; k ++)
01305 {
01306 val += src[k] * hf_flipped[fp + k];
01307 sum += hf_flipped[fp + k];
01308 }
01309
01310 *dst++ = val / sum;
01311 }
01312
01313
01314 for (int i = 0; i < w - hfs + 1; ++i)
01315 {
01316 int val = 0;
01317 for (int k = 0; k < hfs; k ++)
01318 val += src[k] * hf_flipped[k];
01319 *dst++ = (val >> shiftbits);
01320 src++;
01321 }
01322
01323
01324 for (int j = hfs - 2; j >= hfs2; j --)
01325 {
01326 int sum = 0;
01327 int val = 0;
01328 for (int k = 0; k <= j; k ++)
01329 {
01330 val += src[k] * hf_flipped[k];
01331 sum += hf_flipped[k];
01332 }
01333
01334 *dst++ = val / sum;
01335 src++;
01336 }
01337 src += hfs2;
01338 }
01339 }
01340
01341
01342 void c_intg_x_filter_clean_small_manybits(const int* src,
01343 const int w, const int h,
01344 const int* hf_flipped, const int hfs,
01345 const int shiftbits,
01346 int* dst)
01347 {
01348 ASSERT(w < hfs);
01349 ASSERT(hfs > 0);
01350
01351 ASSERT(hfs & 1);
01352 const int hfs2 = (hfs - 1) / 2;
01353
01354 for (int j = 0; j < h; ++j)
01355 for (int i = 0; i < w; ++i)
01356 {
01357 int sum = 0;
01358 for (int k = 0; k < hfs; k ++)
01359 if (i + k - hfs2 >= 0 && i + k - hfs2 < w)
01360 sum += hf_flipped[k];
01361
01362 int val = 0;
01363 for (int k = 0; k < hfs; k ++)
01364 if (i + k - hfs2 >= 0 && i + k - hfs2 < w)
01365 val += (src[k - hfs2] / sum) * hf_flipped[k];
01366
01367 *dst++ = val;
01368 src ++;
01369 }
01370 }
01371
01372
01373 void c_intg_x_filter_clean_small_fewbits(const int* src,
01374 const int w, const int h,
01375 const int* hf_flipped, const int hfs,
01376 const int shiftbits,
01377 int* dst)
01378 {
01379 ASSERT(w < hfs);
01380 ASSERT(hfs > 0);
01381
01382 ASSERT(hfs & 1);
01383 const int hfs2 = (hfs - 1) / 2;
01384
01385 for (int j = 0; j < h; ++j)
01386 for (int i = 0; i < w; ++i)
01387 {
01388 int sum = 0;
01389 int val = 0;
01390 for (int k = 0; k < hfs; k ++)
01391 if (i + k - hfs2 >= 0 && i + k - hfs2 < w)
01392 {
01393 val += src[k - hfs2] * hf_flipped[k];
01394 sum += hf_flipped[k];
01395 }
01396
01397 *dst++ = val / sum;
01398 src ++;
01399 }
01400 }
01401
01402
01403 void c_intg_y_filter_clean_manybits(const int* src,
01404 const int w, const int h,
01405 const int* vf_flipped, const int vfs,
01406 const int shiftbits,
01407 int* dst)
01408 {
01409 ASSERT(h >= vfs);
01410 ASSERT(vfs > 0);
01411
01412 ASSERT(vfs & 1);
01413 const int vfs2 = (vfs - 1) / 2;
01414
01415 int ww[vfs];
01416 for (int x = 0; x < vfs; x ++)
01417 ww[x] = w * x;
01418
01419
01420 for (int j = vfs2; j < vfs - 1; ++j)
01421 {
01422 int fp = vfs - 1 - j;
01423 for (int i = 0; i < w; ++i)
01424 {
01425 int sum = 0;
01426 for (int k = 0; k <= j; k ++)
01427 sum += vf_flipped[fp + k];
01428
01429 int val = 0;
01430 for (int k = 0; k <= j; k ++)
01431 val += (src[ww[k]] / sum) * vf_flipped[fp + k];
01432
01433 *dst++ = val;
01434 src++;
01435 }
01436 src -= w;
01437 }
01438
01439
01440 for (int j = 0; j < h - vfs + 1; ++j)
01441 for (int i = 0; i < w; ++i)
01442 {
01443 int val = 0;
01444 for (int k = 0; k < vfs; k ++)
01445 val += (src[ww[k]] >> shiftbits) * vf_flipped[k];
01446 *dst++ = val;
01447 src++;
01448 }
01449
01450
01451 for (int j = vfs - 2; j >= vfs2; j --)
01452 for (int i = 0; i < w; ++i)
01453 {
01454 int sum = 0;
01455 for (int k = 0; k <= j; k ++)
01456 sum += vf_flipped[k];
01457
01458 int val = 0;
01459 for (int k = 0; k <= j; k ++)
01460 val += (src[ww[k]] / sum) * vf_flipped[k];
01461
01462 *dst++ = val;
01463 ++src;
01464 }
01465 }
01466
01467
01468 void c_intg_y_filter_clean_fewbits(const int* src,
01469 const int w, const int h,
01470 const int* vf_flipped, const int vfs,
01471 const int shiftbits,
01472 int* dst)
01473 {
01474 ASSERT(h >= vfs);
01475 ASSERT(vfs > 0);
01476
01477 ASSERT(vfs & 1);
01478 const int vfs2 = (vfs - 1) / 2;
01479
01480 int ww[vfs];
01481 for (int x = 0; x < vfs; x ++)
01482 ww[x] = w * x;
01483
01484
01485 for (int j = vfs2; j < vfs - 1; ++j)
01486 {
01487 int fp = vfs - 1 - j;
01488 for (int i = 0; i < w; ++i)
01489 {
01490 int sum = 0;
01491 int val = 0;
01492 for (int k = 0; k <= j; k ++)
01493 {
01494 val += src[ww[k]] * vf_flipped[fp + k];
01495 sum += vf_flipped[fp + k];
01496 }
01497
01498 *dst++ = val / sum;
01499 src++;
01500 }
01501 src -= w;
01502 }
01503
01504
01505 for (int j = 0; j < h - vfs + 1; ++j)
01506 for (int i = 0; i < w; ++i)
01507 {
01508 int val = 0;
01509 for (int k = 0; k < vfs; k ++)
01510 val += src[ww[k]] * vf_flipped[k];
01511 *dst++ = (val >> shiftbits);
01512 src++;
01513 }
01514
01515
01516 for (int j = vfs - 2; j >= vfs2; j --)
01517 for (int i = 0; i < w; ++i)
01518 {
01519 int sum = 0;
01520 int val = 0;
01521 for (int k = 0; k <= j; k ++)
01522 {
01523 val += src[ww[k]] * vf_flipped[k];
01524 sum += vf_flipped[k];
01525 }
01526
01527 *dst++ = val / sum;
01528 ++src;
01529 }
01530 }
01531
01532
01533 void c_intg_y_filter_clean_small_manybits(const int* src,
01534 const int w, const int h,
01535 const int* vf_flipped, const int vfs,
01536 const int shiftbits,
01537 int* dst)
01538 {
01539 ASSERT(h < vfs);
01540 ASSERT(vfs > 0);
01541
01542 ASSERT(vfs & 1);
01543 const int vfs2 = (vfs - 1) / 2;
01544
01545 for (int j = 0; j < h; ++j)
01546 for (int i = 0; i < w; ++i)
01547 {
01548 int sum = 0;
01549 for (int k = 0; k < vfs; k ++)
01550 if (j + k - vfs2 >= 0 && j + k - vfs2 < h)
01551 sum += vf_flipped[k];
01552
01553 int val = 0;
01554 for (int k = 0; k < vfs; k ++)
01555 if (j + k - vfs2 >= 0 && j + k - vfs2 < h)
01556 val += (src[w * (k - vfs2)] / sum) * vf_flipped[k];
01557
01558 *dst++ = val;
01559 ++src;
01560 }
01561 }
01562
01563
01564 void c_intg_y_filter_clean_small_fewbits(const int* src,
01565 const int w, const int h,
01566 const int* vf_flipped, const int vfs,
01567 const int shiftbits,
01568 int* dst)
01569 {
01570 ASSERT(h < vfs);
01571 ASSERT(vfs > 0);
01572
01573 ASSERT(vfs & 1);
01574 const int vfs2 = (vfs - 1) / 2;
01575
01576 for (int j = 0; j < h; ++j)
01577 for (int i = 0; i < w; ++i)
01578 {
01579 int sum = 0;
01580 int val = 0;
01581 for (int k = 0; k < vfs; k ++)
01582 if (j + k - vfs2 >= 0 && j + k - vfs2 < h)
01583 {
01584 val += src[w * (k - vfs2)] * vf_flipped[k];
01585 sum += vf_flipped[k];
01586 }
01587
01588 *dst++ = val / sum;
01589 ++src;
01590 }
01591 }
01592
01593
01594
01595
01596
01597
01598
01599
01600 #endif // IMAGE_C_INTEGER_MATH_OPS_C_DEFINED