Diff for /parser3/src/classes/gd/Attic/gif.C between versions 1.16 and 1.33

version 1.16, 2001/10/16 07:47:16 version 1.33, 2003/11/20 17:07:44
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 * const 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 32  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 *) malloc_atomic(asy);
         colorsTotal = 0;          colorsTotal = 0;
         transparent = (-1);          transparent = (-1);
         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 337  void gdImage::Arc(int cx, int cy, int w, Line 337  void gdImage::Arc(int cx, int cy, int w,
                 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);      
                         }                          }
Line 402  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 642  void gdImage::Copy(gdImage& dst, int dst Line 648  void gdImage::Copy(gdImage& dst, int dst
         }          }
 }                         }                       
   
 void gdImage::CopyResized(gdImage& dst, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)  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;          gdImage& src=*this;
         int c;  
         int x, y;          int x, y;
         int tox, toy;          int srcTransparent=src.GetTransparent();
         int ydest;          int dstTransparent=dst.GetTransparent();
         int i;          for (y = dstY; (y < dstY + dstH); y++) {
         int colorMap[gdMaxColors];                  for (x = dstX; (x < dstX + dstW); x++) {
         /* Stretch vectors */                          int pd = dst.GetPixel (x, y);
         int *stx;                          /* Added 7/24/95: support transparent copies */
         int *sty;                          /* fixed by paf 20030116, another fix below */
         /* We only need to use floating point to determine the correct                          if (pd == dstTransparent)
                 stretch vector for one line's worth. */                                  continue;
         double accum;                          
         stx = (int *) malloc(sizeof(int) * srcW);                          double sy1, sy2, sx1, sx2;
         sty = (int *) malloc(sizeof(int) * srcH);                          double sx, sy;
         accum = 0;                          double spixels = 0;
         for (i=0; (i < srcW); i++) {                          double red = 0.0, green = 0.0, blue = 0.0;
                 int got;                          bool transparent=true;
                 accum += (double)dstW/(double)srcW;                          sy1 = ((double) y - (double) dstY) * (double) srcH /
                 got = floor(accum);                                  (double) dstH;
                 stx[i] = got;                          sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH /
                 accum -= got;                                  (double) dstH;
         }                          sy = sy1;
         accum = 0;                          do
         for (i=0; (i < srcH); i++) {                          {
                 int got;                                  double yportion;
                 accum += (double)dstH/(double)srcH;                                  if (floor (sy) == floor (sy1))
                 got = floor(accum);                                  {
                 sty[i] = got;                                          yportion = 1.0 - (sy - floor (sy));
                 accum -= got;                                          if (yportion > sy2 - sy1)
         }                                          {
         for (i=0; (i<gdMaxColors); i++) {                                                  yportion = sy2 - sy1;
                 colorMap[i] = (-1);                                          }
         }                                          sy = floor (sy);
         toy = dstY;  
         for (y=srcY; (y < (srcY + srcH)); y++) {  
                 for (ydest=0; (ydest < sty[y-srcY]); ydest++) {  
                         tox = dstX;  
                         for (x=srcX; (x < (srcX + srcW)); x++) {  
                                 int nc;  
                                 if (!stx[x - srcX]) {  
                                         continue;  
                                 }                                  }
                                 c = src.GetPixel(x, y);                                  else if (sy == floor (sy2))
                                 /* Added 7/24/95: support transparent copies */                                  {
                                 if (src.GetTransparent() == c) {                                          yportion = sy2 - floor (sy2);
                                         tox += stx[x-srcX];  
                                         continue;  
                                 }                                  }
                                 /* Have we established a mapping for this color? */                                  else
                                 if (colorMap[c] == (-1)) {                                  {
                                         /* If it's the same image, mapping is trivial */                                          yportion = 1.0;
                                         if (&dst == &src) {                                  }
                                                 nc = c;                                  sx1 = ((double) x - (double) dstX) * (double) srcW /
                                         } else {                                           dstW;
                                                 /* First look for an exact match */                                  sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW /
                                                 nc = dst.ColorExact(                                          dstW;
                                                         src.red[c], src.green[c],                                  sx = sx1;
                                                         src.blue[c]);                                  do
                                         }                                         {
                                         if (nc == (-1)) {                                          double xportion;
                                                 /* No, so try to allocate it */                                          double pcontribution;
                                                 nc = dst.ColorAllocate(                                          int p;
                                                         src.red[c], src.green[c],                                          if (floor (sx) == floor (sx1))
                                                         src.blue[c]);                                          {
                                                 /* If we're out of colors, go for the                                                  xportion = 1.0 - (sx - floor (sx));
                                                         closest color */                                                  if (xportion > sx2 - sx1)
                                                 if (nc == (-1)) {                                                  {
                                                         nc = dst.ColorClosest(                                                          xportion = sx2 - sx1;
                                                                 src.red[c], src.green[c],  
                                                                 src.blue[c]);  
                                                 }                                                  }
                                                   sx = floor (sx);
                                         }                                          }
                                         colorMap[c] = nc;                                          else if (sx == floor (sx2))
                                 }                                          {
                                 for (i=0; (i < stx[x - srcX]); i++) {                                                  xportion = sx2 - floor (sx2);
                                         dst.SetPixel(tox, toy, colorMap[c]);                                          }
                                         tox++;                                          else
                                 }                                          {
                         }                                                  xportion = 1.0;
                         toy++;                                          }
                 }                                          pcontribution = xportion * yportion;
         }                                          p = src.GetPixel (
         free(stx);                                                  (int) sx,
         free(sty);                                                  (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);
   
 static int gdGetWord(int *result, FILE *in)                          if(transparent)
 {                                  continue;
         int r;  
         r = getc(in);  
         if (r == EOF) {  
                 return 0;  
         }  
         *result = r << 8;  
         r = getc(in);     
         if (r == EOF) {  
                 return 0;  
         }  
         *result += r;  
         return 1;  
 }  
   
 static void gdPutWord(int w, FILE *out)                          if (spixels != 0.0) {
 {                                  red /= spixels;
         putc((unsigned char)(w >> 8), out);                                  green /= spixels;
         putc((unsigned char)(w & 0xFF), out);                                  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);
   
 static int gdGetByte(int *result, FILE *in)                                          /* If we're out of colors, go for the closest color */
 {                                          if (nc == (-1))
         int r;                                                  nc = dst.ColorClosest((int)red, (int)green, (int)blue);
         r = getc(in);                                  }
         if (r == EOF) {                          }
                 return 0;                          dst.SetPixel(x, y, nc);
         }                  }
         *result = r;      }
         return 1;  
 }  }
   
 void gdImage::Polygon(Point *p, int n, int c, bool closed)  void gdImage::Polygon(Point *p, int n, int c, bool closed)
Line 908  void gdImage::LineReplaceColor(int x1, i Line 923  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 1040  void gdImage::SetLineWidth(int width) Line 1056  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.16  
changed lines
  Added in v.1.33


E-mail: