Diff for /parser3/src/classes/gd/Attic/gif.C between versions 1.9 and 1.30.2.3

version 1.9, 2001/09/26 10:32:25 version 1.30.2.3, 2003/02/04 12:08:55
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-2003 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 "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 38  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 53  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 269  void gdImage::Line(int x1, int y1, int x Line 271  void gdImage::Line(int x1, int y1, int x
   at least for me) and there are other inefficiencies (small circles    at least for me) and there are other inefficiencies (small circles
   do far too much work). */    do far too much work). */
   
   void gdImage::Arc(int cx, int cy, int w, int h, int s, int e, int color)
   {
   #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 lx = 0, ly = 0;
                   int w2, h2;
                   w2 = w/2;
                   h2 = h/2;
                   while (e < s) 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++) {
                           int x, y;
                           x = ((long)cost[i] * (long)w2 / costScale) + cx; 
                           y = ((long)sint[i] * (long)h2 / sintScale) + cy;
                           if (i != s) {
                                   Line(lx, ly, x, y, color);      
                           }
                           lx = x;
                           ly = y;
                   }
   #if 0
           }
   #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)
   {
           int i;
           int lx = 0, ly = 0;
           int w2, h2;
           w2 = w/2;
           h2 = h/2;
           while (e < s) 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++) {
                   int x, y;
                   x = ((long)cost[i] * (long)w2 / costScale) + cx; 
                   y = ((long)sint[i] * (long)h2 / sintScale) + cy;
                   if(i==s || i==e)
                           Line(cx, cy, x, y, color);
                   if (i != s) {
                           Line(lx, ly, x, y, color);      
                   }
                   lx = x;
                   ly = y;
           }
   }
   
   
   
 void gdImage::FillToBorder(int x, int y, int border, int color)  void gdImage::FillToBorder(int x, int y, int border, int color)
 {  {
         if(!BoundsSafe(x, y)) //PAF          if(!BoundsSafe(x, y)) //PAF
Line 419  void gdImage::Rectangle(int x1, int y1, Line 577  void gdImage::Rectangle(int x1, int y1,
   
 void gdImage::FilledRectangle(int x1, int y1, int x2, int y2, int color)  void gdImage::FilledRectangle(int x1, int y1, int x2, int y2, int color)
 {  {
           if(x1>x2) {
                   int t=x1;
                   x1=x2;
                   x2=t;
           }
           if(y1>y2) {
                   int t=y1;
                   y1=y2;
                   y2=t;
           }
         int x, y;          int x, y;
   
         for (y=y1; (y<=y2); y++)          for (y=y1; (y<=y2); y++)
                 for (x=x1; (x<=x2); x++)                  for (x=x1; (x<=x2); x++)
                         SetPixel(x, y, color);                          SetPixel(x, y, color);
Line 479  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;
           int srcTransparent=src.GetTransparent();
           int dstTransparent=dst.GetTransparent();
           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 */
                           /* fixed by paf 20030116, another fix below */
                           if (pd == dstTransparent)
                                   continue;
                           
                           double sy1, sy2, sx1, sx2;
                           double sx, sy;
                           double spixels = 0;
                           double red = 0.0, green = 0.0, blue = 0.0;
                           bool transparent=true;
                           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);
                                           // fix added 20020116 by paf to support transparent src
                                           if (p!=srcTransparent) {
                                                   transparent = false;
                                                   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(transparent)
                                   continue;
   
                           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 656  void gdImage::LineReplaceColor(int x1, i Line 956  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)
Line 788  void gdImage::SetLineWidth(int width) Line 1089  void gdImage::SetLineWidth(int width)
         lineWidth=width;          lineWidth=width;
 }  }
   
 void gdImage::SetLineStyle(const char *alineStyle)  void gdImage::SetLineStyle(const char* alineStyle)
 {  {
         lineStyle=alineStyle;          lineStyle=alineStyle;
 }  }

Removed from v.1.9  
changed lines
  Added in v.1.30.2.3


E-mail: