diff options
author | Patrick Scott <phanna@android.com> | 2010-06-28 16:55:16 -0400 |
---|---|---|
committer | Patrick Scott <phanna@android.com> | 2010-06-28 16:55:16 -0400 |
commit | 5f6bd84e375226bf228fc8ac90318957ec9e1e7f (patch) | |
tree | da1284f5023ad422da3263b48f1cefa6d6443912 /pngwutil.c | |
parent | 342380c79a16cc2e5ba7859c3fc4e40f2661ea45 (diff) | |
download | external_libpng-5f6bd84e375226bf228fc8ac90318957ec9e1e7f.zip external_libpng-5f6bd84e375226bf228fc8ac90318957ec9e1e7f.tar.gz external_libpng-5f6bd84e375226bf228fc8ac90318957ec9e1e7f.tar.bz2 |
Upgrade libpng to 1.2.44 for security fixes.
Change-Id: Iae257ca6ea7031a99f38e9de196d71ef8b94f9aa
Diffstat (limited to 'pngwutil.c')
-rw-r--r-- | pngwutil.c | 181 |
1 files changed, 111 insertions, 70 deletions
@@ -1,8 +1,8 @@ /* pngwutil.c - utilities to write a PNG file * - * Last changed in libpng 1.2.37 [June 4, 2009] - * Copyright (c) 1998-2009 Glenn Randers-Pehrson + * Last changed in libpng 1.2.43 [February 25, 2010] + * Copyright (c) 1998-2010 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.) * @@ -12,6 +12,7 @@ */ #define PNG_INTERNAL +#define PNG_NO_PEDANTIC_WARNINGS #include "png.h" #ifdef PNG_WRITE_SUPPORTED @@ -102,9 +103,11 @@ png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name, png_debug2(0, "Writing %s chunk, length = %lu", chunk_name, (unsigned long)length); + if (png_ptr == NULL) return; + /* Write the length and the chunk name */ png_save_uint_32(buf, length); png_memcpy(buf + 4, chunk_name, 4); @@ -191,7 +194,7 @@ png_text_compress(png_structp png_ptr, if (compression >= PNG_TEXT_COMPRESSION_LAST) { -#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) +#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) char msg[50]; png_snprintf(msg, 50, "Unknown compression type %d", compression); png_warning(png_ptr, msg); @@ -398,6 +401,7 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, png_byte buf[13]; /* Buffer to store the IHDR info */ png_debug(1, "in png_write_IHDR"); + /* Check that we have valid input data from the application info */ switch (color_type) { @@ -409,7 +413,8 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, case 4: case 8: case 16: png_ptr->channels = 1; break; - default: png_error(png_ptr, "Invalid bit depth for grayscale image"); + default: png_error(png_ptr, + "Invalid bit depth for grayscale image"); } break; case PNG_COLOR_TYPE_RGB: @@ -457,7 +462,7 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, * 5. The color_type is RGB or RGBA */ if ( -#if defined(PNG_MNG_FEATURES_SUPPORTED) +#ifdef PNG_MNG_FEATURES_SUPPORTED !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && (color_type == PNG_COLOR_TYPE_RGB || @@ -485,7 +490,7 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, png_ptr->bit_depth = (png_byte)bit_depth; png_ptr->color_type = (png_byte)color_type; png_ptr->interlaced = (png_byte)interlace_type; -#if defined(PNG_MNG_FEATURES_SUPPORTED) +#ifdef PNG_MNG_FEATURES_SUPPORTED png_ptr->filter_type = (png_byte)filter_type; #endif png_ptr->compression_type = (png_byte)compression_type; @@ -575,8 +580,9 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) png_byte buf[3]; png_debug(1, "in png_write_PLTE"); + if (( -#if defined(PNG_MNG_FEATURES_SUPPORTED) +#ifdef PNG_MNG_FEATURES_SUPPORTED !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && #endif num_pal == 0) || num_pal > 256) @@ -604,7 +610,7 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, (png_uint_32)(num_pal * 3)); -#ifndef PNG_NO_POINTER_INDEXING +#ifdef PNG_POINTER_INDEXING_SUPPORTED for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) { buf[0] = pal_ptr->red; @@ -613,7 +619,9 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) png_write_chunk_data(png_ptr, buf, (png_size_t)3); } #else - /* This is a little slower but some buggy compilers need to do this instead */ + /* This is a little slower but some buggy compilers need to do this + * instead + */ pal_ptr=palette; for (i = 0; i < num_pal; i++) { @@ -634,6 +642,7 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) #ifdef PNG_USE_LOCAL_ARRAYS PNG_IDAT; #endif + png_debug(1, "in png_write_IDAT"); /* Optimize the CMF field in the zlib stream. */ @@ -688,13 +697,15 @@ png_write_IEND(png_structp png_ptr) #ifdef PNG_USE_LOCAL_ARRAYS PNG_IEND; #endif + png_debug(1, "in png_write_IEND"); + png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL, (png_size_t)0); png_ptr->mode |= PNG_HAVE_IEND; } -#if defined(PNG_WRITE_gAMA_SUPPORTED) +#ifdef PNG_WRITE_gAMA_SUPPORTED /* Write a gAMA chunk */ #ifdef PNG_FLOATING_POINT_SUPPORTED void /* PRIVATE */ @@ -707,6 +718,7 @@ png_write_gAMA(png_structp png_ptr, double file_gamma) png_byte buf[4]; png_debug(1, "in png_write_gAMA"); + /* file_gamma is saved in 1/100,000ths */ igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5); png_save_uint_32(buf, igamma); @@ -723,6 +735,7 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) png_byte buf[4]; png_debug(1, "in png_write_gAMA"); + /* file_gamma is saved in 1/100,000ths */ png_save_uint_32(buf, (png_uint_32)file_gamma); png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); @@ -730,7 +743,7 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) #endif #endif -#if defined(PNG_WRITE_sRGB_SUPPORTED) +#ifdef PNG_WRITE_sRGB_SUPPORTED /* Write a sRGB chunk */ void /* PRIVATE */ png_write_sRGB(png_structp png_ptr, int srgb_intent) @@ -741,6 +754,7 @@ png_write_sRGB(png_structp png_ptr, int srgb_intent) png_byte buf[1]; png_debug(1, "in png_write_sRGB"); + if (srgb_intent >= PNG_sRGB_INTENT_LAST) png_warning(png_ptr, "Invalid sRGB rendering intent specified"); @@ -749,7 +763,7 @@ png_write_sRGB(png_structp png_ptr, int srgb_intent) } #endif -#if defined(PNG_WRITE_iCCP_SUPPORTED) +#ifdef PNG_WRITE_iCCP_SUPPORTED /* Write an iCCP chunk */ void /* PRIVATE */ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, @@ -788,6 +802,14 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, ((*( (png_bytep)profile + 2))<< 8) | ((*( (png_bytep)profile + 3)) ); + if (embedded_profile_len < 0) + { + png_warning(png_ptr, + "Embedded profile length in iCCP chunk is negative"); + png_free(png_ptr, new_name); + return; + } + if (profile_len < embedded_profile_len) { png_warning(png_ptr, @@ -822,7 +844,7 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, } #endif -#if defined(PNG_WRITE_sPLT_SUPPORTED) +#ifdef PNG_WRITE_sPLT_SUPPORTED /* Write a sPLT chunk */ void /* PRIVATE */ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) @@ -836,11 +858,12 @@ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) int entry_size = (spalette->depth == 8 ? 6 : 10); int palette_size = entry_size * spalette->nentries; png_sPLT_entryp ep; -#ifdef PNG_NO_POINTER_INDEXING +#ifndef PNG_POINTER_INDEXING_SUPPORTED int i; #endif png_debug(1, "in png_write_sPLT"); + if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0) return; @@ -852,7 +875,7 @@ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, (png_size_t)1); /* Loop through each palette entry, writing appropriately */ -#ifndef PNG_NO_POINTER_INDEXING +#ifdef PNG_POINTER_INDEXING_SUPPORTED for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++) { if (spalette->depth == 8) @@ -902,7 +925,7 @@ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) } #endif -#if defined(PNG_WRITE_sBIT_SUPPORTED) +#ifdef PNG_WRITE_sBIT_SUPPORTED /* Write the sBIT chunk */ void /* PRIVATE */ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) @@ -914,6 +937,7 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) png_size_t size; png_debug(1, "in png_write_sBIT"); + /* Make sure we don't depend upon the order of PNG_COLOR_8 */ if (color_type & PNG_COLOR_MASK_COLOR) { @@ -958,7 +982,7 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) } #endif -#if defined(PNG_WRITE_cHRM_SUPPORTED) +#ifdef PNG_WRITE_cHRM_SUPPORTED /* Write the cHRM chunk */ #ifdef PNG_FLOATING_POINT_SUPPORTED void /* PRIVATE */ @@ -985,7 +1009,7 @@ png_write_cHRM(png_structp png_ptr, double white_x, double white_y, int_blue_x = (png_uint_32)(blue_x * 100000.0 + 0.5); int_blue_y = (png_uint_32)(blue_y * 100000.0 + 0.5); -#if !defined(PNG_NO_CHECK_cHRM) +#ifdef PNG_CHECK_cHRM_SUPPORTED if (png_check_cHRM_fixed(png_ptr, int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y, int_blue_x, int_blue_y)) #endif @@ -1021,8 +1045,9 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, png_byte buf[32]; png_debug(1, "in png_write_cHRM"); + /* Each value is saved in 1/100,000ths */ -#if !defined(PNG_NO_CHECK_cHRM) +#ifdef PNG_CHECK_cHRM_SUPPORTED if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) #endif @@ -1045,7 +1070,7 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, #endif #endif -#if defined(PNG_WRITE_tRNS_SUPPORTED) +#ifdef PNG_WRITE_tRNS_SUPPORTED /* Write the tRNS chunk */ void /* PRIVATE */ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, @@ -1057,6 +1082,7 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, png_byte buf[6]; png_debug(1, "in png_write_tRNS"); + if (color_type == PNG_COLOR_TYPE_PALETTE) { if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) @@ -1101,7 +1127,7 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, } #endif -#if defined(PNG_WRITE_bKGD_SUPPORTED) +#ifdef PNG_WRITE_bKGD_SUPPORTED /* Write the background chunk */ void /* PRIVATE */ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) @@ -1112,10 +1138,11 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) png_byte buf[6]; png_debug(1, "in png_write_bKGD"); + if (color_type == PNG_COLOR_TYPE_PALETTE) { if ( -#if defined(PNG_MNG_FEATURES_SUPPORTED) +#ifdef PNG_MNG_FEATURES_SUPPORTED (png_ptr->num_palette || (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && #endif @@ -1154,7 +1181,7 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) } #endif -#if defined(PNG_WRITE_hIST_SUPPORTED) +#ifdef PNG_WRITE_hIST_SUPPORTED /* Write the histogram */ void /* PRIVATE */ png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) @@ -1166,6 +1193,7 @@ png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) png_byte buf[3]; png_debug(1, "in png_write_hIST"); + if (num_hist > (int)png_ptr->num_palette) { png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, @@ -1206,6 +1234,7 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) int kwarn=0; png_debug(1, "in png_check_keyword"); + *new_key = NULL; if (key == NULL || (key_len = png_strlen(key)) == 0) @@ -1229,7 +1258,7 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) if ((png_byte)*kp < 0x20 || ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1)) { -#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) +#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) char msg[40]; png_snprintf(msg, 40, @@ -1316,7 +1345,7 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) } #endif -#if defined(PNG_WRITE_tEXt_SUPPORTED) +#ifdef PNG_WRITE_tEXt_SUPPORTED /* Write a tEXt chunk */ void /* PRIVATE */ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, @@ -1329,6 +1358,7 @@ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, png_charp new_key; png_debug(1, "in png_write_tEXt"); + if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) return; @@ -1356,7 +1386,7 @@ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, } #endif -#if defined(PNG_WRITE_zTXt_SUPPORTED) +#ifdef PNG_WRITE_zTXt_SUPPORTED /* Write a compressed text chunk */ void /* PRIVATE */ png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, @@ -1416,7 +1446,7 @@ png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, } #endif -#if defined(PNG_WRITE_iTXt_SUPPORTED) +#ifdef PNG_WRITE_iTXt_SUPPORTED /* Write an iTXt chunk */ void /* PRIVATE */ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, @@ -1505,7 +1535,7 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, } #endif -#if defined(PNG_WRITE_oFFs_SUPPORTED) +#ifdef PNG_WRITE_oFFs_SUPPORTED /* Write the oFFs chunk */ void /* PRIVATE */ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, @@ -1517,6 +1547,7 @@ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, png_byte buf[9]; png_debug(1, "in png_write_oFFs"); + if (unit_type >= PNG_OFFSET_LAST) png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); @@ -1527,7 +1558,7 @@ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9); } #endif -#if defined(PNG_WRITE_pCAL_SUPPORTED) +#ifdef PNG_WRITE_pCAL_SUPPORTED /* Write the pCAL chunk (described in the PNG extensions document) */ void /* PRIVATE */ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, @@ -1543,6 +1574,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, int i; png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); + if (type >= PNG_EQUATION_LAST) png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); @@ -1589,9 +1621,9 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, } #endif -#if defined(PNG_WRITE_sCAL_SUPPORTED) +#ifdef PNG_WRITE_sCAL_SUPPORTED /* Write the sCAL chunk */ -#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) +#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) void /* PRIVATE */ png_write_sCAL(png_structp png_ptr, int unit, double width, double height) { @@ -1604,14 +1636,15 @@ png_write_sCAL(png_structp png_ptr, int unit, double width, double height) png_debug(1, "in png_write_sCAL"); buf[0] = (char)unit; -#if defined(_WIN32_WCE) +#ifdef _WIN32_WCE /* sprintf() function is not supported on WindowsCE */ { wchar_t wc_buf[32]; size_t wc_len; swprintf(wc_buf, TEXT("%12.12e"), width); wc_len = wcslen(wc_buf); - WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, + NULL); total_len = wc_len + 2; swprintf(wc_buf, TEXT("%12.12e"), height); wc_len = wcslen(wc_buf); @@ -1663,7 +1696,7 @@ png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, #endif #endif -#if defined(PNG_WRITE_pHYs_SUPPORTED) +#ifdef PNG_WRITE_pHYs_SUPPORTED /* Write the pHYs chunk */ void /* PRIVATE */ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, @@ -1676,6 +1709,7 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, png_byte buf[9]; png_debug(1, "in png_write_pHYs"); + if (unit_type >= PNG_RESOLUTION_LAST) png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); @@ -1687,7 +1721,7 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, } #endif -#if defined(PNG_WRITE_tIME_SUPPORTED) +#ifdef PNG_WRITE_tIME_SUPPORTED /* Write the tIME chunk. Use either png_convert_from_struct_tm() * or png_convert_from_time_t(), or fill in the structure yourself. */ @@ -1700,6 +1734,7 @@ png_write_tIME(png_structp png_ptr, png_timep mod_time) png_byte buf[7]; png_debug(1, "in png_write_tIME"); + if (mod_time->month > 12 || mod_time->month < 1 || mod_time->day > 31 || mod_time->day < 1 || mod_time->hour > 23 || mod_time->second > 60) @@ -1724,7 +1759,6 @@ void /* PRIVATE */ png_write_start_row(png_structp png_ptr) { #ifdef PNG_WRITE_INTERLACING_SUPPORTED -#ifdef PNG_USE_LOCAL_ARRAYS /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ @@ -1739,11 +1773,11 @@ png_write_start_row(png_structp png_ptr) /* Offset to next interlace block in the y direction */ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif -#endif png_size_t buf_size; png_debug(1, "in png_write_start_row"); + buf_size = (png_size_t)(PNG_ROWBYTES( png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1); @@ -1752,7 +1786,7 @@ png_write_start_row(png_structp png_ptr) (png_uint_32)buf_size); png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; -#ifndef PNG_NO_WRITE_FILTER +#ifdef PNG_WRITE_FILTER_SUPPORTED /* Set up filtering buffer, if using this filter */ if (png_ptr->do_filter & PNG_FILTER_SUB) { @@ -1764,33 +1798,32 @@ png_write_start_row(png_structp png_ptr) /* We only need to keep the previous row if we are using one of these. */ if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) { - /* Set up previous row buffer */ - png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, - (png_uint_32)buf_size); - png_memset(png_ptr->prev_row, 0, buf_size); + /* Set up previous row buffer */ + png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, + (png_uint_32)buf_size); if (png_ptr->do_filter & PNG_FILTER_UP) { png_ptr->up_row = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(png_ptr->rowbytes + 1)); + (png_uint_32)(png_ptr->rowbytes + 1)); png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; } if (png_ptr->do_filter & PNG_FILTER_AVG) { png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(png_ptr->rowbytes + 1)); + (png_uint_32)(png_ptr->rowbytes + 1)); png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; } if (png_ptr->do_filter & PNG_FILTER_PAETH) { png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(png_ptr->rowbytes + 1)); + (png_uint_32)(png_ptr->rowbytes + 1)); png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; } } -#endif /* PNG_NO_WRITE_FILTER */ +#endif /* PNG_WRITE_FILTER_SUPPORTED */ #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* If interlaced, we need to set up width and height of pass */ @@ -1824,7 +1857,6 @@ void /* PRIVATE */ png_write_finish_row(png_structp png_ptr) { #ifdef PNG_WRITE_INTERLACING_SUPPORTED -#ifdef PNG_USE_LOCAL_ARRAYS /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ @@ -1839,11 +1871,11 @@ png_write_finish_row(png_structp png_ptr) /* Offset to next interlace block in the y direction */ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif -#endif int ret; png_debug(1, "in png_write_finish_row"); + /* Next row */ png_ptr->row_number++; @@ -1931,7 +1963,7 @@ png_write_finish_row(png_structp png_ptr) png_ptr->zstream.data_type = Z_BINARY; } -#if defined(PNG_WRITE_INTERLACING_SUPPORTED) +#ifdef PNG_WRITE_INTERLACING_SUPPORTED /* Pick out the correct pixels for the interlace pass. * The basic idea here is to go through the row with a source * pointer and a destination pointer (sp and dp), and copy the @@ -1942,7 +1974,6 @@ png_write_finish_row(png_structp png_ptr) void /* PRIVATE */ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) { -#ifdef PNG_USE_LOCAL_ARRAYS /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ @@ -1950,11 +1981,11 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) /* Offset to next interlace block */ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -#endif png_debug(1, "in png_do_write_interlace"); + /* We don't have to do anything on the last pass (6) */ -#if defined(PNG_USELESS_TESTS_SUPPORTED) +#ifdef PNG_USELESS_TESTS_SUPPORTED if (row != NULL && row_info != NULL && pass < 6) #else if (pass < 6) @@ -2114,23 +2145,32 @@ void /* PRIVATE */ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) { png_bytep best_row; -#ifndef PNG_NO_WRITE_FILTER +#ifdef PNG_WRITE_FILTER_SUPPORTED png_bytep prev_row, row_buf; png_uint_32 mins, bpp; png_byte filter_to_do = png_ptr->do_filter; png_uint_32 row_bytes = row_info->rowbytes; -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED int num_p_filters = (int)png_ptr->num_prev_filters; -#endif +#endif png_debug(1, "in png_write_find_filter"); + +#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS) + { + /* These will never be selected so we need not test them. */ + filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); + } +#endif + /* Find out how many bytes offset each pixel is */ bpp = (row_info->pixel_depth + 7) >> 3; prev_row = png_ptr->prev_row; #endif best_row = png_ptr->row_buf; -#ifndef PNG_NO_WRITE_FILTER +#ifdef PNG_WRITE_FILTER_SUPPORTED row_buf = best_row; mins = PNG_MAXSUM; @@ -2173,7 +2213,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) sum += (v < 128) ? v : 256 - v; } -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { png_uint_32 sumhi, sumlo; @@ -2237,7 +2277,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) png_uint_32 i; int v; -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* We temporarily increase the "minimum sum" by the factor we * would reduce the sum of this filter, so that we can do the * early exit comparison without scaling the sum each time. @@ -2290,7 +2330,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) break; } -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; @@ -2351,7 +2391,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) int v; -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; @@ -2393,7 +2433,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) break; } -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; @@ -2456,7 +2496,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) png_uint_32 i; int v; -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; @@ -2505,7 +2545,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) break; } -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; @@ -2589,7 +2629,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) png_uint_32 i; int v; -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; @@ -2670,7 +2710,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) break; } -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { int j; @@ -2706,13 +2746,13 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) best_row = png_ptr->paeth_row; } } -#endif /* PNG_NO_WRITE_FILTER */ +#endif /* PNG_WRITE_FILTER_SUPPORTED */ /* Do the actual writing of the filtered row data from the chosen filter. */ png_write_filtered_row(png_ptr, best_row); -#ifndef PNG_NO_WRITE_FILTER -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_FILTER_SUPPORTED +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* Save the type of filter we picked this time for future calculations */ if (png_ptr->num_prev_filters > 0) { @@ -2724,7 +2764,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) png_ptr->prev_filters[j] = best_row[0]; } #endif -#endif /* PNG_NO_WRITE_FILTER */ +#endif /* PNG_WRITE_FILTER_SUPPORTED */ } @@ -2733,6 +2773,7 @@ void /* PRIVATE */ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) { png_debug(1, "in png_write_filtered_row"); + png_debug1(2, "filter = %d", filtered_row[0]); /* Set up the zlib input buffer */ @@ -2778,7 +2819,7 @@ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) /* Finish row - updates counters and flushes zlib if last row */ png_write_finish_row(png_ptr); -#if defined(PNG_WRITE_FLUSH_SUPPORTED) +#ifdef PNG_WRITE_FLUSH_SUPPORTED png_ptr->flush_rows++; if (png_ptr->flush_dist > 0 && |