scale.cc

Go to the documentation of this file.
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 // 2xSaI scaler
00100 template <class Source_pixel, class Dest_pixel, class Manip_pixels>
00101 void Scale_2xSaI
00102   (
00103   Source_pixel *source, // ->source pixels.
00104   int srcx, int srcy,   // Start of rectangle within src.
00105   int srcw, int srch,   // Dims. of rectangle.
00106   int sline_pixels,   // Pixels (words)/line for source.
00107   int sheight,      // Source height.
00108   Dest_pixel *dest,   // ->dest pixels.
00109   int dline_pixels,   // Pixels (words)/line for dest.
00110   const Manip_pixels& manip // Manipulator methods.
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           // Init offset to prev. line, next 2.
00121     int prev1_yoff = srcy ? sline_pixels : 0;
00122     int next1_yoff = sline_pixels, next2_yoff = 2*sline_pixels;
00123           // Figure threshholds for counters.
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) // Last/next-to-last row?
00129       if (y == ybeforelast)
00130         next2_yoff = sline_pixels;
00131       else    // Very last line?
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         // Last/next-to-last row?
00149       if (x >= xbeforelast)
00150         if (x == xbeforelast)
00151           next2_xoff = 1;
00152         else
00153           next2_xoff = next1_xoff = 0;
00154 
00155       //---------------------------------------
00156       // Map of the pixels:                    I|E F|J
00157       //                                       G|A B|K
00158       //                                       H|C D|L
00159       //                                       M|N O|P
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           //product = colorA;
00186           manip.copy(product, colorA);
00187          }
00188          else
00189          {
00190           //product = INTERPOLATE(colorA, colorB);
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           //product1 = colorA;
00198           manip.copy(product1, colorA);
00199          }
00200          else
00201          {
00202           //product1 = INTERPOLATE(colorA, colorC);
00203           product1 = Interpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(colorA, colorC, manip);
00204          }
00205          //product2 = colorA;
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           //product = colorB;
00215           manip.copy(product, colorB);
00216          }
00217          else
00218          {
00219           //product = INTERPOLATE(colorA, colorB);
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           //product1 = colorC;
00227           manip.copy(product1, colorC);
00228          }
00229          else
00230          {
00231           //product1 = INTERPOLATE(colorA, colorC);
00232           product1 = Interpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(colorA, colorC, manip);
00233          }
00234          //product2 = colorB;
00235          manip.copy(product2, colorB);
00236       }
00237       else
00238       if ((colorA == colorD) && (colorB == colorC))
00239       {
00240          if (colorA == colorB)
00241          {
00242           //product = colorA;
00243           manip.copy(product, colorA);
00244           //product1 = colorA;
00245           manip.copy(product1, colorA);
00246           //product2 = colorA;
00247           manip.copy(product2, colorA);
00248          }
00249          else
00250          {
00251           register int r = 0;
00252           //product1 = INTERPOLATE(colorA, colorC);
00253           product1 = Interpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(colorA, colorC, manip);
00254           //product = INTERPOLATE(colorA, colorB);
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             //product2 = colorA;
00264             manip.copy(product2, colorA);
00265           else
00266           if (r < 0)
00267             //product2 = colorB;
00268             manip.copy(product2, colorB);
00269           else
00270           {
00271             //product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD);
00272             product2 = QInterpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(colorA, colorB, colorC, colorD, manip);
00273           }
00274          }
00275       }
00276       else
00277       {
00278          //product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD);
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           //product = colorA;
00284           manip.copy(product, colorA);
00285          }
00286          else
00287          if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
00288          {
00289           //product = colorB;
00290           manip.copy(product, colorB);
00291          }
00292          else
00293          {
00294           //product = INTERPOLATE(colorA, colorB);
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           //product1 = colorA;
00301           manip.copy(product1, colorA);
00302          }
00303          else
00304          if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI))
00305          {
00306           //product1 = colorC;
00307           manip.copy(product1, colorC);
00308          }
00309          else
00310          {
00311           //product1 = INTERPOLATE(colorA, colorC);
00312           product1 = Interpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(colorA, colorC, manip);
00313          }
00314       }
00315 
00316 
00317       //product = colorA | (product << 16);
00318       //product1 = product1 | (product2 << 16);
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     }//end of for ( finish= width etc..)
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, // ->source pixels.
00342   int srcx, int srcy,   // Start of rectangle within src.
00343   int srcw, int srch,   // Dims. of rectangle.
00344   int sline_pixels,   // Pixels (words)/line for source.
00345   int sheight,      // Source height.
00346   Dest_pixel *dest,   // ->dest pixels.
00347   int dline_pixels,   // Pixels (words)/line for dest.
00348   const Manip_pixels& manip // Manipulator methods.
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       //---------------------------------------  B0 B1 B2 B3
00381       //                                         4  5  6  S2
00382       //                                         1  2  3  S1
00383       //                                         A0 A1 A2 A3
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          //product2b = product1b = color2;
00440         manip.copy(product2b, color2);
00441           product1b = product2b;
00442       }
00443       else
00444       if (color5 == color3 && color2 != color6)
00445       {
00446          //product2b = product1b = color5;
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                 //r += GetResult (color6, color5, color1, colorA1);
00456                 //r += GetResult (color6, color5, color4, colorB1);
00457                 //r += GetResult (color6, color5, colorA2, colorS1);
00458                 //r += GetResult (color6, color5, colorB2, colorS2);
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           //product2b = product1b = color6;
00467           manip.copy(product2b, color6);
00468           product1b = product2b;
00469         }
00470           else
00471           if (r < 0)
00472         {
00473           //product2b = product1b = color5;
00474           manip.copy(product2b, color5);
00475           product1b = product2b;
00476         }
00477           else
00478           {
00479             //product2b = product1b = INTERPOLATE (color5, color6);
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             //product2b = Q_INTERPOLATE (color3, color3, color3, color2);
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             //product2b = Q_INTERPOLATE (color2, color2, color2, color3);
00493             product2b = QInterpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color3, color2, color2, color2, manip);
00494          else
00495             //product2b = INTERPOLATE (color2, color3);
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             //product1b = Q_INTERPOLATE (color6, color6, color6, color5);
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             //product1b = Q_INTERPOLATE (color6, color5, color5, color5);
00505             product1b = QInterpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color6, color5, color5, color5, manip);
00506          else
00507             //product1b = INTERPOLATE (color5, color6);
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           //product2a = INTERPOLATE (color2, color5);
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           //product2a = INTERPOLATE(color2, color5);
00518           product2a = Interpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color5, color2, manip);
00519       else
00520           //product2a = color2;
00521         manip.copy(product2a, color2);
00522 
00523 
00524       if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
00525           //product1a = INTERPOLATE (color2, color5);
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           //product1a = INTERPOLATE(color2, color5);
00530           product1a = Interpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color5, color2, manip);
00531       else
00532           //product1a = color5;
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, // ->source pixels.
00556   int srcx, int srcy,   // Start of rectangle within src.
00557   int srcw, int srch,   // Dims. of rectangle.
00558   int sline_pixels,   // Pixels (words)/line for source.
00559   int sheight,      // Source height.
00560   Dest_pixel *dest,   // ->dest pixels.
00561   int dline_pixels,   // Pixels (words)/line for dest.
00562   const Manip_pixels& manip // Manipulator methods.
00563   )
00564 {
00565 
00566   // Need to ensure that the update is alligned to 4 pixels - Colourless
00567   // The idea was to prevent artifacts from appearing, but it doesn't seem
00568   // to help
00569   /*
00570   {
00571     int sx = ((srcx-4)/4)*4;
00572     int ex = ((srcx+srcw+7)/4)*4;
00573     int sy = ((srcy-4)/4)*4;
00574     int ey = ((srcy+srch+7)/4)*4;
00575 
00576     if (sx < 0) sx = 0;
00577     if (sy < 0) sy = 0;
00578     if (ex > sline_pixels) ex = sline_pixels;
00579     if (ey > sheight) ey = sheight;
00580 
00581     srcx = sx;
00582     srcy = sy;
00583     srcw = ex - sx;
00584     srch = ey - sy;
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       //---------------------------------------  B0 B1 B2 B3
00617       //                                         4  5  6  S2
00618       //                                         1  2  3  S1
00619       //                                         A0 A1 A2 A3
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          //product1b = product2a = color2;
00677          manip.copy(product2a, color2);
00678          product1b = product2a;
00679 
00680 
00681          if ((color1 == color2) || (color6 == colorB2))
00682          {
00683            //product1a = INTERPOLATE (color2, color5);
00684            //product1a = INTERPOLATE (color2, product1a);
00685            product1a = QInterpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color2, color2, color2, color5, manip);
00686 
00687          }
00688          else
00689          {
00690            //product1a = INTERPOLATE (color5, color6);
00691            product1a = Interpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color6, color5, manip);
00692          }
00693 
00694          if ((color6 == colorS2) || (color2 == colorA1))
00695                {
00696                    //product2b = INTERPOLATE (color2, color3);
00697                    //product2b = INTERPOLATE (color2, product2b);
00698            product2b = QInterpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color2, color2, color2, color3, manip);
00699 
00700                }
00701                else
00702                {
00703                    //product2b = INTERPOLATE (color2, color3);
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                //product2b = product1a = color5;
00711            manip.copy(product1a, color5);
00712          product2b = product1a;
00713 
00714  
00715                if ((colorB1 == color5) ||  (color3 == colorS1))
00716                {
00717                    //product1b = INTERPOLATE (color5, color6);
00718            //product1b = INTERPOLATE (color5, product1b);
00719            product1b = QInterpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color5, color5, color5, color6, manip);
00720                }
00721                else
00722                {
00723                   //product1b = INTERPOLATE (color5, color6);
00724           product1b = Interpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color5, color6, manip);
00725                }
00726 
00727          if ((color3 == colorA2) || (color4 == color5))
00728                {
00729                    //product2a = INTERPOLATE (color5, color2);
00730                    //product2a = INTERPOLATE (color5, product2a);
00731            product2a = QInterpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color2, color5, color5, color5, manip);
00732                }
00733                else
00734                {
00735                   //product2a = INTERPOLATE (color2, color3);
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                //r += GetResult (color6, color5, color1, colorA1);
00746                //r += GetResult (color6, color5, color4, colorB1);
00747                //r += GetResult (color6, color5, colorA2, colorS1);
00748                //r += GetResult (color6, color5, colorB2, colorS2);
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                   //product1b = product2a = color2;
00757              manip.copy(product2a, color2);
00758            product1b = product2a;
00759                   //product1a = product2b = INTERPOLATE (color5, color6);
00760           product1a = product2b = Interpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color5, color6, manip);
00761                }
00762                else
00763                if (r < 0)
00764                {
00765                   //product2b = product1a = color5;
00766            manip.copy(product1a, color5);
00767            product2b = product1a;
00768                   //product1b = product2a = INTERPOLATE (color5, color6);
00769           product1b = product2a = Interpolate_2xSaI< Source_pixel,  Dest_pixel,  Manip_pixels>(color5, color6, manip);
00770                }
00771                else
00772                {
00773                   //product2b = product1a = color5;
00774            manip.copy(product1a, color5);
00775            product2b = product1a;
00776                   //product1b = product2a = color2;
00777            manip.copy(product2a, color2);
00778              product1b = product2a;
00779 
00780                }
00781             }
00782             else
00783             {
00784                   //product2b = product1a = INTERPOLATE (color2, color6);
00785                   //product2b = Q_INTERPOLATE (color3, color3, color3, product2b);
00786                   //product1a = Q_INTERPOLATE (color5, color5, color5, product1a);
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                   //product2a = product1b = INTERPOLATE (color5, color3);
00791                   //product2a = Q_INTERPOLATE (color2, color2, color2, product2a);
00792                   //product1b = Q_INTERPOLATE (color6, color6, color6, product1b);
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 // fill `row' with the the disassembled color components from the original
00822 // pixel values in `from'; if we run out of source pixels, just keep copying
00823 // the last one we got
00824 template <class Source_pixel, class Manip_pixels>
00825 inline void fill_rgb_row
00826   (
00827    Source_pixel *from,
00828    int src_width, // number of pixels to read from 'from'
00829    COMPONENT *row,
00830    int width,   // number of pixels to write into 'row'
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   // any remaining elements to be written to 'row' are a replica of the
00844   // preceding pixel
00845   COMPONENT *p = row-3;
00846   while (row < all_stop) {
00847     // we're guaranteed three elements per pixel; could unroll the loop
00848     // further, especially with a Duff's Device, but the gains would be
00849     // probably limited (judging by profiler output)
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,   // ->source pixels.
00861   int srcx, int srcy,   // Start of rectangle within src.
00862   int srcw, int srch,   // Dims. of rectangle.
00863   int sline_pixels,   // Pixels (words)/line for source.
00864   int sheight,      // Source height.
00865   Dest_pixel *dest,   // ->dest pixels.
00866   int dline_pixels,   // Pixels (words)/line for dest.
00867   const Manip_pixels& manip // Manipulator methods.
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   // the following are static because we don't want to be freeing and
00875   // reallocating space on each call, as malloc()s are usually very
00876   // expensive; we do allow it to grow though
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     // every pixel in the src region, is extended to 4 pixels in the
00906     // destination, arranged in a square 'quad'; if the current src
00907     // pixel is 'a', then in what follows 'b' is the src pixel to the
00908     // right, 'c' is the src pixel below, and 'd' is the src pixel to
00909     // the right and down
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       // upper left pixel in quad: just copy it in
00928       *to++ = manip.rgb(*ar, *ag, *ab);
00929 
00930       // upper right
00931       *to++ = manip.rgb((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
00932 
00933       // lower left
00934       *to_odd++ = manip.rgb((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
00935 
00936       // lower right
00937       *to_odd++ = manip.rgb((*ar+*br+*cr+*dr)>>2,
00938                       (*ag+*bg+*cg+*dg)>>2,
00939                     (*ab+*bb+*cb+*db)>>2);
00940 
00941       // 'b' becomes 'a', 'd' becomes 'c'
00942       ar = br;
00943       ag = bg;
00944       ab = bb;
00945       cr = dr;
00946       cg = dg;
00947       cb = db;
00948       }
00949 
00950     // the "next" rgb row becomes the current; the old current rgb row is
00951     // recycled and serves as the new "next" row
00952     COMPONENT *temp;
00953     temp = rgb_row_cur;
00954     rgb_row_cur = rgb_row_next;
00955     rgb_row_next = temp;
00956 
00957     // update the pointers for start of next pair of lines
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,   // ->source pixels.
00969   int srcx, int srcy,   // Start of rectangle within src.
00970   int srcw, int srch,   // Dims. of rectangle.
00971   int sline_pixels,   // Pixels (words)/line for source.
00972   int sheight,      // Source height.
00973   Dest_pixel *dest,   // ->dest pixels.
00974   int dline_pixels,   // Pixels (words)/line for dest.
00975   const Manip_pixels& manip // Manipulator methods.
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   // the following are static because we don't want to be freeing and
00983   // reallocating space on each call, as malloc()s are usually very
00984   // expensive; we do allow it to grow though
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     // every pixel in the src region, is extended to 4 pixels in the
01014     // destination, arranged in a square 'quad'; if the current src
01015     // pixel is 'a', then in what follows 'b' is the src pixel to the
01016     // right, 'c' is the src pixel below, and 'd' is the src pixel to
01017     // the right and down
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       // upper left pixel in quad: just copy it in
01036       //*to++ = manip.rgb(*ar, *ag, *ab);
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       // upper right
01050       *to++ = manip.rgb((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
01051 
01052       // lower left
01053       *to_odd++ = manip.rgb((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
01054 
01055       // lower right
01056       *to_odd++ = manip.rgb((*ar+*br+*cr+*dr)>>2,
01057                       (*ag+*bg+*cg+*dg)>>2,
01058                     (*ab+*bb+*cb+*db)>>2);
01059 
01060       // 'b' becomes 'a', 'd' becomes 'c'
01061       ar = br;
01062       ag = bg;
01063       ab = bb;
01064       cr = dr;
01065       cg = dg;
01066       cb = db;
01067       }
01068 
01069     // the "next" rgb row becomes the current; the old current rgb row is
01070     // recycled and serves as the new "next" row
01071     COMPONENT *temp;
01072     temp = rgb_row_cur;
01073     rgb_row_cur = rgb_row_next;
01074     rgb_row_next = temp;
01075 
01076     // update the pointers for start of next pair of lines
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 /* Testing */
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);   // ++++DOn't try to run this!
01095   Scale2x<unsigned char, unsigned short, Manip8to16>
01096           (src8, 20, 40, dest, manip8);
01097   }
01098 #endif
01099 
01100 
01101 //
01102 // Point Sampling Scaler
01103 //
01104 void Scale_point
01105 (
01106   const unsigned char *source,  // ->source pixels.
01107   const int srcx, const int srcy, // Start of rectangle within src.
01108   const int srcw, const int srch, // Dims. of rectangle.
01109   const int sline_pixels,   // Pixels (words)/line for source.
01110   const int sheight,    // Source height.
01111   unsigned char *dest,    // ->dest pixels.
01112   const int dline_pixels,   // Pixels (words)/line for dest.
01113   const int factor    // Scale 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 // Interlaced Point Sampling Scaler
01178 //
01179 void Scale_interlace
01180 (
01181   const unsigned char *source,  // ->source pixels.
01182   const int srcx, const int srcy, // Start of rectangle within src.
01183   const int srcw, const int srch, // Dims. of rectangle.
01184   const int sline_pixels,   // Pixels (words)/line for source.
01185   const int sheight,    // Source height.
01186   unsigned char *dest,    // ->dest pixels.
01187   const int dline_pixels,   // Pixels (words)/line for dest.
01188   const int factor    // Scale 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 // Scale2X algorithm by Andrea Mazzoleni.
01255 //
01256 /* This file is part of the Scale2x project.
01257  *
01258  * Copyright (C) 2001-2002 Andrea Mazzoleni
01259  *
01260  * This program is free software; you can redistribute it and/or modify
01261  * it under the terms of the GNU General Public License as published by
01262  * the Free Software Foundation; either version 2 of the License, or
01263  * (at your option) any later version.
01264  *
01265  * This program is distributed in the hope that it will be useful,
01266  * but WITHOUT ANY WARRANTY; without even the implied warranty of
01267  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
01268  * GNU General Public License for more details.
01269  *
01270  * You should have received a copy of the GNU General Public License
01271  * along with this program; if not, write to the Free Software
01272  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
01273  */
01274 void Scale2x_noblur
01275 (
01276   const unsigned char *src, // ->source pixels.
01277   const int srcx, const int srcy, // Start of rectangle within src.
01278   const int srcw, const int srch, // Dims. of rectangle.
01279   const int sline_pixels,   // Pixels (words)/line for source.
01280   const int sheight,    // Source height.
01281   unsigned char *dest,    // ->dest pixels.
01282   const int dline_pixels    // Pixels (words)/line for dest.
01283 )
01284 {
01285   dest += srcy*2*dline_pixels + srcx*2;
01286   unsigned char *dest0 = dest, *dest1 = dest + dline_pixels;
01287           // ->current row.
01288   const unsigned char *src1 = src + srcy*sline_pixels + srcx;
01289   const unsigned char *src0 = src1 - sline_pixels;  // ->prev. row.
01290   const unsigned char *src2 = src1 + sline_pixels;  // ->next row.
01291   const unsigned char * limit_y = src1 + srch*sline_pixels;
01292   const unsigned char * limit_x = src1 + srcw;
01293           // Very end of source surface:
01294   const unsigned char * end_src = src + sheight*sline_pixels;
01295 
01296   if (src0 < src)
01297     src0 = src1;    // Don't go before row 0.
01298   if (srcx + srcw == sline_pixels)  // Going to right edge?
01299     limit_x--;    // Stop 1 pixel before it.
01300   while (src1 < limit_y)
01301     {
01302     if (src2 > end_src)
01303       src2 = src1;  // On last row.
01304     if (srcx == 0)    // First pixel.
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           // Middle pixels.
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       {   // End pixel in row.
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) // End of first row?
01364       src0 -= sline_pixels;
01365     limit_x += sline_pixels;
01366     dest0 = dest1;
01367     dest1 += dline_pixels;
01368     }
01369 }
01370 
01371 
01372 
01373 

Generated on Mon Jul 9 14:42:47 2007 for ExultEngine by  doxygen 1.5.1