]> granicus.if.org Git - php/commitdiff
Syncronize bundled GD library with latest GD (2.0.11).
authorIlia Alshanetsky <iliaa@php.net>
Fri, 17 Jan 2003 18:34:07 +0000 (18:34 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Fri, 17 Jan 2003 18:34:07 +0000 (18:34 +0000)
ext/gd/gd.c
ext/gd/libgd/gd.c
ext/gd/libgd/gd.h
ext/gd/libgd/gd_gd2.c
ext/gd/libgd/gd_jpeg.c

index 2bced6403d6099f00d6741a5fba37023295b6a41..756eb53488a93236905d6fe802fd95e740d6404f 100644 (file)
@@ -1562,17 +1562,18 @@ PHP_FUNCTION(imagecreatefromgd2part)
  */
 static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) 
 {
-       zval **imgind, **file, **quality;
+       zval **imgind, **file, **quality, **type;
        gdImagePtr im;
        char *fn = NULL;
        FILE *fp;
        int argc = ZEND_NUM_ARGS();
-       int q = -1, i;
+       int q = -1, i, t = 1;
 
        /* The quality parameter for Wbmp stands for the threshold when called from image2wbmp() */
        /* When called from imagewbmp() the quality parameter stands for the foreground color. Default: black. */
+       /* The quality parameter for gd2 stands for chunk size */
 
-       if (argc < 1 || argc > 3 || zend_get_parameters_ex(argc, &imgind, &file, &quality) == FAILURE) {
+       if (argc < 1 || argc > 4 || zend_get_parameters_ex(argc, &imgind, &file, &quality, &type) == FAILURE) {
                ZEND_WRONG_PARAM_COUNT();
        }
 
@@ -1585,6 +1586,10 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
                        convert_to_long_ex(quality);
                        q = Z_LVAL_PP(quality);
                }
+               if (argc == 4) {
+                       convert_to_long_ex(type);
+                       t = Z_LVAL_PP(type);
+               }
        }
 
        if ((argc == 2) || (argc == 3 && Z_STRLEN_PP(file))) {
@@ -1622,7 +1627,10 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
                                break;
 #endif                         
                        default:
-                               (*func_p)(im, fp);
+                               if (q == -1) {
+                                       q = 128;
+                               }
+                               (*func_p)(im, fp, q, t);
                                break;
                }
                fflush(fp);
@@ -1749,7 +1757,7 @@ PHP_FUNCTION(imagegd)
 /* }}} */
 
 #ifdef HAVE_GD_GD2
-/* {{{ proto int imagegd2(int im [, string filename])
+/* {{{ proto int imagegd2(int im [, string filename, [, int chunk_size, [, int type]]])
    Output GD2 image to browser or file */
 PHP_FUNCTION(imagegd2)
 {
index 6548d7b2564d5579e63a32549671b9d6273840bf..9e9ea358f746bd898b2ab48a2fa3a4cc476d31b2 100644 (file)
@@ -81,6 +81,9 @@ static const unsigned char gd_toascii[256] =
 };
 #endif /*CHARSET_EBCDIC */
 
+/* 2.0.10: cast instead of floor() yields 35% performance improvement. Thanks to John Buckman. */
+#define floor_cast(exp) ((long) exp)
+
 extern int gdCosT[];
 extern int gdSinT[];
 
@@ -661,6 +664,76 @@ gdImagePaletteCopy (gdImagePtr to, gdImagePtr from)
 
 }
 
+/* 2.0.10: before the drawing routines, some code to clip points that are
+ * outside the drawing window.  Nick Atty (nick@canalplan.org.uk)
+ *
+ * This is the Sutherland Hodgman Algorithm, as implemented by
+ * Duvanenko, Robbins and Gyurcsik - SH(DRG) for short.  See Dr Dobb's
+ * Journal, January 1996, pp107-110 and 116-117
+ *
+ * Given the end points of a line, and a bounding rectangle (which we
+ * know to be from (0,0) to (SX,SY)), adjust the endpoints to be on
+ * the edges of the rectangle if the line should be drawn at all,
+ * otherwise return a failure code 
+ */
+
+/* this does "one-dimensional" clipping: note that the second time it
+ *  is called, all the x parameters refer to height and the y to width
+ *  - the comments ignore this (if you can understand it when it's
+ *  looking at the X parameters, it should become clear what happens on
+ *  the second call!)  The code is simplified from that in the article,
+ *  as we know that gd images always start at (0,0) 
+ */
+
+static int clip_1d(int *x0, int *y0, int *x1, int *y1, int maxdim) {
+       double m;      /* gradient of line */
+
+       if (*x0 < 0) {  /* start of line is left of window */
+               if(*x1 < 0) { /* as is the end, so the line never cuts the window */
+                       return 0;
+               }
+               m = (*y1 - *y0)/(double)(*x1 - *x0); /* calculate the slope of the line */
+               /* adjust x0 to be on the left boundary (ie to be zero), and y0 to match */
+               *y0 -= m * *x0;
+               *x0 = 0;
+               /* now, perhaps, adjust the far end of the line as well */
+               if (*x1 > maxdim) {
+                       *y1 += m * (maxdim - *x1);
+                       *x1 = maxdim;
+               }
+               return 1;
+       }
+       if (*x0 > maxdim) { /* start of line is right of window - complement of above */
+               if (*x1 > maxdim) { /* as is the end, so the line misses the window */
+                       return 0;
+               }
+               m = (*y1 - *y0)/(double)(*x1 - *x0);  /* calculate the slope of the line */
+               *y0 += m * (maxdim - *x0); /* adjust so point is on the right boundary */
+               *x0 = maxdim;                  
+               /* now, perhaps, adjust the end of the line */
+               if (*x1 < 0) {
+                       *y1 -= m * *x1;
+                       *x1 = 0;
+               }
+               return 1;
+       }
+       /* the final case - the start of the line is inside the window */
+       if (*x1 > maxdim) { /* other end is outside to the right */
+               m = (*y1 - *y0)/(double)(*x1 - *x0);  /* calculate the slope of the line */
+               *y1 += m * (maxdim - *x1);
+               *x1 = maxdim;
+               return 1;
+       }
+       if (*x1 < 0) { /* other end is outside to the left */
+               m = (*y1 - *y0)/(double)(*x1 - *x0);  /* calculate the slope of the line */
+               *y1 -= m * *x1;
+               *x1 = 0;
+               return 1;
+       }
+       /* only get here if both points are inside the window */
+       return 1;
+}
+
 void
 gdImageSetPixel (gdImagePtr im, int x, int y, int color)
 {
@@ -871,158 +944,139 @@ gdImageGetPixel (gdImagePtr im, int x, int y)
 void
 gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
 {
-  int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
-  int wid;
-  int w, wstart;
-  int thick = im->thick;
-  dx = abs (x2 - x1);
-  dy = abs (y2 - y1);
-  if (dy <= dx)
-    {
-      /* More-or-less horizontal. use wid for vertical stroke */
-      /* Doug Claar: watch out for NaN in atan2 (2.0.5) */
-      if ((dx == 0) && (dy == 0)) {
-        wid = 1;
-      } else {
-        wid = (int)(thick * cos (atan2 (dy, dx)));
-        if (wid == 0) {
-          wid = 1;
-        }
-      }
-      d = 2 * dy - dx;
-      incr1 = 2 * dy;
-      incr2 = 2 * (dy - dx);
-      if (x1 > x2)
-       {
-         x = x2;
-         y = y2;
-         ydirflag = (-1);
-         xend = x1;
-       }
-      else
-       {
-         x = x1;
-         y = y1;
-         ydirflag = 1;
-         xend = x2;
-       }
-
-      /* Set up line thickness */
-      wstart = y - wid / 2;
-      for (w = wstart; w < wstart + wid; w++)
-       gdImageSetPixel (im, x, w, color);
+       int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
+       int wid;
+       int w, wstart;
+       int thick = im->thick;
 
-      if (((y2 - y1) * ydirflag) > 0)
-       {
-         while (x < xend)
-           {
-             x++;
-             if (d < 0)
-               {
-                 d += incr1;
-               }
-             else
-               {
-                 y++;
-                 d += incr2;
-               }
-             wstart = y - wid / 2;
-             for (w = wstart; w < wstart + wid; w++)
-               gdImageSetPixel (im, x, w, color);
-           }
+       /* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */
+       if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im))) {
+               return;
        }
-      else
-       {
-         while (x < xend)
-           {
-             x++;
-             if (d < 0)
-               {
-                 d += incr1;
+       
+       dx = abs(x2 - x1);
+       dy = abs(y2 - y1);
+       if (dy <= dx) {
+               /* More-or-less horizontal. use wid for vertical stroke */
+               /* Doug Claar: watch out for NaN in atan2 (2.0.5) */
+               if ((dx == 0) && (dy == 0)) {
+                       wid = 1;
+               } else {
+                       wid = (int)(thick * cos (atan2 (dy, dx)));
+                       if (wid == 0) {
+                               wid = 1;
+                       }
                }
-             else
-               {
-                 y--;
-                 d += incr2;
+               d = 2 * dy - dx;
+               incr1 = 2 * dy;
+               incr2 = 2 * (dy - dx);
+               if (x1 > x2) {
+                       x = x2;
+                       y = y2;
+                       ydirflag = (-1);
+                       xend = x1;
+               } else {
+                       x = x1;
+                       y = y1;
+                       ydirflag = 1;
+                       xend = x2;
                }
-             wstart = y - wid / 2;
-             for (w = wstart; w < wstart + wid; w++)
-               gdImageSetPixel (im, x, w, color);
-           }
-       }
-    }
-  else
-    {
-      /* More-or-less vertical. use wid for horizontal stroke */
-      wid = (int)(thick * sin (atan2 (dy, dx)));
-      if (wid == 0)
-       wid = 1;
-
-      d = 2 * dx - dy;
-      incr1 = 2 * dx;
-      incr2 = 2 * (dx - dy);
-      if (y1 > y2)
-       {
-         y = y2;
-         x = x2;
-         yend = y1;
-         xdirflag = (-1);
-       }
-      else
-       {
-         y = y1;
-         x = x1;
-         yend = y2;
-         xdirflag = 1;
-       }
 
-      /* Set up line thickness */
-      wstart = x - wid / 2;
-      for (w = wstart; w < wstart + wid; w++)
-       gdImageSetPixel (im, w, y, color);
+               /* Set up line thickness */
+               wstart = y - wid / 2;
+               for (w = wstart; w < wstart + wid; w++) {
+                       gdImageSetPixel(im, x, w, color);
+               }
 
-      if (((x2 - x1) * xdirflag) > 0)
-       {
-         while (y < yend)
-           {
-             y++;
-             if (d < 0)
-               {
-                 d += incr1;
+               if (((y2 - y1) * ydirflag) > 0) {
+                       while (x < xend) {
+                               x++;
+                               if (d < 0) {
+                                       d += incr1;
+                               } else {
+                                       y++;
+                                       d += incr2;
+                               }
+                               wstart = y - wid / 2;
+                               for (w = wstart; w < wstart + wid; w++) {
+                                       gdImageSetPixel (im, x, w, color);
+                               }
+                       }
+               } else {
+                       while (x < xend) {
+                               x++;
+                               if (d < 0) {
+                                       d += incr1;
+                               } else {
+                                       y--;
+                                       d += incr2;
+                               }
+                               wstart = y - wid / 2;
+                               for (w = wstart; w < wstart + wid; w++) {
+                                       gdImageSetPixel (im, x, w, color);
+                               }
+                       }
                }
-             else
-               {
-                 x++;
-                 d += incr2;
+       } else {
+               /* More-or-less vertical. use wid for horizontal stroke */
+               wid = (int)(thick * sin (atan2 (dy, dx)));
+               if (wid == 0) {
+                       wid = 1;
                }
-             wstart = x - wid / 2;
-             for (w = wstart; w < wstart + wid; w++)
-               gdImageSetPixel (im, w, y, color);
-           }
-       }
-      else
-       {
-         while (y < yend)
-           {
-             y++;
-             if (d < 0)
-               {
-                 d += incr1;
+
+               d = 2 * dx - dy;
+               incr1 = 2 * dx;
+               incr2 = 2 * (dx - dy);
+               if (y1 > y2) {
+                       y = y2;
+                       x = x2;
+                       yend = y1;
+                       xdirflag = (-1);
+               } else {
+                       y = y1;
+                       x = x1;
+                       yend = y2;
+                       xdirflag = 1;
                }
-             else
-               {
-                 x--;
-                 d += incr2;
+
+               /* Set up line thickness */
+               wstart = x - wid / 2;
+               for (w = wstart; w < wstart + wid; w++) {
+                       gdImageSetPixel (im, w, y, color);
+               }
+
+               if (((x2 - x1) * xdirflag) > 0) {
+                       while (y < yend) {
+                               y++;
+                               if (d < 0) {
+                                       d += incr1;
+                               } else {
+                                       x++;
+                                       d += incr2;
+                               }
+                               wstart = x - wid / 2;
+                               for (w = wstart; w < wstart + wid; w++) {
+                                       gdImageSetPixel (im, w, y, color);
+                               }
+                       }
+               } else {
+                       while (y < yend) {
+                               y++;
+                               if (d < 0) {
+                                       d += incr1;
+                               } else {
+                                       x--;
+                                       d += incr2;
+                               }
+                               wstart = x - wid / 2;
+                               for (w = wstart; w < wstart + wid; w++) {
+                                       gdImageSetPixel (im, w, y, color);
+                               }
+                       }
                }
-             wstart = x - wid / 2;
-             for (w = wstart; w < wstart + wid; w++)
-               gdImageSetPixel (im, w, y, color);
-           }
        }
-    }
 }
 
-
 #define BLEND_COLOR(a, nc, c, cc) \
 nc = (cc) + (((((c) - (cc)) * (a)) + ((((c) - (cc)) * (a)) >> 8) + 0x80) >> 8);
 
@@ -1317,13 +1371,6 @@ dashedSet (gdImagePtr im, int x, int y, int color,
   *onP = on;
 }
 
-int
-gdImageBoundsSafe (gdImagePtr im, int x, int y)
-{
-  return (!(((y < 0) || (y >= im->sy)) ||
-           ((x < 0) || (x >= im->sx))));
-}
-
 void
 gdImageChar (gdImagePtr im, gdFontPtr f, int x, int y,
             int c, int color)
@@ -1831,154 +1878,127 @@ gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
 void
 gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
 {
-  int x, y;
-  for (y = y1; (y <= y2); y++)
-    {
-      for (x = x1; (x <= x2); x++)
-       {
-         gdImageSetPixel (im, x, y, color);
+       int x, y;
+  
+       /* Nick Atty: limit the points at the edge.  Note that this also
+        * 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;
+       }
+       if (x1 > gdImageSX(im)) {
+               x1 = gdImageSX(im);
+       }
+       if(y1 < 0) {
+               y1 = 0;
+       }
+       if (y1 > gdImageSY(im)) {
+               y1 = gdImageSY(im);
+       }
+
+       for (y = y1; (y <= y2); y++) {
+               for (x = x1; (x <= x2); x++) {
+                       gdImageSetPixel (im, x, y, color);
+               }
        }
-    }
 }
 
 void
 gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h)
 {
-  int c;
-  int x, y;
-  int tox, toy;
-  int i;
-  int colorMap[gdMaxColors];
-  if (dst->trueColor)
-    {
-      /* 2.0: much easier when the destination is truecolor. */
+       int c;
+       int x, y;
+       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. 
+                */
                
-               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);
+               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    {
+               } 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,
-                                                               gdTrueColor(src->red[c], src->green[c], src->blue[c]));
+                       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, gdTrueColor(src->red[c], src->green[c], src->blue[c]));
                                        }
+                               }
+                       }
                }
-           }
+               return;
        }
-      return;
-    }
 
-         /* Destination is palette based */
-
-    if (src->trueColor) {  /* But source is truecolor (Ouch!) */
-        toy = dstY;
-        for (y = srcY; (y < (srcY + h)); y++)
-        {
-            tox = dstX;
-            for (x = srcX; (x < (srcX + w)); x++)
-            {
-                int nc;
-                c = gdImageGetPixel (src, x, y);
-
-                /* Get best match possible. */
-                nc = gdImageColorResolveAlpha (
-                         dst,
-                         gdTrueColorGetRed(c),
-                         gdTrueColorGetGreen(c),
-                         gdTrueColorGetBlue(c),
-                         gdTrueColorGetAlpha(c));
-
-                gdImageSetPixel (dst, tox, toy, nc);
-                tox++;
-            }
-            toy++;
-        }
-        return;
-    }
+       /* Destination is palette based */
+       if (src->trueColor) { /* But source is truecolor (Ouch!) */
+               toy = dstY;
+               for (y = srcY; (y < (srcY + h)); y++) {
+                       tox = dstX;
+                       for (x = srcX; (x < (srcX + w)); x++) {
+                               int nc;
+                               c = gdImageGetPixel (src, x, y);
 
-       /* Palette based to palette based */
+                               /* Get best match possible. */
+                               nc = gdImageColorResolveAlpha (dst, gdTrueColorGetRed(c), gdTrueColorGetGreen(c), gdTrueColorGetBlue(c), gdTrueColorGetAlpha(c));
 
-  for (i = 0; (i < gdMaxColors); i++)
-    {
-      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. */
-             mapTo = gdImageColorResolveAlpha (dst,
-                                             gdTrueColorGetRed (c),
-                                           gdTrueColorGetGreen (c),
-                                            gdTrueColorGetBlue (c),
-                                          gdTrueColorGetAlpha (c));
-           }
-         else if (colorMap[c] == (-1))
-           {
-             /* If it's the same image, mapping is trivial */
-             if (dst == src)
-               {
-                 nc = c;
+                               gdImageSetPixel (dst, tox, toy, nc);
+                               tox++;
+                       }
+                       toy++;
                }
-             else
-               {
-                 /* Get best match possible. This
-                    function never returns error. */
-                 nc = gdImageColorResolveAlpha (
-                                                 dst,
-                                                 src->red[c], src->green[c],
-                                              src->blue[c], src->alpha[c]);
+               return;
+       }
+
+       /* Palette based to palette based */
+       for (i = 0; (i < gdMaxColors); i++) {
+               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. 
+                                */
+                               mapTo = gdImageColorResolveAlpha (dst, gdTrueColorGetRed (c), gdTrueColorGetGreen (c), gdTrueColorGetBlue (c), gdTrueColorGetAlpha (c));
+                       } else if (colorMap[c] == (-1)) {
+                               /* If it's the same image, mapping is trivial */
+                               if (dst == src) {
+                                       nc = c;
+                               } else {
+                                       /* Get best match possible. This function never returns error. */
+                                       nc = gdImageColorResolveAlpha (dst, src->red[c], src->green[c], src->blue[c], src->alpha[c]);
+                               }
+                               colorMap[c] = nc;
+                               mapTo = colorMap[c];  
+                       } else {
+                               mapTo = colorMap[c];  
+                       }
+                       gdImageSetPixel (dst, tox, toy, mapTo);
+                       tox++;
                }
-             colorMap[c] = nc;
-              mapTo = colorMap[c];  
-           }
-          else
-            {
-              mapTo = colorMap[c];  
-            }
-         gdImageSetPixel (dst, tox, toy, mapTo);
-         tox++;
+               toy++;
        }
-      toy++;
-    }
 }
 
 /* This function is a substitute for real alpha channel operations,
@@ -2230,14 +2250,14 @@ void gdImageCopyResampled (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, i
                        sy = sy1;
                        do {
                                float yportion;
-                               if (floorf(sy) == floorf(sy1)) {
-                                       yportion = 1.0f - (sy - floorf(sy));
+                               if (floor_cast(sy) == floor_cast(sy1)) {
+                                       yportion = 1.0f - (sy - floor_cast(sy));
                                        if (yportion > sy2 - sy1) {
                                                yportion = sy2 - sy1;
                                        }
-                                       sy = floorf(sy);
+                                       sy = floor_cast(sy);
                                } else if (sy == floorf(sy2)) {
-                                       yportion = sy2 - floorf(sy2);
+                                       yportion = sy2 - floor_cast(sy2);
                                } else {
                                        yportion = 1.0f;
                                }
@@ -2248,14 +2268,14 @@ void gdImageCopyResampled (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, i
                                        float xportion;
                                        float pcontribution;
                                        int p;
-                                       if (floorf(sx) == floorf(sx1)) {
-                                               xportion = 1.0f - (sx - floorf(sx));
+                                       if (floorf(sx) == floor_cast(sx1)) {
+                                               xportion = 1.0f - (sx - floor_cast(sx));
                                                if (xportion > sx2 - sx1) {
                                                        xportion = sx2 - sx1;
                                                }
-                                               sx = floorf(sx);
+                                               sx = floor_cast(sx);
                                        } else if (sx == floorf(sx2)) {
-                                               xportion = sx2 - floorf(sx2);
+                                               xportion = sx2 - floor_cast(sx2);
                                        } else {
                                                xportion = 1.0f;
                                        }
index b3a5045ac839304ee0e19a21e45be6f8adec9402..709b98c10c27bcd4b8e894bb26f2e7a8ad024cfc 100644 (file)
@@ -256,7 +256,6 @@ void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
 void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
 /* Solid bar. Upper left corner first, lower right corner second. */
 void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
-int gdImageBoundsSafe(gdImagePtr im, int x, int y);
 void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);
 void gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);
 void gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color);
@@ -586,4 +585,6 @@ int gdImageCompare(gdImagePtr im1, gdImagePtr im2);
 }
 #endif
 
+#define gdImageBoundsSafe(im, x, y) (!(y < 0 || y >= (im)->sy || x < 0 || x >= (im)->sx))
+
 #endif /* GD_H */
index 10156bfb946cf896987b93ba1514fd4359575538..59c711763ba16545a276a6110570d68d635e62a3 100644 (file)
 #define TRUE 1
 #define FALSE 0
 
+/* 2.11: not part of the API, as the save routine can figure it out
+ *     from im->trueColor, and the load routine doesn't need to tell
+ *     the end user the saved format. NOTE: adding 2 is assumed
+ *     to result in the correct format value for truecolor! 
+*/
+#define GD2_FMT_TRUECOLOR_RAW 3
+#define GD2_FMT_TRUECOLOR_COMPRESSED 4
+
+#define gd2_compressed(fmt) (((fmt) == GD2_FMT_COMPRESSED) || ((fmt) == GD2_FMT_TRUECOLOR_COMPRESSED))
+#define gd2_truecolor(fmt) (((fmt) == GD2_FMT_TRUECOLOR_RAW) || ((fmt) == GD2_FMT_TRUECOLOR_COMPRESSED))
+
 /* Use this for commenting out debug-print statements. */
 /* Just use the first '#define' to allow all the prints... */
 /* #define GD2_DBG(s) (s) */
 #define GD2_DBG(s)
 
 typedef struct
-  {
-    int offset;
-    int size;
-  }
+{
+       int offset;
+       int size;
+}
 t_chunk_info;
 
-extern int _gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag);
-extern void _gdPutColors (gdImagePtr im, gdIOCtx * out);
+extern int _gdGetColors(gdIOCtx * in, gdImagePtr im, int gd2xFlag);
+extern void _gdPutColors(gdImagePtr im, gdIOCtx * out);
 
 /* */
 /* Read the extra info in the gd2 header. */
 /* */
-static
-int
-_gd2GetHeader (gdIOCtxPtr in, int *sx, int *sy,
- int *cs, int *vers, int *fmt, int *ncx, int *ncy, t_chunk_info ** chunkIdx)
+static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, int *fmt, int *ncx, int *ncy, t_chunk_info ** chunkIdx)
 {
-  int i;
-  int ch;
-  char id[5];
-  t_chunk_info *cidx;
-  int sidx;
-  int nc;
-
-  GD2_DBG(php_gd_error("Reading gd2 header info\n"));
-
-  for (i = 0; i < 4; i++)
-    {
-      ch = gdGetC (in);
-      if (ch == EOF)
-       {
-         goto fail1;
-       };
-      id[i] = ch;
-    };
-  id[4] = 0;
-
-  GD2_DBG(php_gd_error("Got file code: %s\n", id));
-
-  /* Equiv. of 'magick'.  */
-  if (strcmp (id, GD2_ID) != 0)
-    {
-      GD2_DBG(php_gd_error("Not a valid gd2 file\n"));
-      goto fail1;
-    };
-
-  /* Version */
-  if (gdGetWord (vers, in) != 1)
-    {
-      goto fail1;
-    };
-  GD2_DBG(php_gd_error("Version: %d\n", *vers));
-
-  if ((*vers != 1) && (*vers != 2))
-    {
-      GD2_DBG(php_gd_error("Bad version: %d\n", *vers));
-      goto fail1;
-    };
-
-  /* Image Size */
-  if (!gdGetWord (sx, in))
-    {
-      GD2_DBG(php_gd_error("Could not get x-size\n"));
-      goto fail1;
-    }
-  if (!gdGetWord (sy, in))
-    {
-      GD2_DBG(php_gd_error("Could not get y-size\n"));
-      goto fail1;
-    }
-  GD2_DBG(php_gd_error("Image is %dx%d\n", *sx, *sy));
-
-  /* Chunk Size (pixels, not bytes!) */
-  if (gdGetWord (cs, in) != 1)
-    {
-      goto fail1;
-    };
-  GD2_DBG(php_gd_error("ChunkSize: %d\n", *cs));
-
-  if ((*cs < GD2_CHUNKSIZE_MIN) || (*cs > GD2_CHUNKSIZE_MAX))
-    {
-      GD2_DBG(php_gd_error("Bad chunk size: %d\n", *cs));
-      goto fail1;
-    };
-
-  /* Data Format */
-  if (gdGetWord (fmt, in) != 1)
-    {
-      goto fail1;
-    };
-  GD2_DBG(php_gd_error("Format: %d\n", *fmt));
-
-  if ((*fmt != GD2_FMT_RAW) && (*fmt != GD2_FMT_COMPRESSED))
-    {
-      GD2_DBG(php_gd_error("Bad data format: %d\n", *fmt));
-      goto fail1;
-    };
-
-
-  /* # of chunks wide */
-  if (gdGetWord (ncx, in) != 1)
-    {
-      goto fail1;
-    };
-  GD2_DBG(php_gd_error("%d Chunks Wide\n", *ncx));
-
-  /* # of chunks high */
-  if (gdGetWord (ncy, in) != 1)
-    {
-      goto fail1;
-    };
-  GD2_DBG(php_gd_error("%d Chunks vertically\n", *ncy));
-
-  if ((*fmt) == GD2_FMT_COMPRESSED)
-    {
-      nc = (*ncx) * (*ncy);
-      GD2_DBG(php_gd_error("Reading %d chunk index entries\n", nc));
-      sidx = sizeof (t_chunk_info) * nc;
-      cidx = gdCalloc (sidx, 1);
-      for (i = 0; i < nc; i++)
-       {
-         if (gdGetInt (&cidx[i].offset, in) != 1)
-           {
-             goto fail1;
-           };
-         if (gdGetInt (&cidx[i].size, in) != 1)
-           {
-             goto fail1;
-           };
-       };
-      *chunkIdx = cidx;
-    };
-
-  GD2_DBG(php_gd_error("gd2 header complete\n"));
-
-  return 1;
+       int i;
+       int ch;
+       char id[5];
+       t_chunk_info *cidx;
+       int sidx;
+       int nc;
+
+       GD2_DBG(php_gd_error("Reading gd2 header info\n"));
+
+       for (i = 0; i < 4; i++) {
+               ch = gdGetC(in);
+               if (ch == EOF) {
+                       goto fail1;
+               }
+               id[i] = ch;
+       }
+       id[4] = 0;
+
+       GD2_DBG(php_gd_error("Got file code: %s\n", id));
+
+       /* Equiv. of 'magick'.  */
+       if (strcmp(id, GD2_ID) != 0) {
+               GD2_DBG(php_gd_error("Not a valid gd2 file\n"));
+               goto fail1;
+       }
+
+       /* Version */
+       if (gdGetWord(vers, in) != 1) {
+               goto fail1;
+       }
+       GD2_DBG(php_gd_error("Version: %d\n", *vers));
+
+       if ((*vers != 1) && (*vers != 2)) {
+               GD2_DBG(php_gd_error("Bad version: %d\n", *vers));
+               goto fail1;
+       }
+
+       /* Image Size */
+       if (!gdGetWord(sx, in)) {
+               GD2_DBG(php_gd_error("Could not get x-size\n"));
+               goto fail1;
+       }
+       if (!gdGetWord(sy, in)) {
+               GD2_DBG(php_gd_error("Could not get y-size\n"));
+               goto fail1;
+       }
+       GD2_DBG(php_gd_error("Image is %dx%d\n", *sx, *sy));
+
+       /* Chunk Size (pixels, not bytes!) */
+       if (gdGetWord(cs, in) != 1) {
+               goto fail1;
+       }
+       GD2_DBG(php_gd_error("ChunkSize: %d\n", *cs));
+
+       if ((*cs < GD2_CHUNKSIZE_MIN) || (*cs > GD2_CHUNKSIZE_MAX)) {
+               GD2_DBG(php_gd_error("Bad chunk size: %d\n", *cs));
+               goto fail1;
+       }
+
+       /* Data Format */
+       if (gdGetWord(fmt, in) != 1) {
+               goto fail1;
+       }
+       GD2_DBG(php_gd_error("Format: %d\n", *fmt));
+
+       if ((*fmt != GD2_FMT_RAW) && (*fmt != GD2_FMT_COMPRESSED) && (*fmt != GD2_FMT_TRUECOLOR_RAW) && (*fmt != GD2_FMT_TRUECOLOR_COMPRESSED)) {
+               GD2_DBG(php_gd_error("Bad data format: %d\n", *fmt));
+               goto fail1;
+       }
+
+       /* # of chunks wide */
+       if (gdGetWord(ncx, in) != 1) {
+               goto fail1;
+       }
+       GD2_DBG(php_gd_error("%d Chunks Wide\n", *ncx));
+
+       /* # of chunks high */
+       if (gdGetWord(ncy, in) != 1) {
+               goto fail1;
+       }
+       GD2_DBG(php_gd_error("%d Chunks vertically\n", *ncy));
+
+       if (gd2_compressed(*fmt)) {
+               nc = (*ncx) * (*ncy);
+               GD2_DBG(php_gd_error("Reading %d chunk index entries\n", nc));
+               sidx = sizeof(t_chunk_info) * nc;
+               cidx = gdCalloc(sidx, 1);
+               for (i = 0; i < nc; i++) {
+                       if (gdGetInt(&cidx[i].offset, in) != 1) {
+                               goto fail1;
+                       }
+                       if (gdGetInt(&cidx[i].size, in) != 1) {
+                               goto fail1;
+                       }
+               }
+               *chunkIdx = cidx;
+       }
+
+       GD2_DBG(php_gd_error("gd2 header complete\n"));
+
+       return 1;
 
 fail1:
-  return 0;
+       return 0;
 }
 
-static
-  gdImagePtr
-_gd2CreateFromFile (gdIOCtxPtr in, int *sx, int *sy,
-                   int *cs, int *vers, int *fmt,
-                   int *ncx, int *ncy, t_chunk_info ** cidx)
+static gdImagePtr _gd2CreateFromFile (gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, int *fmt, int *ncx, int *ncy, t_chunk_info ** cidx)
 {
-  gdImagePtr im;
-
-  if (_gd2GetHeader (in, sx, sy, cs, vers, fmt, ncx, ncy, cidx) != 1)
-    {
-      GD2_DBG(php_gd_error("Bad GD2 header\n"));
-      goto fail1;
-    }
-
-  im = gdImageCreateTrueColor(*sx, *sy);
-  if (im == NULL)
-    {
-      GD2_DBG(php_gd_error("Could not create gdImage\n"));
-      goto fail1;
-    };
-
-  if (!_gdGetColors (in, im, (*vers) == 2))
-    {
-      GD2_DBG(php_gd_error("Could not read color palette\n"));
-      goto fail2;
-    }
-  GD2_DBG(php_gd_error("Image palette completed: %d colours\n", im->colorsTotal));
-
-  return im;
+       gdImagePtr im;
+
+       if (_gd2GetHeader (in, sx, sy, cs, vers, fmt, ncx, ncy, cidx) != 1) {
+               GD2_DBG(php_gd_error("Bad GD2 header\n"));
+               goto fail1;
+       }
+
+       if (gd2_truecolor(*fmt)) {
+               im = gdImageCreateTrueColor(*sx, *sy);
+       } else {
+               im = gdImageCreate(*sx, *sy);
+       }
+       if (im == NULL) {
+               GD2_DBG(php_gd_error("Could not create gdImage\n"));
+               goto fail1;
+       }
+
+       if (!_gdGetColors(in, im, (*vers) == 2)) {
+               GD2_DBG(php_gd_error("Could not read color palette\n"));
+               goto fail2;
+       }
+       GD2_DBG(php_gd_error("Image palette completed: %d colours\n", im->colorsTotal));
+
+       return im;
 
 fail2:
-  gdImageDestroy (im);
-  return 0;
+       gdImageDestroy(im);
+       return 0;
 
 fail1:
-  return 0;
-
+       return 0;
 }
 
-static
-int
-_gd2ReadChunk (int offset, char *compBuf, int compSize, char *chunkBuf, uLongf * chunkLen, gdIOCtx * in)
+static int _gd2ReadChunk (int offset, char *compBuf, int compSize, char *chunkBuf, uLongf * chunkLen, gdIOCtx * in)
 {
-  int zerr;
-
-  if (gdTell (in) != offset)
-    {
-      GD2_DBG(php_gd_error("Positioning in file to %d\n", offset));
-      gdSeek (in, offset);
-    }
-  else
-    {
-      GD2_DBG(php_gd_error("Already Positioned in file to %d\n", offset));
-    };
-
-  /* Read and uncompress an entire chunk. */
-  GD2_DBG(php_gd_error("Reading file\n"));
-  if (gdGetBuf (compBuf, compSize, in) != compSize)
-    {
-      return FALSE;
-    };
-  GD2_DBG(php_gd_error("Got %d bytes. Uncompressing into buffer of %d bytes\n", compSize, (int)*chunkLen));
-  zerr = uncompress ((unsigned char *) chunkBuf, chunkLen,
-                    (unsigned char *) compBuf, compSize);
-  if (zerr != Z_OK)
-    {
-      GD2_DBG(php_gd_error("Error %d from uncompress\n", zerr));
-      return FALSE;
-    };
-  GD2_DBG(php_gd_error("Got chunk\n"));
-  return TRUE;
+       int zerr;
+
+       if (gdTell(in) != offset) {
+               GD2_DBG(php_gd_error("Positioning in file to %d\n", offset));
+               gdSeek(in, offset);
+       } else {
+               GD2_DBG(php_gd_error("Already Positioned in file to %d\n", offset));
+       }
+
+       /* Read and uncompress an entire chunk. */
+       GD2_DBG(php_gd_error("Reading file\n"));
+       if (gdGetBuf(compBuf, compSize, in) != compSize) {
+               return FALSE;
+       }
+       GD2_DBG(php_gd_error("Got %d bytes. Uncompressing into buffer of %d bytes\n", compSize, (int)*chunkLen));
+       zerr = uncompress((unsigned char *) chunkBuf, chunkLen, (unsigned char *) compBuf, compSize);
+       if (zerr != Z_OK) {
+               GD2_DBG(php_gd_error("Error %d from uncompress\n", zerr));
+               return FALSE;
+       }
+       GD2_DBG(php_gd_error("Got chunk\n"));
+       
+       return TRUE;
 }
 
-gdImagePtr
-gdImageCreateFromGd2 (FILE * inFile)
+gdImagePtr gdImageCreateFromGd2 (FILE * inFile)
 {
-  gdIOCtx *in = gdNewFileCtx (inFile);
-  gdImagePtr im;
+       gdIOCtx *in = gdNewFileCtx(inFile);
+       gdImagePtr im;
 
-  im = gdImageCreateFromGd2Ctx (in);
+       im = gdImageCreateFromGd2Ctx(in);
 
-  in->gd_free (in);
+       in->gd_free(in);
 
-  return im;
+       return im;
 }
 
-gdImagePtr
-gdImageCreateFromGd2Ctx (gdIOCtxPtr in)
+gdImagePtr gdImageCreateFromGd2Ctx (gdIOCtxPtr in)
 {
-  int sx, sy;
-  int i;
-  int ncx, ncy, nc, cs, cx, cy;
-  int x, y, ylo, yhi, xlo, xhi;
-  int vers, fmt;
-  t_chunk_info *chunkIdx = NULL;       /* So we can gdFree it with impunity. */
-  unsigned char *chunkBuf = NULL;      /* So we can gdFree it with impunity. */
-  int chunkNum = 0;
-  int chunkMax = 0;
-  uLongf chunkLen;
-  int chunkPos = 0;
-  int compMax = 0;
-  int bytesPerPixel;
-  char *compBuf = NULL;                /* So we can gdFree it with impunity. */
-
-  gdImagePtr im;
-
-  /* Get the header */
-  im = _gd2CreateFromFile (in, &sx, &sy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx);
-
-  if (im == NULL)
-    {
-      return 0;
-    };
-  bytesPerPixel = im->trueColor ? 4 : 1;
-  nc = ncx * ncy;
-
-  if (fmt == GD2_FMT_COMPRESSED)
-    {
-      /* Find the maximum compressed chunk size. */
-      compMax = 0;
-      for (i = 0; (i < nc); i++)
-       {
-         if (chunkIdx[i].size > compMax)
-           {
-             compMax = chunkIdx[i].size;
-           };
-       };
-      compMax++;
-
-      /* Allocate buffers */
-      chunkMax = cs * bytesPerPixel * cs;
-      chunkBuf = gdCalloc (chunkMax, 1);
-      compBuf = gdCalloc (compMax, 1);
-      GD2_DBG(php_gd_error("Largest compressed chunk is %d bytes\n", compMax));
-    };
-
-/*      if ( (ncx != sx / cs) || (ncy != sy / cs)) { */
-/*              goto fail2; */
-/*      }; */
-
-  /* Read the data... */
-  for (cy = 0; (cy < ncy); cy++)
-    {
-      for (cx = 0; (cx < ncx); cx++)
-       {
-
-         ylo = cy * cs;
-         yhi = ylo + cs;
-         if (yhi > im->sy)
-           {
-             yhi = im->sy;
-           };
-
-         GD2_DBG(php_gd_error("Processing Chunk %d (%d, %d), y from %d to %d\n", chunkNum, cx, cy, ylo, yhi));
-
-         if (fmt == GD2_FMT_COMPRESSED)
-           {
-
-             chunkLen = chunkMax;
-
-             if (!_gd2ReadChunk (chunkIdx[chunkNum].offset,
-                                 compBuf,
-                                 chunkIdx[chunkNum].size,
-                                 chunkBuf, &chunkLen, in))
-               {
-                 GD2_DBG(php_gd_error("Error reading comproessed chunk\n"));
-                 goto fail2;
-               };
-
-             chunkPos = 0;
-           };
-
-         for (y = ylo; (y < yhi); y++)
-           {
-
-             xlo = cx * cs;
-             xhi = xlo + cs;
-             if (xhi > im->sx)
-               {
-                 xhi = im->sx;
-               };
-             /*GD2_DBG(php_gd_error("y=%d: ",y)); */
-             if (fmt == GD2_FMT_RAW)
-               {
-                 for (x = xlo; x < xhi; x++)
-                   {
-
-                     if (im->trueColor)
-                       {
-                         if (!gdGetInt (&im->tpixels[y][x], in))
-                           {
-                             /*php_gd_error("EOF while reading\n"); */
-                             /*gdImageDestroy(im); */
-                             /*return 0; */
-                             im->tpixels[y][x] = 0;
-                           }
-                       }
-                     else
-                       {
-                         int ch;
-                         if (!gdGetByte (&ch, in))
-                           {
-                             /*php_gd_error("EOF while reading\n"); */
-                             /*gdImageDestroy(im); */
-                             /*return 0; */
-                             ch = 0;
-                           }
-                         im->pixels[y][x] = ch;
+       int sx, sy;
+       int i;
+       int ncx, ncy, nc, cs, cx, cy;
+       int x, y, ylo, yhi, xlo, xhi;
+       int vers, fmt;
+       t_chunk_info *chunkIdx = NULL;  /* So we can gdFree it with impunity. */
+       unsigned char *chunkBuf = NULL; /* So we can gdFree it with impunity. */
+       int chunkNum = 0;
+       int chunkMax = 0;
+       uLongf chunkLen;
+       int chunkPos = 0;
+       int compMax = 0;
+       int bytesPerPixel;
+       char *compBuf = NULL;           /* So we can gdFree it with impunity. */
+
+       gdImagePtr im;
+
+       /* Get the header */
+       if (!(im = _gd2CreateFromFile(in, &sx, &sy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx))) {
+                return 0;
+       }
+
+       bytesPerPixel = im->trueColor ? 4 : 1;
+       nc = ncx * ncy;
+
+       if (gd2_compressed(fmt)) {
+               /* Find the maximum compressed chunk size. */
+               compMax = 0;
+               for (i = 0; (i < nc); i++) {
+                       if (chunkIdx[i].size > compMax) {
+                               compMax = chunkIdx[i].size;
                        }
-                   }
                }
-             else
-               {
-                 for (x = xlo; x < xhi; x++)
-                   {
-                     if (im->trueColor)
-                       {
-                         /* 2.0.1: work around a gcc bug by being verbose.
-                            TBB */
-                         int a = chunkBuf[chunkPos++] << 24;
-                         int r = chunkBuf[chunkPos++] << 16;
-                         int g = chunkBuf[chunkPos++] << 8;
-                         int b = chunkBuf[chunkPos++];
-                         im->tpixels[y][x] = a + r + g + b;
+               compMax++;
+
+               /* Allocate buffers */
+               chunkMax = cs * bytesPerPixel * cs;
+               chunkBuf = gdCalloc(chunkMax, 1);
+               compBuf = gdCalloc(compMax, 1);
+               
+               GD2_DBG(php_gd_error("Largest compressed chunk is %d bytes\n", compMax));
+       }
+
+       /* Read the data... */
+       for (cy = 0; (cy < ncy); cy++) {
+               for (cx = 0; (cx < ncx); cx++) {
+                       ylo = cy * cs;
+                       yhi = ylo + cs;
+                       if (yhi > im->sy) {
+                               yhi = im->sy;
+                       }
+
+                       GD2_DBG(php_gd_error("Processing Chunk %d (%d, %d), y from %d to %d\n", chunkNum, cx, cy, ylo, yhi));
+
+                       if (gd2_compressed(fmt)) {
+                               chunkLen = chunkMax;
+
+                               if (!_gd2ReadChunk(chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, chunkBuf, &chunkLen, in)) {
+                                       GD2_DBG(php_gd_error("Error reading comproessed chunk\n"));
+                                       goto fail2;
+                               }
+
+                               chunkPos = 0;
                        }
-                     else
-                       {
-                         im->pixels[y][x] = chunkBuf[chunkPos++];
+
+                       for (y = ylo; (y < yhi); y++) {
+                               xlo = cx * cs;
+                               xhi = xlo + cs;
+                               if (xhi > im->sx) {
+                                       xhi = im->sx;
+                               }
+
+                               if (!gd2_compressed(fmt)) {
+                                       for (x = xlo; x < xhi; x++) {
+                                               if (im->trueColor) {
+                                                       if (!gdGetInt(&im->tpixels[y][x], in)) {
+                                                               im->tpixels[y][x] = 0;
+                                                       }
+                                               } else {
+                                                       int ch;
+                                                       if (!gdGetByte(&ch, in)) {
+                                                               ch = 0;
+                                                       }
+                                                       im->pixels[y][x] = ch;
+                                               }
+                                       }
+                               } else {
+                                       for (x = xlo; x < xhi; x++) {
+                                               if (im->trueColor) {
+                                                       /* 2.0.1: work around a gcc bug by being verbose. TBB */
+                                                       int a = chunkBuf[chunkPos++] << 24;
+                                                       int r = chunkBuf[chunkPos++] << 16;
+                                                       int g = chunkBuf[chunkPos++] << 8;
+                                                       int b = chunkBuf[chunkPos++];
+                                                       im->tpixels[y][x] = a + r + g + b;
+                                               } else {
+                                                       im->pixels[y][x] = chunkBuf[chunkPos++];
+                                               }
+                                       }
+                               }
                        }
-                   };
-               };
-             /*GD2_DBG(php_gd_error("\n")); */
-           };
-         chunkNum++;
-       };
-    };
+                       chunkNum++;
+               }
+       }
 
-  GD2_DBG(php_gd_error("Freeing memory\n"));
+       GD2_DBG(php_gd_error("Freeing memory\n"));
 
-  gdFree (chunkBuf);
-  gdFree (compBuf);
-  gdFree (chunkIdx);
+       if (chunkBuf) {
+               gdFree(chunkBuf);
+       }
+       if (compBuf) {
+               gdFree(compBuf);
+       }
+       if (chunkIdx) {
+               gdFree(chunkIdx);
+       }
 
-  GD2_DBG(php_gd_error("Done\n"));
+       GD2_DBG(php_gd_error("Done\n"));
 
-  return im;
+       return im;
 
 fail2:
-  gdImageDestroy (im);
-  gdFree (chunkBuf);
-  gdFree (compBuf);
-  gdFree (chunkIdx);
-  return 0;
+       gdImageDestroy(im);
+       if (chunkBuf) {
+               gdFree(chunkBuf);
+       }
+       if (compBuf) {
+               gdFree(compBuf);
+       }
+       if (chunkIdx) {
+               gdFree(chunkIdx);
+       }
 
+       return 0;
 }
 
-gdImagePtr
-gdImageCreateFromGd2Part (FILE * inFile, int srcx, int srcy, int w, int h)
+gdImagePtr gdImageCreateFromGd2Part (FILE * inFile, int srcx, int srcy, int w, int h) 
 {
-  gdImagePtr im;
-  gdIOCtx *in = gdNewFileCtx (inFile);
+       gdImagePtr im;
+       gdIOCtx *in = gdNewFileCtx(inFile);
 
-  im = gdImageCreateFromGd2PartCtx (in, srcx, srcy, w, h);
+       im = gdImageCreateFromGd2PartCtx(in, srcx, srcy, w, h);
 
-  in->gd_free (in);
+       in->gd_free(in);
 
-  return im;
+       return im;
 }
 
-gdImagePtr
-gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, int h)
+gdImagePtr gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, int h)
 {
-  int scx, scy, ecx, ecy, fsx, fsy;
-  int nc, ncx, ncy, cs, cx, cy;
-  int x, y, ylo, yhi, xlo, xhi;
-  int dstart, dpos;
-  int i;
-  int ch, vers, fmt;
-  t_chunk_info *chunkIdx = NULL;
-  char *chunkBuf = NULL;
-  int chunkNum;
-  int chunkMax = 0;
-  uLongf chunkLen;
-  int chunkPos = 0;
-  int compMax;
-  char *compBuf = NULL;
-
-  gdImagePtr im;
-
-  /* */
-  /* The next few lines are basically copied from gd2CreateFromFile */
-  /* - we change the file size, so don't want to use the code directly. */
-  /*   but we do need to know the file size. */
-  /* */
-  if (_gd2GetHeader (in, &fsx, &fsy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx) != 1)
-    {
-      goto fail1;
-    }
-
-  GD2_DBG(php_gd_error("File size is %dx%d\n", fsx, fsy));
-
-  /* This is the difference - make a file based on size of chunks. */
-  im = gdImageCreate (w, h);
-  if (im == NULL)
-    {
-      goto fail1;
-    };
-
-  if (!_gdGetColors (in, im, vers == 2))
-    {
-      goto fail2;
-    }
-  GD2_DBG(php_gd_error("Image palette completed: %d colours\n", im->colorsTotal));
-
-  /* Process the header info */
-  nc = ncx * ncy;
-
-  if (fmt == GD2_FMT_COMPRESSED)
-    {
-      /* Find the maximum compressed chunk size. */
-      compMax = 0;
-      for (i = 0; (i < nc); i++)
-       {
-         if (chunkIdx[i].size > compMax)
-           {
-             compMax = chunkIdx[i].size;
-           };
-       };
-      compMax++;
-
-      if (im->trueColor)
-       {
-         chunkMax = cs * cs * 4;
-       }
-      else
-       {
-         chunkMax = cs * cs;
-       }
-      chunkBuf = gdCalloc (chunkMax, 1);
-      compBuf = gdCalloc (compMax, 1);
-    };
-
-/*      Don't bother with this... */
-/*      if ( (ncx != sx / cs) || (ncy != sy / cs)) { */
-/*              goto fail2; */
-/*      }; */
-
-
-  /* Work out start/end chunks */
-  scx = srcx / cs;
-  scy = srcy / cs;
-  if (scx < 0)
-    {
-      scx = 0;
-    };
-  if (scy < 0)
-    {
-      scy = 0;
-    };
-
-  ecx = (srcx + w) / cs;
-  ecy = (srcy + h) / cs;
-  if (ecx >= ncx)
-    {
-      ecx = ncx - 1;
-    };
-  if (ecy >= ncy)
-    {
-      ecy = ncy - 1;
-    };
-
-  /* Remember file position of image data. */
-  dstart = gdTell (in);
-  GD2_DBG(php_gd_error("Data starts at %d\n", dstart));
-
-  /* Loop through the chunks. */
-  for (cy = scy; (cy <= ecy); cy++)
-    {
-
-      ylo = cy * cs;
-      yhi = ylo + cs;
-      if (yhi > fsy)
-       {
-         yhi = fsy;
-       };
-
-      for (cx = scx; (cx <= ecx); cx++)
-       {
-
-         xlo = cx * cs;
-         xhi = xlo + cs;
-         if (xhi > fsx)
-           {
-             xhi = fsx;
-           };
-
-         GD2_DBG(php_gd_error("Processing Chunk (%d, %d), from %d to %d\n", cx, cy, ylo, yhi));
-
-         if (fmt == GD2_FMT_RAW)
-           {
-             GD2_DBG(php_gd_error("Using raw format data\n"));
-             if (im->trueColor)
-               {
-                 dpos = (cy * (cs * fsx) + cx * cs * (yhi - ylo) * 4) + dstart;
+       int scx, scy, ecx, ecy, fsx, fsy;
+       int nc, ncx, ncy, cs, cx, cy;
+       int x, y, ylo, yhi, xlo, xhi;
+       int dstart, dpos;
+       int i;
+       int ch, vers, fmt;
+       t_chunk_info *chunkIdx = NULL;
+       char *chunkBuf = NULL;
+       int chunkNum;
+       int chunkMax = 0;
+       uLongf chunkLen;
+       int chunkPos = 0;
+       int compMax;
+       char *compBuf = NULL;
+
+       gdImagePtr im;
+
+       /* The next few lines are basically copied from gd2CreateFromFile
+        * we change the file size, so don't want to use the code directly.
+        * but we do need to know the file size.
+        */
+       if (_gd2GetHeader(in, &fsx, &fsy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx) != 1) {
+               goto fail1;
+       }
+
+       GD2_DBG(php_gd_error("File size is %dx%d\n", fsx, fsy));
+
+       /* This is the difference - make a file based on size of chunks. */
+       if (gd2_truecolor(fmt)) {
+               im = gdImageCreateTrueColor(w, h);
+       } else {
+               im = gdImageCreate(w, h);
+       }
+       if (im == NULL) {
+               goto fail1;
+       }
+
+       if (!_gdGetColors(in, im, vers == 2)) {
+               goto fail2;
+       }
+       GD2_DBG(php_gd_error("Image palette completed: %d colours\n", im->colorsTotal));
+
+       /* Process the header info */
+       nc = ncx * ncy;
+
+       if (gd2_compressed(fmt)) {
+               /* Find the maximum compressed chunk size. */
+               compMax = 0;
+               for (i = 0; (i < nc); i++) {
+                       if (chunkIdx[i].size > compMax) {
+                               compMax = chunkIdx[i].size;
+                       }
                }
-             else
-               {
-                 dpos = cy * (cs * fsx) + cx * cs * (yhi - ylo) + dstart;
+               compMax++;
+
+               if (im->trueColor) {
+                       chunkMax = cs * cs * 4;
+               } else {
+                       chunkMax = cs * cs;
                }
+               chunkBuf = gdCalloc(chunkMax, 1);
+               compBuf = gdCalloc(compMax, 1);
+       }
 
-             if (gdSeek (in, dpos) != 0)
-               {
-                 php_gd_error_ex(E_WARNING, "Error from seek: %d\n", errno);
-                 goto fail2;
-               };
-             GD2_DBG(php_gd_error("Reading (%d, %d) from position %d\n", cx, cy, dpos - dstart));
-           }
-         else
-           {
-             chunkNum = cx + cy * ncx;
-
-             chunkLen = chunkMax;
-             if (!_gd2ReadChunk (chunkIdx[chunkNum].offset,
-                                 compBuf,
-                                 chunkIdx[chunkNum].size,
-                                 chunkBuf, &chunkLen, in))
-               {
-                 php_gd_error("Error reading comproessed chunk\n");
-                 goto fail2;
-               };
-             chunkPos = 0;
-             GD2_DBG(php_gd_error("Reading (%d, %d) from chunk %d\n", cx, cy, chunkNum));
-           };
-
-         GD2_DBG(php_gd_error("   into (%d, %d) - (%d, %d)\n", xlo, ylo, xhi, yhi));
-         for (y = ylo; (y < yhi); y++)
-           {
-
-             for (x = xlo; x < xhi; x++)
-               {
-                 if (fmt == GD2_FMT_RAW)
-                   {
-                     if (im->trueColor)
-                       {
-                         if (!gdGetInt (&ch, in))
-                           {
-                             ch = 0;
-                             /*php_gd_error("EOF while reading file\n"); */
-                             /*goto fail2; */
-                           }
-                       }
-                     else
-                       {
-                         ch = gdGetC (in);
-                         if (ch == EOF)
-                           {
-                             ch = 0;
-                             /*php_gd_error("EOF while reading file\n"); */
-                             /*goto fail2; */
-                           }
+       /* Work out start/end chunks */
+       scx = srcx / cs;
+       scy = srcy / cs;
+       if (scx < 0) {
+               scx = 0;
+       }
+       if (scy < 0) {
+               scy = 0;
+       }
+
+       ecx = (srcx + w) / cs;
+       ecy = (srcy + h) / cs;
+       if (ecx >= ncx) {
+               ecx = ncx - 1;
+       }
+       if (ecy >= ncy) {
+               ecy = ncy - 1;
+       }
+
+       /* Remember file position of image data. */
+       dstart = gdTell(in);
+       GD2_DBG(php_gd_error("Data starts at %d\n", dstart));
+
+       /* Loop through the chunks. */
+       for (cy = scy; (cy <= ecy); cy++) {
+               ylo = cy * cs;
+               yhi = ylo + cs;
+               if (yhi > fsy) {
+                       yhi = fsy;
+               }
+
+               for (cx = scx; cx <= ecx; cx++) {
+
+                       xlo = cx * cs;
+                       xhi = xlo + cs;
+                       if (xhi > fsx) {
+                               xhi = fsx;
                        }
-                   }
-                 else
-                   {
-                     if (im->trueColor)
-                       {
-                          ch = chunkBuf[chunkPos++];
-                          ch = (ch << 8) + chunkBuf[chunkPos++];
-                          ch = (ch << 8) + chunkBuf[chunkPos++];
-                          ch = (ch << 8) + chunkBuf[chunkPos++];
+
+                       GD2_DBG(php_gd_error("Processing Chunk (%d, %d), from %d to %d\n", cx, cy, ylo, yhi));
+
+                       if (!gd2_compressed(fmt)) {
+                               GD2_DBG(php_gd_error("Using raw format data\n"));
+                               if (im->trueColor) {
+                                       dpos = (cy * (cs * fsx) * 4 + cx * cs * (yhi - ylo) * 4) + dstart;
+                               } else {
+                                       dpos = cy * (cs * fsx) + cx * cs * (yhi - ylo) + dstart;
+                               }
+
+                               /* gd 2.0.11: gdSeek returns TRUE on success, not 0. Longstanding bug. 01/16/03 */
+                               if (!gdSeek(in, dpos)) {
+                                       php_gd_error_ex(E_WARNING, "Error from seek: %d\n", errno);
+                                       goto fail2;
+                               }
+                               GD2_DBG(php_gd_error("Reading (%d, %d) from position %d\n", cx, cy, dpos - dstart));
+                       } else {
+                               chunkNum = cx + cy * ncx;
+
+                               chunkLen = chunkMax;
+                               if (!_gd2ReadChunk (chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, chunkBuf, &chunkLen, in)) {
+                                       php_gd_error("Error reading comproessed chunk\n");
+                                       goto fail2;
+                               }
+                               chunkPos = 0;
+                               GD2_DBG(php_gd_error("Reading (%d, %d) from chunk %d\n", cx, cy, chunkNum));
                        }
-                     else
-                       {
-                         ch = chunkBuf[chunkPos++];
+
+                       GD2_DBG(php_gd_error("   into (%d, %d) - (%d, %d)\n", xlo, ylo, xhi, yhi));
+
+                       for (y = ylo; (y < yhi); y++) {
+                               for (x = xlo; x < xhi; x++) {
+                                       if (!gd2_compressed(fmt)) {
+                                               if (im->trueColor) {
+                                                       if (!gdGetInt(&ch, in)) {
+                                                               ch = 0;
+                                                       }
+                                               } else {
+                                                       ch = gdGetC(in);
+                                                       if (ch == EOF) {
+                                                               ch = 0;
+                                                       }
+                                               }
+                                       } else {
+                                               if (im->trueColor) {
+                                                       ch = chunkBuf[chunkPos++];
+                                                       ch = (ch << 8) + chunkBuf[chunkPos++];
+                                                       ch = (ch << 8) + chunkBuf[chunkPos++];
+                                                       ch = (ch << 8) + chunkBuf[chunkPos++];
+                                               } else {
+                                                       ch = chunkBuf[chunkPos++];
+                                               }
+                                       }
+
+                                       /* Only use a point that is in the image. */
+                                       if ((x >= srcx) && (x < (srcx + w)) && (x < fsx) && (x >= 0) && (y >= srcy) && (y < (srcy + h)) && (y < fsy) && (y >= 0)) {
+                                               if (im->trueColor) {  
+                                                       im->tpixels[y - srcy][x - srcx] = ch;
+                                               } else {
+                                                       im->pixels[y - srcy][x - srcx] = ch;
+                                               }   
+                                       }
+                               }
                        }
-                   };
-
-                 /* Only use a point that is in the image. */
-                 if ((x >= srcx) && (x < (srcx + w)) && (x < fsx) && (x >= 0)
-                 && (y >= srcy) && (y < (srcy + h)) && (y < fsy) && (y >= 0)
-                   )
-                   {
-                     im->pixels[y - srcy][x - srcx] = ch;
-                   }
-               };
-           };
-       };
-    };
-
-  gdFree (chunkBuf);
-  gdFree (compBuf);
-  gdFree (chunkIdx);
-
-  return im;
+               }
+       }
+
+       if (chunkBuf) {
+               gdFree(chunkBuf);
+       }
+       if (compBuf) {
+               gdFree(compBuf);
+       }
+       if (chunkIdx) {
+               gdFree(chunkIdx);
+       }
+       
+       return im;
 
 fail2:
-  gdImageDestroy (im);
+       gdImageDestroy(im);
 fail1:
-  gdFree (chunkBuf);
-  gdFree (compBuf);
-  gdFree (chunkIdx);
-
-  return 0;
+       if (chunkBuf) {
+               gdFree(chunkBuf);
+       }
+       if (compBuf) {
+               gdFree(compBuf);
+       }
+       if (chunkIdx) {
+               gdFree(chunkIdx);
+       }
 
+       return 0;
 }
 
-static
-void
-_gd2PutHeader (gdImagePtr im, gdIOCtx * out, int cs, int fmt, int cx, int cy)
+static void _gd2PutHeader (gdImagePtr im, gdIOCtx * out, int cs, int fmt, int cx, int cy)
 {
-  int i;
-
-  /* Send the gd2 id, to verify file format. */
-  for (i = 0; i < 4; i++)
-    {
-      gdPutC ((unsigned char) (GD2_ID[i]), out);
-    };
-
-  /* */
-  /* We put the version info first, so future versions can easily change header info. */
-  /* */
-  gdPutWord (GD2_VERS, out);
-  gdPutWord (im->sx, out);
-  gdPutWord (im->sy, out);
-  gdPutWord (cs, out);
-  gdPutWord (fmt, out);
-  gdPutWord (cx, out);
-  gdPutWord (cy, out);
+       int i;
+
+       /* Send the gd2 id, to verify file format. */
+       for (i = 0; i < 4; i++) {
+               gdPutC((unsigned char) (GD2_ID[i]), out);
+       }
+
+       /* We put the version info first, so future versions can easily change header info. */
 
+       gdPutWord(GD2_VERS, out);
+       gdPutWord(im->sx, out);
+       gdPutWord(im->sy, out);
+       gdPutWord(cs, out);
+       gdPutWord(fmt, out);
+       gdPutWord(cx, out);
+       gdPutWord(cy, out);
 }
 
-static void
-_gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt)
+static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt)
 {
-  int ncx, ncy, cx, cy;
-  int x, y, ylo, yhi, xlo, xhi;
-  int chunkLen;
-  int chunkNum = 0;
-  char *chunkData = NULL;      /* So we can gdFree it with impunity. */
-  char *compData = NULL;       /* So we can gdFree it with impunity. */
-  uLongf compLen;
-  int idxPos = 0;
-  int idxSize;
-  t_chunk_info *chunkIdx = NULL;
-  int posSave;
-  int bytesPerPixel = im->trueColor ? 4 : 1;
-  int compMax = 0;
-
-  /*php_gd_error("Trying to write GD2 file\n"); */
-
-  /* */
-  /* Force fmt to a valid value since we don't return anything. */
-  /* */
-  if ((fmt == 0) || ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)))
-    {
-      fmt = GD2_FMT_COMPRESSED;
-    };
-
-  /* */
-  /* Make sure chunk size is valid. These are arbitrary values; 64 because it seems */
-  /* a little silly to expect performance improvements on a 64x64 bit scale, and  */
-  /* 4096 because we buffer one chunk, and a 16MB buffer seems a little largei - it may be */
-  /* OK for one user, but for another to read it, they require the buffer. */
-  /* */
-  if (cs == 0)
-    {
-      cs = GD2_CHUNKSIZE;
-    }
-  else if (cs < GD2_CHUNKSIZE_MIN)
-    {
-      cs = GD2_CHUNKSIZE_MIN;
-    }
-  else if (cs > GD2_CHUNKSIZE_MAX)
-    {
-      cs = GD2_CHUNKSIZE_MAX;
-    };
-
-  /* Work out number of chunks. */
-  ncx = im->sx / cs + 1;
-  ncy = im->sy / cs + 1;
-
-  /* Write the standard header. */
-  _gd2PutHeader (im, out, cs, fmt, ncx, ncy);
-
-  if (fmt == GD2_FMT_COMPRESSED)
-    {
-      /* */
-      /* Work out size of buffer for compressed data, If CHUNKSIZE is large, */
-      /* then these will be large! */
-      /* */
-      /* The zlib notes say output buffer size should be (input size) * 1.01 * 12 */
-      /* - we'll use 1.02 to be paranoid. */
-      /* */
-      compMax = (int)(cs * bytesPerPixel * cs * 1.02f) + 12;
-
-      /* */
-      /* Allocate the buffers.  */
-      /* */
-      chunkData = gdCalloc (cs * bytesPerPixel * cs, 1);
-      compData = gdCalloc (compMax, 1);
-
-      /* */
-      /* Save the file position of chunk index, and allocate enough space for */
-      /* each chunk_info block . */
-      /* */
-      idxPos = gdTell (out);
-      idxSize = ncx * ncy * sizeof (t_chunk_info);
-      GD2_DBG(php_gd_error("Index size is %d\n", idxSize));
-      gdSeek (out, idxPos + idxSize);
-
-      chunkIdx = gdCalloc (idxSize * sizeof (t_chunk_info), 1);
-    };
-
-  _gdPutColors (im, out);
-
-  GD2_DBG(php_gd_error("Size: %dx%d\n", im->sx, im->sy));
-  GD2_DBG(php_gd_error("Chunks: %dx%d\n", ncx, ncy));
-
-  for (cy = 0; (cy < ncy); cy++)
-    {
-      for (cx = 0; (cx < ncx); cx++)
-       {
-
-         ylo = cy * cs;
-         yhi = ylo + cs;
-         if (yhi > im->sy)
-           {
-             yhi = im->sy;
-           };
-
-         GD2_DBG(php_gd_error("Processing Chunk (%dx%d), y from %d to %d\n", cx, cy, ylo, yhi));
-         chunkLen = 0;
-         for (y = ylo; (y < yhi); y++)
-           {
-
-             GD2_DBG(php_gd_error("y=%d: ",y));
-
-             xlo = cx * cs;
-             xhi = xlo + cs;
-             if (xhi > im->sx)
-               {
-                 xhi = im->sx;
-               };
-
-             if (fmt == GD2_FMT_COMPRESSED)
-               {
-                 for (x = xlo; x < xhi; x++)
-                   {
-                     GD2_DBG(php_gd_error("%d...",x));
-                     if (im->trueColor)
-                       {
-                         int p = im->tpixels[y][x];
-                         chunkData[chunkLen++] = gdTrueColorGetAlpha (p);
-                         chunkData[chunkLen++] = gdTrueColorGetRed (p);
-                         chunkData[chunkLen++] = gdTrueColorGetGreen (p);
-                         chunkData[chunkLen++] = gdTrueColorGetBlue (p);
-                       }
-                     else
-                       {
-                         chunkData[chunkLen++] = im->pixels[y][x];
+       int ncx, ncy, cx, cy;
+       int x, y, ylo, yhi, xlo, xhi;
+       int chunkLen;
+       int chunkNum = 0;
+       char *chunkData = NULL; /* So we can gdFree it with impunity. */
+       char *compData = NULL;  /* So we can gdFree it with impunity. */
+       uLongf compLen;
+       int idxPos = 0;
+       int idxSize;
+       t_chunk_info *chunkIdx = NULL; /* So we can gdFree it with impunity. */
+       int posSave;
+       int bytesPerPixel = im->trueColor ? 4 : 1;
+       int compMax = 0;
+
+       /* Force fmt to a valid value since we don't return anything. */
+       if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)) {      
+               fmt = im->trueColor ? GD2_FMT_TRUECOLOR_COMPRESSED : GD2_FMT_COMPRESSED;
+       }
+       if (im->trueColor) {
+               fmt += 2;
+       }
+       /* Make sure chunk size is valid. These are arbitrary values; 64 because it seems
+        * a little silly to expect performance improvements on a 64x64 bit scale, and
+        * 4096 because we buffer one chunk, and a 16MB buffer seems a little large - it may be
+        * OK for one user, but for another to read it, they require the buffer.
+        */
+       if (cs == 0) {
+               cs = GD2_CHUNKSIZE;
+       } else if (cs < GD2_CHUNKSIZE_MIN) {
+               cs = GD2_CHUNKSIZE_MIN;
+       } else if (cs > GD2_CHUNKSIZE_MAX) {
+               cs = GD2_CHUNKSIZE_MAX;
+       }
+
+       /* Work out number of chunks. */
+       ncx = im->sx / cs + 1;
+       ncy = im->sy / cs + 1;
+
+       /* Write the standard header. */
+       _gd2PutHeader (im, out, cs, fmt, ncx, ncy);
+
+       if (gd2_compressed(fmt)) {
+               /* Work out size of buffer for compressed data, If CHUNKSIZE is large,
+                * then these will be large!
+                */
+
+               /* The zlib notes say output buffer size should be (input size) * 1.01 * 12
+                * - we'll use 1.02 to be paranoid.
+                */
+               compMax = (int)(cs * bytesPerPixel * cs * 1.02f) + 12;
+
+               /* Allocate the buffers.  */
+               chunkData = gdCalloc(cs * bytesPerPixel * cs, 1);
+               compData = gdCalloc(compMax, 1);
+
+               /* Save the file position of chunk index, and allocate enough space for
+                * each chunk_info block . 
+                */
+               idxPos = gdTell(out);
+               idxSize = ncx * ncy * sizeof(t_chunk_info);
+               GD2_DBG(php_gd_error("Index size is %d\n", idxSize));
+               gdSeek(out, idxPos + idxSize);
+
+               chunkIdx = gdCalloc(idxSize * sizeof(t_chunk_info), 1);
+       }
+
+       _gdPutColors (im, out);
+
+       GD2_DBG(php_gd_error("Size: %dx%d\n", im->sx, im->sy));
+       GD2_DBG(php_gd_error("Chunks: %dx%d\n", ncx, ncy));
+
+       for (cy = 0; (cy < ncy); cy++) {
+               for (cx = 0; (cx < ncx); cx++) {
+                       ylo = cy * cs;
+                       yhi = ylo + cs;
+                       if (yhi > im->sy) {
+                               yhi = im->sy;
                        }
-                   };
-               }
-             else
-               {
-                 for (x = xlo; x < xhi; x++)
-                   {
-                     GD2_DBG(php_gd_error("%d, ",x)); 
-
-                     if (im->trueColor)
-                       {
-                         gdPutInt (im->tpixels[y][x], out);
+
+                       GD2_DBG(php_gd_error("Processing Chunk (%dx%d), y from %d to %d\n", cx, cy, ylo, yhi));
+                       chunkLen = 0;
+                       for (y = ylo; (y < yhi); y++) {
+                               GD2_DBG(php_gd_error("y=%d: ",y));
+                               xlo = cx * cs;
+                               xhi = xlo + cs;
+                               if (xhi > im->sx) {
+                                       xhi = im->sx;
+                               }
+
+                               if (gd2_compressed(fmt)) {
+                                       for (x = xlo; x < xhi; x++) {
+                                               GD2_DBG(php_gd_error("%d...",x));
+                                               if (im->trueColor) {
+                                                       int p = im->tpixels[y][x];
+                                                       chunkData[chunkLen++] = gdTrueColorGetAlpha(p);
+                                                       chunkData[chunkLen++] = gdTrueColorGetRed(p);
+                                                       chunkData[chunkLen++] = gdTrueColorGetGreen(p);
+                                                       chunkData[chunkLen++] = gdTrueColorGetBlue(p);
+                                               } else {
+                                                       chunkData[chunkLen++] = im->pixels[y][x];
+                                               }
+                                       }
+                               } else {
+                                       for (x = xlo; x < xhi; x++) {
+                                               GD2_DBG(php_gd_error("%d, ",x)); 
+
+                                               if (im->trueColor) {
+                                                       gdPutInt(im->tpixels[y][x], out);
+                                               } else {
+                                                       gdPutC((unsigned char) im->pixels[y][x], out);
+                                               }
+                                       }
+                               }
+                               GD2_DBG(php_gd_error("y=%d done.\n",y)); 
                        }
-                     else
-                       {
-                         gdPutC ((unsigned char) im->pixels[y][x], out);
+
+                       if (gd2_compressed(fmt)) {
+                               compLen = compMax;
+                               if (compress((unsigned char *) &compData[0], &compLen, (unsigned char *) &chunkData[0], chunkLen) != Z_OK) {
+                                       php_gd_error("Error from compressing\n");
+                               } else {
+                                       chunkIdx[chunkNum].offset = gdTell(out);
+                                       chunkIdx[chunkNum++].size = compLen;
+                                       GD2_DBG(php_gd_error("Chunk %d size %d offset %d\n", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset));
+
+                                       if (gdPutBuf (compData, compLen, out) <= 0) {
+                                               /* Any alternate suggestions for handling this? */
+                                               php_gd_error_ex(E_WARNING, "Error %d on write\n", errno);
+                                       }
+                               }
                        }
-                   };
-               };
-             GD2_DBG(php_gd_error("y=%d done.\n",y)); 
-           };
-         if (fmt == GD2_FMT_COMPRESSED)
-           {
-             compLen = compMax;
-             if (compress ((unsigned char *)
-                           &compData[0], &compLen,
-                           (unsigned char *) &chunkData[0],
-                           chunkLen) != Z_OK)
-               {
-                 php_gd_error ("Error from compressing\n");
                }
-             else
-               {
-                 chunkIdx[chunkNum].offset = gdTell (out);
-                 chunkIdx[chunkNum++].size = compLen;
-                 GD2_DBG(php_gd_error("Chunk %d size %d offset %d\n", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset));
-
-                 if (gdPutBuf (compData, compLen, out) <= 0)
-                   {
-                     /* Any alternate suggestions for handling this? */
-                     php_gd_error_ex (E_WARNING, "Error %d on write\n", errno);
-                   };
-               };
-           };
-       };
-    };
-  if (fmt == GD2_FMT_COMPRESSED)
-    {
-      /* Save the position, write the index, restore position (paranoia). */
-      GD2_DBG(php_gd_error("Seeking %d to write index\n", idxPos));
-      posSave = gdTell (out);
-      gdSeek (out, idxPos);
-      GD2_DBG(php_gd_error("Writing index\n"));
-      for (x = 0; x < chunkNum; x++)
-       {
-         GD2_DBG(php_gd_error("Chunk %d size %d offset %d\n", x, chunkIdx[x].size, chunkIdx[x].offset));
-         gdPutInt (chunkIdx[x].offset, out);
-         gdPutInt (chunkIdx[x].size, out);
-       };
-      /* We don't use fwrite for *endian reasons. */
-      /*fwrite(chunkIdx, sizeof(int)*2, chunkNum, out); */
-      gdSeek (out, posSave);
-    };
-
-  GD2_DBG(php_gd_error("Freeing memory\n"));
-  gdFree (chunkData);
-  gdFree (compData);
-  gdFree (chunkIdx);
-  GD2_DBG(php_gd_error("Done\n"));
-
-  /*php_gd_error("Memory block size is %d\n",gdTell(out)); */
+       }
+
+       if (gd2_compressed(fmt)) {
+               /* Save the position, write the index, restore position (paranoia). */
+               GD2_DBG(php_gd_error("Seeking %d to write index\n", idxPos));
+               posSave = gdTell(out);
+               gdSeek(out, idxPos);
+               GD2_DBG(php_gd_error("Writing index\n"));
+               for (x = 0; x < chunkNum; x++) {
+                       GD2_DBG(php_gd_error("Chunk %d size %d offset %d\n", x, chunkIdx[x].size, chunkIdx[x].offset));
+                       gdPutInt(chunkIdx[x].offset, out);
+                       gdPutInt(chunkIdx[x].size, out);
+               }
+               gdSeek(out, posSave);
+       }
 
+       GD2_DBG(php_gd_error("Freeing memory\n"));
+       if (chunkData) {
+               gdFree(chunkData);
+       }
+       if (compData) { 
+               gdFree(compData);
+       }
+       if (chunkIdx) {
+               gdFree(chunkIdx);
+       }
+       GD2_DBG(php_gd_error("Done\n"));
 }
 
-void
-gdImageGd2 (gdImagePtr im, FILE * outFile, int cs, int fmt)
+void gdImageGd2 (gdImagePtr im, FILE * outFile, int cs, int fmt)
 {
-  gdIOCtx *out = gdNewFileCtx (outFile);
-  _gdImageGd2 (im, out, cs, fmt);
-  out->gd_free (out);
+       gdIOCtx *out = gdNewFileCtx(outFile);
+
+       _gdImageGd2(im, out, cs, fmt);
+       
+       out->gd_free(out);
 }
 
-void *
-gdImageGd2Ptr (gdImagePtr im, int cs, int fmt, int *size)
+void *gdImageGd2Ptr (gdImagePtr im, int cs, int fmt, int *size)
 {
-  void *rv;
-  gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
-  _gdImageGd2 (im, out, cs, fmt);
-  rv = gdDPExtractData (out, size);
-  out->gd_free (out);
-  return rv;
+       void *rv;
+       gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
+
+       _gdImageGd2(im, out, cs, fmt);
+       rv = gdDPExtractData(out, size);
+       out->gd_free(out);
+       
+       return rv;
 }
index 4c41124f617c101dde961c740e36528edf516be6..7794dc890bc9ba9fec47311a3b8e9bdef72af5af 100644 (file)
@@ -16,6 +16,9 @@
  * Modification 4/18/00 TBB: JPEG_DEBUG rather than just DEBUG,
  * so VC++ builds don't spew to standard output, causing
  * major CGI brain damage
+ *
+ * 2.0.10: more efficient gdImageCreateFromJpegCtx, thanks to
+ * Christian Aberger 
  */
 
 #include <stdio.h>
 static const char *const GD_JPEG_VERSION = "1.0";
 
 typedef struct _jmpbuf_wrapper
-  {
-    jmp_buf jmpbuf;
-  }
-jmpbuf_wrapper;
+{
+       jmp_buf jmpbuf;
+} jmpbuf_wrapper;
 
 /* Called by the IJG JPEG library upon encountering a fatal error */
 static void
 fatal_jpeg_error (j_common_ptr cinfo)
 {
-  jmpbuf_wrapper *jmpbufw;
-
-  php_gd_error("gd-jpeg: JPEG library reports unrecoverable error: ");
-  (*cinfo->err->output_message) (cinfo);
-
-  jmpbufw = (jmpbuf_wrapper *) cinfo->client_data;
-  jpeg_destroy (cinfo);
-
-  if (jmpbufw != 0)
-    {
-      longjmp (jmpbufw->jmpbuf, 1);
-      php_gd_error_ex(E_ERROR, "gd-jpeg: EXTREMELY fatal error: longjmp"
-              " returned control; terminating\n");
-    }
-  else
-    {
-      php_gd_error_ex(E_ERROR, "gd-jpeg: EXTREMELY fatal error: jmpbuf"
-              " unrecoverable; terminating\n");
-    }
-
-  exit (99);
+       jmpbuf_wrapper *jmpbufw;
+
+       php_gd_error("gd-jpeg: JPEG library reports unrecoverable error: ");
+       (*cinfo->err->output_message) (cinfo);
+
+       jmpbufw = (jmpbuf_wrapper *) cinfo->client_data;
+       jpeg_destroy (cinfo);
+
+       if (jmpbufw != 0) {
+               longjmp (jmpbufw->jmpbuf, 1);
+               php_gd_error_ex(E_ERROR, "gd-jpeg: EXTREMELY fatal error: longjmp returned control; terminating");
+       } else {
+               php_gd_error_ex(E_ERROR, "gd-jpeg: EXTREMELY fatal error: jmpbuf unrecoverable; terminating");
+       }
+
+       exit (99);
 }
 
 /*
@@ -76,25 +73,27 @@ fatal_jpeg_error (j_common_ptr cinfo)
  * represent higher quality but also larger image size.  If QUALITY is
  * negative, the IJG JPEG library's default quality is used (which
  * should be near optimal for many applications).  See the IJG JPEG
- * library documentation for more details.  */
+ * library documentation for more details.
+ */
 
 void
 gdImageJpeg (gdImagePtr im, FILE * outFile, int quality)
 {
-  gdIOCtx *out = gdNewFileCtx (outFile);
-  gdImageJpegCtx (im, out, quality);
-  out->gd_free (out);
+       gdIOCtx *out = gdNewFileCtx (outFile);
+       gdImageJpegCtx (im, out, quality);
+       out->gd_free (out);
 }
 
 void *
 gdImageJpegPtr (gdImagePtr im, int *size, int quality)
 {
-  void *rv;
-  gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
-  gdImageJpegCtx (im, out, quality);
-  rv = gdDPExtractData (out, size);
-  out->gd_free (out);
-  return rv;
+       void *rv;
+       gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
+       gdImageJpegCtx (im, out, quality);
+       rv = gdDPExtractData (out, size);
+       out->gd_free (out);
+
+       return rv;
 }
 
 void jpeg_gdIOCtx_dest (j_compress_ptr cinfo, gdIOCtx * outfile);
@@ -102,168 +101,127 @@ void jpeg_gdIOCtx_dest (j_compress_ptr cinfo, gdIOCtx * outfile);
 void
 gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality)
 {
-  struct jpeg_compress_struct cinfo;
-  struct jpeg_error_mgr jerr;
-  int i, j, jidx;
-  /* volatile so we can gdFree it on return from longjmp */
-  volatile JSAMPROW row = 0;
-  JSAMPROW rowptr[1];
-  jmpbuf_wrapper jmpbufw;
-  JDIMENSION nlines;
-  char comment[255];
-
-#ifdef JPEG_DEBUG
-  printf ("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
-  printf ("gd-jpeg: JPEG library version %d, %d-bit sample values\n",
-         JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
-  if (!im->trueColor)
-    {
-      for (i = 0; i < im->colorsTotal; i++)
-       {
-         if (!im->open[i])
-           printf ("gd-jpeg: gd colormap index %d: (%d, %d, %d)\n", i,
-                   im->red[i], im->green[i], im->blue[i]);
+       struct jpeg_compress_struct cinfo;
+       struct jpeg_error_mgr jerr;
+       int i, j, jidx;
+       /* volatile so we can gdFree it on return from longjmp */
+       volatile JSAMPROW row = 0;
+       JSAMPROW rowptr[1];
+       jmpbuf_wrapper jmpbufw;
+       JDIMENSION nlines;
+       char comment[255];
+
+       memset (&cinfo, 0, sizeof (cinfo));
+       memset (&jerr, 0, sizeof (jerr));
+
+       cinfo.err = jpeg_std_error (&jerr);
+       cinfo.client_data = &jmpbufw;
+       if (setjmp (jmpbufw.jmpbuf) != 0) {
+               /* we're here courtesy of longjmp */
+               if (row) {
+                       gdFree (row);
+               }
+               return;
        }
-    }
-#endif /* JPEG_DEBUG */
-
-  memset (&cinfo, 0, sizeof (cinfo));
-  memset (&jerr, 0, sizeof (jerr));
-
-  cinfo.err = jpeg_std_error (&jerr);
-  cinfo.client_data = &jmpbufw;
-  if (setjmp (jmpbufw.jmpbuf) != 0)
-    {
-      /* we're here courtesy of longjmp */
-      if (row)
-       gdFree (row);
-      return;
-    }
-
-  cinfo.err->error_exit = fatal_jpeg_error;
-
-  jpeg_create_compress (&cinfo);
-
-  cinfo.image_width = im->sx;
-  cinfo.image_height = im->sy;
-  cinfo.input_components = 3;  /* # of color components per pixel */
-  cinfo.in_color_space = JCS_RGB;      /* colorspace of input image */
-  jpeg_set_defaults (&cinfo);
-  if (quality >= 0)
-    jpeg_set_quality (&cinfo, quality, TRUE);
-
-  /* If user requests interlace, translate that to progressive JPEG */
-  if (gdImageGetInterlaced (im))
-    {
-#ifdef JPEG_DEBUG
-      printf ("gd-jpeg: interlace set, outputting progressive"
-             " JPEG image\n");
-#endif
-      jpeg_simple_progression (&cinfo);
-    }
-
-  jpeg_gdIOCtx_dest (&cinfo, outfile);
-
-  row = (JSAMPROW) gdCalloc (1, cinfo.image_width * cinfo.input_components
-                            * sizeof (JSAMPLE));
-  if (row == 0)
-    {
-      php_gd_error("gd-jpeg: error: unable to allocate JPEG row "
-              "structure: gdCalloc returns NULL\n");
-      jpeg_destroy_compress (&cinfo);
-      return;
-    }
-
-  rowptr[0] = row;
-
-  jpeg_start_compress (&cinfo, TRUE);
-
-  sprintf (comment, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d),",
-          GD_JPEG_VERSION, JPEG_LIB_VERSION);
-  if (quality >= 0)
-    sprintf (comment + strlen (comment), " quality = %d\n",
-            quality);
-  else
-    strcat (comment + strlen (comment), " default quality\n");
-  jpeg_write_marker (&cinfo, JPEG_COM, (unsigned char *) comment,
-                    (unsigned int) strlen (comment));
-  if (im->trueColor)
-    {
+
+       cinfo.err->error_exit = fatal_jpeg_error;
+
+       jpeg_create_compress (&cinfo);
+
+       cinfo.image_width = im->sx;
+       cinfo.image_height = im->sy;
+       cinfo.input_components = 3;     /* # of color components per pixel */
+       cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
+       jpeg_set_defaults (&cinfo);
+       if (quality >= 0) {
+               jpeg_set_quality (&cinfo, quality, TRUE);
+       }
+
+       /* If user requests interlace, translate that to progressive JPEG */
+       if (gdImageGetInterlaced (im)) {
+               jpeg_simple_progression (&cinfo);
+       }
+
+       jpeg_gdIOCtx_dest (&cinfo, outfile);
+
+       row = (JSAMPROW) gdCalloc (1, cinfo.image_width * cinfo.input_components * sizeof (JSAMPLE));
+       rowptr[0] = row;
+
+       jpeg_start_compress (&cinfo, TRUE);
+
+       if (quality >= 0) {
+               snprintf(comment, sizeof(comment)-1, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d), quality = %d\n", GD_JPEG_VERSION, JPEG_LIB_VERSION, quality);
+       } else {
+               snprintf(comment, sizeof(comment)-1, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d), default quality\n", GD_JPEG_VERSION, JPEG_LIB_VERSION);
+       }
+       jpeg_write_marker (&cinfo, JPEG_COM, (unsigned char *) comment, (unsigned int) strlen (comment));
+       if (im->trueColor) {
+
 #if BITS_IN_JSAMPLE == 12
-      php_gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit\n"
-        "precision. This is mostly useless, because JPEGs on the web are\n"
-        "8-bit and such versions of the jpeg library won't read or write\n"
-              "them. GD doesn't support these unusual images. Edit your\n"
-        "jmorecfg.h file to specify the correct precision and completely\n"
-              "'make clean' and 'make install' libjpeg again. Sorry.\n");
-      goto error;
+               php_gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry");
+               goto error;
 #endif /* BITS_IN_JSAMPLE == 12 */
-      for (i = 0; i < im->sy; i++)
-       {
-         for (jidx = 0, j = 0; j < im->sx; j++)
-           {
-             int val = im->tpixels[i][j];
-             row[jidx++] = gdTrueColorGetRed (val);
-             row[jidx++] = gdTrueColorGetGreen (val);
-             row[jidx++] = gdTrueColorGetBlue (val);
-           }
-
-         nlines = jpeg_write_scanlines (&cinfo, rowptr, 1);
-         if (nlines != 1)
-           php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines"
-                    " returns %u -- expected 1\n", nlines);
-       }
-    }
-  else
-    {
-      for (i = 0; i < im->sy; i++)
-       {
-         for (jidx = 0, j = 0; j < im->sx; j++)
-           {
-             int idx = im->pixels[i][j];
-
-             /*
-              * NB: Although gd RGB values are ints, their max value is
-              * 255 (see the documentation for gdImageColorAllocate())
-              * -- perfect for 8-bit JPEG encoding (which is the norm)
-              */
+
+               for (i = 0; i < im->sy; i++) {
+                       for (jidx = 0, j = 0; j < im->sx; j++) {
+                               int val = im->tpixels[i][j];
+
+                               row[jidx++] = gdTrueColorGetRed (val);
+                               row[jidx++] = gdTrueColorGetGreen (val);
+                               row[jidx++] = gdTrueColorGetBlue (val);
+                       }
+
+                       nlines = jpeg_write_scanlines (&cinfo, rowptr, 1);
+                       if (nlines != 1) {
+                               php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1\n", nlines);
+                       }
+               }
+       } else {
+               for (i = 0; i < im->sy; i++) {
+                       for (jidx = 0, j = 0; j < im->sx; j++) {
+                               int idx = im->pixels[i][j];
+
+                               /* NB: Although gd RGB values are ints, their max value is
+                                * 255 (see the documentation for gdImageColorAllocate())
+                                * -- perfect for 8-bit JPEG encoding (which is the norm)
+                                */
 #if BITS_IN_JSAMPLE == 8
-             row[jidx++] = im->red[idx];
-             row[jidx++] = im->green[idx];
-             row[jidx++] = im->blue[idx];
+                               row[jidx++] = im->red[idx];
+                               row[jidx++] = im->green[idx];
+                               row[jidx++] = im->blue[idx];
 #elif BITS_IN_JSAMPLE == 12
-             row[jidx++] = im->red[idx] << 4;
-             row[jidx++] = im->green[idx] << 4;
-             row[jidx++] = im->blue[idx] << 4;
+                               row[jidx++] = im->red[idx] << 4;
+                               row[jidx++] = im->green[idx] << 4;
+                               row[jidx++] = im->blue[idx] << 4;
 #else
 #error IJG JPEG library BITS_IN_JSAMPLE value must be 8 or 12
 #endif
-           }
+                       }
 
-         nlines = jpeg_write_scanlines (&cinfo, rowptr, 1);
-         if (nlines != 1)
-           php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines"
-                    " returns %u -- expected 1\n", nlines);
+                       nlines = jpeg_write_scanlines (&cinfo, rowptr, 1);
+                       if (nlines != 1) {
+                               php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1\n", nlines);
+                       }
+               }
        }
-    }
-  jpeg_finish_compress (&cinfo);
-  jpeg_destroy_compress (&cinfo);
-  gdFree (row);
+
+       jpeg_finish_compress (&cinfo);
+       jpeg_destroy_compress (&cinfo);
+       gdFree (row);
 }
 
 gdImagePtr
 gdImageCreateFromJpeg (FILE * inFile)
 {
-  gdImagePtr im;
-  gdIOCtx *in = gdNewFileCtx (inFile);
-  im = gdImageCreateFromJpegCtx (in);
-  in->gd_free (in);
-  return im;
+       gdImagePtr im;
+       gdIOCtx *in = gdNewFileCtx (inFile);
+       im = gdImageCreateFromJpegCtx (in);
+       in->gd_free (in);
+
+       return im;
 }
 
-void
-  jpeg_gdIOCtx_src (j_decompress_ptr cinfo,
-                   gdIOCtx * infile);
+void jpeg_gdIOCtx_src (j_decompress_ptr cinfo, gdIOCtx * infile);
 
 /* 
  * Create a gd-format image from the JPEG-format INFILE.  Returns the
@@ -272,197 +230,122 @@ void
 gdImagePtr
 gdImageCreateFromJpegCtx (gdIOCtx * infile)
 {
-  struct jpeg_decompress_struct cinfo;
-  struct jpeg_error_mgr jerr;
-  jmpbuf_wrapper jmpbufw;
-  /* volatile so we can gdFree them after longjmp */
-  volatile JSAMPROW row = 0;
-  volatile gdImagePtr im = 0;
-  JSAMPROW rowptr[1];
-  unsigned int i, j;
-  int retval;
-  JDIMENSION nrows;
-
-#ifdef JPEG_DEBUG
-  printf ("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
-  printf ("gd-jpeg: JPEG library version %d, %d-bit sample values\n",
-         JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
-#endif
+       struct jpeg_decompress_struct cinfo;
+       struct jpeg_error_mgr jerr;
+       jmpbuf_wrapper jmpbufw;
+       /* volatile so we can gdFree them after longjmp */
+       volatile JSAMPROW row = 0;
+       volatile gdImagePtr im = 0;
+       JSAMPROW rowptr[1];
+       unsigned int i, j;
+       int retval;
+       JDIMENSION nrows;
+
+       memset (&cinfo, 0, sizeof (cinfo));
+       memset (&jerr, 0, sizeof (jerr));
+
+       cinfo.err = jpeg_std_error (&jerr);
+       cinfo.client_data = &jmpbufw;
+       if (setjmp (jmpbufw.jmpbuf) != 0) {
+               /* we're here courtesy of longjmp */
+               if (row) {
+                       gdFree (row);
+               }
+               if (im) {
+                       gdImageDestroy (im);
+               }
+               return 0;
+       }
 
-  memset (&cinfo, 0, sizeof (cinfo));
-  memset (&jerr, 0, sizeof (jerr));
+       cinfo.err->error_exit = fatal_jpeg_error;
 
-  cinfo.err = jpeg_std_error (&jerr);
-  cinfo.client_data = &jmpbufw;
-  if (setjmp (jmpbufw.jmpbuf) != 0)
-    {
-      /* we're here courtesy of longjmp */
-      if (row)
-       gdFree (row);
-      if (im)
-       gdImageDestroy (im);
-      return 0;
-    }
-
-  cinfo.err->error_exit = fatal_jpeg_error;
-
-  jpeg_create_decompress (&cinfo);
-
-  jpeg_gdIOCtx_src (&cinfo, infile);
-
-  retval = jpeg_read_header (&cinfo, TRUE);
-  if (retval != JPEG_HEADER_OK)
-    php_gd_error_ex(E_WARNING, "gd-jpeg: warning: jpeg_read_header returns"
-            " %d, expected %d\n", retval, JPEG_HEADER_OK);
-
-  if (cinfo.image_height > INT_MAX)
-    php_gd_error_ex(E_WARNING, "gd-jpeg: warning: JPEG image height (%u) is"
-            " greater than INT_MAX (%d) (and thus greater than"
-            " gd can handle)", cinfo.image_height,
-            INT_MAX);
-
-  if (cinfo.image_width > INT_MAX)
-    php_gd_error_ex(E_WARNING, "gd-jpeg: warning: JPEG image width (%u) is"
-            " greater than INT_MAX (%d) (and thus greater than"
-            " gd can handle)\n", cinfo.image_width, INT_MAX);
-
-  im = gdImageCreateTrueColor ((int) cinfo.image_width,
-                              (int) cinfo.image_height);
-  if (im == 0)
-    {
-      php_gd_error("gd-jpeg error: cannot allocate gdImage"
-              " struct\n");
-      goto error;
-    }
-
-  /*
-   * Force the image into RGB colorspace, but don't 
-   * reduce the number of colors anymore (GD 2.0) 
-   */
-  cinfo.out_color_space = JCS_RGB;
-
-  if (jpeg_start_decompress (&cinfo) != TRUE)
-    php_gd_error("gd-jpeg: warning: jpeg_start_decompress"
-            " reports suspended data source\n");
-
-#ifdef JPEG_DEBUG
-  printf ("gd-jpeg: JPEG image information:");
-  if (cinfo.saw_JFIF_marker)
-    printf (" JFIF version %d.%.2d",
-           (int) cinfo.JFIF_major_version,
-           (int) cinfo.JFIF_minor_version);
-  else if (cinfo.saw_Adobe_marker)
-    printf (" Adobe format");
-  else
-    printf (" UNKNOWN format");
-
-  printf (" %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width,
-         cinfo.image_height, cinfo.output_width,
-         cinfo.output_height, cinfo.data_precision);
-  printf (" %s", (cinfo.progressive_mode ? "progressive" :
-                 "baseline"));
-  printf (" image, %d quantized colors, ",
-         cinfo.actual_number_of_colors);
-
-  switch (cinfo.jpeg_color_space)
-    {
-    case JCS_GRAYSCALE:
-      printf ("grayscale");
-      break;
-
-    case JCS_RGB:
-      printf ("RGB");
-      break;
-
-    case JCS_YCbCr:
-      printf ("YCbCr (a.k.a. YUV)");
-      break;
-
-    case JCS_CMYK:
-      printf ("CMYK");
-      break;
-
-    case JCS_YCCK:
-      printf ("YCbCrK");
-      break;
-
-    default:
-      printf ("UNKNOWN (value: %d)", (int) cinfo.jpeg_color_space);
-      break;
-    }
-  printf (" colorspace\n");
-  fflush (stdout);
-#endif /* JPEG_DEBUG */
-
-  /* REMOVED by TBB 2/12/01. This field of the structure is
-     documented as private, and sure enough it's gone in the
-     latest libjpeg, replaced by something else. Unfortunately
-     there is still no right way to find out if the file was
-     progressive or not; just declare your intent before you
-     write one by calling gdImageInterlace(im, 1) yourself. 
-     After all, we're not really supposed to rework JPEGs and
-     write them out again anyway. Lossy compression, remember? */
+       jpeg_create_decompress (&cinfo);
+
+       jpeg_gdIOCtx_src (&cinfo, infile);
+
+       retval = jpeg_read_header (&cinfo, TRUE);
+       if (retval != JPEG_HEADER_OK) { 
+               php_gd_error_ex(E_WARNING, "gd-jpeg: warning: jpeg_read_header returned %d, expected %d", retval, JPEG_HEADER_OK);
+       }
+
+       if (cinfo.image_height > INT_MAX) {
+               php_gd_error_ex(E_WARNING, "gd-jpeg: warning: JPEG image height (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_height, INT_MAX);
+       }
+
+       if (cinfo.image_width > INT_MAX) {
+               php_gd_error_ex(E_WARNING, "gd-jpeg: warning: JPEG image width (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_width, INT_MAX);
+       }
+
+       im = gdImageCreateTrueColor ((int) cinfo.image_width, (int) cinfo.image_height);
+       if (im == 0) {
+               php_gd_error("gd-jpeg error: cannot allocate gdImage struct");
+               goto error;
+       }
+
+       /* Force the image into RGB colorspace, but don't reduce the number of colors anymore (GD 2.0) */
+       cinfo.out_color_space = JCS_RGB;
+
+       if (jpeg_start_decompress (&cinfo) != TRUE) {
+               php_gd_error("gd-jpeg: warning: jpeg_start_decompress reports suspended data source");
+       }
+
+       /* REMOVED by TBB 2/12/01. This field of the structure is
+        * documented as private, and sure enough it's gone in the
+        * latest libjpeg, replaced by something else. Unfortunately
+        * there is still no right way to find out if the file was
+        * progressive or not; just declare your intent before you
+        * write one by calling gdImageInterlace(im, 1) yourself. 
+        * After all, we're not really supposed to rework JPEGs and
+        * write them out again anyway. Lossy compression, remember? 
+        */
 #if 0
   gdImageInterlace (im, cinfo.progressive_mode != 0);
 #endif
-  if (cinfo.output_components != 3)
-    {
-      php_gd_error_ex(E_WARNING, "gd-jpeg: error: JPEG color quantization"
-              " request resulted in output_components == %d"
-              " (expected 3)\n", cinfo.output_components);
-      goto error;
-    }
+
+       if (cinfo.output_components != 3) {
+               php_gd_error_ex(E_WARNING, "gd-jpeg: error: JPEG color quantization request resulted in output_components == %d (expected 3)", cinfo.output_components);
+               goto error;
+       }
 
 #if BITS_IN_JSAMPLE == 12
-  php_gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit\n"
-        "precision. This is mostly useless, because JPEGs on the web are\n"
-        "8-bit and such versions of the jpeg library won't read or write\n"
-          "them. GD doesn't support these unusual images. Edit your\n"
-        "jmorecfg.h file to specify the correct precision and completely\n"
-          "'make clean' and 'make install' libjpeg again. Sorry.\n");
-  goto error;
+       php_gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry.");
+       goto error;
 #endif /* BITS_IN_JSAMPLE == 12 */
 
-  row = gdCalloc (cinfo.output_width * 3, sizeof (JSAMPLE));
-  if (row == 0)
-    {
-      php_gd_error("gd-jpeg: error: unable to allocate row for"
-              " JPEG scanline: gdCalloc returns NULL\n");
-      goto error;
-    }
-  rowptr[0] = row;
-
-  for (i = 0; i < cinfo.output_height; i++)
-    {
-      nrows = jpeg_read_scanlines (&cinfo, rowptr, 1);
-      if (nrows != 1)
-       {
-         php_gd_error_ex(E_WARNING, "gd-jpeg: error: jpeg_read_scanlines"
-                  " returns %u, expected 1\n", nrows);
-         goto error;
+       row = gdCalloc (cinfo.output_width * 3, sizeof (JSAMPLE));
+       rowptr[0] = row;
+
+       for (i = 0; i < cinfo.output_height; i++) {
+               register JSAMPROW currow = row;
+               register int *tpix = im->tpixels[i];
+               nrows = jpeg_read_scanlines (&cinfo, rowptr, 1);
+               if (nrows != 1) {
+                       php_gd_error_ex(E_WARNING, "gd-jpeg: error: jpeg_read_scanlines returns %u, expected 1", nrows);
+                       goto error;
+               }
+               for (j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) {
+                       *tpix = gdTrueColor (currow[0], currow[1], currow[2]);
+               }
        }
 
-      for (j = 0; j < cinfo.output_width; j++)
-       im->tpixels[i][j] = gdTrueColor (row[j * 3], row[j * 3 + 1],
-                                        row[j * 3 + 2]);
-    }
-
-  if (jpeg_finish_decompress (&cinfo) != TRUE)
-    php_gd_error("gd-jpeg: warning: jpeg_finish_decompress"
-            " reports suspended data source\n");
+       if (jpeg_finish_decompress (&cinfo) != TRUE) {
+               php_gd_error("gd-jpeg: warning: jpeg_finish_decompress reports suspended data source");
+       }
 
+       jpeg_destroy_decompress (&cinfo);
+       gdFree (row);
 
-  jpeg_destroy_decompress (&cinfo);
-  gdFree (row);
-  return im;
+       return im;
 
 error:
-  jpeg_destroy_decompress (&cinfo);
-  if (row)
-    gdFree (row);
-  if (im)
-    gdImageDestroy (im);
-  return 0;
+       jpeg_destroy_decompress (&cinfo);
+       if (row) {
+               gdFree (row);
+       }
+       if (im) {
+               gdImageDestroy (im);
+       }
+       return 0;
 }
 
 /*
@@ -488,15 +371,13 @@ typedef int safeboolean;
 /* Expanded data source object for gdIOCtx input */
 
 typedef struct
-  {
-    struct jpeg_source_mgr pub;        /* public fields */
+{
+       struct jpeg_source_mgr pub;     /* public fields */
 
-    gdIOCtx *infile;           /* source stream */
-    unsigned char *buffer;     /* start of buffer */
-    safeboolean start_of_file; /* have we gotten any data yet? */
-     
-  }
-my_source_mgr;
+       gdIOCtx *infile;                /* source stream */
+       unsigned char *buffer;  /* start of buffer */
+       safeboolean start_of_file;      /* have we gotten any data yet? */
+} my_source_mgr;
 
 typedef my_source_mgr *my_src_ptr;
 
@@ -510,13 +391,13 @@ typedef my_source_mgr *my_src_ptr;
 void
 init_source (j_decompress_ptr cinfo)
 {
-  my_src_ptr src = (my_src_ptr) cinfo->src;
+       my_src_ptr src = (my_src_ptr) cinfo->src;
 
-  /* We reset the empty-input-file flag for each image,
-   * but we don't clear the input buffer.
-   * This is correct behavior for reading a series of images from one source.
-   */
-  src->start_of_file = TRUE;
+       /* We reset the empty-input-file flag for each image,
+        * but we don't clear the input buffer.
+        * This is correct behavior for reading a series of images from one source.
+        */
+       src->start_of_file = TRUE;
 }
 
 
@@ -558,56 +439,42 @@ init_source (j_decompress_ptr cinfo)
 safeboolean
 fill_input_buffer (j_decompress_ptr cinfo)
 {
-  my_src_ptr src = (my_src_ptr) cinfo->src;
-  size_t nbytes = 0;
+       my_src_ptr src = (my_src_ptr) cinfo->src;
+       size_t nbytes = 0;
   
-  /* size_t got; */
-  /* char *s; */
-    memset (src->buffer, 0, INPUT_BUF_SIZE);
+       /* size_t got; */
+       /* char *s; */
+       memset (src->buffer, 0, INPUT_BUF_SIZE);
   
-    while (nbytes < INPUT_BUF_SIZE)
-    {
-      
-       int got = gdGetBuf (src->buffer + nbytes, 
-                           INPUT_BUF_SIZE - nbytes,
-                           src->infile);
+       while (nbytes < INPUT_BUF_SIZE) {
+               int got = gdGetBuf (src->buffer + nbytes,  INPUT_BUF_SIZE - nbytes, src->infile);
       
-       if ((got == EOF) || (got == 0))
-       {
-         
-         /* EOF or error. If we got any data, don't worry about it.
-            If we didn't, then this is unexpected. */ 
-           if (!nbytes)
-           {
-             
-               nbytes = -1;
-             
-           }
-         
-           break;
-         
+               if ((got == EOF) || (got == 0)) {
+                 /* EOF or error. If we got any data, don't worry about it. If we didn't, then this is unexpected. */ 
+                       if (!nbytes) {
+                               nbytes = -1;
+                       }
+                       break;
+               }
+               nbytes += got;
        }
-      
-       nbytes += got;
-      
-    }
   
-    if (nbytes <= 0)
-    {
-      if (src->start_of_file)  /* Treat empty input file as fatal error */
-       ERREXIT (cinfo, JERR_INPUT_EMPTY);
-      WARNMS (cinfo, JWRN_JPEG_EOF);
-      /* Insert a fake EOI marker */
-      src->buffer[0] = (unsigned char) 0xFF;
-      src->buffer[1] = (unsigned char) JPEG_EOI;
-      nbytes = 2;
-    }
-
-  src->pub.next_input_byte = src->buffer;
-  src->pub.bytes_in_buffer = nbytes;
-  src->start_of_file = FALSE;
-
-  return TRUE;
+       if (nbytes <= 0) {
+               if (src->start_of_file) { /* Treat empty input file as fatal error */
+                       ERREXIT (cinfo, JERR_INPUT_EMPTY);
+               }
+               WARNMS (cinfo, JWRN_JPEG_EOF);
+               /* Insert a fake EOI marker */
+               src->buffer[0] = (unsigned char) 0xFF;
+               src->buffer[1] = (unsigned char) JPEG_EOI;
+               nbytes = 2;
+       }
+
+       src->pub.next_input_byte = src->buffer;
+       src->pub.bytes_in_buffer = nbytes;
+       src->start_of_file = FALSE;
+
+       return TRUE;
 }
 
 
@@ -626,24 +493,22 @@ fill_input_buffer (j_decompress_ptr cinfo)
 void
 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
 {
-  my_src_ptr src = (my_src_ptr) cinfo->src;
-
-  /* Just a dumb implementation for now. Not clear that being smart is worth
-   * any trouble anyway --- large skips are infrequent.
-   */
-  if (num_bytes > 0)
-    {
-      while (num_bytes > (long) src->pub.bytes_in_buffer)
-       {
-         num_bytes -= (long) src->pub.bytes_in_buffer;
-         (void) fill_input_buffer (cinfo);
-         /* note we assume that fill_input_buffer will never return FALSE,
-          * so suspension need not be handled.
-          */
+       my_src_ptr src = (my_src_ptr) cinfo->src;
+
+       /* Just a dumb implementation for now. Not clear that being smart is worth
+        * any trouble anyway --- large skips are infrequent.
+        */
+       if (num_bytes > 0) {
+               while (num_bytes > (long) src->pub.bytes_in_buffer) {
+                       num_bytes -= (long) src->pub.bytes_in_buffer;
+                       (void) fill_input_buffer (cinfo);
+                       /* note we assume that fill_input_buffer will never return FALSE,
+                        * so suspension need not be handled.
+                        */
+               }
+               src->pub.next_input_byte += (size_t) num_bytes;
+               src->pub.bytes_in_buffer -= (size_t) num_bytes;
        }
-      src->pub.next_input_byte += (size_t) num_bytes;
-      src->pub.bytes_in_buffer -= (size_t) num_bytes;
-    }
 }
 
 
@@ -668,11 +533,9 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes)
 void
 term_source (j_decompress_ptr cinfo)
 {
-  
 #if 0
-/* never used */
-    my_src_ptr src = (my_src_ptr) cinfo->src;
-  
+       * never used */
+       my_src_ptr src = (my_src_ptr) cinfo->src;
 #endif
 }
 
@@ -684,50 +547,44 @@ term_source (j_decompress_ptr cinfo)
  */
 
 void
-jpeg_gdIOCtx_src (j_decompress_ptr cinfo,
-                 gdIOCtx * infile)
+jpeg_gdIOCtx_src (j_decompress_ptr cinfo, gdIOCtx * infile)
 {
-  my_src_ptr src;
-
-  /* The source object and input buffer are made permanent so that a series
-   * of JPEG images can be read from the same file by calling jpeg_gdIOCtx_src
-   * only before the first one.  (If we discarded the buffer at the end of
-   * one image, we'd likely lose the start of the next one.)
-   * This makes it unsafe to use this manager and a different source
-   * manager serially with the same JPEG object.  Caveat programmer.
-   */
-  if (cinfo->src == NULL)
-    {                          /* first time for this JPEG object? */
-      cinfo->src = (struct jpeg_source_mgr *)
-       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
-                                   sizeof (my_source_mgr));
-      src = (my_src_ptr) cinfo->src;
-      src->buffer = (unsigned char *)
-       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
-                                   INPUT_BUF_SIZE * sizeof (unsigned char));
+       my_src_ptr src;
+
+       /* The source object and input buffer are made permanent so that a series
+        * of JPEG images can be read from the same file by calling jpeg_gdIOCtx_src
+        * only before the first one.  (If we discarded the buffer at the end of
+        * one image, we'd likely lose the start of the next one.)
+        * This makes it unsafe to use this manager and a different source
+        * manager serially with the same JPEG object.  Caveat programmer.
+        */
+       if (cinfo->src == NULL) { /* first time for this JPEG object? */
+               cinfo->src = (struct jpeg_source_mgr *)
+               (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof (my_source_mgr));
+               src = (my_src_ptr) cinfo->src;
+               src->buffer = (unsigned char *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * sizeof (unsigned char));
       
-    }
-
-  src = (my_src_ptr) cinfo->src;
-  src->pub.init_source = init_source;
-  src->pub.fill_input_buffer = fill_input_buffer;
-  src->pub.skip_input_data = skip_input_data;
-  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
-  src->pub.term_source = term_source;
-  src->infile = infile;
-  src->pub.bytes_in_buffer = 0;        /* forces fill_input_buffer on first read */
-  src->pub.next_input_byte = NULL;     /* until buffer loaded */
+       }
+
+       src = (my_src_ptr) cinfo->src;
+       src->pub.init_source = init_source;
+       src->pub.fill_input_buffer = fill_input_buffer;
+       src->pub.skip_input_data = skip_input_data;
+       src->pub.resync_to_restart = jpeg_resync_to_restart;    /* use default method */
+       src->pub.term_source = term_source;
+       src->infile = infile;
+       src->pub.bytes_in_buffer = 0;   /* forces fill_input_buffer on first read */
+       src->pub.next_input_byte = NULL;        /* until buffer loaded */
 }
 
 /* Expanded data destination object for stdio output */
 
 typedef struct
 {
-  struct jpeg_destination_mgr pub;     /* public fields */
-  gdIOCtx *outfile;            /* target stream */
-  unsigned char *buffer;       /* start of buffer */
-}
-my_destination_mgr;
+       struct jpeg_destination_mgr pub; /* public fields */
+       gdIOCtx *outfile;                /* target stream */
+       unsigned char *buffer;           /* start of buffer */
+} my_destination_mgr;
 
 typedef my_destination_mgr *my_dest_ptr;
 
@@ -741,15 +598,13 @@ typedef my_destination_mgr *my_dest_ptr;
 void
 init_destination (j_compress_ptr cinfo)
 {
-  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+       my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
 
-  /* Allocate the output buffer --- it will be released when done with image */
-  dest->buffer = (unsigned char *)
-    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-                               OUTPUT_BUF_SIZE * sizeof (unsigned char));
+       /* Allocate the output buffer --- it will be released when done with image */
+       dest->buffer = (unsigned char *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * sizeof (unsigned char));
 
-  dest->pub.next_output_byte = dest->buffer;
-  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+       dest->pub.next_output_byte = dest->buffer;
+       dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
 }
 
 
@@ -779,16 +634,16 @@ init_destination (j_compress_ptr cinfo)
 safeboolean
 empty_output_buffer (j_compress_ptr cinfo)
 {
-  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+       my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
 
-  if (gdPutBuf (dest->buffer, OUTPUT_BUF_SIZE, dest->outfile) !=
-      (size_t) OUTPUT_BUF_SIZE)
-    ERREXIT (cinfo, JERR_FILE_WRITE);
+       if (gdPutBuf (dest->buffer, OUTPUT_BUF_SIZE, dest->outfile) != (size_t) OUTPUT_BUF_SIZE) {
+               ERREXIT (cinfo, JERR_FILE_WRITE);
+       }
 
-  dest->pub.next_output_byte = dest->buffer;
-  dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+       dest->pub.next_output_byte = dest->buffer;
+       dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
 
-  return TRUE;
+       return TRUE;
 }
 
 
@@ -804,15 +659,13 @@ empty_output_buffer (j_compress_ptr cinfo)
 void
 term_destination (j_compress_ptr cinfo)
 {
-  my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
-  size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
-
-  /* Write any data remaining in the buffer */
-  if (datacount > 0)
-    {
-      if ((size_t)gdPutBuf (dest->buffer, datacount, dest->outfile) != datacount)
-       ERREXIT (cinfo, JERR_FILE_WRITE);
-    }
+       my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+       size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
+
+       /* Write any data remaining in the buffer */
+       if (datacount > 0 && ((size_t)gdPutBuf (dest->buffer, datacount, dest->outfile) != datacount)) {
+               ERREXIT (cinfo, JERR_FILE_WRITE);
+       }
 }
 
 
@@ -825,26 +678,23 @@ term_destination (j_compress_ptr cinfo)
 void
 jpeg_gdIOCtx_dest (j_compress_ptr cinfo, gdIOCtx * outfile)
 {
-  my_dest_ptr dest;
-
-  /* The destination object is made permanent so that multiple JPEG images
-   * can be written to the same file without re-executing jpeg_stdio_dest.
-   * This makes it dangerous to use this manager and a different destination
-   * manager serially with the same JPEG object, because their private object
-   * sizes may be different.  Caveat programmer.
-   */
-  if (cinfo->dest == NULL)
-    {                          /* first time for this JPEG object? */
-      cinfo->dest = (struct jpeg_destination_mgr *)
-       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
-                                   sizeof (my_destination_mgr));
-    }
-
-  dest = (my_dest_ptr) cinfo->dest;
-  dest->pub.init_destination = init_destination;
-  dest->pub.empty_output_buffer = empty_output_buffer;
-  dest->pub.term_destination = term_destination;
-  dest->outfile = outfile;
+       my_dest_ptr dest;
+
+       /* The destination object is made permanent so that multiple JPEG images
+        * can be written to the same file without re-executing jpeg_stdio_dest.
+        * This makes it dangerous to use this manager and a different destination
+        * manager serially with the same JPEG object, because their private object
+        * sizes may be different.  Caveat programmer.
+        */
+       if (cinfo->dest == NULL) { /* first time for this JPEG object? */
+               cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof (my_destination_mgr));
+       }
+
+       dest = (my_dest_ptr) cinfo->dest;
+       dest->pub.init_destination = init_destination;
+       dest->pub.empty_output_buffer = empty_output_buffer;
+       dest->pub.term_destination = term_destination;
+       dest->outfile = outfile;
 }
 
 #endif /* HAVE_JPEG */