]> git.saurik.com Git - wxWidgets.git/blobdiff - src/png/pngread.c
repaired recently broken framelayout
[wxWidgets.git] / src / png / pngread.c
index 1618b73095b67919b2d0e19d9fa2defa721d908b..01613b1641b13e5d08b0ee67a0984677a14a3fd4 100644 (file)
@@ -1,12 +1,11 @@
 
 /* pngread.c - read a PNG file
  *
 
 /* pngread.c - read a PNG file
  *
- * libpng 1.0.1
+ * libpng 1.0.3 - January 14, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
- * Copyright (c) 1998, Glenn Randers-Pehrson
- * March 15, 1998
+ * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
  *
  * This file contains routines that an application calls directly to
  * read a PNG file or stream.
  *
  * This file contains routines that an application calls directly to
  * read a PNG file or stream.
 
 /* Create a PNG structure for reading, and allocate any memory needed. */
 png_structp
 
 /* Create a PNG structure for reading, and allocate any memory needed. */
 png_structp
-png_create_read_struct(png_const_charp user_png_ver, voidp error_ptr,
+png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
    png_error_ptr error_fn, png_error_ptr warn_fn)
 {
    png_error_ptr error_fn, png_error_ptr warn_fn)
 {
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
+      warn_fn, NULL, NULL, NULL));
+}
+
+/* Alternate create PNG structure for reading, and allocate any memory needed. */
+png_structp
+png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
    png_structp png_ptr;
 #ifdef USE_FAR_KEYWORD
    jmp_buf jmpbuf;
 #endif
    png_debug(1, "in png_create_read_struct\n");
    png_structp png_ptr;
 #ifdef USE_FAR_KEYWORD
    jmp_buf jmpbuf;
 #endif
    png_debug(1, "in png_create_read_struct\n");
+#ifdef PNG_USER_MEM_SUPPORTED
+   if ((png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+      (png_malloc_ptr)malloc_fn)) == NULL)
+#else
    if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
    if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
+#endif
    {
       return (png_structp)NULL;
    }
    {
       return (png_structp)NULL;
    }
@@ -42,6 +60,11 @@ png_create_read_struct(png_const_charp user_png_ver, voidp error_ptr,
 #ifdef USE_FAR_KEYWORD
    png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
 #endif
 #ifdef USE_FAR_KEYWORD
    png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
 #endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif /* PNG_USER_MEM_SUPPORTED */
+
    png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
 
    /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
    png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
 
    /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
@@ -82,7 +105,7 @@ png_create_read_struct(png_const_charp user_png_ver, voidp error_ptr,
 }
 
 /* Initialize PNG structure for reading, and allocate any memory needed.
 }
 
 /* Initialize PNG structure for reading, and allocate any memory needed.
-   This interface is depreciated in favour of the png_create_read_struct(),
+   This interface is deprecated in favour of the png_create_read_struct(),
    and it will eventually disappear. */
 void
 png_read_init(png_structp png_ptr)
    and it will eventually disappear. */
 void
 png_read_init(png_structp png_ptr)
@@ -125,7 +148,7 @@ png_read_init(png_structp png_ptr)
 /* Read the information before the actual image data.  This has been
  * changed in v0.90 to allow reading a file that already has the magic
  * bytes read from the stream.  You can tell libpng how many bytes have
 /* Read the information before the actual image data.  This has been
  * changed in v0.90 to allow reading a file that already has the magic
  * bytes read from the stream.  You can tell libpng how many bytes have
- * been read from the beginning of the stream (up to the maxumum of 8)
+ * been read from the beginning of the stream (up to the maximum of 8)
  * via png_set_sig_bytes(), and we will only check the remaining bytes
  * here.  The application can then have access to the signature bytes we
  * read if it is determined that this isn't a valid PNG file.
  * via png_set_sig_bytes(), and we will only check the remaining bytes
  * here.  The application can then have access to the signature bytes we
  * read if it is determined that this isn't a valid PNG file.
@@ -258,7 +281,7 @@ png_read_update_info(png_structp png_ptr, png_infop info_ptr)
 
 /* Initialize palette, background, etc, after transformations
  * are set, but before any reading takes place.  This allows
 
 /* Initialize palette, background, etc, after transformations
  * are set, but before any reading takes place.  This allows
- * the user to obtail a gamma corrected palette, for example.
+ * the user to obtain a gamma-corrected palette, for example.
  * If the user doesn't call this, we will do it ourselves.
  */
 void
  * If the user doesn't call this, we will do it ourselves.
  */
 void
@@ -279,6 +302,38 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
    /* save jump buffer and error functions */
    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
       png_read_start_row(png_ptr);
    /* save jump buffer and error functions */
    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
       png_read_start_row(png_ptr);
+   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+   {
+   /* check for transforms that have been set but were defined out */
+#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
+   if (png_ptr->transformations & PNG_FILLER)
+      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACK)
+      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
+   if (png_ptr->transformations & PNG_BGR)
+      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
+#endif
+   }
 
 #if defined(PNG_READ_INTERLACING_SUPPORTED)
    /* if interlaced and we do not need a new row, combine row and return */
 
 #if defined(PNG_READ_INTERLACING_SUPPORTED)
    /* if interlaced and we do not need a new row, combine row and return */
@@ -457,10 +512,10 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
 /* Read one or more rows of image data.  If the image is interlaced,
  * and png_set_interlace_handling() has been called, the rows need to
  * contain the contents of the rows from the previous pass.  If the
 /* Read one or more rows of image data.  If the image is interlaced,
  * and png_set_interlace_handling() has been called, the rows need to
  * contain the contents of the rows from the previous pass.  If the
- * image has alpha or transparency, and png_handle_alpha() has been
+ * image has alpha or transparency, and png_handle_alpha()[*] has been
  * called, the rows contents must be initialized to the contents of the
  * screen.
  * called, the rows contents must be initialized to the contents of the
  * screen.
- * 
+ *
  * "row" holds the actual image, and pixels are placed in it
  * as they arrive.  If the image is displayed after each pass, it will
  * appear to "sparkle" in.  "display_row" can be used to display a
  * "row" holds the actual image, and pixels are placed in it
  * as they arrive.  If the image is displayed after each pass, it will
  * appear to "sparkle" in.  "display_row" can be used to display a
@@ -474,6 +529,8 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
  * also, but you may.  If the image is not interlaced, or if you have
  * not called png_set_interlace_handling(), the display_row buffer will
  * be ignored, so pass NULL to it.
  * also, but you may.  If the image is not interlaced, or if you have
  * not called png_set_interlace_handling(), the display_row buffer will
  * be ignored, so pass NULL to it.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.3.
  */
 
 void
  */
 
 void
@@ -488,29 +545,32 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
    /* save jump buffer and error functions */
    rp = row;
    dp = display_row;
    /* save jump buffer and error functions */
    rp = row;
    dp = display_row;
-   for (i = 0; i < num_rows; i++)
-   {
-      png_bytep rptr;
-      png_bytep dptr;
+   if (rp != NULL && dp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep rptr = *rp++;
+         png_bytep dptr = *dp++;
 
 
-      if (rp != NULL)
-         rptr = *rp;
-      else
-         rptr = NULL;
-      if (dp != NULL)
-         dptr = *dp;
-      else
-         dptr = NULL;
-      png_read_row(png_ptr, rptr, dptr);
-      if (row != NULL)
+         png_read_row(png_ptr, rptr, dptr);
+      }
+   else if(rp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep rptr = *rp;
+         png_read_row(png_ptr, rptr, NULL);
          rp++;
          rp++;
-      if (display_row != NULL)
+      }
+   else if(dp != NULL)
+      for (i = 0; i < num_rows; i++)
+      {
+         png_bytep dptr = *dp;
+         png_read_row(png_ptr, NULL, dptr);
          dp++;
          dp++;
-   }
+      }
 }
 
 /* Read the entire image.  If the image has an alpha channel or a tRNS
 }
 
 /* Read the entire image.  If the image has an alpha channel or a tRNS
- * chunk, and you have called png_handle_alpha(), you will need to
+ * chunk, and you have called png_handle_alpha()[*], you will need to
  * initialize the image to the current image that PNG will be overlaying.
  * We set the num_rows again here, in case it was incorrectly set in
  * png_read_start_row() by a call to png_read_update_info() or
  * initialize the image to the current image that PNG will be overlaying.
  * We set the num_rows again here, in case it was incorrectly set in
  * png_read_start_row() by a call to png_read_update_info() or
@@ -518,11 +578,13 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
  * prior to either of these functions like it should have been.  You can
  * only call this function once.  If you desire to have an image for
  * each pass of a interlaced image, use png_read_rows() instead.
  * prior to either of these functions like it should have been.  You can
  * only call this function once.  If you desire to have an image for
  * each pass of a interlaced image, use png_read_rows() instead.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.3.
  */
 void
 png_read_image(png_structp png_ptr, png_bytepp image)
 {
  */
 void
 png_read_image(png_structp png_ptr, png_bytepp image)
 {
-   png_uint_32 i;
+   png_uint_32 i,image_height;
    int pass, j;
    png_bytepp rp;
 
    int pass, j;
    png_bytepp rp;
 
@@ -530,12 +592,13 @@ png_read_image(png_structp png_ptr, png_bytepp image)
    /* save jump buffer and error functions */
    pass = png_set_interlace_handling(png_ptr);
 
    /* save jump buffer and error functions */
    pass = png_set_interlace_handling(png_ptr);
 
-   png_ptr->num_rows = png_ptr->height; /* Make sure this is set correctly */
+   image_height=png_ptr->height;
+   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
 
    for (j = 0; j < pass; j++)
    {
       rp = image;
 
    for (j = 0; j < pass; j++)
    {
       rp = image;
-      for (i = 0; i < png_ptr->height; i++)
+      for (i = 0; i < image_height; i++)
       {
          png_read_row(png_ptr, *rp, NULL);
          rp++;
       {
          png_read_row(png_ptr, *rp, NULL);
          rp++;
@@ -647,6 +710,9 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
 {
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL, end_info_ptr = NULL;
 {
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL, end_info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_free_ptr free_fn = NULL;
+#endif /* PNG_USER_MEM_SUPPORTED */
 
    png_debug(1, "in png_destroy_read_struct\n");
    /* save jump buffer and error functions */
 
    png_debug(1, "in png_destroy_read_struct\n");
    /* save jump buffer and error functions */
@@ -659,6 +725,10 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
    if (end_info_ptr_ptr != NULL)
       end_info_ptr = *end_info_ptr_ptr;
 
    if (end_info_ptr_ptr != NULL)
       end_info_ptr = *end_info_ptr_ptr;
 
+#ifdef PNG_USER_MEM_SUPPORTED
+   free_fn = png_ptr->free_fn;
+#endif
+
    png_read_destroy(png_ptr, info_ptr, end_info_ptr);
 
    if (info_ptr != NULL)
    png_read_destroy(png_ptr, info_ptr, end_info_ptr);
 
    if (info_ptr != NULL)
@@ -666,7 +736,12 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
 #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
       png_free(png_ptr, info_ptr->text);
 #endif
 #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
       png_free(png_ptr, info_ptr->text);
 #endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)info_ptr, free_fn);
+#else
       png_destroy_struct((png_voidp)info_ptr);
       png_destroy_struct((png_voidp)info_ptr);
+#endif
       *info_ptr_ptr = (png_infop)NULL;
    }
 
       *info_ptr_ptr = (png_infop)NULL;
    }
 
@@ -675,13 +750,21 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
 #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
       png_free(png_ptr, end_info_ptr->text);
 #endif
 #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
       png_free(png_ptr, end_info_ptr->text);
 #endif
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)end_info_ptr, free_fn);
+#else
       png_destroy_struct((png_voidp)end_info_ptr);
       png_destroy_struct((png_voidp)end_info_ptr);
+#endif
       *end_info_ptr_ptr = (png_infop)NULL;
    }
 
    if (png_ptr != NULL)
    {
       *end_info_ptr_ptr = (png_infop)NULL;
    }
 
    if (png_ptr != NULL)
    {
+#ifdef PNG_USER_MEM_SUPPORTED
+      png_destroy_struct_2((png_voidp)png_ptr, free_fn);
+#else
       png_destroy_struct((png_voidp)png_ptr);
       png_destroy_struct((png_voidp)png_ptr);
+#endif
       *png_ptr_ptr = (png_structp)NULL;
    }
 }
       *png_ptr_ptr = (png_structp)NULL;
    }
 }
@@ -694,6 +777,9 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
    png_error_ptr error_fn;
    png_error_ptr warning_fn;
    png_voidp error_ptr;
    png_error_ptr error_fn;
    png_error_ptr warning_fn;
    png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_free_ptr free_fn;
+#endif
 
    png_debug(1, "in png_read_destroy\n");
    /* save jump buffer and error functions */
 
    png_debug(1, "in png_read_destroy\n");
    /* save jump buffer and error functions */
@@ -729,33 +815,39 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
    if (png_ptr->gamma_16_table != NULL)
    {
       int i;
    if (png_ptr->gamma_16_table != NULL)
    {
       int i;
-      for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
       {
          png_free(png_ptr, png_ptr->gamma_16_table[i]);
       }
       {
          png_free(png_ptr, png_ptr->gamma_16_table[i]);
       }
+   png_free(png_ptr, png_ptr->gamma_16_table);
    }
    }
-#endif
 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
-   png_free(png_ptr, png_ptr->gamma_16_table);
    if (png_ptr->gamma_16_from_1 != NULL)
    {
       int i;
    if (png_ptr->gamma_16_from_1 != NULL)
    {
       int i;
-      for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
       {
          png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
       }
       {
          png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
       }
-   }
    png_free(png_ptr, png_ptr->gamma_16_from_1);
    png_free(png_ptr, png_ptr->gamma_16_from_1);
+   }
    if (png_ptr->gamma_16_to_1 != NULL)
    {
       int i;
    if (png_ptr->gamma_16_to_1 != NULL)
    {
       int i;
-      for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
+      int istop = (1 << (8 - png_ptr->gamma_shift));
+      for (i = 0; i < istop; i++)
       {
          png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
       }
       {
          png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
       }
-   }
    png_free(png_ptr, png_ptr->gamma_16_to_1);
    png_free(png_ptr, png_ptr->gamma_16_to_1);
+   }
 #endif
 #endif
+#endif
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+   png_free(png_ptr, png_ptr->time_buffer);
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
 
    inflateEnd(&png_ptr->zstream);
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 
    inflateEnd(&png_ptr->zstream);
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
@@ -770,12 +862,18 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
    error_fn = png_ptr->error_fn;
    warning_fn = png_ptr->warning_fn;
    error_ptr = png_ptr->error_ptr;
    error_fn = png_ptr->error_fn;
    warning_fn = png_ptr->warning_fn;
    error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   free_fn = png_ptr->free_fn;
+#endif
 
    png_memset(png_ptr, 0, sizeof (png_struct));
 
    png_ptr->error_fn = error_fn;
    png_ptr->warning_fn = warning_fn;
    png_ptr->error_ptr = error_ptr;
 
    png_memset(png_ptr, 0, sizeof (png_struct));
 
    png_ptr->error_fn = error_fn;
    png_ptr->warning_fn = warning_fn;
    png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+   png_ptr->free_fn = free_fn;
+#endif
 
    png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
 }
 
    png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
 }