Rev 1897 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1897 | Rev 3928 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* pngset.c - storage of image information into info struct |
1 | /* pngset.c - storage of image information into info struct |
2 | * |
2 | * |
3 | * Last changed in libpng 1.5.1 [February 3, 2011] |
3 | * Last changed in libpng 1.6.3 [July 18, 2013] |
4 | * Copyright (c) 1998-2011 Glenn Randers-Pehrson |
4 | * Copyright (c) 1998-2013 Glenn Randers-Pehrson |
5 | * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
5 | * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
6 | * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
6 | * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
7 | * |
7 | * |
8 | * This code is released under the libpng license. |
8 | * This code is released under the libpng license. |
9 | * For conditions of distribution and use, see the disclaimer |
9 | * For conditions of distribution and use, see the disclaimer |
Line 20... | Line 20... | ||
20 | #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) |
20 | #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) |
Line 21... | Line 21... | ||
21 | 21 | ||
22 | #ifdef PNG_bKGD_SUPPORTED |
22 | #ifdef PNG_bKGD_SUPPORTED |
23 | void PNGAPI |
23 | void PNGAPI |
24 | png_set_bKGD(png_structp png_ptr, png_infop info_ptr, |
24 | png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, |
25 | png_const_color_16p background) |
25 | png_const_color_16p background) |
26 | { |
26 | { |
Line 27... | Line 27... | ||
27 | png_debug1(1, "in %s storage function", "bKGD"); |
27 | png_debug1(1, "in %s storage function", "bKGD"); |
28 | 28 | ||
Line 29... | Line 29... | ||
29 | if (png_ptr == NULL || info_ptr == NULL) |
29 | if (png_ptr == NULL || info_ptr == NULL || background == NULL) |
30 | return; |
30 | return; |
31 | 31 | ||
32 | png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); |
32 | info_ptr->background = *background; |
Line 33... | Line 33... | ||
33 | info_ptr->valid |= PNG_INFO_bKGD; |
33 | info_ptr->valid |= PNG_INFO_bKGD; |
34 | } |
34 | } |
35 | #endif |
35 | #endif |
36 | 36 | ||
37 | #ifdef PNG_cHRM_SUPPORTED |
37 | #ifdef PNG_cHRM_SUPPORTED |
38 | void PNGFAPI |
38 | void PNGFAPI |
39 | png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, |
39 | png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr, |
- | 40 | png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, |
|
- | 41 | png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, |
|
40 | png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, |
42 | png_fixed_point blue_x, png_fixed_point blue_y) |
Line 41... | Line 43... | ||
41 | png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, |
43 | { |
42 | png_fixed_point blue_x, png_fixed_point blue_y) |
44 | png_xy xy; |
Line 43... | Line -... | ||
43 | { |
- | |
44 | png_debug1(1, "in %s storage function", "cHRM fixed"); |
45 | |
45 | - | ||
46 | if (png_ptr == NULL || info_ptr == NULL) |
46 | png_debug1(1, "in %s storage function", "cHRM fixed"); |
47 | return; |
- | |
48 | 47 | ||
49 | # ifdef PNG_CHECK_cHRM_SUPPORTED |
48 | if (png_ptr == NULL || info_ptr == NULL) |
50 | if (png_check_cHRM_fixed(png_ptr, |
49 | return; |
51 | white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) |
50 | |
52 | # endif |
51 | xy.redx = red_x; |
53 | { |
52 | xy.redy = red_y; |
- | 53 | xy.greenx = green_x; |
|
54 | info_ptr->x_white = white_x; |
54 | xy.greeny = green_y; |
55 | info_ptr->y_white = white_y; |
55 | xy.bluex = blue_x; |
56 | info_ptr->x_red = red_x; |
56 | xy.bluey = blue_y; |
- | 57 | xy.whitex = white_x; |
|
- | 58 | xy.whitey = white_y; |
|
57 | info_ptr->y_red = red_y; |
59 | |
- | 60 | if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy, |
|
- | 61 | 2/* override with app values*/)) |
|
- | 62 | info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; |
|
- | 63 | ||
- | 64 | png_colorspace_sync_info(png_ptr, info_ptr); |
|
- | 65 | } |
|
- | 66 | ||
- | 67 | void PNGFAPI |
|
- | 68 | png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr, |
|
- | 69 | png_fixed_point int_red_X, png_fixed_point int_red_Y, |
|
- | 70 | png_fixed_point int_red_Z, png_fixed_point int_green_X, |
|
- | 71 | png_fixed_point int_green_Y, png_fixed_point int_green_Z, |
|
- | 72 | png_fixed_point int_blue_X, png_fixed_point int_blue_Y, |
|
- | 73 | png_fixed_point int_blue_Z) |
|
- | 74 | { |
|
- | 75 | png_XYZ XYZ; |
|
- | 76 | ||
- | 77 | png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); |
|
- | 78 | ||
- | 79 | if (png_ptr == NULL || info_ptr == NULL) |
|
- | 80 | return; |
|
- | 81 | ||
- | 82 | XYZ.red_X = int_red_X; |
|
- | 83 | XYZ.red_Y = int_red_Y; |
|
- | 84 | XYZ.red_Z = int_red_Z; |
|
- | 85 | XYZ.green_X = int_green_X; |
|
- | 86 | XYZ.green_Y = int_green_Y; |
|
- | 87 | XYZ.green_Z = int_green_Z; |
|
- | 88 | XYZ.blue_X = int_blue_X; |
|
- | 89 | XYZ.blue_Y = int_blue_Y; |
|
58 | info_ptr->x_green = green_x; |
90 | XYZ.blue_Z = int_blue_Z; |
Line 59... | Line 91... | ||
59 | info_ptr->y_green = green_y; |
91 | |
60 | info_ptr->x_blue = blue_x; |
92 | if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, &XYZ, 2)) |
61 | info_ptr->y_blue = blue_y; |
93 | info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; |
62 | info_ptr->valid |= PNG_INFO_cHRM; |
94 | |
63 | } |
95 | png_colorspace_sync_info(png_ptr, info_ptr); |
64 | } |
96 | } |
65 | 97 | ||
66 | # ifdef PNG_FLOATING_POINT_SUPPORTED |
98 | # ifdef PNG_FLOATING_POINT_SUPPORTED |
Line 78... | Line 110... | ||
78 | png_fixed(png_ptr, green_y, "cHRM Green Y"), |
110 | png_fixed(png_ptr, green_y, "cHRM Green Y"), |
79 | png_fixed(png_ptr, blue_x, "cHRM Blue X"), |
111 | png_fixed(png_ptr, blue_x, "cHRM Blue X"), |
80 | png_fixed(png_ptr, blue_y, "cHRM Blue Y")); |
112 | png_fixed(png_ptr, blue_y, "cHRM Blue Y")); |
81 | } |
113 | } |
82 | # endif /* PNG_FLOATING_POINT_SUPPORTED */ |
114 | |
- | 115 | void PNGAPI |
|
- | 116 | png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, |
|
- | 117 | double red_Y, double red_Z, double green_X, double green_Y, double green_Z, |
|
- | 118 | double blue_X, double blue_Y, double blue_Z) |
|
- | 119 | { |
|
- | 120 | png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, |
|
- | 121 | png_fixed(png_ptr, red_X, "cHRM Red X"), |
|
- | 122 | png_fixed(png_ptr, red_Y, "cHRM Red Y"), |
|
- | 123 | png_fixed(png_ptr, red_Z, "cHRM Red Z"), |
|
- | 124 | png_fixed(png_ptr, green_X, "cHRM Red X"), |
|
- | 125 | png_fixed(png_ptr, green_Y, "cHRM Red Y"), |
|
- | 126 | png_fixed(png_ptr, green_Z, "cHRM Red Z"), |
|
- | 127 | png_fixed(png_ptr, blue_X, "cHRM Red X"), |
|
- | 128 | png_fixed(png_ptr, blue_Y, "cHRM Red Y"), |
|
- | 129 | png_fixed(png_ptr, blue_Z, "cHRM Red Z")); |
|
- | 130 | } |
|
- | 131 | # endif /* PNG_FLOATING_POINT_SUPPORTED */ |
|
83 | 132 | ||
Line 84... | Line 133... | ||
84 | #endif /* PNG_cHRM_SUPPORTED */ |
133 | #endif /* PNG_cHRM_SUPPORTED */ |
Line 85... | Line 134... | ||
85 | 134 | ||
86 | #ifdef PNG_gAMA_SUPPORTED |
135 | #ifdef PNG_gAMA_SUPPORTED |
87 | void PNGFAPI |
136 | void PNGFAPI |
88 | png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point |
137 | png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, |
89 | file_gamma) |
138 | png_fixed_point file_gamma) |
90 | { |
139 | { |
Line 91... | Line 140... | ||
91 | png_debug1(1, "in %s storage function", "gAMA"); |
140 | png_debug1(1, "in %s storage function", "gAMA"); |
92 | 141 | ||
Line 93... | Line -... | ||
93 | if (png_ptr == NULL || info_ptr == NULL) |
- | |
94 | return; |
- | |
95 | - | ||
96 | /* Previously these values were limited, however they must be |
- | |
97 | * wrong, therefore storing them (and setting PNG_INFO_gAMA) |
- | |
98 | * must be wrong too. |
142 | if (png_ptr == NULL || info_ptr == NULL) |
99 | */ |
- | |
100 | if (file_gamma > (png_fixed_point)PNG_UINT_31_MAX) |
- | |
101 | png_warning(png_ptr, "Gamma too large, ignored"); |
143 | return; |
102 | - | ||
103 | else if (file_gamma <= 0) |
- | |
104 | png_warning(png_ptr, "Negative or zero gamma ignored"); |
- | |
105 | - | ||
106 | else |
- | |
107 | { |
- | |
108 | info_ptr->gamma = file_gamma; |
144 | |
Line 109... | Line 145... | ||
109 | info_ptr->valid |= PNG_INFO_gAMA; |
145 | png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma); |
110 | } |
146 | png_colorspace_sync_info(png_ptr, info_ptr); |
111 | } |
147 | } |
112 | 148 | ||
113 | # ifdef PNG_FLOATING_POINT_SUPPORTED |
149 | # ifdef PNG_FLOATING_POINT_SUPPORTED |
114 | void PNGAPI |
150 | void PNGAPI |
115 | png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) |
151 | png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma) |
116 | { |
152 | { |
117 | png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, |
153 | png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, |
Line 118... | Line 154... | ||
118 | "png_set_gAMA")); |
154 | "png_set_gAMA")); |
119 | } |
155 | } |
120 | # endif |
156 | # endif |
- | 157 | #endif |
|
121 | #endif |
158 | |
122 | 159 | #ifdef PNG_hIST_SUPPORTED |
|
Line 123... | Line 160... | ||
123 | #ifdef PNG_hIST_SUPPORTED |
160 | void PNGAPI |
Line 144... | Line 181... | ||
144 | 181 | ||
Line 145... | Line 182... | ||
145 | /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in |
182 | /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in |
146 | * version 1.2.1 |
183 | * version 1.2.1 |
147 | */ |
184 | */ |
148 | png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, |
185 | info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr, |
149 | PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)); |
186 | PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16)))); |
Line 150... | Line 187... | ||
150 | 187 | ||
151 | if (png_ptr->hist == NULL) |
188 | if (info_ptr->hist == NULL) |
152 | { |
189 | { |
153 | png_warning(png_ptr, "Insufficient memory for hIST chunk data"); |
190 | png_warning(png_ptr, "Insufficient memory for hIST chunk data"); |
154 | return; |
191 | return; |
Line -... | Line 192... | ||
- | 192 | } |
|
- | 193 | ||
155 | } |
194 | info_ptr->free_me |= PNG_FREE_HIST; |
156 | 195 | ||
Line 157... | Line -... | ||
157 | for (i = 0; i < info_ptr->num_palette; i++) |
- | |
158 | png_ptr->hist[i] = hist[i]; |
196 | for (i = 0; i < info_ptr->num_palette; i++) |
159 | - | ||
160 | info_ptr->hist = png_ptr->hist; |
197 | info_ptr->hist[i] = hist[i]; |
161 | info_ptr->valid |= PNG_INFO_hIST; |
198 | |
Line 162... | Line 199... | ||
162 | info_ptr->free_me |= PNG_FREE_HIST; |
199 | info_ptr->valid |= PNG_INFO_hIST; |
163 | } |
200 | } |
164 | #endif |
201 | #endif |
165 | 202 | ||
166 | void PNGAPI |
203 | void PNGAPI |
167 | png_set_IHDR(png_structp png_ptr, png_infop info_ptr, |
204 | png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr, |
168 | png_uint_32 width, png_uint_32 height, int bit_depth, |
205 | png_uint_32 width, png_uint_32 height, int bit_depth, |
Line 199... | Line 236... | ||
199 | info_ptr->channels++; |
236 | info_ptr->channels++; |
200 | 237 | ||
Line 201... | Line 238... | ||
201 | info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); |
238 | info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); |
Line 202... | Line -... | ||
202 | - | ||
203 | /* Check for potential overflow */ |
- | |
204 | if (width > |
- | |
205 | (PNG_UINT_32_MAX >> 3) /* 8-byte RRGGBBAA pixels */ |
- | |
206 | - 48 /* bigrowbuf hack */ |
- | |
207 | - 1 /* filter byte */ |
- | |
208 | - 7*8 /* rounding of width to multiple of 8 pixels */ |
- | |
209 | - 8) /* extra max_pixel_depth pad */ |
- | |
210 | info_ptr->rowbytes = 0; |
- | |
211 | else |
239 | |
212 | info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); |
240 | info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); |
Line 213... | Line 241... | ||
213 | } |
241 | } |
214 | 242 | ||
215 | #ifdef PNG_oFFs_SUPPORTED |
243 | #ifdef PNG_oFFs_SUPPORTED |
216 | void PNGAPI |
244 | void PNGAPI |
217 | png_set_oFFs(png_structp png_ptr, png_infop info_ptr, |
245 | png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr, |
218 | png_int_32 offset_x, png_int_32 offset_y, int unit_type) |
246 | png_int_32 offset_x, png_int_32 offset_y, int unit_type) |
Line 219... | Line 247... | ||
219 | { |
247 | { |
Line 230... | Line 258... | ||
230 | #endif |
258 | #endif |
231 | 259 | ||
Line 232... | Line 260... | ||
232 | #ifdef PNG_pCAL_SUPPORTED |
260 | #ifdef PNG_pCAL_SUPPORTED |
233 | void PNGAPI |
261 | void PNGAPI |
234 | png_set_pCAL(png_structp png_ptr, png_infop info_ptr, |
262 | png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, |
235 | png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, |
263 | png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, |
236 | int nparams, png_const_charp units, png_charpp params) |
264 | int nparams, png_const_charp units, png_charpp params) |
237 | { |
265 | { |
238 | png_size_t length; |
266 | png_size_t length; |
239 | int i; |
267 | int i; |
Line 240... | Line 268... | ||
240 | 268 | ||
Line 241... | Line 269... | ||
241 | png_debug1(1, "in %s storage function", "pCAL"); |
269 | png_debug1(1, "in %s storage function", "pCAL"); |
- | 270 | ||
242 | 271 | if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL |
|
Line 243... | Line 272... | ||
243 | if (png_ptr == NULL || info_ptr == NULL) |
272 | || (nparams > 0 && params == NULL)) |
244 | return; |
273 | return; |
245 | 274 | ||
Line 246... | Line 275... | ||
246 | length = png_strlen(purpose) + 1; |
275 | length = strlen(purpose) + 1; |
Line 247... | Line 276... | ||
247 | png_debug1(3, "allocating purpose for info (%lu bytes)", |
276 | png_debug1(3, "allocating purpose for info (%lu bytes)", |
248 | (unsigned long)length); |
277 | (unsigned long)length); |
249 | 278 | ||
Line -... | Line 279... | ||
- | 279 | /* TODO: validate format of calibration name and unit name */ |
|
- | 280 | ||
- | 281 | /* Check that the type matches the specification. */ |
|
250 | /* TODO: validate format of calibration name and unit name */ |
282 | if (type < 0 || type > 3) |
251 | 283 | png_error(png_ptr, "Invalid pCAL equation type"); |
|
- | 284 | ||
252 | /* Check that the type matches the specification. */ |
285 | if (nparams < 0 || nparams > 255) |
253 | if (type < 0 || type > 3) |
286 | png_error(png_ptr, "Invalid pCAL parameter count"); |
Line 254... | Line 287... | ||
254 | png_error(png_ptr, "Invalid pCAL equation type"); |
287 | |
- | 288 | /* Validate params[nparams] */ |
|
Line 255... | Line 289... | ||
255 | 289 | for (i=0; i |
|
256 | /* Validate params[nparams] */ |
290 | if (params[i] == NULL || |
257 | for (i=0; i |
291 | !png_check_fp_string(params[i], strlen(params[i]))) |
258 | if (!png_check_fp_string(params[i], png_strlen(params[i]))) |
292 | png_error(png_ptr, "Invalid format for pCAL parameter"); |
259 | png_error(png_ptr, "Invalid format for pCAL parameter"); |
293 | |
Line 260... | Line 294... | ||
260 | 294 | info_ptr->pcal_purpose = png_voidcast(png_charp, |
|
Line 261... | Line 295... | ||
261 | info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); |
295 | png_malloc_warn(png_ptr, length)); |
262 | 296 | ||
263 | if (info_ptr->pcal_purpose == NULL) |
297 | if (info_ptr->pcal_purpose == NULL) |
264 | { |
298 | { |
265 | png_warning(png_ptr, "Insufficient memory for pCAL purpose"); |
299 | png_warning(png_ptr, "Insufficient memory for pCAL purpose"); |
Line 266... | Line 300... | ||
266 | return; |
300 | return; |
267 | } |
301 | } |
268 | 302 | ||
Line 269... | Line 303... | ||
269 | png_memcpy(info_ptr->pcal_purpose, purpose, length); |
303 | memcpy(info_ptr->pcal_purpose, purpose, length); |
- | 304 | ||
Line 270... | Line 305... | ||
270 | 305 | png_debug(3, "storing X0, X1, type, and nparams in info"); |
|
271 | png_debug(3, "storing X0, X1, type, and nparams in info"); |
306 | info_ptr->pcal_X0 = X0; |
272 | info_ptr->pcal_X0 = X0; |
307 | info_ptr->pcal_X1 = X1; |
273 | info_ptr->pcal_X1 = X1; |
308 | info_ptr->pcal_type = (png_byte)type; |
274 | info_ptr->pcal_type = (png_byte)type; |
309 | info_ptr->pcal_nparams = (png_byte)nparams; |
Line 275... | Line 310... | ||
275 | info_ptr->pcal_nparams = (png_byte)nparams; |
310 | |
Line 276... | Line 311... | ||
276 | 311 | length = strlen(units) + 1; |
|
277 | length = png_strlen(units) + 1; |
312 | png_debug1(3, "allocating units for info (%lu bytes)", |
Line 278... | Line 313... | ||
278 | png_debug1(3, "allocating units for info (%lu bytes)", |
313 | (unsigned long)length); |
279 | (unsigned long)length); |
314 | |
280 | 315 | info_ptr->pcal_units = png_voidcast(png_charp, |
|
281 | info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); |
316 | png_malloc_warn(png_ptr, length)); |
282 | 317 | ||
Line 283... | Line 318... | ||
283 | if (info_ptr->pcal_units == NULL) |
318 | if (info_ptr->pcal_units == NULL) |
Line 284... | Line 319... | ||
284 | { |
319 | { |
285 | png_warning(png_ptr, "Insufficient memory for pCAL units"); |
320 | png_warning(png_ptr, "Insufficient memory for pCAL units"); |
286 | return; |
321 | return; |
287 | } |
322 | } |
288 | 323 | ||
Line 289... | Line 324... | ||
289 | png_memcpy(info_ptr->pcal_units, units, length); |
324 | memcpy(info_ptr->pcal_units, units, length); |
Line 312... | Line 347... | ||
312 | png_warning(png_ptr, "Insufficient memory for pCAL parameter"); |
347 | png_warning(png_ptr, "Insufficient memory for pCAL parameter"); |
313 | return; |
348 | return; |
314 | } |
349 | } |
315 | 350 | ||
Line 316... | Line 351... | ||
316 | png_memcpy(info_ptr->pcal_params[i], params[i], length); |
351 | memcpy(info_ptr->pcal_params[i], params[i], length); |
317 | } |
352 | } |
Line 318... | Line 353... | ||
318 | 353 | ||
319 | info_ptr->valid |= PNG_INFO_pCAL; |
354 | info_ptr->valid |= PNG_INFO_pCAL; |
320 | info_ptr->free_me |= PNG_FREE_PCAL; |
355 | info_ptr->free_me |= PNG_FREE_PCAL; |
321 | } |
356 | } |
Line 322... | Line 357... | ||
322 | #endif |
357 | #endif |
323 | 358 | ||
324 | #ifdef PNG_sCAL_SUPPORTED |
359 | #ifdef PNG_sCAL_SUPPORTED |
325 | void PNGAPI |
360 | void PNGAPI |
326 | png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, |
361 | png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, |
327 | int unit, png_const_charp swidth, png_const_charp sheight) |
362 | int unit, png_const_charp swidth, png_const_charp sheight) |
Line 328... | Line 363... | ||
328 | { |
363 | { |
Line 338... | Line 373... | ||
338 | */ |
373 | */ |
339 | if (unit != 1 && unit != 2) |
374 | if (unit != 1 && unit != 2) |
340 | png_error(png_ptr, "Invalid sCAL unit"); |
375 | png_error(png_ptr, "Invalid sCAL unit"); |
341 | 376 | ||
Line 342... | Line 377... | ||
342 | if (swidth == NULL || (lengthw = png_strlen(swidth)) <= 0 || |
377 | if (swidth == NULL || (lengthw = strlen(swidth)) == 0 || |
343 | swidth[0] == 45 /*'-'*/ || !png_check_fp_string(swidth, lengthw)) |
378 | swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) |
344 | png_error(png_ptr, "Invalid sCAL width"); |
379 | png_error(png_ptr, "Invalid sCAL width"); |
Line 345... | Line 380... | ||
345 | 380 | ||
346 | if (sheight == NULL || (lengthh = png_strlen(sheight)) <= 0 || |
381 | if (sheight == NULL || (lengthh = strlen(sheight)) == 0 || |
347 | sheight[0] == 45 /*'-'*/ || !png_check_fp_string(sheight, lengthh)) |
382 | sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) |
Line 348... | Line 383... | ||
348 | png_error(png_ptr, "Invalid sCAL height"); |
383 | png_error(png_ptr, "Invalid sCAL height"); |
Line 349... | Line 384... | ||
349 | 384 | ||
Line 350... | Line 385... | ||
350 | info_ptr->scal_unit = (png_byte)unit; |
385 | info_ptr->scal_unit = (png_byte)unit; |
Line 351... | Line 386... | ||
351 | 386 | ||
- | 387 | ++lengthw; |
|
Line 352... | Line 388... | ||
352 | ++lengthw; |
388 | |
353 | 389 | png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); |
|
354 | png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); |
390 | |
355 | 391 | info_ptr->scal_s_width = png_voidcast(png_charp, |
|
356 | info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw); |
392 | png_malloc_warn(png_ptr, lengthw)); |
Line 357... | Line 393... | ||
357 | 393 | ||
Line 358... | Line 394... | ||
358 | if (info_ptr->scal_s_width == NULL) |
394 | if (info_ptr->scal_s_width == NULL) |
Line 359... | Line 395... | ||
359 | { |
395 | { |
Line 360... | Line 396... | ||
360 | png_warning(png_ptr, "Memory allocation failed while processing sCAL"); |
396 | png_warning(png_ptr, "Memory allocation failed while processing sCAL"); |
- | 397 | return; |
|
Line 361... | Line 398... | ||
361 | return; |
398 | } |
362 | } |
399 | |
363 | 400 | memcpy(info_ptr->scal_s_width, swidth, lengthw); |
|
364 | png_memcpy(info_ptr->scal_s_width, swidth, lengthw); |
401 | |
Line 365... | Line 402... | ||
365 | 402 | ++lengthh; |
|
366 | ++lengthh; |
403 | |
367 | 404 | png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); |
|
Line 368... | Line 405... | ||
368 | png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); |
405 | |
Line 369... | Line 406... | ||
369 | 406 | info_ptr->scal_s_height = png_voidcast(png_charp, |
|
370 | info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh); |
407 | png_malloc_warn(png_ptr, lengthh)); |
371 | 408 | ||
Line 372... | Line 409... | ||
372 | if (info_ptr->scal_s_height == NULL) |
409 | if (info_ptr->scal_s_height == NULL) |
373 | { |
410 | { |
374 | png_free (png_ptr, info_ptr->scal_s_width); |
411 | png_free (png_ptr, info_ptr->scal_s_width); |
375 | info_ptr->scal_s_width = NULL; |
412 | info_ptr->scal_s_width = NULL; |
376 | 413 | ||
377 | png_warning(png_ptr, "Memory allocation failed while processing sCAL"); |
414 | png_warning(png_ptr, "Memory allocation failed while processing sCAL"); |
Line 378... | Line 415... | ||
378 | return; |
415 | return; |
379 | } |
416 | } |
Line 403... | Line 440... | ||
403 | /* Convert 'width' and 'height' to ASCII. */ |
440 | /* Convert 'width' and 'height' to ASCII. */ |
404 | char swidth[PNG_sCAL_MAX_DIGITS+1]; |
441 | char swidth[PNG_sCAL_MAX_DIGITS+1]; |
405 | char sheight[PNG_sCAL_MAX_DIGITS+1]; |
442 | char sheight[PNG_sCAL_MAX_DIGITS+1]; |
406 | 443 | ||
Line 407... | Line 444... | ||
407 | png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width, |
444 | png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, |
408 | PNG_sCAL_PRECISION); |
445 | PNG_sCAL_PRECISION); |
409 | png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height, |
446 | png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height, |
410 | PNG_sCAL_PRECISION); |
447 | PNG_sCAL_PRECISION); |
Line 411... | Line 448... | ||
411 | 448 | ||
412 | png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); |
449 | png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); |
413 | } |
450 | } |
414 | } |
451 | } |
Line 415... | Line 452... | ||
415 | # endif |
452 | # endif |
416 | 453 | ||
417 | # ifdef PNG_FIXED_POINT_SUPPORTED |
454 | # ifdef PNG_FIXED_POINT_SUPPORTED |
418 | void PNGAPI |
455 | void PNGAPI |
419 | png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, |
456 | png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit, |
420 | png_fixed_point width, png_fixed_point height) |
457 | png_fixed_point width, png_fixed_point height) |
Line 421... | Line 458... | ||
421 | { |
458 | { |
Line 433... | Line 470... | ||
433 | /* Convert 'width' and 'height' to ASCII. */ |
470 | /* Convert 'width' and 'height' to ASCII. */ |
434 | char swidth[PNG_sCAL_MAX_DIGITS+1]; |
471 | char swidth[PNG_sCAL_MAX_DIGITS+1]; |
435 | char sheight[PNG_sCAL_MAX_DIGITS+1]; |
472 | char sheight[PNG_sCAL_MAX_DIGITS+1]; |
436 | 473 | ||
Line 437... | Line 474... | ||
437 | png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width); |
474 | png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width); |
438 | png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height); |
475 | png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height); |
Line 439... | Line 476... | ||
439 | 476 | ||
440 | png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); |
477 | png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); |
441 | } |
478 | } |
442 | } |
479 | } |
443 | # endif |
480 | # endif |
Line 444... | Line 481... | ||
444 | #endif |
481 | #endif |
445 | 482 | ||
446 | #ifdef PNG_pHYs_SUPPORTED |
483 | #ifdef PNG_pHYs_SUPPORTED |
447 | void PNGAPI |
484 | void PNGAPI |
448 | png_set_pHYs(png_structp png_ptr, png_infop info_ptr, |
485 | png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr, |
449 | png_uint_32 res_x, png_uint_32 res_y, int unit_type) |
486 | png_uint_32 res_x, png_uint_32 res_y, int unit_type) |
Line 450... | Line 487... | ||
450 | { |
487 | { |
Line 460... | Line 497... | ||
460 | } |
497 | } |
461 | #endif |
498 | #endif |
462 | 499 | ||
Line 463... | Line 500... | ||
463 | void PNGAPI |
500 | void PNGAPI |
464 | png_set_PLTE(png_structp png_ptr, png_infop info_ptr, |
501 | png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, |
465 | png_const_colorp palette, int num_palette) |
502 | png_const_colorp palette, int num_palette) |
466 | { |
503 | { |
Line 467... | Line 504... | ||
467 | 504 | ||
Line 481... | Line 518... | ||
481 | return; |
518 | return; |
482 | } |
519 | } |
483 | } |
520 | } |
484 | 521 | ||
Line -... | Line 522... | ||
- | 522 | if ((num_palette > 0 && palette == NULL) || |
|
- | 523 | (num_palette == 0 |
|
- | 524 | # ifdef PNG_MNG_FEATURES_SUPPORTED |
|
- | 525 | && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 |
|
- | 526 | # endif |
|
- | 527 | )) |
|
- | 528 | { |
|
- | 529 | png_chunk_report(png_ptr, "Invalid palette", PNG_CHUNK_ERROR); |
|
- | 530 | return; |
|
- | 531 | } |
|
- | 532 | ||
485 | /* It may not actually be necessary to set png_ptr->palette here; |
533 | /* It may not actually be necessary to set png_ptr->palette here; |
486 | * we do it for backward compatibility with the way the png_handle_tRNS |
534 | * we do it for backward compatibility with the way the png_handle_tRNS |
487 | * function used to do the allocation. |
535 | * function used to do the allocation. |
- | 536 | * |
|
- | 537 | * 1.6.0: the above statement appears to be incorrect; something has to set |
|
- | 538 | * the palette inside png_struct on read. |
|
488 | */ |
539 | */ |
489 | png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); |
540 | png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); |
Line 490... | Line 541... | ||
490 | 541 | ||
491 | /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead |
542 | /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead |
492 | * of num_palette entries, in case of an invalid PNG file that has |
543 | * of num_palette entries, in case of an invalid PNG file that has |
493 | * too-large sample values. |
544 | * too-large sample values. |
494 | */ |
545 | */ |
495 | png_ptr->palette = (png_colorp)png_calloc(png_ptr, |
546 | png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, |
Line -... | Line 547... | ||
- | 547 | PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); |
|
496 | PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); |
548 | |
497 | 549 | if (num_palette > 0) |
|
498 | png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color)); |
550 | memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color))); |
Line 499... | Line 551... | ||
499 | info_ptr->palette = png_ptr->palette; |
551 | info_ptr->palette = png_ptr->palette; |
Line 500... | Line 552... | ||
500 | info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; |
552 | info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; |
501 | 553 | ||
Line 502... | Line 554... | ||
502 | info_ptr->free_me |= PNG_FREE_PLTE; |
554 | info_ptr->free_me |= PNG_FREE_PLTE; |
503 | 555 | ||
504 | info_ptr->valid |= PNG_INFO_PLTE; |
556 | info_ptr->valid |= PNG_INFO_PLTE; |
505 | } |
557 | } |
506 | 558 | ||
507 | #ifdef PNG_sBIT_SUPPORTED |
559 | #ifdef PNG_sBIT_SUPPORTED |
Line 508... | Line 560... | ||
508 | void PNGAPI |
560 | void PNGAPI |
509 | png_set_sBIT(png_structp png_ptr, png_infop info_ptr, |
561 | png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, |
Line 510... | Line 562... | ||
510 | png_const_color_8p sig_bit) |
562 | png_const_color_8p sig_bit) |
511 | { |
563 | { |
512 | png_debug1(1, "in %s storage function", "sBIT"); |
564 | png_debug1(1, "in %s storage function", "sBIT"); |
513 | 565 | ||
Line 514... | Line 566... | ||
514 | if (png_ptr == NULL || info_ptr == NULL) |
566 | if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL) |
515 | return; |
567 | return; |
516 | 568 | ||
517 | png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8)); |
569 | info_ptr->sig_bit = *sig_bit; |
518 | info_ptr->valid |= PNG_INFO_sBIT; |
570 | info_ptr->valid |= PNG_INFO_sBIT; |
Line 519... | Line 571... | ||
519 | } |
571 | } |
520 | #endif |
572 | #endif |
Line 521... | Line 573... | ||
521 | 573 | ||
522 | #ifdef PNG_sRGB_SUPPORTED |
574 | #ifdef PNG_sRGB_SUPPORTED |
523 | void PNGAPI |
575 | void PNGAPI |
Line 524... | Line 576... | ||
524 | png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent) |
576 | png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) |
525 | { |
577 | { |
526 | png_debug1(1, "in %s storage function", "sRGB"); |
578 | png_debug1(1, "in %s storage function", "sRGB"); |
527 | 579 | ||
528 | if (png_ptr == NULL || info_ptr == NULL) |
580 | if (png_ptr == NULL || info_ptr == NULL) |
Line 529... | Line 581... | ||
529 | return; |
581 | return; |
530 | 582 | ||
Line 531... | Line 583... | ||
531 | info_ptr->srgb_intent = (png_byte)srgb_intent; |
583 | (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent); |
532 | info_ptr->valid |= PNG_INFO_sRGB; |
584 | png_colorspace_sync_info(png_ptr, info_ptr); |
- | 585 | } |
|
533 | } |
586 | |
534 | 587 | void PNGAPI |
|
535 | void PNGAPI |
588 | png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, |
Line 536... | Line -... | ||
536 | png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, |
- | |
537 | int srgb_intent) |
589 | int srgb_intent) |
538 | { |
- | |
539 | png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); |
- | |
540 | - | ||
541 | if (png_ptr == NULL || info_ptr == NULL) |
- | |
542 | return; |
- | |
543 | - | ||
544 | png_set_sRGB(png_ptr, info_ptr, srgb_intent); |
- | |
545 | 590 | { |
|
546 | # ifdef PNG_gAMA_SUPPORTED |
591 | png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); |
Line 547... | Line 592... | ||
547 | png_set_gAMA_fixed(png_ptr, info_ptr, 45455L); |
592 | |
548 | # endif |
593 | if (png_ptr == NULL || info_ptr == NULL) |
549 | 594 | return; |
|
550 | # ifdef PNG_cHRM_SUPPORTED |
595 | |
551 | png_set_cHRM_fixed(png_ptr, info_ptr, |
596 | if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent)) |
552 | /* color x y */ |
597 | { |
553 | /* white */ 31270L, 32900L, |
598 | /* This causes the gAMA and cHRM to be written too */ |
554 | /* red */ 64000L, 33000L, |
599 | info_ptr->colorspace.flags |= |
555 | /* green */ 30000L, 60000L, |
600 | PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; |
Line 556... | Line 601... | ||
556 | /* blue */ 15000L, 6000L |
601 | } |
Line 557... | Line 602... | ||
557 | ); |
602 | |
558 | # endif /* cHRM */ |
603 | png_colorspace_sync_info(png_ptr, info_ptr); |
Line -... | Line 604... | ||
- | 604 | } |
|
- | 605 | #endif /* sRGB */ |
|
- | 606 | ||
- | 607 | ||
- | 608 | #ifdef PNG_iCCP_SUPPORTED |
|
- | 609 | void PNGAPI |
|
- | 610 | png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, |
|
- | 611 | png_const_charp name, int compression_type, |
|
- | 612 | png_const_bytep profile, png_uint_32 proflen) |
|
- | 613 | { |
|
- | 614 | png_charp new_iccp_name; |
|
- | 615 | png_bytep new_iccp_profile; |
|
- | 616 | png_size_t length; |
|
- | 617 | ||
- | 618 | png_debug1(1, "in %s storage function", "iCCP"); |
|
- | 619 | ||
- | 620 | if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) |
|
- | 621 | return; |
|
- | 622 | ||
- | 623 | if (compression_type != PNG_COMPRESSION_TYPE_BASE) |
|
- | 624 | png_app_error(png_ptr, "Invalid iCCP compression method"); |
|
- | 625 | ||
- | 626 | /* Set the colorspace first because this validates the profile; do not |
|
- | 627 | * override previously set app cHRM or gAMA here (because likely as not the |
|
559 | } |
628 | * application knows better than libpng what the correct values are.) Pass |
560 | #endif /* sRGB */ |
629 | * the info_ptr color_type field to png_colorspace_set_ICC because in the |
Line 561... | Line 630... | ||
561 | 630 | * write case it has not yet been stored in png_ptr. |
|
562 | 631 | */ |
|
563 | #ifdef PNG_iCCP_SUPPORTED |
632 | { |
564 | void PNGAPI |
633 | int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, |
565 | png_set_iCCP(png_structp png_ptr, png_infop info_ptr, |
634 | proflen, profile, info_ptr->color_type); |
Line 566... | Line 635... | ||
566 | png_const_charp name, int compression_type, |
635 | |
- | 636 | png_colorspace_sync_info(png_ptr, info_ptr); |
|
567 | png_const_bytep profile, png_uint_32 proflen) |
637 | |
Line 568... | Line 638... | ||
568 | { |
638 | /* Don't do any of the copying if the profile was bad, or inconsistent. */ |
569 | png_charp new_iccp_name; |
639 | if (!result) |
570 | png_bytep new_iccp_profile; |
640 | return; |
571 | png_uint_32 length; |
641 | |
572 | 642 | /* But do write the gAMA and cHRM chunks from the profile. */ |
|
573 | png_debug1(1, "in %s storage function", "iCCP"); |
643 | info_ptr->colorspace.flags |= |
574 | 644 | PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; |
|
Line 575... | Line 645... | ||
575 | if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) |
645 | } |
Line 576... | Line 646... | ||
576 | return; |
646 | |
Line 577... | Line 647... | ||
577 | 647 | length = strlen(name)+1; |
|
578 | length = png_strlen(name)+1; |
648 | new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length)); |
579 | new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); |
649 | |
580 | - | ||
581 | if (new_iccp_name == NULL) |
- | |
582 | { |
- | |
583 | png_warning(png_ptr, "Insufficient memory to process iCCP chunk"); |
- | |
584 | return; |
650 | if (new_iccp_name == NULL) |
585 | } |
651 | { |
586 | 652 | png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk"); |
|
587 | png_memcpy(new_iccp_name, name, length); |
653 | return; |
Line 588... | Line 654... | ||
588 | new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen); |
654 | } |
589 | 655 | ||
590 | if (new_iccp_profile == NULL) |
656 | memcpy(new_iccp_name, name, length); |
591 | { |
657 | new_iccp_profile = png_voidcast(png_bytep, |
592 | png_free (png_ptr, new_iccp_name); |
658 | png_malloc_warn(png_ptr, proflen)); |
593 | png_warning(png_ptr, |
659 | |
594 | "Insufficient memory to process iCCP profile"); |
660 | if (new_iccp_profile == NULL) |
Line 595... | Line 661... | ||
595 | return; |
661 | { |
596 | } |
662 | png_free(png_ptr, new_iccp_name); |
597 | 663 | png_benign_error(png_ptr, |
|
Line 598... | Line 664... | ||
598 | png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); |
664 | "Insufficient memory to process iCCP profile"); |
599 | 665 | return; |
|
600 | png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); |
666 | } |
601 | 667 | ||
602 | info_ptr->iccp_proflen = proflen; |
668 | memcpy(new_iccp_profile, profile, proflen); |
Line 603... | Line 669... | ||
603 | info_ptr->iccp_name = new_iccp_name; |
669 | |
604 | info_ptr->iccp_profile = new_iccp_profile; |
- | |
605 | /* Compression is always zero but is here so the API and info structure |
670 | png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); |
Line 606... | Line 671... | ||
606 | * does not have to change if we introduce multiple compression types |
671 | |
607 | */ |
672 | info_ptr->iccp_proflen = proflen; |
Line 608... | Line 673... | ||
608 | info_ptr->iccp_compression = (png_byte)compression_type; |
673 | info_ptr->iccp_name = new_iccp_name; |
609 | info_ptr->free_me |= PNG_FREE_ICCP; |
674 | info_ptr->iccp_profile = new_iccp_profile; |
- | 675 | info_ptr->free_me |= PNG_FREE_ICCP; |
|
- | 676 | info_ptr->valid |= PNG_INFO_iCCP; |
|
610 | info_ptr->valid |= PNG_INFO_iCCP; |
677 | } |
611 | } |
678 | #endif |
612 | #endif |
679 | |
- | 680 | #ifdef PNG_TEXT_SUPPORTED |
|
- | 681 | void PNGAPI |
|
613 | 682 | png_set_text(png_const_structrp png_ptr, png_inforp info_ptr, |
|
- | 683 | png_const_textp text_ptr, int num_text) |
|
- | 684 | { |
|
- | 685 | int ret; |
|
- | 686 | ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); |
|
614 | #ifdef PNG_TEXT_SUPPORTED |
687 | |
615 | void PNGAPI |
688 | if (ret) |
616 | png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr, |
- | |
Line 617... | Line 689... | ||
617 | int num_text) |
689 | png_error(png_ptr, "Insufficient memory to store text"); |
618 | { |
- | |
619 | int ret; |
690 | } |
620 | ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); |
691 | |
621 | - | ||
Line 622... | Line -... | ||
622 | if (ret) |
- | |
623 | png_error(png_ptr, "Insufficient memory to store text"); |
692 | int /* PRIVATE */ |
624 | } |
- | |
625 | 693 | png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, |
|
626 | int /* PRIVATE */ |
- | |
Line 627... | Line 694... | ||
627 | png_set_text_2(png_structp png_ptr, png_infop info_ptr, |
694 | png_const_textp text_ptr, int num_text) |
628 | png_const_textp text_ptr, int num_text) |
695 | { |
- | 696 | int i; |
|
- | 697 | ||
- | 698 | png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" : |
|
629 | { |
699 | (unsigned long)png_ptr->chunk_name); |
630 | int i; |
700 | |
Line 631... | Line 701... | ||
631 | 701 | if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) |
|
632 | png_debug1(1, "in %s storage function", ((png_ptr == NULL || |
702 | return(0); |
633 | png_ptr->chunk_name[0] == '\0') ? |
- | |
634 | "text" : (png_const_charp)png_ptr->chunk_name)); |
- | |
635 | 703 | ||
636 | if (png_ptr == NULL || info_ptr == NULL || num_text == 0) |
- | |
637 | return(0); |
704 | /* Make sure we have enough space in the "text" array in info_struct |
638 | 705 | * to hold all of the incoming text_ptr objects. This compare can't overflow |
|
639 | /* Make sure we have enough space in the "text" array in info_struct |
- | |
640 | * to hold all of the incoming text_ptr objects. |
706 | * because max_text >= num_text (anyway, subtract of two positive integers |
Line 641... | Line 707... | ||
641 | */ |
707 | * can't overflow in any case.) |
- | 708 | */ |
|
642 | if (info_ptr->num_text + num_text > info_ptr->max_text) |
709 | if (num_text > info_ptr->max_text - info_ptr->num_text) |
- | 710 | { |
|
- | 711 | int old_num_text = info_ptr->num_text; |
|
- | 712 | int max_text; |
|
- | 713 | png_textp new_text = NULL; |
|
- | 714 | ||
643 | { |
715 | /* Calculate an appropriate max_text, checking for overflow. */ |
- | 716 | max_text = old_num_text; |
|
644 | if (info_ptr->text != NULL) |
717 | if (num_text <= INT_MAX - max_text) |
645 | { |
718 | { |
646 | png_textp old_text; |
719 | max_text += num_text; |
647 | int old_max; |
720 | |
648 | 721 | /* Round up to a multiple of 8 */ |
|
Line 649... | Line 722... | ||
649 | old_max = info_ptr->max_text; |
722 | if (max_text < INT_MAX-8) |
650 | info_ptr->max_text = info_ptr->num_text + num_text + 8; |
723 | max_text = (max_text + 8) & ~0x7; |
Line 651... | Line 724... | ||
651 | old_text = info_ptr->text; |
724 | |
652 | info_ptr->text = (png_textp)png_malloc_warn(png_ptr, |
725 | else |
653 | (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); |
726 | max_text = INT_MAX; |
654 | 727 | ||
- | 728 | /* Now allocate a new array and copy the old members in, this does all |
|
655 | if (info_ptr->text == NULL) |
729 | * the overflow checks. |
656 | { |
730 | */ |
Line 657... | Line 731... | ||
657 | png_free(png_ptr, old_text); |
731 | new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, |
Line 658... | Line 732... | ||
658 | return(1); |
732 | info_ptr->text, old_num_text, max_text-old_num_text, |
659 | } |
733 | sizeof *new_text)); |
660 | 734 | } |
|
661 | png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * |
735 | |
Line 706... | Line 780... | ||
706 | { |
780 | { |
707 | /* Set iTXt data */ |
781 | /* Set iTXt data */ |
708 | 782 | ||
Line 709... | Line 783... | ||
709 | if (text_ptr[i].lang != NULL) |
783 | if (text_ptr[i].lang != NULL) |
710 | lang_len = png_strlen(text_ptr[i].lang); |
784 | lang_len = strlen(text_ptr[i].lang); |
Line 711... | Line 785... | ||
711 | 785 | ||
712 | else |
786 | else |
Line 713... | Line 787... | ||
713 | lang_len = 0; |
787 | lang_len = 0; |
714 | 788 | ||
Line 715... | Line 789... | ||
715 | if (text_ptr[i].lang_key != NULL) |
789 | if (text_ptr[i].lang_key != NULL) |
716 | lang_key_len = png_strlen(text_ptr[i].lang_key); |
790 | lang_key_len = strlen(text_ptr[i].lang_key); |
717 | 791 | ||
718 | else |
792 | else |
719 | lang_key_len = 0; |
793 | lang_key_len = 0; |
720 | } |
794 | } |
- | 795 | # else /* PNG_iTXt_SUPPORTED */ |
|
721 | # else /* PNG_iTXt_SUPPORTED */ |
796 | { |
722 | { |
797 | png_chunk_report(png_ptr, "iTXt chunk not supported", |
723 | png_warning(png_ptr, "iTXt chunk not supported"); |
798 | PNG_CHUNK_WRITE_ERROR); |
Line 724... | Line 799... | ||
724 | continue; |
799 | continue; |
Line 738... | Line 813... | ||
738 | } |
813 | } |
739 | 814 | ||
Line 740... | Line 815... | ||
740 | else |
815 | else |
741 | { |
816 | { |
742 | text_length = png_strlen(text_ptr[i].text); |
817 | text_length = strlen(text_ptr[i].text); |
743 | textp->compression = text_ptr[i].compression; |
818 | textp->compression = text_ptr[i].compression; |
744 | } |
819 | } |
Line 745... | Line 820... | ||
745 | 820 | ||
746 | textp->key = (png_charp)png_malloc_warn(png_ptr, |
- | |
747 | (png_size_t) |
821 | textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr, |
Line 748... | Line 822... | ||
748 | (key_len + text_length + lang_len + lang_key_len + 4)); |
822 | key_len + text_length + lang_len + lang_key_len + 4)); |
- | 823 | ||
- | 824 | if (textp->key == NULL) |
|
- | 825 | { |
|
749 | 826 | png_chunk_report(png_ptr, "text chunk: out of memory", |
|
- | 827 | PNG_CHUNK_WRITE_ERROR); |
|
Line 750... | Line 828... | ||
750 | if (textp->key == NULL) |
828 | return 1; |
751 | return(1); |
829 | } |
752 | 830 | ||
753 | png_debug2(2, "Allocated %lu bytes at %p in png_set_text", |
831 | png_debug2(2, "Allocated %lu bytes at %p in png_set_text", |
Line 754... | Line 832... | ||
754 | (unsigned long)(png_uint_32) |
832 | (unsigned long)(png_uint_32) |
755 | (key_len + lang_len + lang_key_len + text_length + 4), |
833 | (key_len + lang_len + lang_key_len + text_length + 4), |
Line 756... | Line 834... | ||
756 | textp->key); |
834 | textp->key); |
757 | 835 | ||
758 | png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); |
836 | memcpy(textp->key, text_ptr[i].key, key_len); |
759 | *(textp->key + key_len) = '\0'; |
837 | *(textp->key + key_len) = '\0'; |
760 | 838 | ||
761 | if (text_ptr[i].compression > 0) |
839 | if (text_ptr[i].compression > 0) |
762 | { |
840 | { |
763 | textp->lang = textp->key + key_len + 1; |
841 | textp->lang = textp->key + key_len + 1; |
764 | png_memcpy(textp->lang, text_ptr[i].lang, lang_len); |
842 | memcpy(textp->lang, text_ptr[i].lang, lang_len); |
765 | *(textp->lang + lang_len) = '\0'; |
843 | *(textp->lang + lang_len) = '\0'; |
Line 766... | Line 844... | ||
766 | textp->lang_key = textp->lang + lang_len + 1; |
844 | textp->lang_key = textp->lang + lang_len + 1; |
Line 776... | Line 854... | ||
776 | textp->text = textp->key + key_len + 1; |
854 | textp->text = textp->key + key_len + 1; |
777 | } |
855 | } |
778 | 856 | ||
Line 779... | Line 857... | ||
779 | if (text_length) |
857 | if (text_length) |
780 | png_memcpy(textp->text, text_ptr[i].text, |
858 | memcpy(textp->text, text_ptr[i].text, text_length); |
781 | (png_size_t)(text_length)); |
- | |
Line 782... | Line 859... | ||
782 | 859 | ||
Line 783... | Line 860... | ||
783 | *(textp->text + text_length) = '\0'; |
860 | *(textp->text + text_length) = '\0'; |
784 | 861 | ||
Line 798... | Line 875... | ||
798 | 875 | ||
Line 799... | Line 876... | ||
799 | info_ptr->num_text++; |
876 | info_ptr->num_text++; |
800 | png_debug1(3, "transferred text chunk %d", info_ptr->num_text); |
877 | png_debug1(3, "transferred text chunk %d", info_ptr->num_text); |
801 | } |
878 | } |
- | 879 | ||
802 | return(0); |
880 | return(0); |
803 | } |
881 | } |
804 | #endif |
882 | #endif |
Line 805... | Line 883... | ||
805 | 883 | ||
806 | #ifdef PNG_tIME_SUPPORTED |
884 | #ifdef PNG_tIME_SUPPORTED |
807 | void PNGAPI |
885 | void PNGAPI |
- | 886 | png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr, |
|
808 | png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time) |
887 | png_const_timep mod_time) |
809 | { |
888 | { |
Line 810... | Line 889... | ||
810 | png_debug1(1, "in %s storage function", "tIME"); |
889 | png_debug1(1, "in %s storage function", "tIME"); |
811 | 890 | ||
812 | if (png_ptr == NULL || info_ptr == NULL || |
891 | if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL || |
Line -... | Line 892... | ||
- | 892 | (png_ptr->mode & PNG_WROTE_tIME)) |
|
- | 893 | return; |
|
- | 894 | ||
- | 895 | if (mod_time->month == 0 || mod_time->month > 12 || |
|
- | 896 | mod_time->day == 0 || mod_time->day > 31 || |
|
- | 897 | mod_time->hour > 23 || mod_time->minute > 59 || |
|
- | 898 | mod_time->second > 60) |
|
- | 899 | { |
|
- | 900 | png_warning(png_ptr, "Ignoring invalid time value"); |
|
813 | (png_ptr->mode & PNG_WROTE_tIME)) |
901 | return; |
814 | return; |
902 | } |
815 | 903 | ||
816 | png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time)); |
904 | info_ptr->mod_time = *mod_time; |
Line 817... | Line 905... | ||
817 | info_ptr->valid |= PNG_INFO_tIME; |
905 | info_ptr->valid |= PNG_INFO_tIME; |
818 | } |
906 | } |
819 | #endif |
907 | #endif |
820 | 908 | ||
821 | #ifdef PNG_tRNS_SUPPORTED |
909 | #ifdef PNG_tRNS_SUPPORTED |
822 | void PNGAPI |
910 | void PNGAPI |
Line 823... | Line 911... | ||
823 | png_set_tRNS(png_structp png_ptr, png_infop info_ptr, |
911 | png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, |
Line 832... | Line 920... | ||
832 | { |
920 | { |
833 | /* It may not actually be necessary to set png_ptr->trans_alpha here; |
921 | /* It may not actually be necessary to set png_ptr->trans_alpha here; |
834 | * we do it for backward compatibility with the way the png_handle_tRNS |
922 | * we do it for backward compatibility with the way the png_handle_tRNS |
835 | * function used to do the allocation. |
923 | * function used to do the allocation. |
836 | */ |
924 | * |
- | 925 | * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively |
|
- | 926 | * relies on png_set_tRNS storing the information in png_struct |
|
- | 927 | * (otherwise it won't be there for the code in pngrtran.c). |
|
- | 928 | */ |
|
837 | 929 | ||
Line 838... | Line 930... | ||
838 | png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); |
930 | png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); |
Line 839... | Line 931... | ||
839 | 931 | ||
840 | /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ |
932 | /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ |
841 | png_ptr->trans_alpha = info_ptr->trans_alpha = |
933 | png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep, |
Line 842... | Line 934... | ||
842 | (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH); |
934 | png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); |
843 | 935 | ||
844 | if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) |
936 | if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) |
Line 845... | Line 937... | ||
845 | png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); |
937 | memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); |
846 | } |
938 | } |
847 | 939 | ||
Line 848... | Line 940... | ||
848 | if (trans_color != NULL) |
940 | if (trans_color != NULL) |
849 | { |
941 | { |
850 | int sample_max = (1 << info_ptr->bit_depth); |
942 | int sample_max = (1 << info_ptr->bit_depth); |
851 | 943 | ||
852 | if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && |
944 | if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && |
853 | (int)trans_color->gray > sample_max) || |
945 | trans_color->gray > sample_max) || |
854 | (info_ptr->color_type == PNG_COLOR_TYPE_RGB && |
946 | (info_ptr->color_type == PNG_COLOR_TYPE_RGB && |
855 | ((int)trans_color->red > sample_max || |
947 | (trans_color->red > sample_max || |
Line 856... | Line 948... | ||
856 | (int)trans_color->green > sample_max || |
948 | trans_color->green > sample_max || |
857 | (int)trans_color->blue > sample_max))) |
- | |
Line 858... | Line 949... | ||
858 | png_warning(png_ptr, |
949 | trans_color->blue > sample_max))) |
859 | "tRNS chunk has out-of-range samples for bit_depth"); |
950 | png_warning(png_ptr, |
860 | 951 | "tRNS chunk has out-of-range samples for bit_depth"); |
|
Line 876... | Line 967... | ||
876 | #endif |
967 | #endif |
877 | 968 | ||
Line 878... | Line 969... | ||
878 | #ifdef PNG_sPLT_SUPPORTED |
969 | #ifdef PNG_sPLT_SUPPORTED |
879 | void PNGAPI |
970 | void PNGAPI |
880 | png_set_sPLT(png_structp png_ptr, |
971 | png_set_sPLT(png_const_structrp png_ptr, |
881 | png_infop info_ptr, png_const_sPLT_tp entries, int nentries) |
972 | png_inforp info_ptr, png_const_sPLT_tp entries, int nentries) |
882 | /* |
973 | /* |
883 | * entries - array of png_sPLT_t structures |
974 | * entries - array of png_sPLT_t structures |
884 | * to be added to the list of palettes |
975 | * to be added to the list of palettes |
885 | * in the info structure. |
976 | * in the info structure. |
886 | * |
977 | * |
887 | * nentries - number of palette structures to be |
978 | * nentries - number of palette structures to be |
888 | * added. |
979 | * added. |
889 | */ |
980 | */ |
890 | { |
981 | { |
891 | png_sPLT_tp np; |
982 | png_sPLT_tp np; |
892 | int i; |
- | |
Line 893... | Line 983... | ||
893 | 983 | ||
894 | if (png_ptr == NULL || info_ptr == NULL) |
984 | if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) |
Line -... | Line 985... | ||
- | 985 | return; |
|
- | 986 | ||
- | 987 | /* Use the internal realloc function, which checks for all the possible |
|
895 | return; |
988 | * overflows. Notice that the parameters are (int) and (size_t) |
896 | 989 | */ |
|
897 | np = (png_sPLT_tp)png_malloc_warn(png_ptr, |
990 | np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, |
Line 898... | Line 991... | ||
898 | (info_ptr->splt_palettes_num + nentries) * |
991 | info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, |
899 | (png_size_t)png_sizeof(png_sPLT_t)); |
992 | sizeof *np)); |
- | 993 | ||
900 | 994 | if (np == NULL) |
|
901 | if (np == NULL) |
995 | { |
902 | { |
996 | /* Out of memory or too many chunks */ |
Line 903... | Line -... | ||
903 | png_warning(png_ptr, "No memory for sPLT palettes"); |
- | |
904 | return; |
- | |
905 | } |
- | |
906 | 997 | png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); |
|
907 | png_memcpy(np, info_ptr->splt_palettes, |
998 | return; |
- | 999 | } |
|
Line 908... | Line -... | ||
908 | info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); |
- | |
909 | - | ||
910 | png_free(png_ptr, info_ptr->splt_palettes); |
1000 | |
911 | info_ptr->splt_palettes=NULL; |
- | |
912 | - | ||
Line -... | Line 1001... | ||
- | 1001 | png_free(png_ptr, info_ptr->splt_palettes); |
|
- | 1002 | info_ptr->splt_palettes = np; |
|
913 | for (i = 0; i < nentries; i++) |
1003 | info_ptr->free_me |= PNG_FREE_SPLT; |
914 | { |
- | |
Line -... | Line 1004... | ||
- | 1004 | ||
915 | png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; |
1005 | np += info_ptr->splt_palettes_num; |
916 | png_const_sPLT_tp from = entries + i; |
1006 | |
- | 1007 | do |
|
917 | png_uint_32 length; |
1008 | { |
918 | 1009 | png_size_t length; |
|
919 | length = png_strlen(from->name) + 1; |
1010 | |
920 | to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length); |
1011 | /* Skip invalid input entries */ |
Line -... | Line 1012... | ||
- | 1012 | if (entries->name == NULL || entries->entries == NULL) |
|
- | 1013 | { |
|
- | 1014 | /* png_handle_sPLT doesn't do this, so this is an app error */ |
|
- | 1015 | png_app_error(png_ptr, "png_set_sPLT: invalid sPLT"); |
|
- | 1016 | /* Just skip the invalid entry */ |
|
- | 1017 | continue; |
|
- | 1018 | } |
|
- | 1019 | ||
- | 1020 | np->depth = entries->depth; |
|
- | 1021 | ||
- | 1022 | /* In the even of out-of-memory just return - there's no point keeping on |
|
921 | 1023 | * trying to add sPLT chunks. |
|
- | 1024 | */ |
|
- | 1025 | length = strlen(entries->name) + 1; |
|
- | 1026 | np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length)); |
|
- | 1027 | ||
- | 1028 | if (np->name == NULL) |
|
922 | if (to->name == NULL) |
1029 | break; |
923 | { |
1030 | |
Line 924... | Line 1031... | ||
924 | png_warning(png_ptr, |
1031 | memcpy(np->name, entries->name, length); |
925 | "Out of memory while processing sPLT chunk"); |
1032 | |
926 | continue; |
- | |
927 | } |
- | |
928 | 1033 | /* IMPORTANT: we have memory now that won't get freed if something else |
|
929 | png_memcpy(to->name, from->name, length); |
- | |
930 | to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, |
1034 | * goes wrong, this code must free it. png_malloc_array produces no |
931 | (png_size_t)(from->nentries * png_sizeof(png_sPLT_entry))); |
1035 | * warnings, use a png_chunk_report (below) if there is an error. |
Line -... | Line 1036... | ||
- | 1036 | */ |
|
- | 1037 | np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr, |
|
- | 1038 | entries->nentries, sizeof (png_sPLT_entry))); |
|
- | 1039 | ||
932 | 1040 | if (np->entries == NULL) |
|
933 | if (to->entries == NULL) |
1041 | { |
Line -... | Line 1042... | ||
- | 1042 | png_free(png_ptr, np->name); |
|
934 | { |
1043 | break; |
- | 1044 | } |
|
935 | png_warning(png_ptr, |
1045 | |
- | 1046 | np->nentries = entries->nentries; |
|
- | 1047 | /* This multiply can't overflow because png_malloc_array has already |
|
936 | "Out of memory while processing sPLT chunk"); |
1048 | * checked it when doing the allocation. |
- | 1049 | */ |
|
Line 937... | Line 1050... | ||
937 | png_free(png_ptr, to->name); |
1050 | memcpy(np->entries, entries->entries, |
938 | to->name = NULL; |
- | |
939 | continue; |
- | |
940 | } |
1051 | entries->nentries * sizeof (png_sPLT_entry)); |
941 | 1052 | ||
942 | png_memcpy(to->entries, from->entries, |
1053 | /* Note that 'continue' skips the advance of the out pointer and out |
Line 943... | Line 1054... | ||
943 | from->nentries * png_sizeof(png_sPLT_entry)); |
1054 | * count, so an invalid entry is not added. |
- | 1055 | */ |
|
- | 1056 | info_ptr->valid |= PNG_INFO_sPLT; |
|
- | 1057 | ++(info_ptr->splt_palettes_num); |
|
- | 1058 | ++np; |
|
- | 1059 | } |
|
- | 1060 | while (++entries, --nentries); |
|
- | 1061 | ||
- | 1062 | if (nentries > 0) |
|
- | 1063 | png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); |
|
- | 1064 | } |
|
- | 1065 | #endif /* PNG_sPLT_SUPPORTED */ |
|
- | 1066 | ||
- | 1067 | #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED |
|
- | 1068 | static png_byte |
|
- | 1069 | check_location(png_const_structrp png_ptr, int location) |
|
- | 1070 | { |
|
- | 1071 | location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT); |
|
- | 1072 | ||
- | 1073 | /* New in 1.6.0; copy the location and check it. This is an API |
|
- | 1074 | * change, previously the app had to use the |
|
- | 1075 | * png_set_unknown_chunk_location API below for each chunk. |
|
- | 1076 | */ |
|
- | 1077 | if (location == 0 && !(png_ptr->mode & PNG_IS_READ_STRUCT)) |
|
- | 1078 | { |
|
- | 1079 | /* Write struct, so unknown chunks come from the app */ |
|
- | 1080 | png_app_warning(png_ptr, |
|
- | 1081 | "png_set_unknown_chunks now expects a valid location"); |
|
- | 1082 | /* Use the old behavior */ |
|
- | 1083 | location = (png_byte)(png_ptr->mode & |
|
- | 1084 | (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); |
|
- | 1085 | } |
|
- | 1086 | ||
- | 1087 | /* This need not be an internal error - if the app calls |
|
- | 1088 | * png_set_unknown_chunks on a read pointer it must get the location right. |
|
- | 1089 | */ |
|
- | 1090 | if (location == 0) |
|
- | 1091 | png_error(png_ptr, "invalid location in png_set_unknown_chunks"); |
|
944 | 1092 | ||
945 | to->nentries = from->nentries; |
1093 | /* Now reduce the location to the top-most set bit by removing each least |
946 | to->depth = from->depth; |
1094 | * significant bit in turn. |
947 | } |
1095 | */ |
948 | 1096 | while (location != (location & -location)) |
|
949 | info_ptr->splt_palettes = np; |
- | |
Line 950... | Line 1097... | ||
950 | info_ptr->splt_palettes_num += nentries; |
1097 | location &= ~(location & -location); |
- | 1098 | ||
951 | info_ptr->valid |= PNG_INFO_sPLT; |
1099 | /* The cast is safe because 'location' is a bit mask and only the low four |
Line -... | Line 1100... | ||
- | 1100 | * bits are significant. |
|
- | 1101 | */ |
|
- | 1102 | return (png_byte)location; |
|
- | 1103 | } |
|
- | 1104 | ||
- | 1105 | void PNGAPI |
|
- | 1106 | png_set_unknown_chunks(png_const_structrp png_ptr, |
|
- | 1107 | png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) |
|
- | 1108 | { |
|
- | 1109 | png_unknown_chunkp np; |
|
- | 1110 | ||
- | 1111 | if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 || |
|
- | 1112 | unknowns == NULL) |
|
- | 1113 | return; |
|
- | 1114 | ||
- | 1115 | /* Check for the failure cases where support has been disabled at compile |
|
- | 1116 | * time. This code is hardly ever compiled - it's here because |
|
- | 1117 | * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this |
|
- | 1118 | * code) but may be meaningless if the read or write handling of unknown |
|
- | 1119 | * chunks is not compiled in. |
|
- | 1120 | */ |
|
- | 1121 | # if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \ |
|
- | 1122 | defined(PNG_READ_SUPPORTED) |
|
- | 1123 | if (png_ptr->mode & PNG_IS_READ_STRUCT) |
|
- | 1124 | { |
|
- | 1125 | png_app_error(png_ptr, "no unknown chunk support on read"); |
|
- | 1126 | return; |
|
- | 1127 | } |
|
952 | info_ptr->free_me |= PNG_FREE_SPLT; |
1128 | # endif |
953 | } |
1129 | # if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \ |
954 | #endif /* PNG_sPLT_SUPPORTED */ |
1130 | defined(PNG_WRITE_SUPPORTED) |
Line 955... | Line 1131... | ||
955 | 1131 | if (!(png_ptr->mode & PNG_IS_READ_STRUCT)) |
|
956 | #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED |
1132 | { |
957 | void PNGAPI |
1133 | png_app_error(png_ptr, "no unknown chunk support on write"); |
958 | png_set_unknown_chunks(png_structp png_ptr, |
1134 | return; |
959 | png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) |
1135 | } |
960 | { |
1136 | # endif |
Line 961... | Line -... | ||
961 | png_unknown_chunkp np; |
- | |
962 | int i; |
- | |
963 | - | ||
964 | if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) |
- | |
965 | return; |
1137 | |
966 | - | ||
967 | np = (png_unknown_chunkp)png_malloc_warn(png_ptr, |
- | |
968 | (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) * |
- | |
969 | png_sizeof(png_unknown_chunk)); |
- | |
970 | 1138 | /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that |
|
971 | if (np == NULL) |
1139 | * unknown critical chunks could be lost with just a warning resulting in |
Line 972... | Line -... | ||
972 | { |
- | |
973 | png_warning(png_ptr, |
- | |
974 | "Out of memory while processing unknown chunk"); |
1140 | * undefined behavior. Now png_chunk_report is used to provide behavior |
Line 975... | Line 1141... | ||
975 | return; |
1141 | * appropriate to read or write. |
- | 1142 | */ |
|
- | 1143 | np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, |
|
- | 1144 | info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, |
|
- | 1145 | sizeof *np)); |
|
- | 1146 | ||
- | 1147 | if (np == NULL) |
|
976 | } |
1148 | { |
Line 977... | Line 1149... | ||
977 | 1149 | png_chunk_report(png_ptr, "too many unknown chunks", |
|
- | 1150 | PNG_CHUNK_WRITE_ERROR); |
|
978 | png_memcpy(np, info_ptr->unknown_chunks, |
1151 | return; |
- | 1152 | } |
|
- | 1153 | ||
Line 979... | Line 1154... | ||
979 | (png_size_t)info_ptr->unknown_chunks_num * |
1154 | png_free(png_ptr, info_ptr->unknown_chunks); |
980 | png_sizeof(png_unknown_chunk)); |
1155 | info_ptr->unknown_chunks = np; /* safe because it is initialized */ |
981 | 1156 | info_ptr->free_me |= PNG_FREE_UNKN; |
|
982 | png_free(png_ptr, info_ptr->unknown_chunks); |
1157 | |
Line 983... | Line 1158... | ||
983 | info_ptr->unknown_chunks = NULL; |
1158 | np += info_ptr->unknown_chunks_num; |
984 | 1159 | ||
- | 1160 | /* Increment unknown_chunks_num each time round the loop to protect the |
|
985 | for (i = 0; i < num_unknowns; i++) |
1161 | * just-allocated chunk data. |
986 | { |
1162 | */ |
987 | png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; |
1163 | for (; num_unknowns > 0; --num_unknowns, ++unknowns) |
988 | png_const_unknown_chunkp from = unknowns + i; |
1164 | { |
Line 989... | Line -... | ||
989 | - | ||
990 | png_memcpy(to->name, from->name, png_sizeof(from->name)); |
1165 | memcpy(np->name, unknowns->name, (sizeof np->name)); |
991 | to->name[png_sizeof(to->name)-1] = '\0'; |
1166 | np->name[(sizeof np->name)-1] = '\0'; |
992 | to->size = from->size; |
1167 | np->location = check_location(png_ptr, unknowns->location); |
Line 993... | Line 1168... | ||
993 | 1168 | ||
994 | /* Note our location in the read or write sequence */ |
1169 | if (unknowns->size == 0) |
- | 1170 | { |
|
- | 1171 | np->data = NULL; |
|
- | 1172 | np->size = 0; |
|
995 | to->location = (png_byte)(png_ptr->mode & 0xff); |
1173 | } |
- | 1174 | ||
996 | 1175 | else |
|
Line 997... | Line 1176... | ||
997 | if (from->size == 0) |
1176 | { |
998 | to->data=NULL; |
1177 | np->data = png_voidcast(png_bytep, |
999 | 1178 | png_malloc_base(png_ptr, unknowns->size)); |
|
1000 | else |
1179 | |
- | 1180 | if (np->data == NULL) |
|
- | 1181 | { |
|
- | 1182 | png_chunk_report(png_ptr, "unknown chunk: out of memory", |
|
- | 1183 | PNG_CHUNK_WRITE_ERROR); |
|
- | 1184 | /* But just skip storing the unknown chunk */ |
|
1001 | { |
1185 | continue; |
1002 | to->data = (png_bytep)png_malloc_warn(png_ptr, |
1186 | } |
- | 1187 | ||
- | 1188 | memcpy(np->data, unknowns->data, unknowns->size); |
|
- | 1189 | np->size = unknowns->size; |
|
- | 1190 | } |
|
- | 1191 | ||
- | 1192 | /* These increments are skipped on out-of-memory for the data - the |
|
- | 1193 | * unknown chunk entry gets overwritten if the png_chunk_report returns. |
|
- | 1194 | * This is correct in the read case (the chunk is just dropped.) |
|
- | 1195 | */ |
|
- | 1196 | ++np; |
|
- | 1197 | ++(info_ptr->unknown_chunks_num); |
|
- | 1198 | } |
|
1003 | (png_size_t)from->size); |
1199 | } |
- | 1200 | ||
- | 1201 | void PNGAPI |
|
1004 | 1202 | png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, |
|
1005 | if (to->data == NULL) |
1203 | int chunk, int location) |
Line 1006... | Line 1204... | ||
1006 | { |
1204 | { |
1007 | png_warning(png_ptr, |
1205 | /* This API is pretty pointless in 1.6.0 because the location can be set |
1008 | "Out of memory while processing unknown chunk"); |
1206 | * before the call to png_set_unknown_chunks. |
1009 | to->size = 0; |
1207 | * |
1010 | } |
1208 | * TODO: add a png_app_warning in 1.7 |
Line 1011... | Line 1209... | ||
1011 | 1209 | */ |
|
1012 | else |
1210 | if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && |
Line 1013... | Line -... | ||
1013 | png_memcpy(to->data, from->data, from->size); |
- | |
1014 | } |
1211 | chunk < info_ptr->unknown_chunks_num) |
Line 1015... | Line 1212... | ||
1015 | } |
1212 | { |
1016 | 1213 | if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0) |
|
1017 | info_ptr->unknown_chunks = np; |
1214 | { |
Line 1018... | Line 1215... | ||
1018 | info_ptr->unknown_chunks_num += num_unknowns; |
1215 | png_app_error(png_ptr, "invalid unknown chunk location"); |
- | 1216 | /* Fake out the pre 1.6.0 behavior: */ |
|
- | 1217 | if ((location & PNG_HAVE_IDAT)) /* undocumented! */ |
|
- | 1218 | location = PNG_AFTER_IDAT; |
|
- | 1219 | ||
- | 1220 | else |
|
- | 1221 | location = PNG_HAVE_IHDR; /* also undocumented */ |
|
- | 1222 | } |
|
- | 1223 | ||
- | 1224 | info_ptr->unknown_chunks[chunk].location = |
|
- | 1225 | check_location(png_ptr, location); |
|
- | 1226 | } |
|
- | 1227 | } |
|
- | 1228 | #endif |
|
- | 1229 | ||
- | 1230 | ||
- | 1231 | #ifdef PNG_MNG_FEATURES_SUPPORTED |
|
- | 1232 | png_uint_32 PNGAPI |
|
- | 1233 | png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features) |
|
- | 1234 | { |
|
- | 1235 | png_debug(1, "in png_permit_mng_features"); |
|
- | 1236 | ||
- | 1237 | if (png_ptr == NULL) |
|
- | 1238 | return 0; |
|
- | 1239 | ||
1019 | info_ptr->free_me |= PNG_FREE_UNKN; |
1240 | png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES; |
1020 | } |
1241 | |
1021 | 1242 | return png_ptr->mng_features_permitted; |
|
1022 | void PNGAPI |
1243 | } |
1023 | png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, |
1244 | #endif |
1024 | int chunk, int location) |
1245 | |
- | 1246 | #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED |
|
1025 | { |
1247 | static unsigned int |
1026 | if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < |
1248 | add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep) |
Line 1027... | Line 1249... | ||
1027 | info_ptr->unknown_chunks_num) |
1249 | { |
1028 | info_ptr->unknown_chunks[chunk].location = (png_byte)location; |
1250 | unsigned int i; |
1029 | } |
1251 | |
1030 | #endif |
1252 | /* Utility function: update the 'keep' state of a chunk if it is already in |
- | 1253 | * the list, otherwise add it to the list. |
|
Line -... | Line 1254... | ||
- | 1254 | */ |
|
1031 | 1255 | for (i=0; i |
|
1032 | 1256 | { |
|
Line 1033... | Line 1257... | ||
1033 | #ifdef PNG_MNG_FEATURES_SUPPORTED |
1257 | list[4] = (png_byte)keep; |
1034 | png_uint_32 PNGAPI |
1258 | return count; |
- | 1259 | } |
|
- | 1260 | ||
Line -... | Line 1261... | ||
- | 1261 | if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT) |
|
- | 1262 | { |
|
- | 1263 | ++count; |
|
- | 1264 | memcpy(list, add, 4); |
|
1035 | png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) |
1265 | list[4] = (png_byte)keep; |
- | 1266 | } |
|
- | 1267 | ||
1036 | { |
1268 | return count; |
- | 1269 | } |
|
- | 1270 | ||
- | 1271 | void PNGAPI |
|
- | 1272 | png_set_keep_unknown_chunks(png_structrp png_ptr, int keep, |
|
- | 1273 | png_const_bytep chunk_list, int num_chunks_in) |
|
- | 1274 | { |
|
- | 1275 | png_bytep new_list; |
|
- | 1276 | unsigned int num_chunks, old_num_chunks; |
|
- | 1277 | ||
- | 1278 | if (png_ptr == NULL) |
|
- | 1279 | return; |
|
- | 1280 | ||
- | 1281 | if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST) |
|
- | 1282 | { |
|
- | 1283 | png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep"); |
|
- | 1284 | return; |
|
Line 1037... | Line 1285... | ||
1037 | png_debug(1, "in png_permit_mng_features"); |
1285 | } |
- | 1286 | ||
1038 | 1287 | if (num_chunks_in <= 0) |
|
Line -... | Line 1288... | ||
- | 1288 | { |
|
- | 1289 | png_ptr->unknown_default = keep; |
|
1039 | if (png_ptr == NULL) |
1290 | |
- | 1291 | /* '0' means just set the flags, so stop here */ |
|
- | 1292 | if (num_chunks_in == 0) |
|
- | 1293 | return; |
|
- | 1294 | } |
|
- | 1295 | ||
1040 | return (png_uint_32)0; |
1296 | if (num_chunks_in < 0) |
- | 1297 | { |
|
- | 1298 | /* Ignore all unknown chunks and all chunks recognized by |
|
- | 1299 | * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND |
|
- | 1300 | */ |
|
Line 1041... | Line 1301... | ||
1041 | 1301 | static PNG_CONST png_byte chunks_to_ignore[] = { |
|
1042 | png_ptr->mng_features_permitted = |
1302 | 98, 75, 71, 68, '\0', /* bKGD */ |
1043 | (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); |
1303 | 99, 72, 82, 77, '\0', /* cHRM */ |
Line -... | Line 1304... | ||
- | 1304 | 103, 65, 77, 65, '\0', /* gAMA */ |
|
- | 1305 | 104, 73, 83, 84, '\0', /* hIST */ |
|
1044 | 1306 | 105, 67, 67, 80, '\0', /* iCCP */ |
|
1045 | return (png_uint_32)png_ptr->mng_features_permitted; |
1307 | 105, 84, 88, 116, '\0', /* iTXt */ |
1046 | } |
- | |
1047 | #endif |
- | |
1048 | 1308 | 111, 70, 70, 115, '\0', /* oFFs */ |
|
1049 | #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED |
1309 | 112, 67, 65, 76, '\0', /* pCAL */ |
1050 | void PNGAPI |
1310 | 112, 72, 89, 115, '\0', /* pHYs */ |
Line -... | Line 1311... | ||
- | 1311 | 115, 66, 73, 84, '\0', /* sBIT */ |
|
- | 1312 | 115, 67, 65, 76, '\0', /* sCAL */ |
|
- | 1313 | 115, 80, 76, 84, '\0', /* sPLT */ |
|
- | 1314 | 115, 84, 69, 82, '\0', /* sTER */ |
|
- | 1315 | 115, 82, 71, 66, '\0', /* sRGB */ |
|
- | 1316 | 116, 69, 88, 116, '\0', /* tEXt */ |
|
1051 | png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep |
1317 | 116, 73, 77, 69, '\0', /* tIME */ |
1052 | chunk_list, int num_chunks) |
1318 | 122, 84, 88, 116, '\0' /* zTXt */ |
Line -... | Line 1319... | ||
- | 1319 | }; |
|
1053 | { |
1320 | |
- | 1321 | chunk_list = chunks_to_ignore; |
|
- | 1322 | num_chunks = (sizeof chunks_to_ignore)/5; |
|
- | 1323 | } |
|
- | 1324 | ||
- | 1325 | else /* num_chunks_in > 0 */ |
|
- | 1326 | { |
|
- | 1327 | if (chunk_list == NULL) |
|
- | 1328 | { |
|
- | 1329 | /* Prior to 1.6.0 this was silently ignored, now it is an app_error |
|
- | 1330 | * which can be switched off. |
|
- | 1331 | */ |
|
- | 1332 | png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list"); |
|
- | 1333 | return; |
|
- | 1334 | } |
|
- | 1335 | ||
- | 1336 | num_chunks = num_chunks_in; |
|
1054 | png_bytep new_list, p; |
1337 | } |
- | 1338 | ||
- | 1339 | old_num_chunks = png_ptr->num_chunk_list; |
|
- | 1340 | if (png_ptr->chunk_list == NULL) |
|
- | 1341 | old_num_chunks = 0; |
|
- | 1342 | ||
- | 1343 | /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow. |
|
- | 1344 | */ |
|
- | 1345 | if (num_chunks + old_num_chunks > UINT_MAX/5) |
|
- | 1346 | { |
|
- | 1347 | png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks"); |
|
- | 1348 | return; |
|
- | 1349 | } |
|
- | 1350 | ||
- | 1351 | /* If these chunks are being reset to the default then no more memory is |
|
- | 1352 | * required because add_one_chunk above doesn't extend the list if the 'keep' |
|
- | 1353 | * parameter is the default. |
|
- | 1354 | */ |
|
- | 1355 | if (keep) |
|
- | 1356 | { |
|
- | 1357 | new_list = png_voidcast(png_bytep, png_malloc(png_ptr, |
|
- | 1358 | 5 * (num_chunks + old_num_chunks))); |
|
- | 1359 | ||
- | 1360 | if (old_num_chunks > 0) |
|
- | 1361 | memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks); |
|
- | 1362 | } |
|
- | 1363 | ||
- | 1364 | else if (old_num_chunks > 0) |
|
- | 1365 | new_list = png_ptr->chunk_list; |
|
- | 1366 | ||
- | 1367 | else |
|
- | 1368 | new_list = NULL; |
|
- | 1369 | ||
- | 1370 | /* Add the new chunks together with each one's handling code. If the chunk |
|
- | 1371 | * already exists the code is updated, otherwise the chunk is added to the |
|
- | 1372 | * end. (In libpng 1.6.0 order no longer matters because this code enforces |
|
- | 1373 | * the earlier convention that the last setting is the one that is used.) |
|
Line 1055... | Line -... | ||
1055 | int i, old_num_chunks; |
- | |
1056 | if (png_ptr == NULL) |
1374 | */ |
1057 | return; |
1375 | if (new_list != NULL) |
1058 | 1376 | { |
|
1059 | if (num_chunks == 0) |
1377 | png_const_bytep inlist; |
Line 1060... | Line 1378... | ||
1060 | { |
1378 | png_bytep outlist; |
1061 | if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) |
1379 | unsigned int i; |
1062 | png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; |
1380 | |
1063 | 1381 | for (i=0; i |
|
1064 | else |
1382 | old_num_chunks = add_one_chunk(new_list, old_num_chunks, |
1065 | png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; |
1383 | chunk_list+5*i, keep); |
Line 1066... | Line 1384... | ||
1066 | 1384 | ||
Line 1116... | Line 1434... | ||
1116 | #endif |
1434 | #endif |
1117 | 1435 | ||
Line 1118... | Line 1436... | ||
1118 | #ifdef PNG_INFO_IMAGE_SUPPORTED |
1436 | #ifdef PNG_INFO_IMAGE_SUPPORTED |
1119 | void PNGAPI |
1437 | void PNGAPI |
1120 | png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) |
1438 | png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, |
- | 1439 | png_bytepp row_pointers) |
|
1121 | { |
1440 | { |
1122 | png_debug1(1, "in %s storage function", "rows"); |
1441 | png_debug1(1, "in %s storage function", "rows"); |
Line 1123... | Line 1442... | ||
1123 | 1442 | ||
1124 | if (png_ptr == NULL || info_ptr == NULL) |
1443 | if (png_ptr == NULL || info_ptr == NULL) |
Line 1134... | Line 1453... | ||
1134 | } |
1453 | } |
1135 | #endif |
1454 | #endif |
1136 | 1455 | ||
Line 1137... | Line 1456... | ||
1137 | void PNGAPI |
1456 | void PNGAPI |
1138 | png_set_compression_buffer_size(png_structp png_ptr, png_size_t size) |
1457 | png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size) |
1139 | { |
1458 | { |
1140 | if (png_ptr == NULL) |
1459 | if (png_ptr == NULL) |
1141 | return; |
1460 | return; |
Line -... | Line 1461... | ||
- | 1461 | ||
1142 | 1462 | if (size == 0 || size > PNG_UINT_31_MAX) |
|
Line -... | Line 1463... | ||
- | 1463 | png_error(png_ptr, "invalid compression buffer size"); |
|
1143 | png_free(png_ptr, png_ptr->zbuf); |
1464 | |
1144 | 1465 | # ifdef PNG_SEQUENTIAL_READ_SUPPORTED |
|
1145 | if (size > ZLIB_IO_MAX) |
1466 | if (png_ptr->mode & PNG_IS_READ_STRUCT) |
1146 | { |
1467 | { |
1147 | png_warning(png_ptr, "Attempt to set buffer size beyond max ignored"); |
- | |
1148 | png_ptr->zbuf_size = ZLIB_IO_MAX; |
1468 | png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ |
- | 1469 | return; |
|
Line -... | Line 1470... | ||
- | 1470 | } |
|
- | 1471 | # endif |
|
1149 | size = ZLIB_IO_MAX; /* must fit */ |
1472 | |
1150 | } |
1473 | # ifdef PNG_WRITE_SUPPORTED |
- | 1474 | if (!(png_ptr->mode & PNG_IS_READ_STRUCT)) |
|
- | 1475 | { |
|
- | 1476 | if (png_ptr->zowner != 0) |
|
- | 1477 | { |
|
- | 1478 | png_warning(png_ptr, |
|
Line -... | Line 1479... | ||
- | 1479 | "Compression buffer size cannot be changed because it is in use"); |
|
- | 1480 | return; |
|
1151 | 1481 | } |
|
- | 1482 | ||
- | 1483 | if (size > ZLIB_IO_MAX) |
|
- | 1484 | { |
|
Line -... | Line 1485... | ||
- | 1485 | png_warning(png_ptr, |
|
- | 1486 | "Compression buffer size limited to system maximum"); |
|
1152 | else |
1487 | size = ZLIB_IO_MAX; /* must fit */ |
1153 | png_ptr->zbuf_size = (uInt)size; |
1488 | } |
1154 | 1489 | ||
1155 | png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); |
1490 | else if (size < 6) |
- | 1491 | { |
|
- | 1492 | /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH |
|
- | 1493 | * if this is permitted. |
|
- | 1494 | */ |
|
1156 | 1495 | png_warning(png_ptr, |
|
- | 1496 | "Compression buffer size cannot be reduced below 6"); |
|
- | 1497 | return; |
|
1157 | /* The following ensures a relatively safe failure if this gets called while |
1498 | } |
- | 1499 | ||
- | 1500 | if (png_ptr->zbuffer_size != size) |
|
- | 1501 | { |
|
1158 | * the buffer is actually in use. |
1502 | png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); |
Line 1159... | Line 1503... | ||
1159 | */ |
1503 | png_ptr->zbuffer_size = (uInt)size; |
1160 | png_ptr->zstream.next_out = png_ptr->zbuf; |
1504 | } |
1161 | png_ptr->zstream.avail_out = 0; |
1505 | } |
1162 | png_ptr->zstream.avail_in = 0; |
1506 | # endif |
1163 | } |
1507 | } |
1164 | 1508 | ||
Line 1165... | Line -... | ||
1165 | void PNGAPI |
- | |
1166 | png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) |
1509 | void PNGAPI |
1167 | { |
1510 | png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) |
1168 | if (png_ptr && info_ptr) |
1511 | { |
1169 | info_ptr->valid &= ~mask; |
1512 | if (png_ptr && info_ptr) |
1170 | } |
1513 | info_ptr->valid &= ~mask; |
1171 | 1514 | } |
|
1172 | 1515 | ||
1173 | 1516 | ||
1174 | #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
1517 | #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
Line 1189... | Line 1532... | ||
1189 | } |
1532 | } |
1190 | 1533 | ||
Line 1191... | Line 1534... | ||
1191 | /* This function was added to libpng 1.4.0 */ |
1534 | /* This function was added to libpng 1.4.0 */ |
1192 | void PNGAPI |
1535 | void PNGAPI |
1193 | png_set_chunk_cache_max (png_structp png_ptr, |
1536 | png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max) |
1194 | png_uint_32 user_chunk_cache_max) |
- | |
1195 | { |
1537 | { |
1196 | if (png_ptr) |
1538 | if (png_ptr) |
1197 | png_ptr->user_chunk_cache_max = user_chunk_cache_max; |
1539 | png_ptr->user_chunk_cache_max = user_chunk_cache_max; |
1198 | } |
1540 | } |
Line 1199... | Line 1541... | ||
1199 | 1541 | ||
1200 | /* This function was added to libpng 1.4.1 */ |
1542 | /* This function was added to libpng 1.4.1 */ |
1201 | void PNGAPI |
1543 | void PNGAPI |
1202 | png_set_chunk_malloc_max (png_structp png_ptr, |
1544 | png_set_chunk_malloc_max (png_structrp png_ptr, |
1203 | png_alloc_size_t user_chunk_malloc_max) |
1545 | png_alloc_size_t user_chunk_malloc_max) |
1204 | { |
1546 | { |
1205 | if (png_ptr) |
1547 | if (png_ptr) |
1206 | png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; |
1548 | png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; |
1207 | } |
1549 | } |
Line 1208... | Line 1550... | ||
1208 | #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ |
1550 | #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ |
1209 | 1551 | ||
1210 | 1552 | ||
1211 | #ifdef PNG_BENIGN_ERRORS_SUPPORTED |
1553 | #ifdef PNG_BENIGN_ERRORS_SUPPORTED |
1212 | void PNGAPI |
1554 | void PNGAPI |
Line -... | Line 1555... | ||
- | 1555 | png_set_benign_errors(png_structrp png_ptr, int allowed) |
|
- | 1556 | { |
|
- | 1557 | png_debug(1, "in png_set_benign_errors"); |
|
- | 1558 | ||
- | 1559 | /* If allowed is 1, png_benign_error() is treated as a warning. |
|
- | 1560 | * |
|
1213 | png_set_benign_errors(png_structp png_ptr, int allowed) |
1561 | * If allowed is 0, png_benign_error() is treated as an error (which |
1214 | { |
1562 | * is the default behavior if png_set_benign_errors() is not called). |
- | 1563 | */ |
|
Line 1215... | Line 1564... | ||
1215 | png_debug(1, "in png_set_benign_errors"); |
1564 | |
1216 | 1565 | if (allowed) |
|
- | 1566 | png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN | |
|
1217 | if (allowed) |
1567 | PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN; |
1218 | png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; |
1568 | |
- | 1569 | else |
|
- | 1570 | png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN | |
|
- | 1571 | PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN); |
|
- | 1572 | } |
|
- | 1573 | #endif /* PNG_BENIGN_ERRORS_SUPPORTED */ |
|
- | 1574 | ||
- | 1575 | #ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED |
|
- | 1576 | /* Whether to report invalid palette index; added at libng-1.5.10. |
|
- | 1577 | * It is possible for an indexed (color-type==3) PNG file to contain |
|
- | 1578 | * pixels with invalid (out-of-range) indexes if the PLTE chunk has |
|
- | 1579 | * fewer entries than the image's bit-depth would allow. We recover |
|
- | 1580 | * from this gracefully by filling any incomplete palette with zeroes |
|
- | 1581 | * (opaque black). By default, when this occurs libpng will issue |
|
- | 1582 | * a benign error. This API can be used to override that behavior. |
|
- | 1583 | */ |
|
- | 1584 | void PNGAPI |
|
- | 1585 | png_set_check_for_invalid_index(png_structrp png_ptr, int allowed) |
|
- | 1586 | { |
|
- | 1587 | png_debug(1, "in png_set_check_for_invalid_index"); |
|
- | 1588 | ||
- | 1589 | if (allowed > 0) |
|
- | 1590 | png_ptr->num_palette_max = 0; |
|
1219 | 1591 |