00001
00007 #ifdef HAVE_CONFIG_H
00008 # include <config.h>
00009 #endif
00010
00011 #include "SDL_video.h"
00012 #ifndef ALPHA_LINUX_CXX
00013 # include <cstring>
00014 #endif
00015
00016 #include "exult_types.h"
00017
00018 #ifndef UNDER_CE
00019 using std::memcpy;
00020 #endif
00021
00031 template <class Source_pixel, class Dest_pixel, class Manip_pixels>
00032 inline Dest_pixel Interpolate_2xSaI (Source_pixel colorA, Source_pixel colorB, const Manip_pixels &manip)
00033 {
00034 unsigned int r0, r1, g0, g1, b0, b1;
00035 manip.split_source(colorA, r0, g0, b0);
00036 manip.split_source(colorB, r1, g1, b1);
00037 int r = (r0 + r1)>>1;
00038 int g = (g0 + g1)>>1;
00039 int b = (b0 + b1)>>1;
00040 return manip.rgb(r, g, b);
00041 }
00042
00043 template <class Source_pixel, class Dest_pixel, class Manip_pixels>
00044 inline Dest_pixel OInterpolate_2xSaI (Source_pixel colorA, Source_pixel colorB, Source_pixel colorC, const Manip_pixels &manip)
00045 {
00046 unsigned int r0, r1, g0, g1, b0, b1;
00047 unsigned int r2, g2, b2;
00048 manip.split_source(colorA, r0, g0, b0);
00049 manip.split_source(colorB, r1, g1, b1);
00050 manip.split_source(colorC, r2, g2, b2);
00051 unsigned int r = ((r0<<2) + (r0<<1) + r1 + r2)>>3;
00052 unsigned int g = ((g0<<2) + (g0<<1) + g1 + g2)>>3;
00053 unsigned int b = ((b0<<2) + (b0<<1) + b1 + b2)>>3;
00054 return manip.rgb(r, g, b);
00055 }
00056
00057 template <class Source_pixel, class Dest_pixel, class Manip_pixels>
00058 inline Dest_pixel QInterpolate_2xSaI (Source_pixel colorA, Source_pixel colorB, Source_pixel colorC, Source_pixel colorD, const Manip_pixels &manip)
00059 {
00060 unsigned int r0, r1, g0, g1, b0, b1;
00061 unsigned int r2, r3, g2, g3, b2, b3;
00062 manip.split_source(colorA, r0, g0, b0);
00063 manip.split_source(colorB, r1, g1, b1);
00064 manip.split_source(colorC, r2, g2, b2);
00065 manip.split_source(colorD, r3, g3, b3);
00066 unsigned int r = (r0 + r1 + r2 + r3)>>2;
00067 unsigned int g = (g0 + g1 + g2 + g3)>>2;
00068 unsigned int b = (b0 + b1 + b2 + b3)>>2;
00069 return manip.rgb(r, g, b);
00070 }
00071
00072 template <class Source_pixel>
00073 inline int GetResult1(Source_pixel A, Source_pixel B, Source_pixel C, Source_pixel D)
00074 {
00075 int x = 0;
00076 int y = 0;
00077 int r = 0;
00078 if (A == C) x+=1; else if (B == C) y+=1;
00079 if (A == D) x+=1; else if (B == D) y+=1;
00080 if (x <= 1) r+=1;
00081 if (y <= 1) r-=1;
00082 return r;
00083 }
00084
00085 template <class Source_pixel>
00086 inline int GetResult2(Source_pixel A, Source_pixel B, Source_pixel C, Source_pixel D)
00087 {
00088 int x = 0;
00089 int y = 0;
00090 int r = 0;
00091 if (A == C) x+=1; else if (B == C) y+=1;
00092 if (A == D) x+=1; else if (B == D) y+=1;
00093 if (x <= 1) r-=1;
00094 if (y <= 1) r+=1;
00095 return r;
00096 }
00097
00098
00099
00100 template <class Source_pixel, class Dest_pixel, class Manip_pixels>
00101 void Scale_2xSaI
00102 (
00103 Source_pixel *source,
00104 int srcx, int srcy,
00105 int srcw, int srch,
00106 int sline_pixels,
00107 int sheight,
00108 Dest_pixel *dest,
00109 int dline_pixels,
00110 const Manip_pixels& manip
00111 )
00112 {
00113 Source_pixel *srcPtr = source + (srcx + srcy*sline_pixels);
00114 Dest_pixel *dstPtr = dest + (2*srcy*dline_pixels + 2*srcx);
00115
00116 if (srcx + srcw >= sline_pixels)
00117 {
00118 srcw = sline_pixels - srcx;
00119 }
00120
00121 int prev1_yoff = srcy ? sline_pixels : 0;
00122 int next1_yoff = sline_pixels, next2_yoff = 2*sline_pixels;
00123
00124 int ybeforelast = sheight - 2 - srcy;
00125 int xbeforelast = sline_pixels - 2 - srcx;
00126 for (int y = 0; y < srch; y++, prev1_yoff = sline_pixels)
00127 {
00128 if (y >= ybeforelast)
00129 if (y == ybeforelast)
00130 next2_yoff = sline_pixels;
00131 else
00132 next2_yoff = next1_yoff = 0;
00133
00134 Source_pixel *bP = srcPtr;
00135 Dest_pixel *dP = dstPtr;
00136 int prev1_xoff = srcx ? 1 : 0;
00137 int next1_xoff = 1, next2_xoff = 2;
00138
00139 for (int x = 0; x < srcw; x++)
00140 {
00141 Source_pixel colorA, colorB;
00142 Source_pixel colorC, colorD,
00143 colorE, colorF, colorG, colorH,
00144 colorI, colorJ, colorK, colorL,
00145 colorM, colorN, colorO, colorP;
00146 Dest_pixel product, product1, product2, orig;
00147
00148
00149 if (x >= xbeforelast)
00150 if (x == xbeforelast)
00151 next2_xoff = 1;
00152 else
00153 next2_xoff = next1_xoff = 0;
00154
00155
00156
00157
00158
00159
00160 colorI = *(bP- prev1_yoff - prev1_xoff);
00161 colorE = *(bP- prev1_yoff);
00162 colorF = *(bP- prev1_yoff + next1_xoff);
00163 colorJ = *(bP- prev1_yoff + next2_xoff);
00164
00165 colorG = *(bP - prev1_xoff);
00166 colorA = *(bP);
00167 colorB = *(bP + next1_xoff);
00168 colorK = *(bP + next2_xoff);
00169
00170 colorH = *(bP + next1_yoff - prev1_xoff);
00171 colorC = *(bP + next1_yoff);
00172 colorD = *(bP + next1_yoff + next1_xoff);
00173 colorL = *(bP + next1_yoff + next2_xoff);
00174
00175 colorM = *(bP + next2_yoff - prev1_xoff);
00176 colorN = *(bP + next2_yoff);
00177 colorO = *(bP + next2_yoff + next1_xoff);
00178 colorP = *(bP + next2_yoff + next2_xoff);
00179
00180 if ((colorA == colorD) && (colorB != colorC))
00181 {
00182 if ( ((colorA == colorE) && (colorB == colorL)) ||
00183 ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) )
00184 {
00185
00186 manip.copy(product, colorA);
00187 }
00188 else
00189 {
00190
00191 product = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(colorA, colorB, manip);
00192 }
00193
00194 if (((colorA == colorG) && (colorC == colorO)) ||
00195 ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) )
00196 {
00197
00198 manip.copy(product1, colorA);
00199 }
00200 else
00201 {
00202
00203 product1 = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(colorA, colorC, manip);
00204 }
00205
00206 manip.copy(product2, colorA);
00207 }
00208 else
00209 if ((colorB == colorC) && (colorA != colorD))
00210 {
00211 if (((colorB == colorF) && (colorA == colorH)) ||
00212 ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) )
00213 {
00214
00215 manip.copy(product, colorB);
00216 }
00217 else
00218 {
00219
00220 product = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(colorA, colorB, manip);
00221 }
00222
00223 if (((colorC == colorH) && (colorA == colorF)) ||
00224 ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) )
00225 {
00226
00227 manip.copy(product1, colorC);
00228 }
00229 else
00230 {
00231
00232 product1 = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(colorA, colorC, manip);
00233 }
00234
00235 manip.copy(product2, colorB);
00236 }
00237 else
00238 if ((colorA == colorD) && (colorB == colorC))
00239 {
00240 if (colorA == colorB)
00241 {
00242
00243 manip.copy(product, colorA);
00244
00245 manip.copy(product1, colorA);
00246
00247 manip.copy(product2, colorA);
00248 }
00249 else
00250 {
00251 register int r = 0;
00252
00253 product1 = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(colorA, colorC, manip);
00254
00255 product = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(colorA, colorB, manip);
00256
00257 r += GetResult1 <Source_pixel>(colorA, colorB, colorG, colorE);
00258 r += GetResult2 <Source_pixel>(colorB, colorA, colorK, colorF);
00259 r += GetResult2 <Source_pixel>(colorB, colorA, colorH, colorN);
00260 r += GetResult1 <Source_pixel>(colorA, colorB, colorL, colorO);
00261
00262 if (r > 0)
00263
00264 manip.copy(product2, colorA);
00265 else
00266 if (r < 0)
00267
00268 manip.copy(product2, colorB);
00269 else
00270 {
00271
00272 product2 = QInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(colorA, colorB, colorC, colorD, manip);
00273 }
00274 }
00275 }
00276 else
00277 {
00278
00279 product2 = QInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(colorA, colorB, colorC, colorD, manip);
00280
00281 if ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ))
00282 {
00283
00284 manip.copy(product, colorA);
00285 }
00286 else
00287 if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
00288 {
00289
00290 manip.copy(product, colorB);
00291 }
00292 else
00293 {
00294
00295 product = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(colorA, colorB, manip);
00296 }
00297
00298 if ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM))
00299 {
00300
00301 manip.copy(product1, colorA);
00302 }
00303 else
00304 if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI))
00305 {
00306
00307 manip.copy(product1, colorC);
00308 }
00309 else
00310 {
00311
00312 product1 = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(colorA, colorC, manip);
00313 }
00314 }
00315
00316
00317
00318
00319 manip.copy(orig, colorA);
00320 *dP = orig;
00321 *(dP+1) = product;
00322 *(dP+dline_pixels) = product1;
00323 *(dP+dline_pixels+1) = product2;
00324
00325 bP += 1;
00326 dP += 2;
00327 prev1_xoff = 1;
00328 }
00329
00330 srcPtr += sline_pixels;
00331 dstPtr += 2*dline_pixels;
00332 prev1_yoff = 1;
00333 };
00334 }
00335
00336
00337
00338 template <class Source_pixel, class Dest_pixel, class Manip_pixels>
00339 void Scale_Super2xSaI
00340 (
00341 Source_pixel *source,
00342 int srcx, int srcy,
00343 int srcw, int srch,
00344 int sline_pixels,
00345 int sheight,
00346 Dest_pixel *dest,
00347 int dline_pixels,
00348 const Manip_pixels& manip
00349 )
00350 {
00351
00352 Source_pixel *srcPtr = source + (srcx + srcy*sline_pixels);
00353 Dest_pixel *dstPtr = dest + (2*srcy*dline_pixels + 2*srcx);
00354
00355 if (srcx + srcw >= sline_pixels)
00356 {
00357 srcw = sline_pixels - srcx;
00358 }
00359
00360 int ybeforelast1 = sheight - 1 - srcy;
00361 int ybeforelast2 = sheight - 2 - srcy;
00362 int xbeforelast1 = sline_pixels - 1 - srcx;
00363 int xbeforelast2 = sline_pixels - 2 - srcx;
00364
00365 for (int y = 0; y < srch; y++)
00366 {
00367 Source_pixel *bP = srcPtr;
00368 Dest_pixel *dP = dstPtr;
00369
00370 for (int x = 0; x < srcw; x++)
00371 {
00372 Source_pixel color4, color5, color6;
00373 Source_pixel color1, color2, color3;
00374 Source_pixel colorA0, colorA1, colorA2, colorA3,
00375 colorB0, colorB1, colorB2, colorB3,
00376 colorS1, colorS2;
00377 Dest_pixel product1a, product1b,
00378 product2a, product2b;
00379
00380
00381
00382
00383
00384
00385 int add1, add2;
00386 int sub1;
00387 int nextl1, nextl2;
00388 int prevl1;
00389
00390 if (x == 0)
00391 sub1 = 0;
00392 else
00393 sub1 = 1;
00394
00395 if (x >= xbeforelast2)
00396 add2 = 0;
00397 else add2 = 1;
00398
00399 if (x >= xbeforelast1)
00400 add1 = 0;
00401 else add1 = 1;
00402
00403 if (y == 0)
00404 prevl1 = 0;
00405 else
00406 prevl1 = sline_pixels;
00407
00408 if (y >= ybeforelast2)
00409 nextl2 = 0;
00410 else nextl2 = sline_pixels;
00411
00412 if (y >= ybeforelast1)
00413 nextl1 = 0;
00414 else nextl1 = sline_pixels;
00415
00416
00417 colorB0 = *(bP- prevl1 - sub1);
00418 colorB1 = *(bP- prevl1);
00419 colorB2 = *(bP- prevl1 + add1);
00420 colorB3 = *(bP- prevl1 + add1 + add2);
00421
00422 color4 = *(bP - sub1);
00423 color5 = *(bP);
00424 color6 = *(bP + add1);
00425 colorS2 = *(bP + add1 + add2);
00426
00427 color1 = *(bP + nextl1 - sub1);
00428 color2 = *(bP + nextl1);
00429 color3 = *(bP + nextl1 + add1);
00430 colorS1 = *(bP + nextl1 + add1 + add2);
00431
00432 colorA0 = *(bP + nextl1 + nextl2 - sub1);
00433 colorA1 = *(bP + nextl1 + nextl2);
00434 colorA2 = *(bP + nextl1 + nextl2 + add1);
00435 colorA3 = *(bP + nextl1 + nextl2 + add1 + add2);
00436
00437 if (color2 == color6 && color5 != color3)
00438 {
00439
00440 manip.copy(product2b, color2);
00441 product1b = product2b;
00442 }
00443 else
00444 if (color5 == color3 && color2 != color6)
00445 {
00446
00447 manip.copy(product2b, color5);
00448 product1b = product2b;
00449 }
00450 else
00451 if (color5 == color3 && color2 == color6)
00452 {
00453 register int r = 0;
00454
00455
00456
00457
00458
00459 r += GetResult1 <Source_pixel>(color5, color6, color4, colorB1);
00460 r += GetResult2 <Source_pixel>(color6, color5, colorA2, colorS1);
00461 r += GetResult2 <Source_pixel>(color6, color5, color1, colorA1);
00462 r += GetResult1 <Source_pixel>(color5, color6, colorB2, colorS2);
00463
00464 if (r > 0)
00465 {
00466
00467 manip.copy(product2b, color6);
00468 product1b = product2b;
00469 }
00470 else
00471 if (r < 0)
00472 {
00473
00474 manip.copy(product2b, color5);
00475 product1b = product2b;
00476 }
00477 else
00478 {
00479
00480 product1b = product2b = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color6, manip);
00481 }
00482
00483 }
00484 else
00485 {
00486
00487 if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
00488
00489 product2b = QInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color3, color3, color3, color2, manip);
00490 else
00491 if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
00492
00493 product2b = QInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color3, color2, color2, color2, manip);
00494 else
00495
00496 product2b = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color2, color3, manip);
00497
00498
00499 if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
00500
00501 product1b = QInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color6, color6, color6, manip);
00502 else
00503 if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
00504
00505 product1b = QInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color6, color5, color5, color5, manip);
00506 else
00507
00508 product1b = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color6, manip);
00509
00510 }
00511
00512 if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
00513
00514 product2a = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color2, manip);
00515 else
00516 if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
00517
00518 product2a = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color2, manip);
00519 else
00520
00521 manip.copy(product2a, color2);
00522
00523
00524 if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
00525
00526 product1a = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color2, manip);
00527 else
00528 if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
00529
00530 product1a = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color2, manip);
00531 else
00532
00533 manip.copy(product1a, color5);
00534
00535
00536 *dP = product1a;
00537 *(dP+1) = product1b;
00538 *(dP+dline_pixels) = product2a;
00539 *(dP+dline_pixels+1) = product2b;
00540
00541 bP += 1;
00542 dP += 2;
00543
00544 }
00545 srcPtr += sline_pixels;
00546 dstPtr += 2*dline_pixels;
00547 };
00548 }
00549
00550
00551
00552 template <class Source_pixel, class Dest_pixel, class Manip_pixels>
00553 void Scale_SuperEagle
00554 (
00555 Source_pixel *source,
00556 int srcx, int srcy,
00557 int srcw, int srch,
00558 int sline_pixels,
00559 int sheight,
00560 Dest_pixel *dest,
00561 int dline_pixels,
00562 const Manip_pixels& manip
00563 )
00564 {
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 Source_pixel *srcPtr = source + (srcx + srcy*sline_pixels);
00589 Dest_pixel *dstPtr = dest + (2*srcy*dline_pixels + 2*srcx);
00590
00591 if (srcx + srcw >= sline_pixels)
00592 {
00593 srcw = sline_pixels - srcx;
00594 }
00595
00596 int ybeforelast1 = sheight - 1 - srcy;
00597 int ybeforelast2 = sheight - 2 - srcy;
00598 int xbeforelast1 = sline_pixels - 1 - srcx;
00599 int xbeforelast2 = sline_pixels - 2 - srcx;
00600
00601 for (int y = 0; y < srch; y++)
00602 {
00603 Source_pixel *bP = srcPtr;
00604 Dest_pixel *dP = dstPtr;
00605
00606 for (int x = 0; x < srcw; x++)
00607 {
00608 Source_pixel color4, color5, color6;
00609 Source_pixel color1, color2, color3;
00610 Source_pixel colorA0, colorA1, colorA2, colorA3,
00611 colorB0, colorB1, colorB2, colorB3,
00612 colorS1, colorS2;
00613 Dest_pixel product1a, product1b,
00614 product2a, product2b;
00615
00616
00617
00618
00619
00620
00621 int add1, add2;
00622 int sub1;
00623 int nextl1, nextl2;
00624 int prevl1;
00625
00626 if (x == 0)
00627 sub1 = 0;
00628 else
00629 sub1 = 1;
00630
00631 if (x >= xbeforelast2)
00632 add2 = 0;
00633 else add2 = 1;
00634
00635 if (x >= xbeforelast1)
00636 add1 = 0;
00637 else add1 = 1;
00638
00639 if (y == 0)
00640 prevl1 = 0;
00641 else
00642 prevl1 = sline_pixels;
00643
00644 if (y >= ybeforelast2)
00645 nextl2 = 0;
00646 else nextl2 = sline_pixels;
00647
00648 if (y >= ybeforelast1)
00649 nextl1 = 0;
00650 else nextl1 = sline_pixels;
00651
00652
00653 colorB0 = *(bP- prevl1 - sub1);
00654 colorB1 = *(bP- prevl1);
00655 colorB2 = *(bP- prevl1 + add1);
00656 colorB3 = *(bP- prevl1 + add1 + add2);
00657
00658 color4 = *(bP - sub1);
00659 color5 = *(bP);
00660 color6 = *(bP + add1);
00661 colorS2 = *(bP + add1 + add2);
00662
00663 color1 = *(bP + nextl1 - sub1);
00664 color2 = *(bP + nextl1);
00665 color3 = *(bP + nextl1 + add1);
00666 colorS1 = *(bP + nextl1 + add1 + add2);
00667
00668 colorA0 = *(bP + nextl1 + nextl2 - sub1);
00669 colorA1 = *(bP + nextl1 + nextl2);
00670 colorA2 = *(bP + nextl1 + nextl2 + add1);
00671 colorA3 = *(bP + nextl1 + nextl2 + add1 + add2);
00672
00673
00674 if (color2 == color6 && color5 != color3)
00675 {
00676
00677 manip.copy(product2a, color2);
00678 product1b = product2a;
00679
00680
00681 if ((color1 == color2) || (color6 == colorB2))
00682 {
00683
00684
00685 product1a = QInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color2, color2, color2, color5, manip);
00686
00687 }
00688 else
00689 {
00690
00691 product1a = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color6, color5, manip);
00692 }
00693
00694 if ((color6 == colorS2) || (color2 == colorA1))
00695 {
00696
00697
00698 product2b = QInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color2, color2, color2, color3, manip);
00699
00700 }
00701 else
00702 {
00703
00704 product2b = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color2, color3, manip);
00705 }
00706 }
00707 else
00708 if (color5 == color3 && color2 != color6)
00709 {
00710
00711 manip.copy(product1a, color5);
00712 product2b = product1a;
00713
00714
00715 if ((colorB1 == color5) || (color3 == colorS1))
00716 {
00717
00718
00719 product1b = QInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color5, color5, color6, manip);
00720 }
00721 else
00722 {
00723
00724 product1b = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color6, manip);
00725 }
00726
00727 if ((color3 == colorA2) || (color4 == color5))
00728 {
00729
00730
00731 product2a = QInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color2, color5, color5, color5, manip);
00732 }
00733 else
00734 {
00735
00736 product2a = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color3, color2, manip);
00737 }
00738
00739 }
00740 else
00741 if (color5 == color3 && color2 == color6)
00742 {
00743 register int r = 0;
00744
00745
00746
00747
00748
00749 r += GetResult1 <Source_pixel>(color5, color6, color4, colorB1);
00750 r += GetResult2 <Source_pixel>(color6, color5, colorA2, colorS1);
00751 r += GetResult2 <Source_pixel>(color6, color5, color1, colorA1);
00752 r += GetResult1 <Source_pixel>(color5, color6, colorB2, colorS2);
00753
00754 if (r > 0)
00755 {
00756
00757 manip.copy(product2a, color2);
00758 product1b = product2a;
00759
00760 product1a = product2b = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color6, manip);
00761 }
00762 else
00763 if (r < 0)
00764 {
00765
00766 manip.copy(product1a, color5);
00767 product2b = product1a;
00768
00769 product1b = product2a = Interpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color6, manip);
00770 }
00771 else
00772 {
00773
00774 manip.copy(product1a, color5);
00775 product2b = product1a;
00776
00777 manip.copy(product2a, color2);
00778 product1b = product2a;
00779
00780 }
00781 }
00782 else
00783 {
00784
00785
00786
00787 product2b = OInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color3, color2, color6, manip);
00788 product1a = OInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color5, color6, color2, manip);
00789
00790
00791
00792
00793 product2a = OInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color2, color5, color3, manip);
00794 product1b = OInterpolate_2xSaI< Source_pixel, Dest_pixel, Manip_pixels>(color6, color5, color3, manip);
00795 }
00796
00797 *dP = product1a;
00798 *(dP+1) = product1b;
00799 *(dP+dline_pixels) = product2a;
00800 *(dP+dline_pixels+1) = product2b;
00801
00802 bP += 1;
00803 dP += 2;
00804
00805 }
00806 srcPtr += sline_pixels;
00807 dstPtr += 2*dline_pixels;
00808 };
00809 }
00810
00811
00812
00818 typedef unsigned int COMPONENT;
00819
00820
00821
00822
00823
00824 template <class Source_pixel, class Manip_pixels>
00825 inline void fill_rgb_row
00826 (
00827 Source_pixel *from,
00828 int src_width,
00829 COMPONENT *row,
00830 int width,
00831 const Manip_pixels& manip
00832 )
00833 {
00834 COMPONENT *copy_start = row + src_width*3;
00835 COMPONENT *all_stop = row + width*3;
00836 while (row < copy_start)
00837 {
00838 COMPONENT& r = *row++;
00839 COMPONENT& g = *row++;
00840 COMPONENT& b = *row++;
00841 manip.split_source(*from++, r, g, b);
00842 }
00843
00844
00845 COMPONENT *p = row-3;
00846 while (row < all_stop) {
00847
00848
00849
00850 *row++ = *p++;
00851 *row++ = *p++;
00852 *row++ = *p++;
00853 }
00854 }
00855
00856
00857 template <class Source_pixel, class Dest_pixel, class Manip_pixels>
00858 void Scale_2xBilinear
00859 (
00860 Source_pixel *source,
00861 int srcx, int srcy,
00862 int srcw, int srch,
00863 int sline_pixels,
00864 int sheight,
00865 Dest_pixel *dest,
00866 int dline_pixels,
00867 const Manip_pixels& manip
00868 )
00869 {
00870 Source_pixel *from = source + srcy*sline_pixels + srcx;
00871 Dest_pixel *to = dest + 2*srcy*dline_pixels + 2*srcx;
00872 Dest_pixel *to_odd = to + dline_pixels;
00873
00874
00875
00876
00877 static unsigned buff_size = 0;
00878 static COMPONENT *rgb_row_cur = 0;
00879 static COMPONENT *rgb_row_next = 0;
00880 if (buff_size < sline_pixels+1) {
00881 delete [] rgb_row_cur;
00882 delete [] rgb_row_next;
00883 buff_size = sline_pixels+1;
00884 rgb_row_cur = new COMPONENT[buff_size*3];
00885 rgb_row_next = new COMPONENT[buff_size*3];
00886 }
00887
00888 int from_width = sline_pixels - srcx;
00889 if (srcw+1 < from_width)
00890 from_width = srcw+1;
00891
00892 fill_rgb_row(from, from_width, rgb_row_cur, srcw+1, manip);
00893
00894 for (unsigned y=0; y < srch; y++)
00895 {
00896 Source_pixel *from_orig = from;
00897 Dest_pixel *to_orig = to;
00898
00899 if (y+1 < sheight)
00900 fill_rgb_row(from+sline_pixels, from_width, rgb_row_next,
00901 srcw+1, manip);
00902 else
00903 fill_rgb_row(from, from_width, rgb_row_next, srcw+1, manip);
00904
00905
00906
00907
00908
00909
00910 COMPONENT *cur_row = rgb_row_cur;
00911 COMPONENT *next_row = rgb_row_next;
00912 COMPONENT *ar = cur_row++;
00913 COMPONENT *ag = cur_row++;
00914 COMPONENT *ab = cur_row++;
00915 COMPONENT *cr = next_row++;
00916 COMPONENT *cg = next_row++;
00917 COMPONENT *cb = next_row++;
00918 for (unsigned x=0; x < srcw; x++)
00919 {
00920 COMPONENT *br = cur_row++;
00921 COMPONENT *bg = cur_row++;
00922 COMPONENT *bb = cur_row++;
00923 COMPONENT *dr = next_row++;
00924 COMPONENT *dg = next_row++;
00925 COMPONENT *db = next_row++;
00926
00927
00928 *to++ = manip.rgb(*ar, *ag, *ab);
00929
00930
00931 *to++ = manip.rgb((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
00932
00933
00934 *to_odd++ = manip.rgb((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
00935
00936
00937 *to_odd++ = manip.rgb((*ar+*br+*cr+*dr)>>2,
00938 (*ag+*bg+*cg+*dg)>>2,
00939 (*ab+*bb+*cb+*db)>>2);
00940
00941
00942 ar = br;
00943 ag = bg;
00944 ab = bb;
00945 cr = dr;
00946 cg = dg;
00947 cb = db;
00948 }
00949
00950
00951
00952 COMPONENT *temp;
00953 temp = rgb_row_cur;
00954 rgb_row_cur = rgb_row_next;
00955 rgb_row_next = temp;
00956
00957
00958 from = from_orig + sline_pixels;
00959 to = to_orig + 2*dline_pixels;
00960 to_odd = to + dline_pixels;
00961 }
00962 }
00963
00964
00965 template <class Source_pixel, class Dest_pixel, class Manip_pixels>
00966 void Scale_2xBilinearPlus
00967 (
00968 Source_pixel *source,
00969 int srcx, int srcy,
00970 int srcw, int srch,
00971 int sline_pixels,
00972 int sheight,
00973 Dest_pixel *dest,
00974 int dline_pixels,
00975 const Manip_pixels& manip
00976 )
00977 {
00978 Source_pixel *from = source + srcy*sline_pixels + srcx;
00979 Dest_pixel *to = dest + 2*srcy*dline_pixels + 2*srcx;
00980 Dest_pixel *to_odd = to + dline_pixels;
00981
00982
00983
00984
00985 static unsigned buff_size = 0;
00986 static COMPONENT *rgb_row_cur = 0;
00987 static COMPONENT *rgb_row_next = 0;
00988 if (buff_size < sline_pixels+1) {
00989 delete [] rgb_row_cur;
00990 delete [] rgb_row_next;
00991 buff_size = sline_pixels+1;
00992 rgb_row_cur = new COMPONENT[buff_size*3];
00993 rgb_row_next = new COMPONENT[buff_size*3];
00994 }
00995
00996 int from_width = sline_pixels - srcx;
00997 if (srcw+1 < from_width)
00998 from_width = srcw+1;
00999
01000 fill_rgb_row(from, from_width, rgb_row_cur, srcw+1, manip);
01001
01002 for (unsigned y=0; y < srch; y++)
01003 {
01004 Source_pixel *from_orig = from;
01005 Dest_pixel *to_orig = to;
01006
01007 if (y+1 < sheight)
01008 fill_rgb_row(from+sline_pixels, from_width, rgb_row_next,
01009 srcw+1, manip);
01010 else
01011 fill_rgb_row(from, from_width, rgb_row_next, srcw+1, manip);
01012
01013
01014
01015
01016
01017
01018 COMPONENT *cur_row = rgb_row_cur;
01019 COMPONENT *next_row = rgb_row_next;
01020 COMPONENT *ar = cur_row++;
01021 COMPONENT *ag = cur_row++;
01022 COMPONENT *ab = cur_row++;
01023 COMPONENT *cr = next_row++;
01024 COMPONENT *cg = next_row++;
01025 COMPONENT *cb = next_row++;
01026 for (unsigned x=0; x < srcw; x++)
01027 {
01028 COMPONENT *br = cur_row++;
01029 COMPONENT *bg = cur_row++;
01030 COMPONENT *bb = cur_row++;
01031 COMPONENT *dr = next_row++;
01032 COMPONENT *dg = next_row++;
01033 COMPONENT *db = next_row++;
01034
01035
01036
01037 #ifdef USE_ORIGINAL_BILINEAR_PLUS
01038 *to++ = manip.rgb(
01039 (((*ar)<<2) +((*ar)) + (*cr+*br+*br) )>> 3,
01040 (((*ag)<<2) +((*ag)) + (*cg+*bg+*bg) )>> 3,
01041 (((*ab)<<2) +((*ab)) + (*cb+*bb+*bb) )>> 3);
01042 #else
01043 *to++ = manip.rgb(
01044 (((*ar)<<3) +((*ar)<<1) + (*cr+*br+*br+*cr) )>> 4,
01045 (((*ag)<<3) +((*ag)<<1) + (*cg+*bg+*bg+*cg) )>> 4,
01046 (((*ab)<<3) +((*ab)<<1) + (*cb+*bb+*bb+*cb) )>> 4);
01047 #endif
01048
01049
01050 *to++ = manip.rgb((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
01051
01052
01053 *to_odd++ = manip.rgb((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
01054
01055
01056 *to_odd++ = manip.rgb((*ar+*br+*cr+*dr)>>2,
01057 (*ag+*bg+*cg+*dg)>>2,
01058 (*ab+*bb+*cb+*db)>>2);
01059
01060
01061 ar = br;
01062 ag = bg;
01063 ab = bb;
01064 cr = dr;
01065 cg = dg;
01066 cb = db;
01067 }
01068
01069
01070
01071 COMPONENT *temp;
01072 temp = rgb_row_cur;
01073 rgb_row_cur = rgb_row_next;
01074 rgb_row_next = temp;
01075
01076
01077 from = from_orig + sline_pixels;
01078 to = to_orig + 2*dline_pixels;
01079 to_odd = to + dline_pixels;
01080 }
01081 }
01082
01083
01084 #if 0
01085 void test()
01086 {
01087 unsigned short *src, *dest;
01088 Manip16to16 manip;
01089
01090 Scale2x<unsigned short, unsigned short, Manip16to16>
01091 (src, 20, 40, dest, manip);
01092
01093 unsigned char *src8;
01094 Manip8to16 manip8(0);
01095 Scale2x<unsigned char, unsigned short, Manip8to16>
01096 (src8, 20, 40, dest, manip8);
01097 }
01098 #endif
01099
01100
01101
01102
01103
01104 void Scale_point
01105 (
01106 const unsigned char *source,
01107 const int srcx, const int srcy,
01108 const int srcw, const int srch,
01109 const int sline_pixels,
01110 const int sheight,
01111 unsigned char *dest,
01112 const int dline_pixels,
01113 const int factor
01114 )
01115 {
01116 source += srcy*sline_pixels + srcx;
01117 dest += srcy*factor*dline_pixels + srcx*factor;
01118
01119 char data;
01120 unsigned char *dest2;
01121 const unsigned char *source2;
01122 const unsigned char * limit_y = source + srch*sline_pixels;
01123 const unsigned char * limit_x = source + srcw;
01124
01125 if (factor == 2) {
01126 uint16 *dest16;
01127 uint16 *dest16_2;
01128 uint16 data16;
01129
01130 while (source < limit_y)
01131 {
01132 source2 = source;
01133
01134 dest16 = (uint16*) dest;
01135 dest += dline_pixels;
01136 dest16_2 = (uint16*) dest;
01137
01138 while (source2 < limit_x)
01139 {
01140 data16 = *source2++;
01141 data16 |= data16 << 8;
01142 *dest16++ = data16;
01143 *dest16_2++ = data16;
01144 }
01145 dest += dline_pixels;
01146 limit_x += sline_pixels;
01147 source += sline_pixels;
01148 }
01149 } else {
01150 const unsigned int y2_pixels = dline_pixels*factor;
01151 const unsigned char * limit_y2 = dest;
01152 const unsigned char * limit_x2;
01153
01154 while (source < limit_y)
01155 {
01156 limit_y2 += y2_pixels;
01157 while (dest < limit_y2)
01158 {
01159 limit_x2 = dest2 = dest;
01160 source2 = source;
01161 while (source2 < limit_x)
01162 {
01163 data = *source2++;
01164 limit_x2 += factor;
01165 while (dest2 < limit_x2)
01166 *dest2++ = data;
01167 }
01168 dest += dline_pixels;
01169 }
01170 limit_x += sline_pixels;
01171 source += sline_pixels;
01172 }
01173 }
01174 }
01175
01176
01177
01178
01179 void Scale_interlace
01180 (
01181 const unsigned char *source,
01182 const int srcx, const int srcy,
01183 const int srcw, const int srch,
01184 const int sline_pixels,
01185 const int sheight,
01186 unsigned char *dest,
01187 const int dline_pixels,
01188 const int factor
01189 )
01190 {
01191 source += srcy*sline_pixels + srcx;
01192 dest += srcy*factor*dline_pixels + srcx*factor;
01193
01194 char data;
01195 unsigned char *dest2;
01196 const unsigned char *source2;
01197 const unsigned char * limit_y = source + srch*sline_pixels;
01198 const unsigned char * limit_x = source + srcw;
01199
01200 if (factor == 2) {
01201 uint16 *dest16;
01202 uint16 data16;
01203
01204 while (source < limit_y)
01205 {
01206 source2 = source;
01207 dest16 = (uint16*) dest;
01208 while (source2 < limit_x)
01209 {
01210 data16 = *source2++;
01211 data16 |= data16 << 8;
01212 *dest16++ = data16;
01213 }
01214 dest += dline_pixels;
01215 dest += dline_pixels;
01216 limit_x += sline_pixels;
01217 source += sline_pixels;
01218 }
01219 } else {
01220 bool visible_line = ((srcy * factor) % 2 == 0);
01221 const unsigned int y2_pixels = dline_pixels*factor;
01222 const unsigned char * limit_y2 = dest;
01223 const unsigned char * limit_x2;
01224
01225 while (source < limit_y)
01226 {
01227 limit_y2 += y2_pixels;
01228 while (dest < limit_y2)
01229 {
01230 if (visible_line)
01231 {
01232 limit_x2 = dest2 = dest;
01233 source2 = source;
01234 while (source2 < limit_x)
01235 {
01236 data = *source2++;
01237 limit_x2 += factor;
01238 while (dest2 < limit_x2)
01239 *dest2++ = data;
01240 }
01241 }
01242 dest += dline_pixels;
01243 visible_line = !visible_line;
01244 }
01245 limit_x += sline_pixels;
01246 source += sline_pixels;
01247 }
01248 }
01249 }
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274 void Scale2x_noblur
01275 (
01276 const unsigned char *src,
01277 const int srcx, const int srcy,
01278 const int srcw, const int srch,
01279 const int sline_pixels,
01280 const int sheight,
01281 unsigned char *dest,
01282 const int dline_pixels
01283 )
01284 {
01285 dest += srcy*2*dline_pixels + srcx*2;
01286 unsigned char *dest0 = dest, *dest1 = dest + dline_pixels;
01287
01288 const unsigned char *src1 = src + srcy*sline_pixels + srcx;
01289 const unsigned char *src0 = src1 - sline_pixels;
01290 const unsigned char *src2 = src1 + sline_pixels;
01291 const unsigned char * limit_y = src1 + srch*sline_pixels;
01292 const unsigned char * limit_x = src1 + srcw;
01293
01294 const unsigned char * end_src = src + sheight*sline_pixels;
01295
01296 if (src0 < src)
01297 src0 = src1;
01298 if (srcx + srcw == sline_pixels)
01299 limit_x--;
01300 while (src1 < limit_y)
01301 {
01302 if (src2 > end_src)
01303 src2 = src1;
01304 if (srcx == 0)
01305 {
01306 dest0[0] = dest1[0] = src1[0];
01307 if (src1[1] == src0[0] && src2[0] != src0[0])
01308 dest0[1] = src0[0];
01309 else
01310 dest0[1] = src1[0];
01311 if (src1[1] == src2[0] && src0[0] != src2[0])
01312 dest1[1] = src2[0];
01313 else
01314 dest1[1] = src1[0];
01315 ++src0; ++src1; ++src2;
01316 dest0 += 2; dest1 += 2;
01317 }
01318
01319 while (src1 < limit_x)
01320 {
01321 if (src1[-1] == src0[0] && src2[0] != src0[0] &&
01322 src1[1] != src0[0])
01323 dest0[0] = src0[0];
01324 else
01325 dest0[0] = src1[0];
01326 if (src1[1] == src0[0] && src2[0] != src0[0] &&
01327 src1[-1] != src0[0])
01328 dest0[1] = src0[0];
01329 else
01330 dest0[1] = src1[0];
01331 if (src1[-1] == src2[0] && src0[0] != src2[0] &&
01332 src1[1] != src2[0])
01333 dest1[0] = src2[0];
01334 else
01335 dest1[0] = src1[0];
01336 if (src1[1] == src2[0] && src0[0] != src2[0] &&
01337 src1[-1] != src2[0])
01338 dest1[1] = src2[0];
01339 else
01340 dest1[1] = src1[0];
01341 ++src0; ++src1; ++src2;
01342 dest0 += 2; dest1 += 2;
01343 }
01344 if (srcx + srcw == sline_pixels)
01345 {
01346 if (src1[-1] == src0[0] && src2[0] != src0[0])
01347 dest0[0] = src0[0];
01348 else
01349 dest0[0] = src1[0];
01350 if (src1[-1] == src2[0] && src0[0] != src2[0])
01351 dest1[0] = src2[0];
01352 else
01353 dest1[0] = src1[0];
01354 dest0[1] = src1[0];
01355 dest1[1] = src1[0];
01356 ++src0; ++src1; ++src2;
01357 dest0 += 2; dest1 += 2;
01358 }
01359 src0 += sline_pixels - srcw;
01360 src1 += sline_pixels - srcw;
01361 src2 += sline_pixels - srcw;
01362 dest1 += dline_pixels - 2*srcw;
01363 if (src0 == src1)
01364 src0 -= sline_pixels;
01365 limit_x += sline_pixels;
01366 dest0 = dest1;
01367 dest1 += dline_pixels;
01368 }
01369 }
01370
01371
01372
01373