diff options
author | Ryan Harrison <rharrison@chromium.org> | 2018-09-04 18:58:21 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-09-04 18:58:21 +0000 |
commit | 6b2e2f0ec7c5f629c5270d14c2339197af7392d8 (patch) | |
tree | bb043a95cb8470b25158d3671c9484a156e30d14 /third_party/libpng16/pngread.c | |
parent | d8b5feae1180185b7d1a41682b2b1a565dd5c630 (diff) | |
download | pdfium-6b2e2f0ec7c5f629c5270d14c2339197af7392d8.tar.xz |
Update libpng from 1.6.22 -> 1.6.34
Updates third_party/libpng16 to Chromium's third_party/libpng @
e87a02987101e2dbe319a4aba6b52470f7624b4a and applies PDFium specific
patches.
BUG=chromium:880322
Change-Id: I6724f55099c70a79da6d6e4863b9c6c9157ec571
Reviewed-on: https://pdfium-review.googlesource.com/41910
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Diffstat (limited to 'third_party/libpng16/pngread.c')
-rw-r--r-- | third_party/libpng16/pngread.c | 347 |
1 files changed, 197 insertions, 150 deletions
diff --git a/third_party/libpng16/pngread.c b/third_party/libpng16/pngread.c index 0572c208cc..da32e9ad9c 100644 --- a/third_party/libpng16/pngread.c +++ b/third_party/libpng16/pngread.c @@ -1,8 +1,8 @@ /* pngread.c - read a PNG file * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.33 [September 28, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 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.) * @@ -28,10 +28,10 @@ png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, { #ifndef PNG_USER_MEM_SUPPORTED png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, NULL, NULL, NULL); + error_fn, warn_fn, NULL, NULL, NULL); #else return png_create_read_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL); + warn_fn, NULL, NULL, NULL); } /* Alternate create PNG structure for reading, and allocate any memory @@ -43,7 +43,7 @@ png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) { png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); + error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); #endif /* USER_MEM */ if (png_ptr != NULL) @@ -175,6 +175,11 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr) png_handle_cHRM(png_ptr, info_ptr, length); #endif +#ifdef PNG_READ_eXIf_SUPPORTED + else if (chunk_name == png_eXIf) + png_handle_eXIf(png_ptr, info_ptr, length); +#endif + #ifdef PNG_READ_gAMA_SUPPORTED else if (chunk_name == png_gAMA) png_handle_gAMA(png_ptr, info_ptr, length); @@ -252,7 +257,7 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr) else png_handle_unknown(png_ptr, info_ptr, length, - PNG_HANDLE_CHUNK_AS_DEFAULT); + PNG_HANDLE_CHUNK_AS_DEFAULT); } } #endif /* SEQUENTIAL_READ */ @@ -279,7 +284,7 @@ png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) /* New in 1.6.0 this avoids the bug of doing the initializations twice */ else png_app_error(png_ptr, - "png_read_update_info/png_start_read_image: duplicate call"); + "png_read_update_info/png_start_read_image: duplicate call"); } } @@ -302,7 +307,7 @@ png_start_read_image(png_structrp png_ptr) /* New in 1.6.0 this avoids the bug of doing the initializations twice */ else png_app_error(png_ptr, - "png_start_read_image/png_read_update_info: duplicate call"); + "png_start_read_image/png_read_update_info: duplicate call"); } } #endif /* SEQUENTIAL_READ */ @@ -359,9 +364,9 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) { - png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); + png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1); + png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3); + png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5); png_uint_32 red = (s0 + s1 + 65536) & 0xffff; png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; *(rp ) = (png_byte)((red >> 8) & 0xff); @@ -534,13 +539,14 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) png_error(png_ptr, "Invalid attempt to read row data"); /* Fill the row with IDAT data: */ + png_ptr->row_buf[0]=255; /* to force error if no data was found */ png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1); if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) { if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, - png_ptr->prev_row + 1, png_ptr->row_buf[0]); + png_ptr->prev_row + 1, png_ptr->row_buf[0]); else png_error(png_ptr, "bad adaptive filter value"); } @@ -584,7 +590,7 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) { if (png_ptr->pass < 6) png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, - png_ptr->transformations); + png_ptr->transformations); if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, 1/*display*/); @@ -719,7 +725,7 @@ png_read_image(png_structrp png_ptr, png_bytepp image) * but the caller should do it! */ png_warning(png_ptr, "Interlace handling should be turned on when " - "using png_read_image"); + "using png_read_image"); /* Make sure this is set correctly */ png_ptr->num_rows = png_ptr->height; } @@ -779,8 +785,8 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED /* Report invalid palette index; added at libng-1.5.10 */ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max > png_ptr->num_palette) - png_benign_error(png_ptr, "Read palette index exceeding num_palette"); + png_ptr->num_palette_max > png_ptr->num_palette) + png_benign_error(png_ptr, "Read palette index exceeding num_palette"); #endif do @@ -842,6 +848,11 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) png_handle_cHRM(png_ptr, info_ptr, length); #endif +#ifdef PNG_READ_eXIf_SUPPORTED + else if (chunk_name == png_eXIf) + png_handle_eXIf(png_ptr, info_ptr, length); +#endif + #ifdef PNG_READ_gAMA_SUPPORTED else if (chunk_name == png_gAMA) png_handle_gAMA(png_ptr, info_ptr, length); @@ -919,7 +930,7 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) else png_handle_unknown(png_ptr, info_ptr, length, - PNG_HANDLE_CHUNK_AS_DEFAULT); + PNG_HANDLE_CHUNK_AS_DEFAULT); } while ((png_ptr->mode & PNG_HAVE_IEND) == 0); } #endif /* SEQUENTIAL_READ */ @@ -1030,8 +1041,7 @@ png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn) #ifdef PNG_INFO_IMAGE_SUPPORTED void PNGAPI png_read_png(png_structrp png_ptr, png_inforp info_ptr, - int transforms, - voidp params) + int transforms, voidp params) { if (png_ptr == NULL || info_ptr == NULL) return; @@ -1307,7 +1317,7 @@ png_image_read_init(png_imagep image) if (info_ptr != NULL) { png_controlp control = png_voidcast(png_controlp, - png_malloc_warn(png_ptr, (sizeof *control))); + png_malloc_warn(png_ptr, (sizeof *control))); if (control != NULL) { @@ -1394,7 +1404,9 @@ png_image_read_header(png_voidp argument) png_structrp png_ptr = image->opaque->png_ptr; png_inforp info_ptr = image->opaque->info_ptr; +#ifdef PNG_BENIGN_ERRORS_SUPPORTED png_set_benign_errors(png_ptr, 1/*warn*/); +#endif png_read_info(png_ptr, info_ptr); /* Do this the fast way; just read directly out of png_struct. */ @@ -1432,7 +1444,7 @@ png_image_read_header(png_voidp argument) break; case PNG_COLOR_TYPE_PALETTE: - cmap_entries = png_ptr->num_palette; + cmap_entries = (png_uint_32)png_ptr->num_palette; break; default: @@ -1470,12 +1482,12 @@ png_image_begin_read_from_stdio(png_imagep image, FILE* file) else return png_image_error(image, - "png_image_begin_read_from_stdio: invalid argument"); + "png_image_begin_read_from_stdio: invalid argument"); } else if (image != NULL) return png_image_error(image, - "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); + "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); return 0; } @@ -1508,12 +1520,12 @@ png_image_begin_read_from_file(png_imagep image, const char *file_name) else return png_image_error(image, - "png_image_begin_read_from_file: invalid argument"); + "png_image_begin_read_from_file: invalid argument"); } else if (image != NULL) return png_image_error(image, - "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); + "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); return 0; } @@ -1550,7 +1562,7 @@ png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) } int PNGAPI png_image_begin_read_from_memory(png_imagep image, - png_const_voidp memory, png_size_t size) + png_const_voidp memory, png_size_t size) { if (image != NULL && image->version == PNG_IMAGE_VERSION) { @@ -1573,12 +1585,12 @@ int PNGAPI png_image_begin_read_from_memory(png_imagep image, else return png_image_error(image, - "png_image_begin_read_from_memory: invalid argument"); + "png_image_begin_read_from_memory: invalid argument"); } else if (image != NULL) return png_image_error(image, - "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); + "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); return 0; } @@ -1624,12 +1636,12 @@ png_image_skip_unused_chunks(png_structrp png_ptr) * IHDR, PLTE, tRNS, IDAT, and IEND chunks. */ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, - NULL, -1); + NULL, -1); /* But do not ignore image data handling chunks */ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, - chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); - } + chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); + } } # define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) @@ -1696,7 +1708,7 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) #ifdef __GNUC__ default: png_error(display->image->opaque->png_ptr, - "unexpected encoding (internal error)"); + "unexpected encoding (internal error)"); #endif } @@ -1705,8 +1717,8 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) static png_uint_32 png_colormap_compose(png_image_read_control *display, - png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, - png_uint_32 background, int encoding) + png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, + png_uint_32 background, int encoding) { /* The file value is composed on the background, the background has the given * encoding and so does the result, the file is encoded with P_FILE and the @@ -1742,14 +1754,14 @@ png_colormap_compose(png_image_read_control *display, */ static void png_create_colormap_entry(png_image_read_control *display, - png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, - png_uint_32 alpha, int encoding) + png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, + png_uint_32 alpha, int encoding) { png_imagep image = display->image; const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? - P_LINEAR : P_sRGB; + P_LINEAR : P_sRGB; const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && - (red != green || green != blue); + (red != green || green != blue); if (ip > 255) png_error(image->opaque->png_ptr, "color-map index out of range"); @@ -1882,7 +1894,7 @@ png_create_colormap_entry(png_image_read_control *display, { case 4: entry[afirst ? 0 : 3] = (png_uint_16)alpha; - /* FALL THROUGH */ + /* FALLTHROUGH */ case 3: if (alpha < 65535) @@ -1904,7 +1916,7 @@ png_create_colormap_entry(png_image_read_control *display, case 2: entry[1 ^ afirst] = (png_uint_16)alpha; - /* FALL THROUGH */ + /* FALLTHROUGH */ case 1: if (alpha < 65535) @@ -1933,6 +1945,7 @@ png_create_colormap_entry(png_image_read_control *display, { case 4: entry[afirst ? 0 : 3] = (png_byte)alpha; + /* FALLTHROUGH */ case 3: entry[afirst + (2 ^ bgr)] = (png_byte)blue; entry[afirst + 1] = (png_byte)green; @@ -1941,6 +1954,7 @@ png_create_colormap_entry(png_image_read_control *display, case 2: entry[1 ^ afirst] = (png_byte)alpha; + /* FALLTHROUGH */ case 1: entry[afirst] = (png_byte)green; break; @@ -1967,7 +1981,7 @@ make_gray_file_colormap(png_image_read_control *display) for (i=0; i<256; ++i) png_create_colormap_entry(display, i, i, i, i, 255, P_FILE); - return i; + return (int)i; } static int @@ -1978,7 +1992,7 @@ make_gray_colormap(png_image_read_control *display) for (i=0; i<256; ++i) png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB); - return i; + return (int)i; } #define PNG_GRAY_COLORMAP_ENTRIES 256 @@ -2029,10 +2043,10 @@ make_ga_colormap(png_image_read_control *display) for (g=0; g<6; ++g) png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, - P_sRGB); + P_sRGB); } - return i; + return (int)i; } #define PNG_GA_COLORMAP_ENTRIES 256 @@ -2053,11 +2067,11 @@ make_rgb_colormap(png_image_read_control *display) for (b=0; b<6; ++b) png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, - P_sRGB); + P_sRGB); } } - return i; + return (int)i; } #define PNG_RGB_COLORMAP_ENTRIES 216 @@ -2105,7 +2119,7 @@ png_image_read_colormap(png_voidp argument) else if (display->background == NULL /* no way to remove it */) png_error(png_ptr, - "a background color must be supplied to remove alpha/transparency"); + "background color must be supplied to remove alpha/transparency"); /* Get a copy of the background color (this avoids repeating the checks * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the @@ -2200,7 +2214,7 @@ png_image_read_colormap(png_voidp argument) */ if (i != trans) png_create_colormap_entry(display, i, val, val, val, 255, - P_FILE/*8-bit with file gamma*/); + P_FILE/*8-bit with file gamma*/); /* Else this entry is transparent. The colors don't matter if * there is an alpha channel (back_alpha == 0), but it does no @@ -2212,7 +2226,7 @@ png_image_read_colormap(png_voidp argument) */ else png_create_colormap_entry(display, i, back_r, back_g, back_b, - back_alpha, output_encoding); + back_alpha, output_encoding); } /* We need libpng to preserve the original encoding. */ @@ -2250,7 +2264,7 @@ png_image_read_colormap(png_voidp argument) if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) png_error(png_ptr, "gray[16] color-map: too few entries"); - cmap_entries = make_gray_colormap(display); + cmap_entries = (unsigned int)make_gray_colormap(display); if (png_ptr->num_trans > 0) { @@ -2277,7 +2291,7 @@ png_image_read_colormap(png_voidp argument) * matches. */ png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 65535, P_LINEAR); + back_g, 65535, P_LINEAR); } /* The background passed to libpng, however, must be the @@ -2291,8 +2305,8 @@ png_image_read_colormap(png_voidp argument) * doesn't. */ png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); output_processing = PNG_CMAP_NONE; break; @@ -2322,7 +2336,7 @@ png_image_read_colormap(png_voidp argument) * background color at full precision. */ png_create_colormap_entry(display, 254, back_r, back_g, back_b, - back_alpha, output_encoding); + back_alpha, output_encoding); } else @@ -2348,7 +2362,7 @@ png_image_read_colormap(png_voidp argument) if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) png_error(png_ptr, "gray+alpha color-map: too few entries"); - cmap_entries = make_ga_colormap(display); + cmap_entries = (unsigned int)make_ga_colormap(display); background_index = PNG_CMAP_GA_BACKGROUND; output_processing = PNG_CMAP_GA; @@ -2382,7 +2396,7 @@ png_image_read_colormap(png_voidp argument) if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) png_error(png_ptr, "gray-alpha color-map: too few entries"); - cmap_entries = make_gray_colormap(display); + cmap_entries = (unsigned int)make_gray_colormap(display); if (output_encoding == P_LINEAR) { @@ -2390,7 +2404,7 @@ png_image_read_colormap(png_voidp argument) /* And make sure the corresponding palette entry matches. */ png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 65535, P_LINEAR); + back_g, 65535, P_LINEAR); } /* The background passed to libpng, however, must be the sRGB @@ -2400,8 +2414,8 @@ png_image_read_colormap(png_voidp argument) c.gray = c.red = c.green = c.blue = (png_uint_16)gray; png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); output_processing = PNG_CMAP_NONE; } @@ -2421,7 +2435,7 @@ png_image_read_colormap(png_voidp argument) { png_uint_32 gray = (i * 256 + 115) / 231; png_create_colormap_entry(display, i++, gray, gray, gray, - 255, P_sRGB); + 255, P_sRGB); } /* NOTE: this preserves the full precision of the application @@ -2430,13 +2444,13 @@ png_image_read_colormap(png_voidp argument) background_index = i; png_create_colormap_entry(display, i++, back_r, back_g, back_b, #ifdef __COVERITY__ - /* Coverity claims that output_encoding cannot be 2 (P_LINEAR) - * here. - */ 255U, + /* Coverity claims that output_encoding + * cannot be 2 (P_LINEAR) here. + */ 255U, #else - output_encoding == P_LINEAR ? 65535U : 255U, + output_encoding == P_LINEAR ? 65535U : 255U, #endif - output_encoding); + output_encoding); /* For non-opaque input composite on the sRGB background - this * requires inverting the encoding for each component. The input @@ -2474,9 +2488,9 @@ png_image_read_colormap(png_voidp argument) png_uint_32 gray = png_sRGB_table[g*51] * alpha; png_create_colormap_entry(display, i++, - PNG_sRGB_FROM_LINEAR(gray + back_rx), - PNG_sRGB_FROM_LINEAR(gray + back_gx), - PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); + PNG_sRGB_FROM_LINEAR(gray + back_rx), + PNG_sRGB_FROM_LINEAR(gray + back_gx), + PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); } } @@ -2502,7 +2516,7 @@ png_image_read_colormap(png_voidp argument) * png_set_tRNS_to_alpha before png_set_background_fixed. */ png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, - -1); + -1); data_encoding = P_sRGB; /* The output will now be one or two 8-bit gray or gray+alpha @@ -2521,7 +2535,7 @@ png_image_read_colormap(png_voidp argument) if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) png_error(png_ptr, "rgb[ga] color-map: too few entries"); - cmap_entries = make_ga_colormap(display); + cmap_entries = (unsigned int)make_ga_colormap(display); background_index = PNG_CMAP_GA_BACKGROUND; output_processing = PNG_CMAP_GA; } @@ -2547,12 +2561,12 @@ png_image_read_colormap(png_voidp argument) png_ptr->num_trans > 0) && png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0) { - cmap_entries = make_gray_file_colormap(display); + cmap_entries = (unsigned int)make_gray_file_colormap(display); data_encoding = P_FILE; } else - cmap_entries = make_gray_colormap(display); + cmap_entries = (unsigned int)make_gray_colormap(display); /* But if the input has alpha or transparency it must be removed */ @@ -2578,13 +2592,13 @@ png_image_read_colormap(png_voidp argument) gray = png_sRGB_table[gray]; /* now P_LINEAR */ gray = PNG_DIV257(png_gamma_16bit_correct(gray, - png_ptr->colorspace.gamma)); /* now P_FILE */ + png_ptr->colorspace.gamma)); /* now P_FILE */ /* And make sure the corresponding palette entry contains * exactly the required sRGB value. */ png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 0/*unused*/, output_encoding); + back_g, 0/*unused*/, output_encoding); } else if (output_encoding == P_LINEAR) @@ -2609,8 +2623,8 @@ png_image_read_colormap(png_voidp argument) */ expand_tRNS = 1; png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); } output_processing = PNG_CMAP_NONE; @@ -2640,11 +2654,11 @@ png_image_read_colormap(png_voidp argument) if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) png_error(png_ptr, "rgb+alpha color-map: too few entries"); - cmap_entries = make_rgb_colormap(display); + cmap_entries = (unsigned int)make_rgb_colormap(display); /* Add a transparent entry. */ png_create_colormap_entry(display, cmap_entries, 255, 255, - 255, 0, P_sRGB); + 255, 0, P_sRGB); /* This is stored as the background index for the processing * algorithm. @@ -2665,7 +2679,7 @@ png_image_read_colormap(png_voidp argument) */ for (b=0; b<256; b = (b << 1) | 0x7f) png_create_colormap_entry(display, cmap_entries++, - r, g, b, 128, P_sRGB); + r, g, b, 128, P_sRGB); } } @@ -2689,10 +2703,10 @@ png_image_read_colormap(png_voidp argument) if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) png_error(png_ptr, "rgb-alpha color-map: too few entries"); - cmap_entries = make_rgb_colormap(display); + cmap_entries = (unsigned int)make_rgb_colormap(display); png_create_colormap_entry(display, cmap_entries, back_r, - back_g, back_b, 0/*unused*/, output_encoding); + back_g, back_b, 0/*unused*/, output_encoding); if (output_encoding == P_LINEAR) { @@ -2714,9 +2728,9 @@ png_image_read_colormap(png_voidp argument) * index. */ if (memcmp((png_const_bytep)display->colormap + - sample_size * cmap_entries, - (png_const_bytep)display->colormap + - sample_size * PNG_RGB_INDEX(r,g,b), + sample_size * cmap_entries, + (png_const_bytep)display->colormap + + sample_size * PNG_RGB_INDEX(r,g,b), sample_size) != 0) { /* The background color must be added. */ @@ -2734,13 +2748,13 @@ png_image_read_colormap(png_voidp argument) */ for (b=0; b<256; b = (b << 1) | 0x7f) png_create_colormap_entry(display, cmap_entries++, - png_colormap_compose(display, r, P_sRGB, 128, - back_r, output_encoding), - png_colormap_compose(display, g, P_sRGB, 128, - back_g, output_encoding), - png_colormap_compose(display, b, P_sRGB, 128, - back_b, output_encoding), - 0/*unused*/, output_encoding); + png_colormap_compose(display, r, P_sRGB, 128, + back_r, output_encoding), + png_colormap_compose(display, g, P_sRGB, 128, + back_g, output_encoding), + png_colormap_compose(display, b, P_sRGB, 128, + back_b, output_encoding), + 0/*unused*/, output_encoding); } } @@ -2758,8 +2772,8 @@ png_image_read_colormap(png_voidp argument) c.blue = (png_uint_16)back_b; png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); output_processing = PNG_CMAP_RGB; } @@ -2774,7 +2788,7 @@ png_image_read_colormap(png_voidp argument) if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) png_error(png_ptr, "rgb color-map: too few entries"); - cmap_entries = make_rgb_colormap(display); + cmap_entries = (unsigned int)make_rgb_colormap(display); output_processing = PNG_CMAP_RGB; } } @@ -2798,11 +2812,11 @@ png_image_read_colormap(png_voidp argument) output_processing = PNG_CMAP_NONE; data_encoding = P_FILE; /* Don't change from color-map indices */ - cmap_entries = png_ptr->num_palette; + cmap_entries = (unsigned int)png_ptr->num_palette; if (cmap_entries > 256) cmap_entries = 256; - if (cmap_entries > image->colormap_entries) + if (cmap_entries > (unsigned int)image->colormap_entries) png_error(png_ptr, "palette color-map: too few entries"); for (i=0; i < cmap_entries; ++i) @@ -2811,7 +2825,7 @@ png_image_read_colormap(png_voidp argument) { if (trans[i] == 0) png_create_colormap_entry(display, i, back_r, back_g, - back_b, 0, output_encoding); + back_b, 0, output_encoding); else { @@ -2819,22 +2833,22 @@ png_image_read_colormap(png_voidp argument) * on the sRGB color in 'back'. */ png_create_colormap_entry(display, i, - png_colormap_compose(display, colormap[i].red, P_FILE, - trans[i], back_r, output_encoding), - png_colormap_compose(display, colormap[i].green, P_FILE, - trans[i], back_g, output_encoding), - png_colormap_compose(display, colormap[i].blue, P_FILE, - trans[i], back_b, output_encoding), - output_encoding == P_LINEAR ? trans[i] * 257U : - trans[i], - output_encoding); + png_colormap_compose(display, colormap[i].red, + P_FILE, trans[i], back_r, output_encoding), + png_colormap_compose(display, colormap[i].green, + P_FILE, trans[i], back_g, output_encoding), + png_colormap_compose(display, colormap[i].blue, + P_FILE, trans[i], back_b, output_encoding), + output_encoding == P_LINEAR ? trans[i] * 257U : + trans[i], + output_encoding); } } else png_create_colormap_entry(display, i, colormap[i].red, - colormap[i].green, colormap[i].blue, - i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); + colormap[i].green, colormap[i].blue, + i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); } /* The PNG data may have indices packed in fewer than 8 bits, it @@ -2860,7 +2874,7 @@ png_image_read_colormap(png_voidp argument) case P_sRGB: /* Change to 8-bit sRGB */ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); - /* FALL THROUGH */ + /* FALLTHROUGH */ case P_FILE: if (png_ptr->bit_depth > 8) @@ -2914,7 +2928,7 @@ png_image_read_colormap(png_voidp argument) png_error(png_ptr, "bad background index (internal error)"); } - display->colormap_processing = output_processing; + display->colormap_processing = (int)output_processing; return 1/*ok*/; } @@ -2924,7 +2938,7 @@ static int png_image_read_and_map(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; int passes; @@ -3061,7 +3075,7 @@ png_image_read_and_map(png_voidp argument) if (alpha >= 196) *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], - inrow[2]); + inrow[2]); else if (alpha < 64) *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; @@ -3113,7 +3127,7 @@ static int png_image_read_colormapped(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); + argument); png_imagep image = display->image; png_controlp control = image->opaque; png_structrp png_ptr = control->png_ptr; @@ -3178,8 +3192,7 @@ png_image_read_colormapped(png_voidp argument) image->colormap_entries == 244 /* 216 + 1 + 27 */) break; - /* goto bad_output; */ - /* FALL THROUGH */ + goto bad_output; default: bad_output: @@ -3223,14 +3236,14 @@ png_image_read_colormapped(png_voidp argument) else { - png_alloc_size_t row_bytes = display->row_bytes; + png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes; while (--passes >= 0) { png_uint_32 y = image->height; png_bytep row = png_voidcast(png_bytep, display->first_row); - while (y-- > 0) + for (; y > 0; --y) { png_read_row(png_ptr, row, NULL); row += row_bytes; @@ -3246,7 +3259,7 @@ static int png_image_read_composite(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; int passes; @@ -3373,7 +3386,7 @@ static int png_image_read_background(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; png_inforp info_ptr = image->opaque->info_ptr; @@ -3433,8 +3446,7 @@ png_image_read_background(png_voidp argument) for (pass = 0; pass < passes; ++pass) { - png_bytep row = png_voidcast(png_bytep, - display->first_row); + png_bytep row = png_voidcast(png_bytep, display->first_row); unsigned int startx, stepx, stepy; png_uint_32 y; @@ -3462,7 +3474,7 @@ png_image_read_background(png_voidp argument) for (; y<height; y += stepy) { png_bytep inrow = png_voidcast(png_bytep, - display->local_row); + display->local_row); png_bytep outrow = first_row + y * step_row; png_const_bytep end_row = outrow + width; @@ -3507,7 +3519,7 @@ png_image_read_background(png_voidp argument) for (; y<height; y += stepy) { png_bytep inrow = png_voidcast(png_bytep, - display->local_row); + display->local_row); png_bytep outrow = first_row + y * step_row; png_const_bytep end_row = outrow + width; @@ -3554,13 +3566,14 @@ png_image_read_background(png_voidp argument) */ { png_uint_16p first_row = png_voidcast(png_uint_16p, - display->first_row); + display->first_row); /* The division by two is safe because the caller passed in a * stride which was multiplied by 2 (below) to get row_bytes. */ ptrdiff_t step_row = display->row_bytes / 2; - int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; - unsigned int outchannels = 1+preserve_alpha; + unsigned int preserve_alpha = (image->format & + PNG_FORMAT_FLAG_ALPHA) != 0; + unsigned int outchannels = 1U+preserve_alpha; int swap_alpha = 0; # ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED @@ -3604,7 +3617,7 @@ png_image_read_background(png_voidp argument) /* Read the row, which is packed: */ png_read_row(png_ptr, png_voidcast(png_bytep, - display->local_row), NULL); + display->local_row), NULL); inrow = png_voidcast(png_const_uint_16p, display->local_row); /* Now do the pre-multiplication on each pixel in this row. @@ -3653,7 +3666,7 @@ static int png_image_read_direct(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; png_inforp info_ptr = image->opaque->info_ptr; @@ -3704,7 +3717,7 @@ png_image_read_direct(png_voidp argument) do_local_background = 1/*maybe*/; png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, - PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); + PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); } change &= ~PNG_FORMAT_FLAG_COLOR; @@ -3746,7 +3759,13 @@ png_image_read_direct(png_voidp argument) mode = PNG_ALPHA_PNG; output_gamma = PNG_DEFAULT_sRGB; } - + + if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) + { + mode = PNG_ALPHA_OPTIMIZED; + change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; + } + /* If 'do_local_background' is set check for the presence of gamma * correction; this is part of the work-round for the libpng bug * described above. @@ -3763,7 +3782,7 @@ png_image_read_direct(png_voidp argument) * final value. */ if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma, - PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0) + PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0) do_local_background = 0; else if (mode == PNG_ALPHA_STANDARD) @@ -3826,8 +3845,8 @@ png_image_read_direct(png_voidp argument) * pixels. */ png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); } else /* compose on row: implemented below. */ @@ -3972,6 +3991,10 @@ png_image_read_direct(png_voidp argument) else if (do_local_compose != 0) /* internal error */ png_error(png_ptr, "png_image_read: alpha channel lost"); + if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) { + info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; + } + if (info_ptr->bit_depth == 16) info_format |= PNG_FORMAT_FLAG_LINEAR; @@ -4057,14 +4080,14 @@ png_image_read_direct(png_voidp argument) else { - png_alloc_size_t row_bytes = display->row_bytes; + png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes; while (--passes >= 0) { png_uint_32 y = image->height; png_bytep row = png_voidcast(png_bytep, display->first_row); - while (y-- > 0) + for (; y > 0; --y) { png_read_row(png_ptr, row, NULL); row += row_bytes; @@ -4077,7 +4100,7 @@ png_image_read_direct(png_voidp argument) int PNGAPI png_image_finish_read(png_imagep image, png_const_colorp background, - void *buffer, png_int_32 row_stride, void *colormap) + void *buffer, png_int_32 row_stride, void *colormap) { if (image != NULL && image->version == PNG_IMAGE_VERSION) { @@ -4087,7 +4110,13 @@ png_image_finish_read(png_imagep image, png_const_colorp background, */ const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); - if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */ + /* The following checks just the 'row_stride' calculation to ensure it + * fits in a signed 32-bit value. Because channels/components can be + * either 1 or 2 bytes in size the length of a row can still overflow 32 + * bits; this is just to verify that the 'row_stride' argument can be + * represented. + */ + if (image->width <= 0x7fffffffU/channels) /* no overflow */ { png_uint_32 check; const png_uint_32 png_row_stride = image->width * channels; @@ -4096,18 +4125,35 @@ png_image_finish_read(png_imagep image, png_const_colorp background, row_stride = (png_int_32)/*SAFE*/png_row_stride; if (row_stride < 0) - check = -row_stride; + check = (png_uint_32)(-row_stride); else - check = row_stride; + check = (png_uint_32)row_stride; + /* This verifies 'check', the absolute value of the actual stride + * passed in and detects overflow in the application calculation (i.e. + * if the app did actually pass in a non-zero 'row_stride'. + */ if (image->opaque != NULL && buffer != NULL && check >= png_row_stride) { /* Now check for overflow of the image buffer calculation; this * limits the whole image size to 32 bits for API compatibility with * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. + * + * The PNG_IMAGE_BUFFER_SIZE macro is: + * + * (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride)) + * + * And the component size is always 1 or 2, so make sure that the + * number of *bytes* that the application is saying are available + * does actually fit into a 32-bit number. + * + * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE + * will be changed to use png_alloc_size_t; bigger images can be + * accomodated on 64-bit systems. */ - if (image->height <= 0xFFFFFFFF/png_row_stride) + if (image->height <= + 0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check) { if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || (image->colormap_entries > 0 && colormap != NULL)) @@ -4127,15 +4173,16 @@ png_image_finish_read(png_imagep image, png_const_colorp background, * all the setup has already been done. */ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) - result = png_safe_execute(image, - png_image_read_colormap, &display) && - png_safe_execute(image, - png_image_read_colormapped, &display); + result = + png_safe_execute(image, + png_image_read_colormap, &display) && + png_safe_execute(image, + png_image_read_colormapped, &display); else result = png_safe_execute(image, - png_image_read_direct, &display); + png_image_read_direct, &display); png_image_free(image); return result; @@ -4143,27 +4190,27 @@ png_image_finish_read(png_imagep image, png_const_colorp background, else return png_image_error(image, - "png_image_finish_read[color-map]: no color-map"); + "png_image_finish_read[color-map]: no color-map"); } else return png_image_error(image, - "png_image_finish_read: image too large"); + "png_image_finish_read: image too large"); } else return png_image_error(image, - "png_image_finish_read: invalid argument"); + "png_image_finish_read: invalid argument"); } else return png_image_error(image, - "png_image_finish_read: row_stride too large"); + "png_image_finish_read: row_stride too large"); } else if (image != NULL) return png_image_error(image, - "png_image_finish_read: damaged PNG_IMAGE_VERSION"); + "png_image_finish_read: damaged PNG_IMAGE_VERSION"); return 0; } |