]> granicus.if.org Git - graphviz/commitdiff
upgrade mylibgd tree to gd-2.0.35
authorellson <devnull@localhost>
Thu, 26 Jul 2007 18:21:54 +0000 (18:21 +0000)
committerellson <devnull@localhost>
Thu, 26 Jul 2007 18:21:54 +0000 (18:21 +0000)
use system gd-2.0.34 or later on fc7 or later distros

12 files changed:
lib/gd/annotate.c
lib/gd/circletexttest.c
lib/gd/fontwheeltest.c
lib/gd/gd.c
lib/gd/gd.h
lib/gd/gd_gd2.c
lib/gd/gd_gif_in.c
lib/gd/gd_gif_out.c
lib/gd/gd_io.h
lib/gd/gd_io_dp.c
lib/gd/gd_io_ss.c
lib/gd/gd_jpeg.c

index a4dc3b274ac309e0c6eb51c13830aed8bfa87f08..7324e433744583846fee4c21733501e589af71d8 100644 (file)
@@ -19,7 +19,7 @@ enum
 int
 main (int argc, char *argv[])
 {
-#ifndef HAVE_LIBFREETYPE
+#ifndef HAVE_FREETYPE2
   /* 2.0.12 */
   fprintf (stderr, "annotate is not useful without freetype.\n"
           "Install freetype, then './configure; make clean; make install'\n"
@@ -207,5 +207,5 @@ main (int argc, char *argv[])
   gdImageDestroy (im);
   fclose (out);
   return 0;
-#endif /* HAVE_LIBFREETYPE */
+#endif /* HAVE_FREETYPE2 */
 }
index 079ed843248e7b7a6f3462a94cfa2015bfc67bdb..1c6658ff4c6552d0dec06cf233d47c789a4e1cf3 100644 (file)
@@ -5,9 +5,6 @@
 #include <stdio.h>
 #include "gd.h"
 
-/* 2.0.22: oops, we need config.h */
-#include "config.h"
-
 int
 main (int argc, char *argv[])
 {
index b8e4f59ae4aefca6ee466e96e359b52620b22707..b552b6a9ccad0196c4132ff673afe258a6789954 100644 (file)
@@ -22,8 +22,6 @@ dowheel (gdImagePtr im, int color, char *fontfile, int fontsize,
        double angle, int x, int y, int offset, char *string)
 {
   int brect[8];
-  gdPoint points[4];
-  int i;
   FILE *err;
   double curangrads, curang, x0, y0;
   char *cp;
@@ -51,15 +49,7 @@ dowheel (gdImagePtr im, int color, char *fontfile, int fontsize,
       if (cp)
        doerr (err, cp);
 
-      /* FIXME - this is silly, but if we try to cast int[] to gdPointPtr
-       * we get a "warning: dereferencing type-punned pointer will break strict -aliasing rules" from gcc
-       * The proper fix probably requires an API change to use gdPoint[] in gdImageString*
-       */
-      for (i = 0; i < 4; i++) {
-       points[i].x = brect[2*i];
-       points[i].y = brect[2*i + 1];
-      }
-      gdImagePolygon (im, points, 4, color);
+      gdImagePolygon (im, (gdPointPtr)brect, 4, color);
     }
 
   fclose (err);
index e809613c80635b65e847fe542052f81c917ed66f..30920c0949343e3a28f1535da7730f78b1ed2944 100644 (file)
@@ -1,3 +1,4 @@
+/* $Id$ */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -71,17 +72,27 @@ BGD_DECLARE(gdImagePtr) gdImageCreate (int sx, int sy)
 {
   int i;
   gdImagePtr im;
+
+  if (overflow2(sizeof (unsigned char *), sy)) {
+               return NULL;
+  }
+  if (overflow2(sizeof (unsigned char *), sx)) {
+               return NULL;
+  }
+
   im = (gdImage *) gdMalloc (sizeof (gdImage));
-  if (!im)
-    return NULL;
+       if (!im) {
+               return NULL;
+       }
+
   memset (im, 0, sizeof (gdImage));
   /* Row-major ever since gd 1.3 */
   im->pixels = (unsigned char **) gdMalloc (sizeof (unsigned char *) * sy);
-  if (!im->pixels)
-    {
-      free(im);
-      return NULL;
-    }
+       if (!im->pixels) {
+               gdFree(im);
+               return NULL;
+       }
+
   im->polyInts = 0;
   im->polyAllocated = 0;
   im->brush = 0;
@@ -91,15 +102,17 @@ BGD_DECLARE(gdImagePtr) gdImageCreate (int sx, int sy)
     {
       /* Row-major ever since gd 1.3 */
       im->pixels[i] = (unsigned char *) gdCalloc (sx, sizeof (unsigned char));
-      if (!im->pixels[i]) 
-       {
-         for (--i ; i >= 0; i--)
-           {
-             gdFree(im->pixels[i]);
-           }
-         gdFree(im);
-         return NULL;
-       }
+                       if (!im->pixels[i]) 
+                       {
+                               for (--i ; i >= 0; i--)
+                               {
+                                       gdFree(im->pixels[i]);
+                               }
+                               gdFree(im->pixels);
+                               gdFree(im);
+                               return NULL;
+                       }
+
     }
   im->sx = sx;
   im->sy = sy;
@@ -128,9 +141,30 @@ BGD_DECLARE(gdImagePtr) gdImageCreateTrueColor (int sx, int sy)
 {
   int i;
   gdImagePtr im;
+
+  if (overflow2(sx, sy)) {
+    return NULL;
+  }
+
+  if (overflow2(sizeof (int *), sy)) {
+    return 0;
+  }
+
+  if (overflow2(sizeof(int), sx)) {
+    return NULL;
+  }
+
   im = (gdImage *) gdMalloc (sizeof (gdImage));
+  if (!im) {
+    return 0;
+  }
   memset (im, 0, sizeof (gdImage));
+
   im->tpixels = (int **) gdMalloc (sizeof (int *) * sy);
+  if (!im->tpixels) {
+    gdFree(im);
+    return 0;
+  }
   im->polyInts = 0;
   im->polyAllocated = 0;
   im->brush = 0;
@@ -139,6 +173,17 @@ BGD_DECLARE(gdImagePtr) gdImageCreateTrueColor (int sx, int sy)
   for (i = 0; (i < sy); i++)
     {
       im->tpixels[i] = (int *) gdCalloc (sx, sizeof (int));
+      if (!im->tpixels[i]) {
+        /* 2.0.34 */
+        i--;
+        while (i >= 0) {
+          gdFree(im->tpixels[i]);
+          i--;
+        }
+        gdFree(im->tpixels);
+        gdFree(im);
+        return 0;
+      }
     }
   im->sx = sx;
   im->sy = sy;
@@ -311,7 +356,7 @@ HWB_Diff (int r1, int g1, int b1, int r2, int g2, int b2)
     }
   else
     {
-      diff = abs (HWB1.H - HWB2.H);
+      diff = fabs (HWB1.H - HWB2.H);
       if (diff > 3)
        {
          diff = 6 - diff;      /* Remember, it's a colour circle */
@@ -892,7 +937,9 @@ gdImageTileApply (gdImagePtr im, int x, int y)
   if (im->trueColor)
     {
       p = gdImageGetTrueColorPixel (im->tile, srcx, srcy);
-      gdImageSetPixel (im, x, y, p);
+                       if (p != gdImageGetTransparent (im->tile)) {
+             gdImageSetPixel (im, x, y, p);
+                       }
     }
   else
     {
@@ -949,7 +996,7 @@ BGD_DECLARE(int) gdImageGetTrueColorPixel (gdImagePtr im, int x, int y)
     {
       return gdTrueColorAlpha (im->red[p], im->green[p], im->blue[p],
                               (im->transparent == p) ? gdAlphaTransparent :
-                              gdAlphaOpaque);
+                              im->alpha[p]);
     }
   else
     {
@@ -964,6 +1011,44 @@ BGD_DECLARE(void) gdImageAABlend (gdImagePtr im)
 
 static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col);
 
+static void gdImageHLine(gdImagePtr im, int y, int x1, int x2, int col)
+{
+       if (im->thick > 1) {
+               int thickhalf = im->thick >> 1;
+               gdImageFilledRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col);
+       } else {
+               if (x2 < x1) {
+                       int t = x2;
+                       x2 = x1;
+                       x1 = t;
+               }
+
+               for (;x1 <= x2; x1++) {
+                       gdImageSetPixel(im, x1, y, col);
+               }
+       }
+       return;
+}
+
+static void gdImageVLine(gdImagePtr im, int x, int y1, int y2, int col)
+{
+       if (im->thick > 1) {
+               int thickhalf = im->thick >> 1;
+               gdImageFilledRectangle(im, x - thickhalf, y1, x + im->thick - thickhalf - 1, y2, col);
+       } else {
+               if (y2 < y1) {
+                       int t = y1;
+                       y1 = y2;
+                       y2 = t;
+               }
+
+               for (;y1 <= y2; y1++) {
+                       gdImageSetPixel(im, x, y1, col);
+               }
+       }
+       return;
+}
+
 /* Bresenham as presented in Foley & Van Dam */
 BGD_DECLARE(void) gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
 {
@@ -971,6 +1056,7 @@ BGD_DECLARE(void) gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, in
   int wid;
   int w, wstart;
   int thick;
+
   if (color == gdAntiAliased)
     {
       /* 
@@ -995,6 +1081,15 @@ BGD_DECLARE(void) gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, in
 
   dx = abs (x2 - x1);
   dy = abs (y2 - y1);
+
+       if (dx == 0) {
+               gdImageVLine(im, x1, y1, y2, color);
+               return;
+       } else if (dy == 0) {
+               gdImageHLine(im, y1, x1, x2, color);
+               return;
+       }
+
   if (dy <= dx)
     {
       /* More-or-less horizontal. use wid for vertical stroke */
@@ -1513,10 +1608,31 @@ BGD_DECLARE(void) gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h,
   int i;
   int lx = 0, ly = 0;
   int fx = 0, fy = 0;
-  while (e < s)
-    {
-      e += 360;
-    }
+
+  if ((s % 360)  == (e % 360)) {
+         s = 0; e = 360;
+  } else {
+         if (s > 360) {
+                 s = s % 360;
+         }
+
+         if (e > 360) {
+                 e = e % 360;
+         }
+
+         while (s < 0) {
+                 s += 360;
+         }
+
+         while (e < s) {
+                 e += 360;
+         }
+
+         if (s == e) {
+                 s = 0; e = 360;
+         }
+  }
+
   for (i = s; (i <= e); i++)
     {
       int x, y;
@@ -1526,7 +1642,7 @@ BGD_DECLARE(void) gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h,
        {
          if (!(style & gdChord))
            {
-             if (style & gdNoFill)
+               if (style & gdNoFill)
                {
                  gdImageLine (im, lx, ly, x, y, color);
                }
@@ -1586,9 +1702,56 @@ BGD_DECLARE(void) gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h,
     }
 }
 
-BGD_DECLARE(void) gdImageFilledEllipse (gdImagePtr im, int cx, int cy, int w, int h, int color)
+BGD_DECLARE(void) gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c)
 {
-  gdImageFilledArc (im, cx, cy, w, h, 0, 360, color, gdPie);
+       int x=0,mx1=0,mx2=0,my1=0,my2=0;
+       long aq,bq,dx,dy,r,rx,ry,a,b;
+       int i;
+       int old_y1,old_y2;
+
+       a=w>>1;
+       b=h>>1;
+
+       gdImageLine(im, mx-a, my, mx+a, my, c);
+
+       mx1 = mx-a;my1 = my;
+       mx2 = mx+a;my2 = my;
+
+       aq = a * a;
+       bq = b * b;
+       dx = aq << 1;
+       dy = bq << 1;
+       r  = a * bq;
+       rx = r << 1;
+       ry = 0;
+       x = a;
+       old_y2=-2;
+       old_y1=-2;
+       while (x > 0){
+               if (r > 0) {
+                       my1++;my2--;
+                       ry +=dx;
+                       r  -=ry;
+               }
+               if (r <= 0){
+                       x--;
+                       mx1++;mx2--;
+                       rx -=dy;
+                       r  +=rx;
+               }
+               if(old_y2!=my2){
+                       for(i=mx1;i<=mx2;i++){
+                               gdImageSetPixel(im,i,my1,c);
+                       }
+               }
+               if(old_y2!=my2){
+                       for(i=mx1;i<=mx2;i++){
+                               gdImageSetPixel(im,i,my2,c);
+                       }
+               }
+               old_y2 = my2;
+               old_y1 = my1;
+       }
 }
 
 BGD_DECLARE(void) gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
@@ -1597,12 +1760,19 @@ BGD_DECLARE(void) gdImageFillToBorder (gdImagePtr im, int x, int y, int border,
   /* Seek left */
   int leftLimit, rightLimit;
   int i;
-  leftLimit = (-1);
+       int restoreAlphaBleding;
+
   if (border < 0)
     {
       /* Refuse to fill to a non-solid border */
       return;
     }
+
+       leftLimit = (-1);
+
+       restoreAlphaBleding = im->alphaBlendingFlag;
+       im->alphaBlendingFlag = 0;
+
   for (i = x; (i >= 0); i--)
     {
       if (gdImageGetPixel (im, i, y) == border)
@@ -1614,6 +1784,7 @@ BGD_DECLARE(void) gdImageFillToBorder (gdImagePtr im, int x, int y, int border,
     }
   if (leftLimit == (-1))
     {
+                       im->alphaBlendingFlag = restoreAlphaBleding;
       return;
     }
   /* Seek right */
@@ -1656,8 +1827,7 @@ BGD_DECLARE(void) gdImageFillToBorder (gdImagePtr im, int x, int y, int border,
       lastBorder = 1;
       for (i = leftLimit; (i <= rightLimit); i++)
        {
-         int c;
-         c = gdImageGetPixel (im, i, y + 1);
+         int c = gdImageGetPixel (im, i, y + 1);
          if (lastBorder)
            {
              if ((c != border) && (c != color))
@@ -1672,165 +1842,329 @@ BGD_DECLARE(void) gdImageFillToBorder (gdImagePtr im, int x, int y, int border,
            }
        }
     }
+       im->alphaBlendingFlag = restoreAlphaBleding;
+}
+
+/*
+ * set the pixel at (x,y) and its 4-connected neighbors
+ * with the same pixel value to the new pixel value nc (new color).
+ * A 4-connected neighbor:  pixel above, below, left, or right of a pixel.
+ * ideas from comp.graphics discussions.
+ * For tiled fill, the use of a flag buffer is mandatory. As the tile image can
+ * contain the same color as the color to fill. To do not bloat normal filling
+ * code I added a 2nd private function.
+ */
+
+static int gdImageTileGet (gdImagePtr im, int x, int y)
+{
+       int srcx, srcy;
+       int tileColor,p;
+       if (!im->tile) {
+               return -1;
+       }
+       srcx = x % gdImageSX(im->tile);
+       srcy = y % gdImageSY(im->tile);
+       p = gdImageGetPixel(im->tile, srcx, srcy);
+       if (p == im->tile->transparent) {
+               tileColor = im->transparent;
+       } else if (im->trueColor) {
+               if (im->tile->trueColor) {
+                       tileColor = p;
+               } else {
+                       tileColor = gdTrueColorAlpha( gdImageRed(im->tile,p), gdImageGreen(im->tile,p), gdImageBlue (im->tile,p), gdImageAlpha (im->tile,p));
+               }
+       } else {
+               if (im->tile->trueColor) {
+                       tileColor = gdImageColorResolveAlpha(im, gdTrueColorGetRed (p), gdTrueColorGetGreen (p), gdTrueColorGetBlue (p), gdTrueColorGetAlpha (p));
+               } else {
+                       tileColor = p;
+                       tileColor = gdImageColorResolveAlpha(im, gdImageRed (im->tile,p), gdImageGreen (im->tile,p), gdImageBlue (im->tile,p), gdImageAlpha (im->tile,p));
+               }
+       }
+       return tileColor;
 }
 
-BGD_DECLARE(void) gdImageFill (gdImagePtr im, int x, int y, int color)
+
+
+/* horizontal segment of scan line y */
+struct seg {int y, xl, xr, dy;};
+
+/* max depth of stack */
+#define FILL_MAX 1200000
+#define FILL_PUSH(Y, XL, XR, DY) \
+    if (sp<stack+FILL_MAX*10 && Y+(DY)>=0 && Y+(DY)<wy2) \
+    {sp->y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;}
+
+#define FILL_POP(Y, XL, XR, DY) \
+    {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}
+
+void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc);
+BGD_DECLARE(void) gdImageFill(gdImagePtr im, int x, int y, int nc)
 {
-  int lastBorder;
-  int old;
-  int leftLimit, rightLimit;
-  int i;
-  old = gdImageGetPixel (im, x, y);
-  if (color == gdTiled)
-    {
-      /* Tile fill -- got to watch out! */
-      int p, tileColor;
-      int srcx, srcy;
-      if (!im->tile)
-       {
-         return;
+       int l, x1, x2, dy;
+       int oc;   /* old pixel value */
+       int wx2,wy2;
+
+       int alphablending_bak;
+
+       /* stack of filled segments */
+       /* struct seg stack[FILL_MAX],*sp = stack;; */
+       struct seg *stack;
+       struct seg *sp;
+
+       if (!im->trueColor && nc > (im->colorsTotal - 1)) {
+               return;
        }
-      /* Refuse to flood-fill with a transparent pattern --
-         I can't do it without allocating another image */
-      if (gdImageGetTransparent (im->tile) != (-1))
-       {
-         return;
+
+       alphablending_bak = im->alphaBlendingFlag;      
+       im->alphaBlendingFlag = 0;
+
+       if (nc==gdTiled) {
+               _gdImageFillTiled(im,x,y,nc);
+               im->alphaBlendingFlag = alphablending_bak;
+               return;
        }
-      srcx = x % gdImageSX (im->tile);
-      srcy = y % gdImageSY (im->tile);
-      p = gdImageGetPixel (im->tile, srcx, srcy);
-      if (im->trueColor)
-       {
-         tileColor = p;
+
+       wx2=im->sx;wy2=im->sy;
+       oc = gdImageGetPixel(im, x, y);
+       if (oc==nc || x<0 || x>wx2 || y<0 || y>wy2) {
+               im->alphaBlendingFlag = alphablending_bak;      
+               return;
        }
-      else
-       {
-         if (im->tile->trueColor)
-           {
-             tileColor = gdImageColorResolveAlpha (im,
-                                                   gdTrueColorGetRed (p),
-                                                   gdTrueColorGetGreen (p),
-                                                   gdTrueColorGetBlue (p),
-                                                   gdTrueColorGetAlpha (p));
-           }
-         else
-           {
-             tileColor = im->tileColorMap[p];
-           }
+
+       /* Do not use the 4 neighbors implementation with
+   * small images
+   */
+       if (im->sx < 4) {
+               int ix = x, iy = y, c;
+               do {
+                       c = gdImageGetPixel(im, ix, iy);
+                       if (c != oc) {
+                               goto done;
+                       }
+                       gdImageSetPixel(im, ix, iy, nc);
+               } while(ix++ < (im->sx -1));
+               ix = x; iy = y + 1;
+               do {
+                       c = gdImageGetPixel(im, ix, iy);
+                       if (c != oc) {
+                               goto done;
+                       }
+                       gdImageSetPixel(im, ix, iy, nc);
+               } while(ix++ < (im->sx -1));
+               goto done;
        }
-      if (old == tileColor)
-       {
-         /* Nothing to be done */
-         return;
+
+       stack = (struct seg *)gdMalloc(sizeof(struct seg) * ((int)(im->sy*im->sx)/4));
+       if (!stack) {
+               return;
        }
-    }
-  else
-    {
-      if (old == color)
-       {
-         /* Nothing to be done */
-         return;
+       sp = stack;
+
+       /* required! */
+       FILL_PUSH(y,x,x,1);
+       /* seed segment (popped 1st) */
+       FILL_PUSH(y+1, x, x, -1);
+       while (sp>stack) {
+               FILL_POP(y, x1, x2, dy);
+
+               for (x=x1; x>=0 && gdImageGetPixel(im,x, y)==oc; x--) {
+                       gdImageSetPixel(im,x, y, nc);
+               }
+               if (x>=x1) {
+                       goto skip;
+               }
+               l = x+1;
+
+                /* leak on left? */
+               if (l<x1) {
+                       FILL_PUSH(y, l, x1-1, -dy);
+               }
+               x = x1+1;
+               do {
+                       for (; x<=wx2 && gdImageGetPixel(im,x, y)==oc; x++) {
+                               gdImageSetPixel(im, x, y, nc);
+                       }
+                       FILL_PUSH(y, l, x-1, dy);
+                       /* leak on right? */
+                       if (x>x2+1) {
+                               FILL_PUSH(y, x2+1, x-1, -dy);
+                       }
+skip:                  for (x++; x<=x2 && (gdImageGetPixel(im, x, y)!=oc); x++);
+
+                       l = x;
+               } while (x<=x2);
        }
-    }
-  /* Seek left */
-  leftLimit = (-1);
-  for (i = x; (i >= 0); i--)
-    {
-      if (gdImageGetPixel (im, i, y) != old)
-       {
-         break;
+
+       gdFree(stack);
+
+done:
+       im->alphaBlendingFlag = alphablending_bak;      
+}
+
+void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
+{
+       int i,l, x1, x2, dy;
+       int oc;   /* old pixel value */
+       int tiled;
+       int wx2,wy2;
+       /* stack of filled segments */
+       struct seg *stack;
+       struct seg *sp;
+
+       int **pts;
+       if(!im->tile){
+               return;
        }
-      gdImageSetPixel (im, i, y, color);
-      leftLimit = i;
-    }
-  if (leftLimit == (-1))
-    {
-      return;
-    }
-  /* Seek right */
-  rightLimit = x;
-  for (i = (x + 1); (i < im->sx); i++)
-    {
-      if (gdImageGetPixel (im, i, y) != old)
-       {
-         break;
+
+       wx2=im->sx;wy2=im->sy;
+       tiled = nc==gdTiled;
+
+       nc =  gdImageTileGet(im,x,y);
+       pts = (int **) gdCalloc(sizeof(int *) * im->sy, sizeof(int));
+       if (!pts) {
+               return;
        }
-      gdImageSetPixel (im, i, y, color);
-      rightLimit = i;
-    }
-  /* Look at lines above and below and start paints */
-  /* Above */
-  if (y > 0)
-    {
-      lastBorder = 1;
-      for (i = leftLimit; (i <= rightLimit); i++)
-       {
-         int c;
-         c = gdImageGetPixel (im, i, y - 1);
-         if (lastBorder)
-           {
-             if (c == old)
-               {
-                 gdImageFill (im, i, y - 1, color);
-                 lastBorder = 0;
+
+       for (i=0; i<im->sy;i++) {
+               pts[i] = (int *) gdCalloc(im->sx, sizeof(int));
+
+               if (!pts[i]) {
+                       for (--i ; i >= 0; i--) {
+                               gdFree(pts[i]);
+                       }
+                       return;
                }
-           }
-         else if (c != old)
-           {
-             lastBorder = 1;
-           }
        }
-    }
-  /* Below */
-  if (y < ((im->sy) - 1))
-    {
-      lastBorder = 1;
-      for (i = leftLimit; (i <= rightLimit); i++)
-       {
-         int c;
-         c = gdImageGetPixel (im, i, y + 1);
-         if (lastBorder)
-           {
-             if (c == old)
-               {
-                 gdImageFill (im, i, y + 1, color);
-                 lastBorder = 0;
+
+       stack = (struct seg *)gdMalloc(sizeof(struct seg) * ((int)(im->sy*im->sx)/4));
+       if (!stack) {
+               return;
+       }
+       sp = stack;
+
+       oc = gdImageGetPixel(im, x, y);
+
+       /* required! */
+       FILL_PUSH(y,x,x,1);
+       /* seed segment (popped 1st) */
+       FILL_PUSH(y+1, x, x, -1);
+       while (sp>stack) {
+               FILL_POP(y, x1, x2, dy);
+               for (x=x1; x>=0 && (!pts[y][x] && gdImageGetPixel(im,x,y)==oc); x--) {
+                       if (pts[y][x]){
+                               /* we should never be here */
+                               break;
+                       }
+                       nc = gdImageTileGet(im,x,y);
+                       pts[y][x]=1;
+                       gdImageSetPixel(im,x, y, nc);
                }
-           }
-         else if (c != old)
-           {
-             lastBorder = 1;
-           }
+               if (x>=x1) {
+                       goto skip;
+               }
+               l = x+1;
+
+               /* leak on left? */
+               if (l<x1) {
+                       FILL_PUSH(y, l, x1-1, -dy);
+               }
+               x = x1+1;
+               do {
+                       for (; x<wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc) ; x++) {
+                               if (pts[y][x]){
+                                       /* we should never be here */
+                                       break;
+                               }
+                               nc = gdImageTileGet(im,x,y);
+                               pts[y][x]=1;
+                               gdImageSetPixel(im, x, y, nc);
+                       }
+                       FILL_PUSH(y, l, x-1, dy);
+                       /* leak on right? */
+                       if (x>x2+1) {
+                               FILL_PUSH(y, x2+1, x-1, -dy);
+                       }
+skip:                  for (x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++);
+                       l = x;
+               } while (x<=x2);
        }
-    }
+       for (i=0; i<im->sy;i++) {
+               gdFree(pts[i]);
+       }
+       gdFree(pts);
+       gdFree(stack);
 }
 
 BGD_DECLARE(void) gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
 {
-  int x1h = x1, x1v = x1, y1h = y1, y1v = y1, x2h = x2, x2v = x2, y2h = y2,
-    y2v = y2;
-  int thick = im->thick;
-  if (thick > 1)
-    {
-      int half = thick / 2;
-      int half1 = thick - half;
+       int x1h = x1, x1v = x1, y1h = y1, y1v = y1, x2h = x2, x2v = x2, y2h = y2, y2v = y2;
+       int thick = im->thick;
+       int half1 = 1;
+       int t;
+
+       if (y2 < y1) {
+               t=y1;
+               y1 = y2;
+               y2 = t;
+
+               t = x1;
+               x1 = x2;
+               x2 = t;
+       }
+
+       x1h = x1; x1v = x1; y1h = y1; y1v = y1; x2h = x2; x2v = x2; y2h = y2; y2v = y2;
+       if (thick > 1) {
+               int cx, cy, x1ul, y1ul, x2lr, y2lr;
+               int half = thick >> 1;
+               half1 = thick - half;
+               x1ul = x1 - half;
+               y1ul = y1 - half;
+               
+               x2lr = x2 + half;
+               y2lr = y2 + half;
+
+               cy = y1ul + thick;
+               while (cy-- > y1ul) {
+                       cx = x1ul - 1;
+                       while (cx++ < x2lr) {
+                               gdImageSetPixel(im, cx, cy, color);
+                       }
+               }
 
-      if (y1 < y2)
-       {
-         y1v = y1h - half;
-         y2v = y2h + half1 - 1;
-       }
-      else
-       {
-         y1v = y1h + half1 - 1;
-         y2v = y2h - half;
-       }
-    }
+               cy = y2lr - thick;
+               while (cy++ < y2lr) {
+                       cx = x1ul - 1;
+                       while (cx++ < x2lr) {
+                               gdImageSetPixel(im, cx, cy, color);
+                       }
+               }
 
-  gdImageLine (im, x1h, y1h, x2h, y1h, color);
-  gdImageLine (im, x1h, y2h, x2h, y2h, color);
-  gdImageLine (im, x1v, y1v, x1v, y2v, color);
-  gdImageLine (im, x2v, y1v, x2v, y2v, color);
+               cy = y1ul + thick - 1;
+               while (cy++ < y2lr -thick) {
+                       cx = x1ul - 1;
+                       while (cx++ < x1ul + thick) {
+                               gdImageSetPixel(im, cx, cy, color);
+                       }
+               }
+
+               cy = y1ul + thick - 1;
+               while (cy++ < y2lr -thick) {
+                       cx = x2lr - thick - 1;
+                       while (cx++ < x2lr) {
+                               gdImageSetPixel(im, cx, cy, color);
+                       }
+               }
+
+               return;
+       } else {
+               y1v = y1h + 1;
+               y2v = y2h - 1;
+               gdImageLine(im, x1h, y1h, x2h, y1h, color);
+               gdImageLine(im, x1h, y2h, x2h, y2h, color);
+               gdImageLine(im, x1v, y1v, x1v, y2v, color);
+               gdImageLine(im, x2v, y1v, x2v, y2v, color);
+       }
 }
 
 BGD_DECLARE(void) gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2,
@@ -1841,13 +2175,24 @@ BGD_DECLARE(void) gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2,
      nicely kills any plotting for rectangles completely outside the
      window as it makes the tests in the for loops fail */
   if (x1 < 0)
-    x1 = 0;
+         x1 = 0;
   if (x1 > gdImageSX (im))
-    x1 = gdImageSX (im);
+         x1 = gdImageSX (im);
   if (y1 < 0)
-    y1 = 0;
+         y1 = 0;
   if (y1 > gdImageSY (im))
-    y1 = gdImageSY (im);
+         y1 = gdImageSY (im);
+
+  if (x1 > x2) {
+         x = x1;
+         x1 = x2;
+         x2 = x;
+  }
+  if (y1 > y2) {
+         y = y1;
+         y1 = y2;
+         y2 = y;
+  }
 
   for (y = y1; (y <= y2); y++)
     {
@@ -1866,52 +2211,60 @@ BGD_DECLARE(void) gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dst
   int tox, toy;
   int i;
   int colorMap[gdMaxColors];
-  if (dst->trueColor)
-    {
-      /* 2.0: much easier when the destination is truecolor. */
-      /* 2.0.10: needs a transparent-index check that is still valid if
-         the source is not truecolor. Thanks to Frank Warmerdam. */
-      for (y = 0; (y < h); y++)
-       {
-         for (x = 0; (x < w); x++)
-           {
-             int p = gdImageGetPixel (src, srcX + x, srcY + y);
-             if (p != src->transparent)
-               {
-                 int c = gdImageGetTrueColorPixel (src, srcX + x,
-                                                   srcY + y);
-                 gdImageSetPixel (dst, dstX + x, dstY + y, c);
-               }
-           }
-       }
-      return;
-    }
+
+  if (dst->trueColor) {
+         /* 2.0: much easier when the destination is truecolor. */
+         /* 2.0.10: needs a transparent-index check that is still valid if
+          *          * the source is not truecolor. Thanks to Frank Warmerdam.
+          */
+
+         if (src->trueColor) {
+                 for (y = 0; (y < h); y++) {
+                         for (x = 0; (x < w); x++) {
+                                 int c = gdImageGetTrueColorPixel (src, srcX + x, srcY + y);
+                                 gdImageSetPixel (dst, dstX + x, dstY + y, c);
+                         }
+                 }
+         } else {
+                 /* source is palette based */
+                 for (y = 0; (y < h); y++) {
+                         for (x = 0; (x < w); x++) {
+                                 int c = gdImageGetPixel (src, srcX + x, srcY + y);
+                                 if (c != src->transparent) {
+                                         gdImageSetPixel(dst, dstX + x, dstY + y, gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]));
+                                 }
+                         }
+                 }
+         }
+         return;
+  }
+
   for (i = 0; (i < gdMaxColors); i++)
-    {
-      colorMap[i] = (-1);
-    }
+  {
+         colorMap[i] = (-1);
+  }
   toy = dstY;
   for (y = srcY; (y < (srcY + h)); y++)
-    {
-      tox = dstX;
-      for (x = srcX; (x < (srcX + w)); x++)
-       {
-         int nc;
-         int mapTo;
-         c = gdImageGetPixel (src, x, y);
-         /* Added 7/24/95: support transparent copies */
-         if (gdImageGetTransparent (src) == c)
-           {
-             tox++;
-             continue;
-           }
-         /* Have we established a mapping for this color? */
-         if (src->trueColor)
-           {
-             /* 2.05: remap to the palette available in the
-                destination image. This is slow and
-                works badly, but it beats crashing! Thanks 
-                to Padhrig McCarthy. */
+  {
+         tox = dstX;
+         for (x = srcX; (x < (srcX + w)); x++)
+         {
+                 int nc;
+                 int mapTo;
+                 c = gdImageGetPixel (src, x, y);
+                 /* Added 7/24/95: support transparent copies */
+                 if (gdImageGetTransparent (src) == c)
+                 {
+                         tox++;
+                         continue;
+                 }
+                 /* Have we established a mapping for this color? */
+                 if (src->trueColor)
+                 {
+                         /* 2.05: remap to the palette available in the
+                                destination image. This is slow and
+                                works badly, but it beats crashing! Thanks 
+                                to Padhrig McCarthy. */
              mapTo = gdImageColorResolveAlpha (dst,
                                                gdTrueColorGetRed (c),
                                                gdTrueColorGetGreen (c),
@@ -2034,8 +2387,8 @@ BGD_DECLARE(void) gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX
          else
            {
              dc = gdImageGetPixel (dst, tox, toy);
-             g = 0.29900 * dst->red[dc]
-               + 0.58700 * dst->green[dc] + 0.11400 * dst->blue[dc];
+             g = 0.29900 * gdImageRed(dst, dc)
+               + 0.58700 * gdImageGreen(dst, dc) + 0.11400 * gdImageBlue(dst, dc);
 
              ncR = gdImageRed (src, c) * (pct / 100.0)
                + g * ((100 - pct) / 100.0);
@@ -2087,7 +2440,15 @@ BGD_DECLARE(void) gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX,
     return;
   }
   stx = (int *) gdMalloc (sizeof (int) * srcW);
+       if (!stx) {
+               return;
+       }
+
   sty = (int *) gdMalloc (sizeof (int) * srcH);
+       if (!sty) {
+               return;
+       }
+
   /* Fixed by Mao Morimoto 2.0.16 */
   for (i = 0; (i < srcW); i++)
     {
@@ -2230,6 +2591,17 @@ BGD_DECLARE(void) gdImageCopyRotated (gdImagePtr dst,
   double scY = srcY + ((double) srcHeight) / 2;
   int cmap[gdMaxColors];
   int i;
+
+       /* 
+                2.0.34: transparency preservation. The transparentness of
+                the transparent color is more important than its hue.
+       */
+       if (src->transparent != -1) {
+               if (dst->transparent == -1) {
+                       dst->transparent = src->transparent;
+               }
+       }
+
   for (i = 0; (i < gdMaxColors); i++)
     {
       cmap[i] = (-1);
@@ -2245,9 +2617,14 @@ BGD_DECLARE(void) gdImageCopyRotated (gdImagePtr dst,
          if ((sx >= srcX) && (sx < srcX + srcWidth) &&
              (sy >= srcY) && (sy < srcY + srcHeight))
            {
-             int c = gdImageGetPixel (src, sx, sy);
-             if (!src->trueColor)
-               {
+                               int c = gdImageGetPixel (src, sx, sy);
+                               /* 2.0.34: transparency wins */
+                               if (c == src->transparent) 
+                               {
+                                       gdImageSetPixel (dst, dx, dy, dst->transparent);
+                               }  
+                                       else if (!src->trueColor)
+                               {
                  /* Use a table to avoid an expensive
                     lookup on every single pixel */
                  if (cmap[c] == -1)
@@ -2478,6 +2855,10 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm (FILE * fd)
     }
   bytes = (w * h / 8) + 1;
   im = gdImageCreate (w, h);
+  if (!im) {
+    return 0;
+  }
+
   gdImageColorAllocate (im, 255, 255, 255);
   gdImageColorAllocate (im, 0, 0, 0);
   x = 0;
@@ -2608,6 +2989,9 @@ BGD_DECLARE(void) gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int
         return;
       }
       im->polyInts = (int *) gdMalloc (sizeof (int) * n);
+                       if (!im->polyInts) {
+                               return;
+                       }
       im->polyAllocated = n;
     }
   if (im->polyAllocated < n)
@@ -2616,8 +3000,14 @@ BGD_DECLARE(void) gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int
        {
          im->polyAllocated *= 2;
        }
+      if (overflow2(sizeof (int), im->polyAllocated)) {
+        return;
+      }
       im->polyInts = (int *) gdRealloc (im->polyInts,
                                        sizeof (int) * im->polyAllocated);
+                       if (!im->polyInts) {
+                               return;
+                       }
     }
   miny = p[0].y;
   maxy = p[0].y;
@@ -2772,6 +3162,9 @@ BGD_DECLARE(void) gdImageSetStyle (gdImagePtr im, int *style, int noOfPixels)
     return;
   }    
   im->style = (int *) gdMalloc (sizeof (int) * noOfPixels);
+       if (!im->style) {
+               return;
+       }
   memcpy (im->style, style, sizeof (int) * noOfPixels);
   im->styleLength = noOfPixels;
   im->stylePos = 0;
@@ -3048,6 +3441,11 @@ nc = (cc) + (((((c) - (cc)) * (a)) + ((((c) - (cc)) * (a)) >> 8) + 0x80) >> 8);
 static void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color, int t)
 {
        int dr,dg,db,p,r,g,b;
+
+       /* 2.0.34: watch out for out of range calls */
+       if (!gdImageBoundsSafeMacro(im, x, y)) {
+               return;
+       }
        p = gdImageGetPixel(im,x,y);
         /* TBB: we have to implement the dont_blend stuff to provide
           the full feature set of the old implementation */
@@ -3068,7 +3466,7 @@ static void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color, int t
        BLEND_COLOR(t, dr, r, dr);
        BLEND_COLOR(t, dg, g, dg);
        BLEND_COLOR(t, db, b, db);
-       im->tpixels[y][x]=gdTrueColorAlpha(dr, dg, db,  gdAlphaOpaque);
+       im->tpixels[y][x] = gdTrueColorAlpha(dr, dg, db,  gdAlphaOpaque);
 }  
 
 static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
@@ -3076,6 +3474,7 @@ static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int co
        /* keep them as 32bits */
        long x, y, inc;
        long dx, dy,tmp;
+
        if (!im->trueColor) {
                /* TBB: don't crash when the image is of the wrong type */
                gdImageLine(im, x1, y1, x2, y2, col);
@@ -3089,6 +3488,15 @@ static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int co
        dx = x2 - x1;
        dy = y2 - y1;
 
+       /* Axis aligned lines */
+       if (dx == 0) {
+               gdImageVLine(im, x1, y1, y2, col);
+               return;
+       } else if (dy == 0) {
+               gdImageHLine(im, y1, x1, x2, col);
+               return;
+       }
+
        if (dx == 0 && dy == 0) {
                /* TBB: allow setting points */
                gdImageSetAAPixelColor(im, x1, y1, col, 0xFF);
index 03f3a018f77991bfdc2f31675d933a75f1ebfa7d..f136ea658050eb400ea16c945ab499e8a12ce0f4 100644 (file)
@@ -5,6 +5,13 @@ extern "C" {
 #ifndef GD_H
 #define GD_H 1
 
+#define GD_MAJOR_VERSION 2
+#define GD_MINOR_VERSION 0
+#define GD_RELEASE_VERSION 35
+#define GD_EXTRA_VERSION ""
+#define GD_VERSION_STRING "2.0.35"
+
+
 /* Do the DLL dance: dllexport when building the DLL,
        dllimport when importing from it, nothing when
        not on Silly Silly Windows (tm Aardman Productions). */
@@ -55,6 +62,11 @@ extern "C"
 #endif
 
 /* some might want to set DEFAULT_FONTPATH from configure in config.h */
+#ifdef NETWARE
+/* default fontpath for netware systems, could probably be handled in configure for 2.1 */
+#define DEFAULT_FONTPATH "sys:/java/nwgfx/lib/x11/fonts/ttf;."
+#define PATHSEPARATOR ";"
+#endif
 
 /* 2.0.23: more Type 1 fonts */
 #ifndef DEFAULT_FONTPATH
@@ -390,7 +402,8 @@ BGD_DECLARE(char *) gdImageStringFT (gdImage * im, int *brect, int fg, char *fon
     int flags;                 /* Logical OR of gdFTEX_ values */
     double linespacing;                /* fine tune line spacing for '\n' */
     int charmap;               /* TBB: 2.0.12: may be gdFTEX_Unicode,
-                                  gdFTEX_Shift_JIS, or gdFTEX_Big5;
+                                  gdFTEX_Shift_JIS, gdFTEX_Big5,
+                                  or gdFTEX_Adobe_Custom;
                                   when not specified, maps are searched
                                   for in the above order. */
     int hdpi;                   /* if (flags & gdFTEX_RESOLUTION) */
@@ -446,6 +459,7 @@ BGD_DECLARE(int) gdFTUseFontConfig(int flag);
 #define gdFTEX_Unicode 0
 #define gdFTEX_Shift_JIS 1
 #define gdFTEX_Big5 2
+#define gdFTEX_Adobe_Custom 3
 
 BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
                           double ptsize, double angle, int x, int y,
@@ -645,6 +659,7 @@ BGD_DECLARE(void) gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h,
                         int e, int color, int style);
 BGD_DECLARE(void) gdImageArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e,
                   int color);
+BGD_DECLARE(void) gdImageEllipse(gdImagePtr im, int cx, int cy, int w, int h, int color);
 BGD_DECLARE(void) gdImageFilledEllipse (gdImagePtr im, int cx, int cy, int w, int h,
                             int color);
 BGD_DECLARE(void) gdImageFillToBorder (gdImagePtr im, int x, int y, int border,
index 4374e4027d040b9a71f5a4c113f0522024e7952b..06bac4375ee2452d4303da669f87e29699b6ae36 100644 (file)
@@ -171,6 +171,9 @@ _gd2GetHeader (gdIOCtxPtr in, int *sx, int *sy,
       GD2_DBG (printf ("Reading %d chunk index entries\n", nc));
       sidx = sizeof (t_chunk_info) * nc;
       cidx = gdCalloc (sidx, 1);
+                       if (!cidx) {
+                               goto fail1;
+                       }
       for (i = 0; i < nc; i++)
        {
          if (gdGetInt (&cidx[i].offset, in) != 1)
@@ -322,7 +325,8 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Ctx (gdIOCtxPtr in)
   if (im == NULL)
     {
       return 0;
-    };
+    }
+
   bytesPerPixel = im->trueColor ? 4 : 1;
   nc = ncx * ncy;
 
@@ -342,7 +346,14 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Ctx (gdIOCtxPtr in)
       /* Allocate buffers */
       chunkMax = cs * bytesPerPixel * cs;
       chunkBuf = gdCalloc (chunkMax, 1);
+                       if (!chunkBuf) {
+                               goto fail2;
+                       }
       compBuf = gdCalloc (compMax, 1);
+                       if (!compBuf) {
+                               goto fail2;
+                       }
+
       GD2_DBG (printf ("Largest compressed chunk is %d bytes\n", compMax));
     };
 
@@ -462,11 +473,17 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Ctx (gdIOCtxPtr in)
 
 fail2:
   gdImageDestroy (im);
-  gdFree (chunkBuf);
-  gdFree (compBuf);
-  gdFree (chunkIdx);
+fail1:
+       if (chunkBuf) {
+               gdFree (chunkBuf);
+       }
+       if (compBuf) {
+               gdFree (compBuf);
+       } 
+       if (chunkIdx) {
+               gdFree (chunkIdx);
+       }
   return 0;
-
 }
 
 BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Part (FILE * inFile, int srcx, int srcy, int w, int h)
@@ -571,7 +588,14 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int
          chunkMax = cs * cs;
        }
       chunkBuf = gdCalloc (chunkMax, 1);
+                       if (!chunkBuf) {
+                               goto fail2;
+                       }
       compBuf = gdCalloc (compMax, 1);
+                       if (!compBuf) {
+                               goto fail2;
+                       }
+
     };
 
 /*      Don't bother with this... */
@@ -748,10 +772,15 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int
 fail2:
   gdImageDestroy (im);
 fail1:
-  gdFree (chunkBuf);
-  gdFree (compBuf);
-  gdFree (chunkIdx);
-
+       if (chunkBuf) {
+         gdFree (chunkBuf);
+       }
+       if (compBuf) {
+         gdFree (compBuf);
+       }
+       if (chunkIdx) {
+       gdFree (chunkIdx);
+       }
   return 0;
 
 }
@@ -851,7 +880,13 @@ _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt)
       /* Allocate the buffers.  */
       /* */
       chunkData = gdCalloc (cs * bytesPerPixel * cs, 1);
+                       if (!chunkData) {
+                               goto fail;
+                       }
       compData = gdCalloc (compMax, 1);
+                       if (!compData) {
+                               goto fail;
+                       }
 
       /* */
       /* Save the file position of chunk index, and allocate enough space for */
@@ -863,6 +898,9 @@ _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt)
       gdSeek (out, idxPos + idxSize);
 
       chunkIdx = gdCalloc (idxSize * sizeof (t_chunk_info), 1);
+      if (!chunkIdx) {
+        goto fail;
+      }
     };
 
   _gdPutColors (im, out);
@@ -984,13 +1022,20 @@ _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt)
       gdSeek (out, posSave);
     };
 
+  /*printf("Memory block size is %d\n",gdTell(out)); */
+fail:
   GD2_DBG (printf ("Freeing memory\n"));
-  gdFree (chunkData);
-  gdFree (compData);
-  gdFree (chunkIdx);
-  GD2_DBG (printf ("Done\n"));
 
-  /*printf("Memory block size is %d\n",gdTell(out)); */
+       if (chunkData) {
+               gdFree (chunkData);
+       }
+       if (compData) {
+               gdFree (compData);
+       } 
+       if (chunkIdx) {
+               gdFree (chunkIdx);
+       }
+  GD2_DBG (printf ("Done\n"));
 
 }
 
index e1f1bdbf6ba1170d534930e53fb0894efc090a48..3a1e8142321065821eabc01fab18c63685fb41ee 100644 (file)
@@ -1,7 +1,3 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #include <stdio.h>
 #include <math.h>
 #include <string.h>
@@ -46,7 +42,7 @@ static int set_verbose(void)
 #define LOCALCOLORMAP  0x80
 #define BitSet(byte, bit)      (((byte) & (bit)) == (bit))
 
-#define        ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0)
+#define        ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) > 0)
 
 #define LM_to_uint(a,b)                        (((b)<<8)|(a))
 
@@ -72,11 +68,29 @@ static struct {
 } Gif89 = { -1, -1, -1, 0 };
 #endif
 
+#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
+
+typedef struct {
+       unsigned char    buf[280];
+       int              curbit, lastbit, done, last_byte;
+} CODE_STATIC_DATA;
+
+typedef struct {
+       int fresh;
+       int code_size, set_code_size;
+       int max_code, max_code_size;
+       int firstcode, oldcode;
+       int clear_code, end_code;
+       int table[2][(1<< MAX_LWZ_BITS)];
+       int stack[STACK_SIZE], *sp;
+       CODE_STATIC_DATA scd;
+} LZW_STATIC_DATA;
+
 static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]);
 static int DoExtension (gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP);
 static int GetDataBlock (gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP);
-static int GetCode (gdIOCtx *fd, int code_size, int flag, int *ZeroDataBlockP);
-static int LWZReadByte (gdIOCtx *fd, int flag, int input_code_size, int *ZeroDataBlockP);
+static int GetCode (gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP);
+static int LWZReadByte (gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP);
 
 static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP); /*1.4//, int ignore); */
 
@@ -114,15 +128,14 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd)
        unsigned char   c;
        unsigned char   ColorMap[3][MAXCOLORMAPSIZE];
        unsigned char   localColorMap[3][MAXCOLORMAPSIZE];
-       int             imw, imh;
-       int             useGlobalColormap;
+       int             imw, imh, screen_width, screen_height;
+       int             gif87a, useGlobalColormap;
        int             bitPixel;
        int            i;
        /*1.4//int             imageCount = 0; */
-       char            version[4];
        /* 2.0.28: threadsafe storage */
        int ZeroDataBlock = FALSE;
-       int             maxcount = 1024;
+       int haveGlobalColormap;
 
        gdImagePtr im = 0;
        if (! ReadOK(fd,buf,6)) {
@@ -131,34 +144,43 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd)
        if (strncmp((char *)buf,"GIF",3) != 0) {
                return 0;
        }
-       strncpy(version, (char *)buf + 3, 3);
-       version[3] = '\0';
+               if (memcmp((char *)buf+3, "87a", 3) == 0) {
+                       gif87a = 1;
+               } else if (memcmp((char *)buf+3, "89a", 3) == 0) {
+                       gif87a = 0;
+               } else {
+                       return 0;
+               }
+
+                        if (! ReadOK(fd,buf,7)) {
+                                return 0;
+                        }
 
-       if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
-               return 0;
-       }
-       if (! ReadOK(fd,buf,7)) {
-               return 0;
-       }
        BitPixel        = 2<<(buf[4]&0x07);
 #if 0
        ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
        Background      = buf[5];
        AspectRatio     = buf[6];
 #endif
-
-       if (BitSet(buf[4], LOCALCOLORMAP)) {    /* Global Colormap */
-               if (ReadColorMap(fd, BitPixel, ColorMap)) {
-                       return 0;
-               }
-       }
+                       screen_width = imw = LM_to_uint(buf[0],buf[1]);
+                       screen_height = imh = LM_to_uint(buf[2],buf[3]);
+
+                       haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP);    /* Global Colormap */
+                       if (haveGlobalColormap) {
+                               if (ReadColorMap(fd, BitPixel, ColorMap)) {
+                                       return 0;
+                               }
+                       }
        for (;;) {
+                                                       int top, left;
+                                                       int width, height;
+
                if (! ReadOK(fd,&c,1)) {
                        return 0;
                }
                if (c == ';') {         /* GIF terminator */
-                       goto terminated;
-              }
+                                                               goto terminated;
+                                      }
 
                if (c == '!') {         /* Extension */
                        if (! ReadOK(fd,&c,1)) {
@@ -169,8 +191,6 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd)
                }
 
                if (c != ',') {         /* Not a valid start character */
-                      if (--maxcount < 0)
-                              goto terminated;  /* Looping */
                        continue;
                }
 
@@ -182,22 +202,36 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd)
 
                useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
 
-               bitPixel = 1<<((buf[8]&0x07)+1);
-
-               imw = LM_to_uint(buf[4],buf[5]);
-               imh = LM_to_uint(buf[6],buf[7]);
-              if (!(im = gdImageCreate(imw, imh))) {
-                        return 0;
-              }
-               im->interlace = BitSet(buf[8], INTERLACE);
-               if (! useGlobalColormap) {
+                                                       bitPixel = 1<<((buf[8]&0x07)+1);
+                                                       left = LM_to_uint(buf[0], buf[1]);
+                                                       top = LM_to_uint(buf[2], buf[3]);
+                                                       width = LM_to_uint(buf[4], buf[5]);
+                                                       height = LM_to_uint(buf[6], buf[7]);
+
+                                                       if (left + width > screen_width || top + height > screen_height) {
+                                                               if (VERBOSE) {
+                                                                       printf("Frame is not confined to screen dimension.\n");
+                                                               }
+                                                               return 0;
+                                                       }
+
+                          if (!(im = gdImageCreate(width, height))) {
+                                  return 0;
+                          }
+                          im->interlace = BitSet(buf[8], INTERLACE);
+               if (!useGlobalColormap) {
                        if (ReadColorMap(fd, bitPixel, localColorMap)) { 
-                                 return 0;
+                                                                                                       gdImageDestroy(im);
+                                                                                                       return 0;
                        }
-                       ReadImage(im, fd, imw, imh, localColorMap, 
+                       ReadImage(im, fd, width, height, localColorMap, 
                                  BitSet(buf[8], INTERLACE), &ZeroDataBlock); 
                } else {
-                       ReadImage(im, fd, imw, imh,
+                                                                                       if (!haveGlobalColormap) {
+                                                                                               gdImageDestroy(im);
+                                                                                               return 0;
+                                                                                       }
+                       ReadImage(im, fd, width, height,
                                  ColorMap, 
                                  BitSet(buf[8], INTERLACE), &ZeroDataBlock);
                }
@@ -212,6 +246,10 @@ terminated:
        if (!im) {
                return 0;
        }
+          if (!im->colorsTotal) {
+                  gdImageDestroy(im);
+                  return 0;
+          }
        /* Check for open colors at the end, so
           we can reduce colorsTotal and ultimately
           BitsPerPixel */
@@ -248,11 +286,11 @@ ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256])
 static int
 DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP)
 {
-       static unsigned char     buf[256];
-       int                      maxcount = 1024;
+       unsigned char     buf[256];
 
        switch (label) {
        case 0xf9:              /* Graphic Control Extension */
+               memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */
                (void) GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP);
 #if 0
                Gif89.disposal    = (buf[0] >> 2) & 0x7;
@@ -262,13 +300,12 @@ DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP)
                if ((buf[0] & 0x1) != 0)
                        *Transparent = buf[3];
 
-               while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) != 0 && --maxcount >= 0)
-                       ;
+               while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0);
                return FALSE;
        default:
                break;
        }
-       while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) != 0 && --maxcount >= 0)
+       while (GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0)
                ;
 
        return FALSE;
@@ -311,185 +348,174 @@ GetDataBlock(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP)
 }
 
 static int
-GetCode_(gdIOCtx *fd, int code_size, int flag, int *ZeroDataBlockP)
+GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
 {
-       static unsigned char    buf[280];
-       static int              curbit, lastbit, done, last_byte;
-       int                     i, j, ret;
-       unsigned char           count;
+       int           i, j, ret;
+       unsigned char count;
 
        if (flag) {
-               curbit = 0;
-               lastbit = 0;
-               done = FALSE;
+               scd->curbit = 0;
+               scd->lastbit = 0;
+               scd->last_byte = 0;
+               scd->done = FALSE;
                return 0;
        }
 
-       if ( (curbit+code_size) >= lastbit) {
-               if (done) {
-                       if (curbit >= lastbit) {
+       if ( (scd->curbit + code_size) >= scd->lastbit) {
+               if (scd->done) {
+                       if (scd->curbit >= scd->lastbit) {
                                 /* Oh well */
                        }                        
                        return -1;
                }
-               buf[0] = buf[last_byte-2];
-               buf[1] = buf[last_byte-1];
+               scd->buf[0] = scd->buf[scd->last_byte-2];
+               scd->buf[1] = scd->buf[scd->last_byte-1];
 
-               if ((count = GetDataBlock(fd, &buf[2], ZeroDataBlockP)) == 0)
-                       done = TRUE;
+               if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0)
+                       scd->done = TRUE;
 
-               last_byte = 2 + count;
-               curbit = (curbit - lastbit) + 16;
-               lastbit = (2+count)*8 ;
+               scd->last_byte = 2 + count;
+               scd->curbit = (scd->curbit - scd->lastbit) + 16;
+               scd->lastbit = (2+count)*8 ;
        }
 
        ret = 0;
-       for (i = curbit, j = 0; j < code_size; ++i, ++j)
-               ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
+       for (i = scd->curbit, j = 0; j < code_size; ++i, ++j)
+               ret |= ((scd->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
 
-       curbit += code_size;
+       scd->curbit += code_size;
        return ret;
 }
 
 static int
-GetCode(gdIOCtx *fd, int code_size, int flag, int *ZeroDataBlockP)
+GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
 {
  int rv;
 
- rv = GetCode_(fd,code_size,flag, ZeroDataBlockP);
+ rv = GetCode_(fd, scd, code_size,flag, ZeroDataBlockP);
  if (VERBOSE) printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv);
  return(rv);
 }
 
-#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
 static int
-LWZReadByte_(gdIOCtx *fd, int flag, int input_code_size, int *ZeroDataBlockP)
+LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
 {
-       static int      fresh = FALSE;
-       int             code, incode;
-       static int      code_size, set_code_size;
-       static int      max_code, max_code_size;
-       static int      firstcode, oldcode;
-       static int      clear_code, end_code;
-       static int      table[2][(1<< MAX_LWZ_BITS)];
-       static int      stack[STACK_SIZE], *sp;
-       register int    i;
+       int code, incode, i;
 
        if (flag) {
-               set_code_size = input_code_size;
-               code_size = set_code_size+1;
-               clear_code = 1 << set_code_size ;
-               end_code = clear_code + 1;
-               max_code_size = 2*clear_code;
-               max_code = clear_code+2;
-
-               GetCode(fd, 0, TRUE, ZeroDataBlockP);
+               sd->set_code_size = input_code_size;
+               sd->code_size = sd->set_code_size+1;
+               sd->clear_code = 1 << sd->set_code_size ;
+               sd->end_code = sd->clear_code + 1;
+               sd->max_code_size = 2*sd->clear_code;
+               sd->max_code = sd->clear_code+2;
+
+               GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP);
                
-               fresh = TRUE;
+               sd->fresh = TRUE;
 
-               for (i = 0; i < clear_code; ++i) {
-                       table[0][i] = 0;
-                       table[1][i] = i;
+               for (i = 0; i < sd->clear_code; ++i) {
+                       sd->table[0][i] = 0;
+                       sd->table[1][i] = i;
                }
                for (; i < (1<<MAX_LWZ_BITS); ++i)
-                       table[0][i] = table[1][0] = 0;
+                       sd->table[0][i] = sd->table[1][0] = 0;
 
-               sp = stack;
+               sd->sp = sd->stack;
 
                return 0;
-       } else if (fresh) {
-               fresh = FALSE;
+       } else if (sd->fresh) {
+               sd->fresh = FALSE;
                do {
-                       firstcode = oldcode =
-                               GetCode(fd, code_size, FALSE, ZeroDataBlockP);
-               } while (firstcode == clear_code);
-               return firstcode;
+                       sd->firstcode = sd->oldcode =
+                               GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
+               } while (sd->firstcode == sd->clear_code);
+               return sd->firstcode;
        }
 
-       if (sp > stack)
-               return *--sp;
+       if (sd->sp > sd->stack)
+               return *--sd->sp;
 
-       while ((code = GetCode(fd, code_size, FALSE, ZeroDataBlockP)) >= 0) {
-               if (code == clear_code) {
-                       for (i = 0; i < clear_code; ++i) {
-                               table[0][i] = 0;
-                               table[1][i] = i;
+       while ((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) {
+               if (code == sd->clear_code) {
+                       for (i = 0; i < sd->clear_code; ++i) {
+                               sd->table[0][i] = 0;
+                               sd->table[1][i] = i;
                        }
                        for (; i < (1<<MAX_LWZ_BITS); ++i)
-                               table[0][i] = table[1][i] = 0;
-                       code_size = set_code_size+1;
-                       max_code_size = 2*clear_code;
-                       max_code = clear_code+2;
-                       sp = stack;
-                       firstcode = oldcode =
-                                       GetCode(fd, code_size, FALSE, ZeroDataBlockP);
-                       return firstcode;
-               } else if (code == end_code) {
+                               sd->table[0][i] = sd->table[1][i] = 0;
+                       sd->code_size = sd->set_code_size+1;
+                       sd->max_code_size = 2*sd->clear_code;
+                       sd->max_code = sd->clear_code+2;
+                       sd->sp = sd->stack;
+                       sd->firstcode = sd->oldcode =
+                                       GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
+                       return sd->firstcode;
+               } else if (code == sd->end_code) {
                        int             count;
                        unsigned char   buf[260];
-                      int             maxcount = 1024;
 
                        if (*ZeroDataBlockP)
                                return -2;
 
-                       while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0  && --maxcount >= 0)
+                       while ((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0)
                                ;
 
-                       if (count != 0 || maxcount < 0)
+                       if (count != 0)
                        return -2;
                }
 
                incode = code;
 
-              if (sp == (stack + STACK_SIZE)) {
+              if (sd->sp == (sd->stack + STACK_SIZE)) {
                       /* Bad compressed data stream */
                       return -1;
               }
 
-               if (code >= max_code) {
-                       *sp++ = firstcode;
-                       code = oldcode;
+               if (code >= sd->max_code) {
+                       *sd->sp++ = sd->firstcode;
+                       code = sd->oldcode;
                }
 
-               while (code >= clear_code) {
-                      if (sp == (stack + STACK_SIZE)) {
+               while (code >= sd->clear_code) {
+                      if (sd->sp == (sd->stack + STACK_SIZE)) {
                               /* Bad compressed data stream */
                               return -1;
                       }
-                       *sp++ = table[1][code];
-                       if (code == table[0][code]) {
+                       *sd->sp++ = sd->table[1][code];
+                       if (code == sd->table[0][code]) {
                                /* Oh well */
                        }
-                       code = table[0][code];
+                       code = sd->table[0][code];
                }
 
-               *sp++ = firstcode = table[1][code];
+               *sd->sp++ = sd->firstcode = sd->table[1][code];
 
-               if ((code = max_code) <(1<<MAX_LWZ_BITS)) {
-                       table[0][code] = oldcode;
-                       table[1][code] = firstcode;
-                       ++max_code;
-                       if ((max_code >= max_code_size) &&
-                               (max_code_size < (1<<MAX_LWZ_BITS))) {
-                               max_code_size *= 2;
-                               ++code_size;
+               if ((code = sd->max_code) <(1<<MAX_LWZ_BITS)) {
+                       sd->table[0][code] = sd->oldcode;
+                       sd->table[1][code] = sd->firstcode;
+                       ++sd->max_code;
+                       if ((sd->max_code >= sd->max_code_size) &&
+                               (sd->max_code_size < (1<<MAX_LWZ_BITS))) {
+                               sd->max_code_size *= 2;
+                               ++sd->code_size;
                        }
                }
 
-               oldcode = incode;
+               sd->oldcode = incode;
 
-               if (sp > stack)
-                       return *--sp;
+               if (sd->sp > sd->stack)
+                       return *--sd->sp;
        }
        return code;
 }
 
 static int
-LWZReadByte(gdIOCtx *fd, int flag, int input_code_size, int *ZeroDataBlockP)
+LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
 {
  int rv;
 
- rv = LWZReadByte_(fd,flag,input_code_size, ZeroDataBlockP);
+ rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP);
  if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv);
  return(rv);
 }
@@ -501,6 +527,19 @@ ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)
        int             v;
        int             xpos = 0, ypos = 0, pass = 0;
        int i;
+       LZW_STATIC_DATA sd;
+
+       /*
+       **  Initialize the Compression routines
+       */
+       if (! ReadOK(fd,&c,1)) {
+               return; 
+       }
+
+               if (c > MAX_LWZ_BITS) {
+                       return; 
+               }
+
        /* Stash the color map into the image */
        for (i=0; (i<gdMaxColors); i++) {
                im->red[i] = cmap[CM_RED][i];   
@@ -510,13 +549,7 @@ ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)
        }
        /* Many (perhaps most) of these colors will remain marked open. */
        im->colorsTotal = gdMaxColors;
-       /*
-       **  Initialize the Compression routines
-       */
-       if (! ReadOK(fd,&c,1)) {
-               return; 
-       }
-       if (LWZReadByte(fd, TRUE, c, ZeroDataBlockP) < 0) {
+       if (LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) {
                return;
        }
 
@@ -525,12 +558,16 @@ ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)
        **  REMOVED For 1.4
        */
        /*if (ignore) { */
-       /*        while (LWZReadByte(fd, FALSE, c) >= 0) */
+       /*        while (LWZReadByte(fd, &sd, FALSE, c) >= 0) */
        /*                ; */
        /*        return; */
        /*} */
 
-       while ((v = LWZReadByte(fd,FALSE,c, ZeroDataBlockP)) >= 0 ) {
+       while ((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0 ) {
+               if (v >= gdMaxColors) {
+                       v = 0;
+               }
+
                /* This how we recognize which colors are actually used. */
                if (im->open[v]) {
                        im->open[v] = 0;
@@ -572,7 +609,7 @@ ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)
        }
 
 fini:
-       if (LWZReadByte(fd,FALSE,c, ZeroDataBlockP)>=0) {
+       if (LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >=0) {
                /* Ignore extra */
        }
 }
index 6c919cc2a96886c2f3356112d65c7a257351ffaa..1310677bd50945e4c388428855d24f70baa8d7d0 100644 (file)
@@ -1,7 +1,3 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #include <stdio.h>
 #include <math.h>
 #include <string.h>
@@ -139,7 +135,7 @@ BGD_DECLARE(void) gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)
        BitsPerPixel = colorstobpp(tim->colorsTotal);
        /* All set, let's do it. */
        GIFEncode(
-               out, tim->sx, tim->sy, interlace, 0, transparent, BitsPerPixel,
+               out, tim->sx, tim->sy, interlace, 0, tim->transparent, BitsPerPixel,
                tim->red, tim->green, tim->blue, tim);
        if (pim) {
                /* Destroy palette based temporary image. */
@@ -450,6 +446,9 @@ BGD_DECLARE(void) gdImageGifAnimEnd(FILE *outFile)
 BGD_DECLARE(void *) gdImageGifAnimEndPtr (int *size)
 {
   char *rv = (char *) gdMalloc (1);
+  if (!rv) {
+    return 0;
+  }
   *rv = ';';
   *size = 1;
   return (void *)rv;
index 40985756cb2701b0f57ff05e89afb9072c63e36c..7f1c42141a26c4dd7b88f495e3d66d8b7402d6be 100644 (file)
@@ -45,7 +45,7 @@ void Putchar (int c, gdIOCtx * ctx);
  int gdGetWord (int *result, gdIOCtx * ctx);
  int gdGetInt (int *result, gdIOCtx * ctx);
 
- int gdSeek (gdIOCtx * ctx, const int);
+ int gdSeek (gdIOCtx * ctx, const int offset);
  long gdTell (gdIOCtx * ctx);
 
 #endif
index e57a2d3cb89baeb806abefe9aa9722fe3a3feb41..05ed0729f699f3e07a0965f27dde40c55729c11a 100644 (file)
@@ -292,7 +292,11 @@ dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len)
     {
       if (remain == 0)
        {
-         return EOF;
+       /* 2.0.34: EOF is incorrect. We use 0 for
+                errors and EOF, just like fileGetbuf,
+                which is a simple fread() wrapper. 
+                TBB. Original bug report: Daniel Cowgill. */
+     return 0; /* NOT EOF */
        }
       rlen = remain;
     }
index 7a68fd16510787f79f80cee15a40ed384386d134..1313668291963734a13022bbf6f2a09317f7cfa9 100644 (file)
@@ -101,7 +101,7 @@ sourceGetbuf (gdIOCtx * ctx, void *buf, int size)
 
   if (res == 0)
     {
-      return EOF;
+      return 0;
     }
   else if (res < 0)
     {
index defa3cfb769b203a411bea16db9262c9d58b01a1..25df8e4975aa0f9183905b6d8b8262f77b80461a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * gd_jpeg.c: Read and write JPEG (JFIF) format image files using the
- * gd graphics library (http://www.boutell.com/gd/).
+ * gd graphics library (http://www.libgd.org).
  * 
  * This software is based in part on the work of the Independent JPEG
  * Group.  For more information on the IJG JPEG software (and JPEG