]> git.saurik.com Git - wxWidgets.git/blobdiff - src/png/pngread.c
reduce black background flicker a bit - there is still some left sometimes initially...
[wxWidgets.git] / src / png / pngread.c
index 24ddeb5c7b247ce1550f747ebe6122c9c76c34e6..22240227d65ed697c126214d0d80f83d4a719e6f 100644 (file)
@@ -1,9 +1,9 @@
 
 /* pngread.c - read a PNG file
  *
- * libpng 1.2.4 - July 8, 2002
+ * libpng 1.2.7 - September 12, 2004
  * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2004 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -59,6 +59,12 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
 #endif
 #endif /* PNG_1_0_X */
 
+   /* added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
+   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
+#endif
+
 #ifdef PNG_SETJMP_SUPPORTED
 #ifdef USE_FAR_KEYWORD
    if (setjmp(jmpbuf))
@@ -77,7 +83,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
       return (NULL);
    }
 #ifdef USE_FAR_KEYWORD
-   png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
+   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
 #endif
 #endif
 
@@ -154,7 +160,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
 #ifdef USE_FAR_KEYWORD
    if (setjmp(jmpbuf))
       PNG_ABORT();
-   png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
+   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
 #else
    if (setjmp(png_ptr->jmpbuf))
       PNG_ABORT();
@@ -180,7 +186,8 @@ png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
 {
    /* We only come here via pre-1.0.12-compiled applications */
 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
-   if(sizeof(png_struct) > png_struct_size || sizeof(png_info) > png_info_size)
+   if(png_sizeof(png_struct) > png_struct_size || 
+      png_sizeof(png_info) > png_info_size)
    {
       char msg[80];
       png_ptr->warning_fn=NULL;
@@ -195,7 +202,7 @@ png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
       png_warning(png_ptr, msg);
    }
 #endif
-   if(sizeof(png_struct) > png_struct_size)
+   if(png_sizeof(png_struct) > png_struct_size)
      {
        png_ptr->error_fn=NULL;
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@@ -204,7 +211,7 @@ png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
        png_error(png_ptr,
        "The png struct allocated by the application for reading is too small.");
      }
-   if(sizeof(png_info) > png_info_size)
+   if(png_sizeof(png_info) > png_info_size)
      {
        png_ptr->error_fn=NULL;
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@@ -247,10 +254,10 @@ png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
 
 #ifdef PNG_SETJMP_SUPPORTED
    /* save jump buffer and error functions */
-   png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
 #endif
 
-   if(sizeof(png_struct) > png_struct_size)
+   if(png_sizeof(png_struct) > png_struct_size)
      {
        png_destroy_struct(png_ptr);
        *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
@@ -258,11 +265,17 @@ png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
      }
 
    /* reset all variables to 0 */
-   png_memset(png_ptr, 0, sizeof (png_struct));
+   png_memset(png_ptr, 0, png_sizeof (png_struct));
 
 #ifdef PNG_SETJMP_SUPPORTED
    /* restore jump buffer */
-   png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
+#endif
+
+   /* added at libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
+   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
 #endif
 
    /* initialize zbuf - compression buffer */
@@ -288,6 +301,7 @@ png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
    png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
 }
 
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 /* 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
@@ -384,7 +398,7 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
       png_uint_32 length;
 
       png_read_data(png_ptr, chunk_length, 4);
-      length = png_get_uint_32(chunk_length);
+      length = png_get_uint_31(png_ptr,chunk_length);
 
       png_reset_crc(png_ptr);
       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
@@ -392,9 +406,6 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
       png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
          length);
 
-      if (length > PNG_MAX_UINT)
-         png_error(png_ptr, "Invalid chunk length.");
-
       /* This should be a binary subdivision search or a hash for
        * matching the chunk name rather than a linear search.
        */
@@ -507,6 +518,7 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
          png_handle_unknown(png_ptr, info_ptr, length);
    }
 }
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 
 /* optional call to update the users info_ptr structure */
 void PNGAPI
@@ -521,6 +533,7 @@ png_read_update_info(png_structp png_ptr, png_infop info_ptr)
    png_read_transform_info(png_ptr, info_ptr);
 }
 
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 /* Initialize palette, background, etc, after transformations
  * are set, but before any reading takes place.  This allows
  * the user to obtain a gamma-corrected palette, for example.
@@ -533,7 +546,9 @@ png_start_read_image(png_structp png_ptr)
    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
       png_read_start_row(png_ptr);
 }
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 void PNGAPI
 png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
 {
@@ -673,10 +688,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
             png_crc_finish(png_ptr, 0);
 
             png_read_data(png_ptr, chunk_length, 4);
-            png_ptr->idat_size = png_get_uint_32(chunk_length);
-
-            if (png_ptr->idat_size > PNG_MAX_UINT)
-              png_error(png_ptr, "Invalid chunk length.");
+            png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
 
             png_reset_crc(png_ptr);
             png_crc_read(png_ptr, png_ptr->chunk_name, 4);
@@ -712,8 +724,8 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
    png_ptr->row_info.channels = png_ptr->channels;
    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
-   png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
-      (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
+   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
+       png_ptr->row_info.width);
 
    if(png_ptr->row_buf[0])
    png_read_filter_row(png_ptr, &(png_ptr->row_info),
@@ -767,7 +779,9 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
    if (png_ptr->read_row_fn != NULL)
       (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
 }
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 /* 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
@@ -789,7 +803,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
  * 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.2.4
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.7
  */
 
 void PNGAPI
@@ -826,7 +840,9 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
          dp++;
       }
 }
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 /* 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
  * initialize the image to the current image that PNG will be overlaying.
@@ -837,7 +853,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
  * 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.2.4
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.7
  */
 void PNGAPI
 png_read_image(png_structp png_ptr, png_bytepp image)
@@ -871,7 +887,9 @@ png_read_image(png_structp png_ptr, png_bytepp image)
       }
    }
 }
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 /* Read the end of the PNG file.  Will not read past the end of the
  * file, will verify the end is accurate, and will read any comments
  * or time information at the end of the file, if info is not NULL.
@@ -946,16 +964,13 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
 #endif /* PNG_GLOBAL_ARRAYS */
 
       png_read_data(png_ptr, chunk_length, 4);
-      length = png_get_uint_32(chunk_length);
+      length = png_get_uint_31(png_ptr,chunk_length);
 
       png_reset_crc(png_ptr);
       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
 
       png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
 
-      if (length > PNG_MAX_UINT)
-         png_error(png_ptr, "Invalid chunk length.");
-
       if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
          png_handle_IHDR(png_ptr, info_ptr, length);
       else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
@@ -1058,6 +1073,7 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
          png_handle_unknown(png_ptr, info_ptr, length);
    } while (!(png_ptr->mode & PNG_HAVE_IEND));
 }
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
 
 /* free all memory used by the read */
 void PNGAPI
@@ -1067,8 +1083,8 @@ 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;
 #ifdef PNG_USER_MEM_SUPPORTED
-   png_free_ptr free_fn = NULL;
-   png_voidp mem_ptr = NULL;
+   png_free_ptr free_fn;
+   png_voidp mem_ptr;
 #endif
 
    png_debug(1, "in png_destroy_read_struct\n");
@@ -1249,7 +1265,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
     * being used again.
     */
 #ifdef PNG_SETJMP_SUPPORTED
-   png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
 #endif
 
    error_fn = png_ptr->error_fn;
@@ -1259,7 +1275,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
    free_fn = png_ptr->free_fn;
 #endif
 
-   png_memset(png_ptr, 0, sizeof (png_struct));
+   png_memset(png_ptr, 0, png_sizeof (png_struct));
 
    png_ptr->error_fn = error_fn;
    png_ptr->warning_fn = warning_fn;
@@ -1269,7 +1285,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
 #endif
 
 #ifdef PNG_SETJMP_SUPPORTED
-   png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
 #endif
 
 }
@@ -1280,6 +1296,8 @@ png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
    png_ptr->read_row_fn = read_row_fn;
 }
 
+
+#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
 #if defined(PNG_INFO_IMAGE_SUPPORTED)
 void PNGAPI
 png_read_png(png_structp png_ptr, png_infop info_ptr,
@@ -1289,34 +1307,38 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
    int row;
 
 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
-   /* invert the alpha channel from opacity to transparency */
+   /* invert the alpha channel from opacity to transparency
+    */
    if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
        png_set_invert_alpha(png_ptr);
 #endif
 
-   /* The call to png_read_info() gives us all of the information from the
+   /* png_read_info() gives us all of the information from the
     * PNG file before the first IDAT (image data chunk).
     */
    png_read_info(png_ptr, info_ptr);
+   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
+      png_error(png_ptr,"Image is too high to process with png_read_png()");
 
    /* -------------- image transformations start here ------------------- */
 
 #if defined(PNG_READ_16_TO_8_SUPPORTED)
-   /* tell libpng to strip 16 bit/color files down to 8 bits/color */
+   /* tell libpng to strip 16 bit/color files down to 8 bits per color
+    */
    if (transforms & PNG_TRANSFORM_STRIP_16)
        png_set_strip_16(png_ptr);
 #endif
 
 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-   /* Strip alpha bytes from the input data without combining with the
-    * background (not recommended).
+   /* Strip alpha bytes from the input data without combining with
+    * the background (not recommended).
     */
    if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
        png_set_strip_alpha(png_ptr);
 #endif
 
 #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
-   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
+   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
     * byte into separate bytes (useful for paletted and grayscale images).
     */
    if (transforms & PNG_TRANSFORM_PACKING)
@@ -1325,7 +1347,8 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
 
 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
    /* Change the order of packed pixels to least significant bit first
-    * (not useful if you are using png_set_packing). */
+    * (not useful if you are using png_set_packing).
+    */
    if (transforms & PNG_TRANSFORM_PACKSWAP)
        png_set_packswap(png_ptr);
 #endif
@@ -1343,10 +1366,12 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
          png_set_expand(png_ptr);
 #endif
 
-   /* We don't handle background color or gamma transformation or dithering. */
+   /* We don't handle background color or gamma transformation or dithering.
+    */
 
 #if defined(PNG_READ_INVERT_SUPPORTED)
-   /* invert monochrome files to have 0 as white and 1 as black */
+   /* invert monochrome files to have 0 as white and 1 as black
+    */
    if (transforms & PNG_TRANSFORM_INVERT_MONO)
        png_set_invert_mono(png_ptr);
 #endif
@@ -1367,19 +1392,22 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
 #endif
 
 #if defined(PNG_READ_BGR_SUPPORTED)
-   /* flip the RGB pixels to BGR (or RGBA to BGRA) */
+   /* flip the RGB pixels to BGR (or RGBA to BGRA)
+    */
    if (transforms & PNG_TRANSFORM_BGR)
        png_set_bgr(png_ptr);
 #endif
 
 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
-   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
+    */
    if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
        png_set_swap_alpha(png_ptr);
 #endif
 
 #if defined(PNG_READ_SWAP_SUPPORTED)
-   /* swap bytes of 16 bit files to least significant byte first */
+   /* swap bytes of 16 bit files to least significant byte first
+    */
    if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
        png_set_swap(png_ptr);
 #endif
@@ -1400,7 +1428,7 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
    if(info_ptr->row_pointers == NULL)
    {
       info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
-         info_ptr->height * sizeof(png_bytep));
+         info_ptr->height * png_sizeof(png_bytep));
 #ifdef PNG_FREE_ME_SUPPORTED
       info_ptr->free_me |= PNG_FREE_ROWS;
 #endif
@@ -1422,3 +1450,4 @@ png_read_png(png_structp png_ptr, png_infop info_ptr,
 
 }
 #endif
+#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */