Diff for /parser3/src/classes/gd/Attic/gif.C between versions 1.13 and 1.28

version 1.13, 2001/10/08 16:06:49 version 1.28, 2002/08/01 11:41:13
Line 1 Line 1
 /** @file  /** @file
         Parser: image manipulations impl1.          Parser: image manipulations impl1.
   
         Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
   
         $Id$  
   
         based on: gd          based on: gd
   
         Written by Tom Boutell, 5/94.          Written by Tom Boutell, 5/94.
Line 17 Line 14
         can incorporate them into new versions.           can incorporate them into new versions. 
 */  */
   
   static const char* IDENT_GIF_C="$Date$";
   
 #include "gif.h"  #include "gif.h"
   
 #include "mtables.h"  #include "mtables.h"
   #include "pa_common.h"
   
 //static void BrushApply(int x, int y);  //static void BrushApply(int x, int y);
 //static void TileApply(int x, int y);  //static void TileApply(int x, int y);
Line 40  void gdImage::Create(int asx, int asy) { Line 40  void gdImage::Create(int asx, int asy) {
         interlace = 0;          interlace = 0;
 }  }
   
 int gdImage::ColorClosest(int r, int g, int b)  int gdImage::ColorClosest(int r, int g, int b, int tolerance)
 {  {
         int i;          int i;
         long rd, gd, bd;          long rd, gd, bd;
Line 55  int gdImage::ColorClosest(int r, int g, Line 55  int gdImage::ColorClosest(int r, int g,
                 gd = (green[i] - g);                  gd = (green[i] - g);
                 bd = (blue[i] - b);                  bd = (blue[i] - b);
                 dist = rd * rd + gd * gd + bd * bd;                  dist = rd * rd + gd * gd + bd * bd;
                 if ((i == 0) || (dist < mindist)) {                  if ((i == 0) || (dist < mindist+tolerance)) {
                         mindist = dist;                           mindist = dist; 
                         ct = i;                          ct = i;
                 }                  }
         }          }
         return ct;          return mindist<tolerance?ct:-1;
 }  }
   
 int gdImage::ColorExact(int r, int g, int b)  int gdImage::ColorExact(int r, int g, int b)
Line 273  void gdImage::Line(int x1, int y1, int x Line 273  void gdImage::Line(int x1, int y1, int x
   
 void gdImage::Arc(int cx, int cy, int w, int h, int s, int e, int color)  void gdImage::Arc(int cx, int cy, int w, int h, int s, int e, int color)
 {  {
         if(w!=h) {  #if 0
           if(s==0 && e==360) { // full 
                   if(w==h) { // circle?
                           /* Bresenham octant code, which I should use eventually */
                           int x, y, d;
                           x = 0;
                           y = w/2;
                           d = 3-w;
                           while (x <= y) {
                                   SetPixel(cx+x, cy+y, color);
                                   SetPixel(cx+x, cy-y, color);
                                   SetPixel(cx-x, cy+y, color);
                                   SetPixel(cx-x, cy-y, color);
                                   SetPixel(cx+y, cy+x, color);
                                   SetPixel(cx+y, cy-x, color);
                                   SetPixel(cx-y, cy+x, color);
                                   SetPixel(cx-y, cy-x, color);
                                   if (d < 0) {
                                           d += 4 * x + 6;
                                   } else {
                                           d += 4 * (x - y) + 10;
                                           y--;
                                   }
                                   x++;
                           }
                   } else { // full ellipse
                           w/=2;
                           h/=2;
                           int elx, ely;
                           long aa, aa2, bb, bb2, d, dx, dy;
                           
                           elx = 0; ely = h; aa = (long)w * w; aa2 = 2 * aa;
                           bb = (long)h * h; bb2 = 2 * bb;
                           d = bb - aa * h + aa/4; dx = 0; dy = aa2 * h;
                           SetPixel(cx, cy - ely, color); SetPixel(cx, cy + ely, color);
                           SetPixel(cx - w, cy, color); SetPixel(cx + w, cy, color);
                           
                           while (dx < dy)
                           {
                                   if (d > 0) { ely--; dy-=aa2; d-=dy;}
                                   elx++; dx+=bb2; d+=bb+dx;
                                   SetPixel(cx + elx, cy + ely, color);
                                   SetPixel(cx - elx, cy + ely, color);
                                   SetPixel(cx + elx, cy - ely, color);
                                   SetPixel(cx - elx, cy - ely, color);
                           };
                           d+=(3 * (aa - bb)/2 - (dx + dy))/2;
                           while (ely > 0)
                           {
                                   if (d < 0) {elx++; dx+=bb2; d+=bb + dx;}
                                   ely--; dy-=aa2; d+=aa - dy;
                                   SetPixel(cx + elx, cy + ely, color);
                                   SetPixel(cx - elx, cy + ely, color);
                                   SetPixel(cx + elx, cy - ely, color);
                                   SetPixel(cx - elx, cy - ely, color);
                           };
                   }
           } else {
   #endif
                 int i;                  int i;
                 int lx = 0, ly = 0;                  int lx = 0, ly = 0;
                 int w2, h2;                  int w2, h2;
                 w2 = w/2;                  w2 = w/2;
                 h2 = h/2;                  h2 = h/2;
                 while (e < s) {                  while (e < s) e += 360;
                         e += 360;                  // paf
                 }                  while(s<0) s+=360;
                   while(s>360) s-=360;
                   while(e<0) e+=360;
                   while(e>360) e-=360;
                 for (i=s; (i <= e); i++) {                  for (i=s; (i <= e); i++) {
                         int x, y;                          int x, y;
                         x = ((long)cost[i % 360] * (long)w2 / costScale) + cx;                           x = ((long)cost[i] * (long)w2 / costScale) + cx; 
                         y = ((long)sint[i % 360] * (long)h2 / sintScale) + cy;                          y = ((long)sint[i] * (long)h2 / sintScale) + cy;
                         if (i != s) {                          if (i != s) {
                                 Line(lx, ly, x, y, color);                                        Line(lx, ly, x, y, color);      
                         }                          }
                         lx = x;                          lx = x;
                         ly = y;                          ly = y;
                 }                  }
         } else {  #if 0
                 /* Bresenham octant code, which I should use eventually */  
                 int x, y, d;  
                 x = 0;  
                 y = w/2;  
                 d = 3-w;  
                 while (x <= y) {  
                         SetPixel(cx+x, cy+y, color);  
                         SetPixel(cx+x, cy-y, color);  
                         SetPixel(cx-x, cy+y, color);  
                         SetPixel(cx-x, cy-y, color);  
                         SetPixel(cx+y, cy+x, color);  
                         SetPixel(cx+y, cy-x, color);  
                         SetPixel(cx-y, cy+x, color);  
                         SetPixel(cx-y, cy-x, color);  
                         if (d < 0) {  
                                 d += 4 * x + 6;  
                         } else {  
                                 d += 4 * (x - y) + 10;  
                                 y--;  
                         }  
                         x++;  
                 }  
         }          }
   #endif
 }  }
   
   /*
   
   // http://firststeps.narod.ru/cgi/18.html
   
   int CGIScreen::Ellipse(int exc, int eyc, int ea, int eb , unsigned char Color)
   {
     int elx, ely;
     long aa, aa2, bb, bb2, d, dx, dy;
   
     elx = 0; ely = eb; aa = (long)ea * ea; aa2 = 2 * aa;
     bb = (long)eb * eb; bb2 = 2 * bb;
     d = bb - aa * eb + aa/4; dx = 0; dy = aa2 * eb;
     PutPixel(exc, eyc - ely, Color); PutPixel(exc, eyc + ely, Color);
     PutPixel(exc - ea, eyc, Color); PutPixel(exc + ea, eyc, Color);
   
     while (dx < dy)
     {
       if (d > 0) { ely--; dy-=aa2; d-=dy;}
       elx++; dx+=bb2; d+=bb+dx;
       PutPixel(exc + elx, eyc + ely, Color);
       PutPixel(exc - elx, eyc + ely, Color);
       PutPixel(exc + elx, eyc - ely, Color);
       PutPixel(exc - elx, eyc - ely, Color);
     };
     d+=(3 * (aa - bb)/2 - (dx + dy))/2;
     while (ely > 0)
     {
       if (d < 0) {elx++; dx+=bb2; d+=bb + dx;}
       ely--; dy-=aa2; d+=aa - dy;
       PutPixel(exc + elx, eyc + ely, Color);
       PutPixel(exc - elx, eyc + ely, Color);
       PutPixel(exc + elx, eyc - ely, Color);
       PutPixel(exc - elx, eyc - ely, Color);
     };
     return 0;
   };
   
   */
   
   
 void gdImage::Sector(int cx, int cy, int w, int h, int s, int e, int color)  void gdImage::Sector(int cx, int cy, int w, int h, int s, int e, int color)
 {  {
Line 326  void gdImage::Sector(int cx, int cy, int Line 405  void gdImage::Sector(int cx, int cy, int
         int w2, h2;          int w2, h2;
         w2 = w/2;          w2 = w/2;
         h2 = h/2;          h2 = h/2;
         while (e < s) {          while (e < s) e += 360;
                 e += 360;          // paf
         }          while(s<0) s+=360;
           while(s>360) s-=360;
           while(e<0) e+=360;
           while(e>360) e-=360;
         for (i=s; (i <= e); i++) {          for (i=s; (i <= e); i++) {
                 int x, y;                  int x, y;
                 x = ((long)cost[i % 360] * (long)w2 / costScale) + cx;                   x = ((long)cost[i] * (long)w2 / costScale) + cx; 
                 y = ((long)sint[i % 360] * (long)h2 / sintScale) + cy;                  y = ((long)sint[i] * (long)h2 / sintScale) + cy;
                 if(i==s || i==e)                  if(i==s || i==e)
                         Line(cx, cy, x, y, color);                          Line(cx, cy, x, y, color);
                 if (i != s) {                  if (i != s) {
Line 566  void gdImage::Copy(gdImage& dst, int dst Line 648  void gdImage::Copy(gdImage& dst, int dst
         }          }
 }                         }                       
   
   void gdImage::CopyResampled(gdImage& dst,
                         int dstX, int dstY,
                         int srcX, int srcY,
                         int dstW, int dstH,
                             int srcW, int srcH,
                             int tolerance)
   {
           gdImage& src=*this;
           int x, y;
           for (y = dstY; (y < dstY + dstH); y++) {
                   for (x = dstX; (x < dstX + dstW); x++) {
                           int pd = dst.GetPixel (x, y);
                           /* Added 7/24/95: support transparent copies */
                           if (src.GetTransparent() == pd)
                                   continue;
                           
                           double sy1, sy2, sx1, sx2;
                           double sx, sy;
                           double spixels = 0;
                           double red = 0.0, green = 0.0, blue = 0.0;
                           sy1 = ((double) y - (double) dstY) * (double) srcH /
                                   (double) dstH;
                           sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH /
                                   (double) dstH;
                           sy = sy1;
                           do
                           {
                                   double yportion;
                                   if (floor (sy) == floor (sy1))
                                   {
                                           yportion = 1.0 - (sy - floor (sy));
                                           if (yportion > sy2 - sy1)
                                           {
                                                   yportion = sy2 - sy1;
                                           }
                                           sy = floor (sy);
                                   }
                                   else if (sy == floor (sy2))
                                   {
                                           yportion = sy2 - floor (sy2);
                                   }
                                   else
                                   {
                                           yportion = 1.0;
                                   }
                                   sx1 = ((double) x - (double) dstX) * (double) srcW /
                                           dstW;
                                   sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW /
                                           dstW;
                                   sx = sx1;
                                   do
                                   {
                                           double xportion;
                                           double pcontribution;
                                           int p;
                                           if (floor (sx) == floor (sx1))
                                           {
                                                   xportion = 1.0 - (sx - floor (sx));
                                                   if (xportion > sx2 - sx1)
                                                   {
                                                           xportion = sx2 - sx1;
                                                   }
                                                   sx = floor (sx);
                                           }
                                           else if (sx == floor (sx2))
                                           {
                                                   xportion = sx2 - floor (sx2);
                                           }
                                           else
                                           {
                                                   xportion = 1.0;
                                           }
                                           pcontribution = xportion * yportion;
                                           p = src.GetPixel (
                                                   (int) sx,
                                                   (int) sy);
                                           red += Red (p) * pcontribution;
                                           green += Green (p) * pcontribution;
                                           blue += Blue (p) * pcontribution;
                                           spixels += xportion * yportion;
                                           sx += 1.0;
                                   } while (sx < sx2);
                                   sy += 1.0;
                           } while (sy < sy2);
                           if (spixels != 0.0) {
                                   red /= spixels;
                                   green /= spixels;
                                   blue /= spixels;
                           }
                           /* Clamping to allow for rounding errors above */
                           if (red > 255.0)
                                   red = 255.0;
                           if (green > 255.0)
                                   green = 255.0;
                           if (blue > 255.0)
                                   blue = 255.0;
                           
                           red=round(red);
                           green=round(green);
                           blue=round(blue);
                           /* First look for an exact match */
                           int nc = dst.ColorExact((int)red, (int)green, (int)blue);
                           if (nc == (-1)) {
                                   /* No, so go for the closest color with high tolerance */
                                   nc = dst.ColorClosest((int)red, (int)green, (int)blue,  tolerance);
                                   if (nc == (-1)) {
                                           /* Not found with even high tolerance, so try to allocate it */
                                           nc = dst.ColorAllocate((int)red, (int)green, (int)blue);
   
                                           /* If we're out of colors, go for the closest color */
                                           if (nc == (-1))
                                                   nc = dst.ColorClosest((int)red, (int)green, (int)blue);
                                   }
                           }
                           dst.SetPixel(x, y, nc);
                   }
       }
   }
   
 static int gdGetWord(int *result, FILE *in)  static int gdGetWord(int *result, FILE *in)
 {  {
         int r;          int r;
Line 743  void gdImage::LineReplaceColor(int x1, i Line 944  void gdImage::LineReplaceColor(int x1, i
         if(y1!=y2)          if(y1!=y2)
                 return;                  return;
   
         for(int x=x1; x<=x2; x++) {          for(int x=x1; x<=x2; x++) 
                 unsigned char *pixel=&pixels[x][y1];                  if(BoundsSafe(x, y1)) {
                 if(*pixel==a)                          unsigned char *pixel=&pixels[x][y1];
                         *pixel=b;                          if(*pixel==a)
         }                                  *pixel=b;
                   }
 }  }
   
 void gdImage::FilledPolygonReplaceColor(Point *p, int n, int a, int b)  void gdImage::FilledPolygonReplaceColor(Point *p, int n, int a, int b)

Removed from v.1.13  
changed lines
  Added in v.1.28


E-mail: