12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* pngread.c - read a PNG file 26 * 27 * This file is available under and governed by the GNU General Public 28 * License version 2 only, as published by the Free Software Foundation. 29 * However, the following notice accompanied the original version of this 30 * file and, per its terms, should not be removed: 31 * 32 * Last changed in libpng 1.6.17 [March 26, 2015] 33 * Copyright (c) 1998-2015 Glenn Randers-Pehrson 34 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 35 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 36 * 37 * This code is released under the libpng license. 38 * For conditions of distribution and use, see the disclaimer 39 * and license in png.h 40 * 41 * This file contains routines that an application calls directly to 42 * read a PNG file or stream. 43 */ 44 45 #include "pngpriv.h" 46 #if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) 47 # include <errno.h> 48 #endif 49 50 #ifdef PNG_READ_SUPPORTED 51 52 /* Create a PNG structure for reading, and allocate any memory needed. */ 53 PNG_FUNCTION(png_structp,PNGAPI 138 139 /* IDAT logic needs to happen here to simplify getting the two flags 140 * right. 141 */ 142 if (chunk_name == png_IDAT) 143 { 144 if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) 145 png_chunk_error(png_ptr, "Missing IHDR before IDAT"); 146 147 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 148 (png_ptr->mode & PNG_HAVE_PLTE) == 0) 149 png_chunk_error(png_ptr, "Missing PLTE before IDAT"); 150 151 else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) 152 png_chunk_benign_error(png_ptr, "Too many IDATs found"); 153 154 png_ptr->mode |= PNG_HAVE_IDAT; 155 } 156 157 else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) 158 png_ptr->mode |= PNG_AFTER_IDAT; 159 160 /* This should be a binary subdivision search or a hash for 161 * matching the chunk name rather than a linear search. 162 */ 163 if (chunk_name == png_IHDR) 164 png_handle_IHDR(png_ptr, info_ptr, length); 165 166 else if (chunk_name == png_IEND) 167 png_handle_IEND(png_ptr, info_ptr, length); 168 169 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 170 else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) 171 { 172 png_handle_unknown(png_ptr, info_ptr, length, keep); 173 174 if (chunk_name == png_PLTE) 175 png_ptr->mode |= PNG_HAVE_PLTE; 176 177 else if (chunk_name == png_IDAT) 178 { 796 /* If png_read_end is called in the middle of reading the rows there may 797 * still be pending IDAT data and an owned zstream. Deal with this here. 798 */ 799 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 800 if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0) 801 #endif 802 png_read_finish_IDAT(png_ptr); 803 804 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED 805 /* Report invalid palette index; added at libng-1.5.10 */ 806 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 807 png_ptr->num_palette_max > png_ptr->num_palette) 808 png_benign_error(png_ptr, "Read palette index exceeding num_palette"); 809 #endif 810 811 do 812 { 813 png_uint_32 length = png_read_chunk_header(png_ptr); 814 png_uint_32 chunk_name = png_ptr->chunk_name; 815 816 if (chunk_name == png_IEND) 817 png_handle_IEND(png_ptr, info_ptr, length); 818 819 else if (chunk_name == png_IHDR) 820 png_handle_IHDR(png_ptr, info_ptr, length); 821 822 else if (info_ptr == NULL) 823 png_crc_finish(png_ptr, length); 824 825 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 826 else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) 827 { 828 if (chunk_name == png_IDAT) 829 { 830 if ((length > 0) || 831 (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) 832 png_benign_error(png_ptr, "Too many IDATs found"); 833 } 834 png_handle_unknown(png_ptr, info_ptr, length, keep); 835 if (chunk_name == png_PLTE) 836 png_ptr->mode |= PNG_HAVE_PLTE; 837 } 838 #endif 839 840 else if (chunk_name == png_IDAT) 841 { 842 /* Zero length IDATs are legal after the last IDAT has been 843 * read, but not after other chunks have been read. 844 */ 845 if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) 846 png_benign_error(png_ptr, "Too many IDATs found"); 847 848 png_crc_finish(png_ptr, length); 849 } 850 else if (chunk_name == png_PLTE) 851 png_handle_PLTE(png_ptr, info_ptr, length); 852 853 #ifdef PNG_READ_bKGD_SUPPORTED 854 else if (chunk_name == png_bKGD) 855 png_handle_bKGD(png_ptr, info_ptr, length); 856 #endif 857 858 #ifdef PNG_READ_cHRM_SUPPORTED 859 else if (chunk_name == png_cHRM) 860 png_handle_cHRM(png_ptr, info_ptr, length); 861 #endif 862 863 #ifdef PNG_READ_gAMA_SUPPORTED 864 else if (chunk_name == png_gAMA) 865 png_handle_gAMA(png_ptr, info_ptr, length); 866 #endif 3859 mode = PNG_ALPHA_OPTIMIZED; 3860 } 3861 } 3862 3863 else /* output needs an alpha channel */ 3864 { 3865 /* This is tricky because it happens before the swap operation has 3866 * been accomplished; however, the swap does *not* swap the added 3867 * alpha channel (weird API), so it must be added in the correct 3868 * place. 3869 */ 3870 png_uint_32 filler; /* opaque filler */ 3871 int where; 3872 3873 if (linear != 0) 3874 filler = 65535; 3875 3876 else 3877 filler = 255; 3878 3879 # ifdef PNG_FORMAT_AFIRST_SUPPORTED 3880 if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) 3881 { 3882 where = PNG_FILLER_BEFORE; 3883 change &= ~PNG_FORMAT_FLAG_AFIRST; 3884 } 3885 3886 else 3887 # endif 3888 where = PNG_FILLER_AFTER; 3889 3890 png_set_add_alpha(png_ptr, filler, where); 3891 } 3892 3893 /* This stops the (irrelevant) call to swap_alpha below. */ 3894 change &= ~PNG_FORMAT_FLAG_ALPHA; 3895 } 3896 3897 /* Now set the alpha mode correctly; this is always done, even if there is 3898 * no alpha channel in either the input or the output because it correctly 3899 * sets the output gamma. 3900 */ 3901 png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); 3902 3903 # ifdef PNG_FORMAT_BGR_SUPPORTED 3904 if ((change & PNG_FORMAT_FLAG_BGR) != 0) 3905 { 3906 /* Check only the output format; PNG is never BGR; don't do this if 3907 * the output is gray, but fix up the 'format' value in that case. 3976 info_format |= PNG_FORMAT_FLAG_COLOR; 3977 3978 if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) 3979 { 3980 /* do_local_compose removes this channel below. */ 3981 if (do_local_compose == 0) 3982 { 3983 /* do_local_background does the same if required. */ 3984 if (do_local_background != 2 || 3985 (format & PNG_FORMAT_FLAG_ALPHA) != 0) 3986 info_format |= PNG_FORMAT_FLAG_ALPHA; 3987 } 3988 } 3989 3990 else if (do_local_compose != 0) /* internal error */ 3991 png_error(png_ptr, "png_image_read: alpha channel lost"); 3992 3993 if (info_ptr->bit_depth == 16) 3994 info_format |= PNG_FORMAT_FLAG_LINEAR; 3995 3996 # ifdef PNG_FORMAT_BGR_SUPPORTED 3997 if ((png_ptr->transformations & PNG_BGR) != 0) 3998 info_format |= PNG_FORMAT_FLAG_BGR; 3999 # endif 4000 4001 # ifdef PNG_FORMAT_AFIRST_SUPPORTED 4002 if (do_local_background == 2) 4003 { 4004 if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) 4005 info_format |= PNG_FORMAT_FLAG_AFIRST; 4006 } 4007 4008 if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 || 4009 ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 && 4010 (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0)) 4011 { 4012 if (do_local_background == 2) 4013 png_error(png_ptr, "unexpected alpha swap transformation"); 4014 4015 info_format |= PNG_FORMAT_FLAG_AFIRST; 4016 } 4017 # endif 4018 4019 /* This is actually an internal error. */ 4020 if (info_format != format) 4021 png_error(png_ptr, "png_read_image: invalid transformations"); 4082 png_uint_32 y = image->height; 4083 png_bytep row = png_voidcast(png_bytep, display->first_row); 4084 4085 while (y-- > 0) 4086 { 4087 png_read_row(png_ptr, row, NULL); 4088 row += row_bytes; 4089 } 4090 } 4091 4092 return 1; 4093 } 4094 } 4095 4096 int PNGAPI 4097 png_image_finish_read(png_imagep image, png_const_colorp background, 4098 void *buffer, png_int_32 row_stride, void *colormap) 4099 { 4100 if (image != NULL && image->version == PNG_IMAGE_VERSION) 4101 { 4102 png_uint_32 check; 4103 4104 if (row_stride == 0) 4105 row_stride = PNG_IMAGE_ROW_STRIDE(*image); 4106 4107 if (row_stride < 0) 4108 check = -row_stride; 4109 4110 else 4111 check = row_stride; 4112 4113 if (image->opaque != NULL && buffer != NULL && 4114 check >= PNG_IMAGE_ROW_STRIDE(*image)) 4115 { 4116 if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || 4117 (image->colormap_entries > 0 && colormap != NULL)) 4118 { 4119 int result; 4120 png_image_read_control display; 4121 4122 memset(&display, 0, (sizeof display)); 4123 display.image = image; 4124 display.buffer = buffer; 4125 display.row_stride = row_stride; 4126 display.colormap = colormap; 4127 display.background = background; 4128 display.local_row = NULL; 4129 4130 /* Choose the correct 'end' routine; for the color-map case all the 4131 * setup has already been done. 4132 */ 4133 if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) 4134 result = 4135 png_safe_execute(image, png_image_read_colormap, &display) && 4136 png_safe_execute(image, png_image_read_colormapped, &display); 4137 4138 else 4139 result = 4140 png_safe_execute(image, png_image_read_direct, &display); 4141 4142 png_image_free(image); 4143 return result; 4144 } 4145 4146 else 4147 return png_image_error(image, 4148 "png_image_finish_read[color-map]: no color-map"); 4149 } 4150 4151 else 4152 return png_image_error(image, 4153 "png_image_finish_read: invalid argument"); 4154 } 4155 4156 else if (image != NULL) 4157 return png_image_error(image, 4158 "png_image_finish_read: damaged PNG_IMAGE_VERSION"); 4159 4160 return 0; 4161 } 4162 4163 #endif /* SIMPLIFIED_READ */ 4164 #endif /* READ */ | 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* pngread.c - read a PNG file 26 * 27 * This file is available under and governed by the GNU General Public 28 * License version 2 only, as published by the Free Software Foundation. 29 * However, the following notice accompanied the original version of this 30 * file and, per its terms, should not be removed: 31 * 32 * Last changed in libpng 1.6.23 [June 9, 2016] 33 * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson 34 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 35 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 36 * 37 * This code is released under the libpng license. 38 * For conditions of distribution and use, see the disclaimer 39 * and license in png.h 40 * 41 * This file contains routines that an application calls directly to 42 * read a PNG file or stream. 43 */ 44 45 #include "pngpriv.h" 46 #if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) 47 # include <errno.h> 48 #endif 49 50 #ifdef PNG_READ_SUPPORTED 51 52 /* Create a PNG structure for reading, and allocate any memory needed. */ 53 PNG_FUNCTION(png_structp,PNGAPI 138 139 /* IDAT logic needs to happen here to simplify getting the two flags 140 * right. 141 */ 142 if (chunk_name == png_IDAT) 143 { 144 if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) 145 png_chunk_error(png_ptr, "Missing IHDR before IDAT"); 146 147 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 148 (png_ptr->mode & PNG_HAVE_PLTE) == 0) 149 png_chunk_error(png_ptr, "Missing PLTE before IDAT"); 150 151 else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) 152 png_chunk_benign_error(png_ptr, "Too many IDATs found"); 153 154 png_ptr->mode |= PNG_HAVE_IDAT; 155 } 156 157 else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) 158 { 159 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; 160 png_ptr->mode |= PNG_AFTER_IDAT; 161 } 162 163 /* This should be a binary subdivision search or a hash for 164 * matching the chunk name rather than a linear search. 165 */ 166 if (chunk_name == png_IHDR) 167 png_handle_IHDR(png_ptr, info_ptr, length); 168 169 else if (chunk_name == png_IEND) 170 png_handle_IEND(png_ptr, info_ptr, length); 171 172 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 173 else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) 174 { 175 png_handle_unknown(png_ptr, info_ptr, length, keep); 176 177 if (chunk_name == png_PLTE) 178 png_ptr->mode |= PNG_HAVE_PLTE; 179 180 else if (chunk_name == png_IDAT) 181 { 799 /* If png_read_end is called in the middle of reading the rows there may 800 * still be pending IDAT data and an owned zstream. Deal with this here. 801 */ 802 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 803 if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0) 804 #endif 805 png_read_finish_IDAT(png_ptr); 806 807 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED 808 /* Report invalid palette index; added at libng-1.5.10 */ 809 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 810 png_ptr->num_palette_max > png_ptr->num_palette) 811 png_benign_error(png_ptr, "Read palette index exceeding num_palette"); 812 #endif 813 814 do 815 { 816 png_uint_32 length = png_read_chunk_header(png_ptr); 817 png_uint_32 chunk_name = png_ptr->chunk_name; 818 819 if (chunk_name != png_IDAT) 820 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; 821 822 if (chunk_name == png_IEND) 823 png_handle_IEND(png_ptr, info_ptr, length); 824 825 else if (chunk_name == png_IHDR) 826 png_handle_IHDR(png_ptr, info_ptr, length); 827 828 else if (info_ptr == NULL) 829 png_crc_finish(png_ptr, length); 830 831 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 832 else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) 833 { 834 if (chunk_name == png_IDAT) 835 { 836 if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) 837 || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) 838 png_benign_error(png_ptr, ".Too many IDATs found"); 839 } 840 png_handle_unknown(png_ptr, info_ptr, length, keep); 841 if (chunk_name == png_PLTE) 842 png_ptr->mode |= PNG_HAVE_PLTE; 843 } 844 #endif 845 846 else if (chunk_name == png_IDAT) 847 { 848 /* Zero length IDATs are legal after the last IDAT has been 849 * read, but not after other chunks have been read. 1.6 does not 850 * always read all the deflate data; specifically it cannot be relied 851 * upon to read the Adler32 at the end. If it doesn't ignore IDAT 852 * chunks which are longer than zero as well: 853 */ 854 if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) 855 || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) 856 png_benign_error(png_ptr, "..Too many IDATs found"); 857 858 png_crc_finish(png_ptr, length); 859 } 860 else if (chunk_name == png_PLTE) 861 png_handle_PLTE(png_ptr, info_ptr, length); 862 863 #ifdef PNG_READ_bKGD_SUPPORTED 864 else if (chunk_name == png_bKGD) 865 png_handle_bKGD(png_ptr, info_ptr, length); 866 #endif 867 868 #ifdef PNG_READ_cHRM_SUPPORTED 869 else if (chunk_name == png_cHRM) 870 png_handle_cHRM(png_ptr, info_ptr, length); 871 #endif 872 873 #ifdef PNG_READ_gAMA_SUPPORTED 874 else if (chunk_name == png_gAMA) 875 png_handle_gAMA(png_ptr, info_ptr, length); 876 #endif 3869 mode = PNG_ALPHA_OPTIMIZED; 3870 } 3871 } 3872 3873 else /* output needs an alpha channel */ 3874 { 3875 /* This is tricky because it happens before the swap operation has 3876 * been accomplished; however, the swap does *not* swap the added 3877 * alpha channel (weird API), so it must be added in the correct 3878 * place. 3879 */ 3880 png_uint_32 filler; /* opaque filler */ 3881 int where; 3882 3883 if (linear != 0) 3884 filler = 65535; 3885 3886 else 3887 filler = 255; 3888 3889 #ifdef PNG_FORMAT_AFIRST_SUPPORTED 3890 if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) 3891 { 3892 where = PNG_FILLER_BEFORE; 3893 change &= ~PNG_FORMAT_FLAG_AFIRST; 3894 } 3895 3896 else 3897 #endif 3898 where = PNG_FILLER_AFTER; 3899 3900 png_set_add_alpha(png_ptr, filler, where); 3901 } 3902 3903 /* This stops the (irrelevant) call to swap_alpha below. */ 3904 change &= ~PNG_FORMAT_FLAG_ALPHA; 3905 } 3906 3907 /* Now set the alpha mode correctly; this is always done, even if there is 3908 * no alpha channel in either the input or the output because it correctly 3909 * sets the output gamma. 3910 */ 3911 png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); 3912 3913 # ifdef PNG_FORMAT_BGR_SUPPORTED 3914 if ((change & PNG_FORMAT_FLAG_BGR) != 0) 3915 { 3916 /* Check only the output format; PNG is never BGR; don't do this if 3917 * the output is gray, but fix up the 'format' value in that case. 3986 info_format |= PNG_FORMAT_FLAG_COLOR; 3987 3988 if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) 3989 { 3990 /* do_local_compose removes this channel below. */ 3991 if (do_local_compose == 0) 3992 { 3993 /* do_local_background does the same if required. */ 3994 if (do_local_background != 2 || 3995 (format & PNG_FORMAT_FLAG_ALPHA) != 0) 3996 info_format |= PNG_FORMAT_FLAG_ALPHA; 3997 } 3998 } 3999 4000 else if (do_local_compose != 0) /* internal error */ 4001 png_error(png_ptr, "png_image_read: alpha channel lost"); 4002 4003 if (info_ptr->bit_depth == 16) 4004 info_format |= PNG_FORMAT_FLAG_LINEAR; 4005 4006 #ifdef PNG_FORMAT_BGR_SUPPORTED 4007 if ((png_ptr->transformations & PNG_BGR) != 0) 4008 info_format |= PNG_FORMAT_FLAG_BGR; 4009 #endif 4010 4011 #ifdef PNG_FORMAT_AFIRST_SUPPORTED 4012 if (do_local_background == 2) 4013 { 4014 if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) 4015 info_format |= PNG_FORMAT_FLAG_AFIRST; 4016 } 4017 4018 if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 || 4019 ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 && 4020 (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0)) 4021 { 4022 if (do_local_background == 2) 4023 png_error(png_ptr, "unexpected alpha swap transformation"); 4024 4025 info_format |= PNG_FORMAT_FLAG_AFIRST; 4026 } 4027 # endif 4028 4029 /* This is actually an internal error. */ 4030 if (info_format != format) 4031 png_error(png_ptr, "png_read_image: invalid transformations"); 4092 png_uint_32 y = image->height; 4093 png_bytep row = png_voidcast(png_bytep, display->first_row); 4094 4095 while (y-- > 0) 4096 { 4097 png_read_row(png_ptr, row, NULL); 4098 row += row_bytes; 4099 } 4100 } 4101 4102 return 1; 4103 } 4104 } 4105 4106 int PNGAPI 4107 png_image_finish_read(png_imagep image, png_const_colorp background, 4108 void *buffer, png_int_32 row_stride, void *colormap) 4109 { 4110 if (image != NULL && image->version == PNG_IMAGE_VERSION) 4111 { 4112 /* Check for row_stride overflow. This check is not performed on the 4113 * original PNG format because it may not occur in the output PNG format 4114 * and libpng deals with the issues of reading the original. 4115 */ 4116 const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); 4117 4118 if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */ 4119 { 4120 png_uint_32 check; 4121 const png_uint_32 png_row_stride = image->width * channels; 4122 4123 if (row_stride == 0) 4124 row_stride = (png_int_32)/*SAFE*/png_row_stride; 4125 4126 if (row_stride < 0) 4127 check = -row_stride; 4128 4129 else 4130 check = row_stride; 4131 4132 if (image->opaque != NULL && buffer != NULL && check >= png_row_stride) 4133 { 4134 /* Now check for overflow of the image buffer calculation; this 4135 * limits the whole image size to 32 bits for API compatibility with 4136 * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. 4137 */ 4138 if (image->height <= 0xFFFFFFFF/png_row_stride) 4139 { 4140 if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || 4141 (image->colormap_entries > 0 && colormap != NULL)) 4142 { 4143 int result; 4144 png_image_read_control display; 4145 4146 memset(&display, 0, (sizeof display)); 4147 display.image = image; 4148 display.buffer = buffer; 4149 display.row_stride = row_stride; 4150 display.colormap = colormap; 4151 display.background = background; 4152 display.local_row = NULL; 4153 4154 /* Choose the correct 'end' routine; for the color-map case 4155 * all the setup has already been done. 4156 */ 4157 if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) 4158 result = png_safe_execute(image, 4159 png_image_read_colormap, &display) && 4160 png_safe_execute(image, 4161 png_image_read_colormapped, &display); 4162 4163 else 4164 result = 4165 png_safe_execute(image, 4166 png_image_read_direct, &display); 4167 4168 png_image_free(image); 4169 return result; 4170 } 4171 4172 else 4173 return png_image_error(image, 4174 "png_image_finish_read[color-map]: no color-map"); 4175 } 4176 4177 else 4178 return png_image_error(image, 4179 "png_image_finish_read: image too large"); 4180 } 4181 4182 else 4183 return png_image_error(image, 4184 "png_image_finish_read: invalid argument"); 4185 } 4186 4187 else 4188 return png_image_error(image, 4189 "png_image_finish_read: row_stride too large"); 4190 } 4191 4192 else if (image != NULL) 4193 return png_image_error(image, 4194 "png_image_finish_read: damaged PNG_IMAGE_VERSION"); 4195 4196 return 0; 4197 } 4198 4199 #endif /* SIMPLIFIED_READ */ 4200 #endif /* READ */ |