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 */
|