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

lib/gd/gd_png.c

index 52218b706aa24c0e2de83a19bc64e4d5bd76824c..135cc02ee32b59c20703d3dafb1df3d47718e99e 100644 (file)
@@ -1,3 +1,4 @@
+/* $Id$ */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -67,10 +68,8 @@ gdPngErrorHandler (png_structp png_ptr, png_const_charp msg)
   fflush (stderr);
 
   jmpbuf_ptr = png_get_error_ptr (png_ptr);
-  if (jmpbuf_ptr == NULL)
-    {                          /* we are completely hosed now */
-      fprintf (stderr,
-              "gd-png:  EXTREMELY fatal error: jmpbuf unrecoverable; terminating.\n");
+  if (jmpbuf_ptr == NULL) {                            /* we are completely hosed now */
+      fprintf (stderr, "gd-png:  EXTREMELY fatal error: jmpbuf unrecoverable; terminating.\n");
       fflush (stderr);
       exit (99);
     }
@@ -82,7 +81,11 @@ gdPngErrorHandler (png_structp png_ptr, png_const_charp msg)
 static void
 gdPngReadData (png_structp png_ptr, png_bytep data, png_size_t length)
 {
-  gdGetBuf (data, length, (gdIOCtx *) png_get_io_ptr (png_ptr));
+  int check;
+  check = gdGetBuf (data, length, (gdIOCtx *) png_get_io_ptr (png_ptr));
+  if (check != length) {
+    png_error(png_ptr, "Read Error: truncated data");
+  }
 }
 
 static void
@@ -122,7 +125,7 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile)
   png_byte sig[8];
   png_structp png_ptr;
   png_infop info_ptr;
-  png_uint_32 width, height, rowbytes;
+       png_uint_32 width, height, rowbytes, w, h;
   int bit_depth, color_type, interlace_type;
   int num_palette, num_trans;
   png_colorp palette;
@@ -138,45 +141,48 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile)
 
   /* Make sure the signature can't match by dumb luck -- TBB */
   /* GRR: isn't sizeof(infile) equal to the size of the pointer? */
-  memset (infile, 0, sizeof (infile));
+       memset (sig, 0, sizeof (sig));
 
   /* first do a quick check that the file really is a PNG image; could
    * have used slightly more general png_sig_cmp() function instead */
-  gdGetBuf (sig, 8, infile);
-  if (!png_check_sig (sig, 8))
-    return NULL;               /* bad signature */
+  if (gdGetBuf (sig, 8, infile) < 8) {
+       return NULL;
+  }
+
+       if (!png_check_sig (sig, 8)) { /* bad signature */
+       return NULL;            /* bad signature */
+       }
 
 #ifndef PNG_SETJMP_NOT_SUPPORTED
-  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, &gdPngJmpbufStruct,
-                                   gdPngErrorHandler, NULL);
+  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, &gdPngJmpbufStruct, gdPngErrorHandler, NULL);
 #else
   png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 #endif
-  if (png_ptr == NULL)
-    {
+  if (png_ptr == NULL) {
       fprintf (stderr, "gd-png error: cannot allocate libpng main struct\n");
       return NULL;
     }
 
   info_ptr = png_create_info_struct (png_ptr);
-  if (info_ptr == NULL)
-    {
+  if (info_ptr == NULL) {
       fprintf (stderr, "gd-png error: cannot allocate libpng info struct\n");
       png_destroy_read_struct (&png_ptr, NULL, NULL);
+
       return NULL;
     }
 
   /* we could create a second info struct here (end_info), but it's only
    * useful if we want to keep pre- and post-IDAT chunk info separated
-   * (mainly for PNG-aware image editors and converters) */
+   * (mainly for PNG-aware image editors and converters) 
+       */
 
   /* setjmp() must be called in every non-callback function that calls a
    * PNG-reading libpng function */
 #ifndef PNG_SETJMP_NOT_SUPPORTED
-  if (setjmp (gdPngJmpbufStruct.jmpbuf))
-    {
-      fprintf (stderr, "gd-png error: setjmp returns error condition\n");
+  if (setjmp (gdPngJmpbufStruct.jmpbuf)) {
+      fprintf (stderr, "gd-png error: setjmp returns error condition 1\n");
       png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
+
       return NULL;
     }
 #endif
@@ -186,52 +192,61 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile)
   png_set_read_fn (png_ptr, (void *) infile, gdPngReadData);
   png_read_info (png_ptr, info_ptr);   /* read all PNG info up to image data */
 
-  png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
-               &interlace_type, NULL, NULL);
-  if ((color_type == PNG_COLOR_TYPE_RGB) ||
-      (color_type == PNG_COLOR_TYPE_RGB_ALPHA))
-    {
+  png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
+  if ((color_type == PNG_COLOR_TYPE_RGB) || (color_type == PNG_COLOR_TYPE_RGB_ALPHA)) {
       im = gdImageCreateTrueColor ((int) width, (int) height);
-    }
-  else
-    {
+    } else {
       im = gdImageCreate ((int) width, (int) height);
     }
-  if (im == NULL)
-    {
+  if (im == NULL) {
       fprintf (stderr, "gd-png error: cannot allocate gdImage struct\n");
       png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
       gdFree (image_data);
       gdFree (row_pointers);
+
       return NULL;
     }
 
-  if (bit_depth == 16)
+  if (bit_depth == 16) {
     png_set_strip_16 (png_ptr);
-  else if (bit_depth < 8)
+  } else if (bit_depth < 8) {
     png_set_packing (png_ptr); /* expand to 1 byte per pixel */
-  switch (color_type)
-    {
+       }
+
+       /* setjmp() must be called in every non-callback function that calls a
+        * PNG-reading libpng function
+        */
+#ifndef PNG_SETJMP_NOT_SUPPORTED
+       if (setjmp(gdPngJmpbufStruct.jmpbuf)) {
+               fprintf(stderr, "gd-png error: setjmp returns error condition 2");
+               png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+               gdFree(image_data);
+               gdFree(row_pointers);
+               if (im) {
+                       gdImageDestroy(im);
+               }
+               return NULL;
+       }
+#endif
+
+  switch (color_type) {
     case PNG_COLOR_TYPE_PALETTE:
       png_get_PLTE (png_ptr, info_ptr, &palette, &num_palette);
 #ifdef DEBUG
-      fprintf (stderr, "gd-png color_type is palette, colors: %d\n",
-              num_palette);
+      fprintf (stderr, "gd-png color_type is palette, colors: %d\n", num_palette);
 #endif /* DEBUG */
-      if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
-       {
-         /* gd 2.0: we support this rather thoroughly now. Grab the
-            first fully transparent entry, if any, as the value of 
-            the simple-transparency index, mostly for backwards
-            binary compatibility. The alpha channel is where it's
-            really at these days. */
+      if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) {
+                               /* gd 2.0: we support this rather thoroughly now. Grab the
+                                * first fully transparent entry, if any, as the value of
+                                * the simple-transparency index, mostly for backwards
+                                * binary compatibility. The alpha channel is where it's
+                                * really at these days.
+                                */
          int firstZero = 1;
          png_get_tRNS (png_ptr, info_ptr, &trans, &num_trans, NULL);
-         for (i = 0; i < num_trans; ++i)
-           {
+         for (i = 0; i < num_trans; ++i) {
              im->alpha[i] = gdAlphaMax - (trans[i] >> 1);
-             if ((trans[i] == 0) && (firstZero))
-               {
+             if ((trans[i] == 0) && (firstZero)) {
                  /* 2.0.5: long-forgotten patch from Wez Furlong */
                  transparent = i;
                  firstZero = 0;
@@ -243,38 +258,31 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile)
     case PNG_COLOR_TYPE_GRAY:
     case PNG_COLOR_TYPE_GRAY_ALPHA:
       /* create a fake palette and check for single-shade transparency */
-      if ((palette =
-          (png_colorp) gdMalloc (256 * sizeof (png_color))) == NULL)
-       {
+      if ((palette = (png_colorp) gdMalloc (256 * sizeof (png_color))) == NULL) {
          fprintf (stderr, "gd-png error: cannot allocate gray palette\n");
          png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
          return NULL;
        }
       palette_allocated = TRUE;
-      if (bit_depth < 8)
-       {
+      if (bit_depth < 8) {
          num_palette = 1 << bit_depth;
-         for (i = 0; i < 256; ++i)
-           {
+         for (i = 0; i < 256; ++i) {
              j = (255 * i) / (num_palette - 1);
              palette[i].red = palette[i].green = palette[i].blue = j;
            }
-       }
-      else
-       {
+       } else {
          num_palette = 256;
-         for (i = 0; i < 256; ++i)
-           {
+         for (i = 0; i < 256; ++i) {
              palette[i].red = palette[i].green = palette[i].blue = i;
            }
        }
-      if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
-       {
+      if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) {
          png_get_tRNS (png_ptr, info_ptr, NULL, NULL, &trans_gray_rgb);
-         if (bit_depth == 16)  /* png_set_strip_16() not yet in effect */
+         if (bit_depth == 16) {        /* png_set_strip_16() not yet in effect */
            transparent = trans_gray_rgb->gray >> 8;
-         else
+        } else {
            transparent = trans_gray_rgb->gray;
+       }
          /* Note slight error in 16-bit case:  up to 256 16-bit shades
           * may get mapped to a single 8-bit shade, and only one of them
           * is supposed to be transparent.  IOW, both opaque pixels and
@@ -293,18 +301,18 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile)
       /* gd 2.0: we now support truecolor. See the comment above
          for a rare situation in which the transparent pixel may not
          work properly with 16-bit channels. */
-      if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
-       {
+      if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) {
          png_get_tRNS (png_ptr, info_ptr, NULL, NULL, &trans_color_rgb);
-         if (bit_depth == 16)  /* png_set_strip_16() not yet in effect */
+         if (bit_depth == 16) {        /* png_set_strip_16() not yet in effect */
            transparent = gdTrueColor (trans_color_rgb->red >> 8,
                                       trans_color_rgb->green >> 8,
                                       trans_color_rgb->blue >> 8);
-         else
+        } else {
            transparent = gdTrueColor (trans_color_rgb->red,
                                       trans_color_rgb->green,
                                       trans_color_rgb->blue);
        }
+       }
       break;
     }
 
@@ -315,52 +323,57 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile)
   if (overflow2(rowbytes, height)) {
     png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
     return NULL;
-  }  
-  if ((image_data = (png_bytep) gdMalloc (rowbytes * height)) == NULL)
-    {
+  }
+       image_data = (png_bytep) gdMalloc (rowbytes * height);
+  if (!image_data) {
       fprintf (stderr, "gd-png error: cannot allocate image data\n");
       png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
+       if (im) {
+               gdImageDestroy(im);
+       }
       return NULL;
     }
   if (overflow2(height, sizeof (png_bytep))) {
     png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
     gdFree (image_data);
+       if (im) {
+               gdImageDestroy(im);
+       }
     return NULL;
-  }    
-  if ((row_pointers =
-       (png_bytepp) gdMalloc (height * sizeof (png_bytep))) == NULL)
-    {
+  }
+
+       row_pointers = (png_bytepp) gdMalloc (height * sizeof (png_bytep));    
+  if (!row_pointers) {
       fprintf (stderr, "gd-png error: cannot allocate row pointers\n");
       png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
+       if (im) {
+               gdImageDestroy(im);
+       }
       gdFree (image_data);
       return NULL;
     }
 
   /* set the individual row_pointers to point at the correct offsets */
-  for (j = 0; j < height; ++j)
-    {
-      row_pointers[j] = image_data + j * rowbytes;
+       for (h = 0; h < height; ++h) {
+               row_pointers[h] = image_data + h * rowbytes;
     }
 
   png_read_image (png_ptr, row_pointers);      /* read whole image... */
   png_read_end (png_ptr, NULL);        /* ...done! */
 
-  if (!im->trueColor)
-    {
+  if (!im->trueColor) {
       im->colorsTotal = num_palette;
       /* load the palette and mark all entries "open" (unused) for now */
       open = im->open;
-      for (i = 0; i < num_palette; ++i)
-       {
+      for (i = 0; i < num_palette; ++i) {
          im->red[i] = palette[i].red;
          im->green[i] = palette[i].green;
          im->blue[i] = palette[i].blue;
          open[i] = 1;
        }
-      for (i = num_palette; i < gdMaxColors; ++i)
-       {
+      for (i = num_palette; i < gdMaxColors; ++i) {
          open[i] = 1;
-       }
+               }
     }
   /* 2.0.12: Slaven Rezic: palette images are not the only images
      with a simple transparent color setting */
@@ -369,58 +382,50 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile)
 
   /* can't nuke structs until done with palette */
   png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
-  switch (color_type)
-    {
+  switch (color_type) {
     case PNG_COLOR_TYPE_RGB:
-      for (j = 0; j < height; j++)
-       {
+                       for (h = 0; h < height; h++) {
          int boffset = 0;
-         for (i = 0; i < width; i++)
-           {
-             register png_byte r = row_pointers[j][boffset++];
-             register png_byte g = row_pointers[j][boffset++];
-             register png_byte b = row_pointers[j][boffset++];
-             im->tpixels[j][i] = gdTrueColor (r, g, b);
+                               for (w = 0; w < width; w++) {
+                                       register png_byte r = row_pointers[h][boffset++];
+                                       register png_byte g = row_pointers[h][boffset++];
+                                       register png_byte b = row_pointers[h][boffset++];
+                                       im->tpixels[h][w] = gdTrueColor (r, g, b);
            }
        }
       break;
     case PNG_COLOR_TYPE_RGB_ALPHA:
-      for (j = 0; j < height; j++)
-       {
+                       for (h = 0; h < height; h++) {
          int boffset = 0;
-         for (i = 0; i < width; i++)
-           {
-             register png_byte r = row_pointers[j][boffset++];
-             register png_byte g = row_pointers[j][boffset++];
-             register png_byte b = row_pointers[j][boffset++];
-             /* gd has only 7 bits of alpha channel resolution, and
-                127 is transparent, 0 opaque. A moment of convenience, 
-                a lifetime of compatibility. */
-             register png_byte a = gdAlphaMax -
-               (row_pointers[j][boffset++] >> 1);
-             im->tpixels[j][i] = gdTrueColorAlpha (r, g, b, a);
+                               for (w = 0; w < width; w++) {
+                                       register png_byte r = row_pointers[h][boffset++];
+                                       register png_byte g = row_pointers[h][boffset++];
+                                       register png_byte b = row_pointers[h][boffset++];
+
+   /* gd has only 7 bits of alpha channel resolution, and
+       * 127 is transparent, 0 opaque. A moment of convenience,
+       *  a lifetime of compatibility.
+       */
+
+                                       register png_byte a = gdAlphaMax - (row_pointers[h][boffset++] >> 1);
+                                       im->tpixels[h][w] = gdTrueColorAlpha(r, g, b, a);
            }
        }
       break;
     default:
       /* Palette image, or something coerced to be one */
-      for (j = 0; j < height; ++j)
-       {
-         for (i = 0; i < width; ++i)
-           {
-             register png_byte idx = row_pointers[j][i];
-             im->pixels[j][i] = idx;
+                       for (h = 0; h < height; ++h) {
+                               for (w = 0; w < width; ++w) {
+                                       register png_byte idx = row_pointers[h][w];
+                                       im->pixels[h][w] = idx;
              open[idx] = 0;
            }
        }
     }
 #ifdef DEBUG
-  if (!im->trueColor)
-    {
-      for (i = num_palette; i < gdMaxColors; ++i)
-       {
-         if (!open[i])
-           {
+  if (!im->trueColor) {
+      for (i = num_palette; i < gdMaxColors; ++i) {
+         if (!open[i]) {
              fprintf (stderr,
                       "gd-png warning: image data references out-of-range"
                       " color index (%d)\n", i);
@@ -429,8 +434,9 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile)
     }
 #endif
 
-  if (palette_allocated)
+  if (palette_allocated) {
     gdFree (palette);
+       }
   gdFree (image_data);
   gdFree (row_pointers);
 
@@ -744,7 +750,7 @@ BGD_DECLARE(void) gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level)
              for (i = 0; i < j; ++i)
                gdFree (row_pointers[i]);
               /* 2.0.29: memory leak TBB */
-              free(row_pointers);
+              gdFree(row_pointers);
              return;
            }
          pOutputRow = *prow_pointers++;