X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1f0299c17dc878540bf190c290392db241b425ad..15c6934360d27110bc36ca747ca6be9f3412c5dc:/src/png/pngread.c diff --git a/src/png/pngread.c b/src/png/pngread.c index 714f5f1429..01613b1641 100644 --- a/src/png/pngread.c +++ b/src/png/pngread.c @@ -1,31 +1,49 @@ /* 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 - * 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. */ #define PNG_INTERNAL -#include "../png/png.h" +#include "png.h" /* 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) { + +#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"); +#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) +#endif { 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 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 @@ -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. - 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) @@ -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 - * 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. @@ -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 - * 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 @@ -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); + 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 */ @@ -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 - * 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. - * + * * "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. + * + * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.3. */ 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; - 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++; - 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++; - } + } } /* 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 @@ -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. + * + * [*] 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) { - png_uint_32 i; + png_uint_32 i,image_height; 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); - 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 (i = 0; i < png_ptr->height; i++) + for (i = 0; i < image_height; i++) { 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; +#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 */ @@ -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; +#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) @@ -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 + +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)info_ptr, free_fn); +#else png_destroy_struct((png_voidp)info_ptr); +#endif *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 +#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); +#endif *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); +#endif *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; +#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 */ @@ -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; - 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); } -#endif #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; - 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); + } 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); + } #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 @@ -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; +#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; +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr->free_fn = free_fn; +#endif png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); }