Diff for /parser3/src/classes/gd/Attic/gif.C between versions 1.6 and 1.30.2.4

version 1.6, 2001/09/18 16:05:42 version 1.30.2.4, 2003/02/21 08:50:02
Line 1 Line 1
 /** @file  /** @file
         Parser: image manipulations impl1.          Parser: image manipulations impl1.
   
         Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)          Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
           Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
         $Id$          based on: gd
   
           Written by Tom Boutell, 5/94.
           Copyright 1994, Cold Spring Harbor Labs.
           Permission granted to use this code in any fashion provided
           that this notice is retained and any alterations are
           labeled as such. It is requested, but not required, that
           you share extensions to this module with us so that we
           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 19  void gdImage::Create(int asx, int asy) { Line 32  void gdImage::Create(int asx, int asy) {
         pixels = (unsigned char **) malloc(sizeof(unsigned char *) * sx);          pixels = (unsigned char **) malloc(sizeof(unsigned char *) * sx);
         polyInts = 0;          polyInts = 0;
         polyAllocated = 0;          polyAllocated = 0;
         lineWidth = 1;  lineStyle=0;          lineWidth = 1;
         for (i=0; (i<asx); i++)          for (i=0; (i<asx); i++)
                 pixels[i] = (unsigned char *) calloc(asy);                  pixels[i] = (unsigned char *) calloc(asy);
         colorsTotal = 0;          colorsTotal = 0;
Line 27  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 42  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 258  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 408  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 468  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 645  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 777  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(CharPtr alineStyle)
 {  {
         lineStyle=alineStyle;          lineStyle=alineStyle;
 }  }

Removed from v.1.6  
changed lines
  Added in v.1.30.2.4


E-mail: