1 | ␍␊ |
2 | /* pngset.c - storage of image information into info struct␍␊ |
3 | *␍␊ |
4 | * Last changed in libpng 1.5.11 [June 14, 2012]␍␊ |
5 | * Copyright (c) 1998-2012 Glenn Randers-Pehrson␍␊ |
6 | * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)␍␊ |
7 | * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)␍␊ |
8 | *␍␊ |
9 | * This code is released under the libpng license.␍␊ |
10 | * For conditions of distribution and use, see the disclaimer␍␊ |
11 | * and license in png.h␍␊ |
12 | *␍␊ |
13 | * The functions here are used during reads to store data from the file␍␊ |
14 | * into the info struct, and during writes to store application data␍␊ |
15 | * into the info struct for writing into the file. This abstracts the␍␊ |
16 | * info struct and allows us to change the structure in the future.␍␊ |
17 | */␍␊ |
18 | ␍␊ |
19 | #include "pngpriv.h"␍␊ |
20 | ␍␊ |
21 | #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)␍␊ |
22 | ␍␊ |
23 | #ifdef PNG_bKGD_SUPPORTED␍␊ |
24 | void PNGAPI␍␊ |
25 | png_set_bKGD(png_structp png_ptr, png_infop info_ptr,␍␊ |
26 | png_const_color_16p background)␍␊ |
27 | {␍␊ |
28 | png_debug1(1, "in %s storage function", "bKGD");␍␊ |
29 | ␍␊ |
30 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
31 | return;␍␊ |
32 | ␍␊ |
33 | png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));␍␊ |
34 | info_ptr->valid |= PNG_INFO_bKGD;␍␊ |
35 | }␍␊ |
36 | #endif␍␊ |
37 | ␍␊ |
38 | #ifdef PNG_cHRM_SUPPORTED␍␊ |
39 | void PNGFAPI␍␊ |
40 | png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,␍␊ |
41 | png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,␍␊ |
42 | png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,␍␊ |
43 | png_fixed_point blue_x, png_fixed_point blue_y)␍␊ |
44 | {␍␊ |
45 | png_debug1(1, "in %s storage function", "cHRM fixed");␍␊ |
46 | ␍␊ |
47 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
48 | return;␍␊ |
49 | ␍␊ |
50 | # ifdef PNG_CHECK_cHRM_SUPPORTED␍␊ |
51 | if (png_check_cHRM_fixed(png_ptr,␍␊ |
52 | white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y))␍␊ |
53 | # endif␍␊ |
54 | {␍␊ |
55 | info_ptr->x_white = white_x;␍␊ |
56 | info_ptr->y_white = white_y;␍␊ |
57 | info_ptr->x_red = red_x;␍␊ |
58 | info_ptr->y_red = red_y;␍␊ |
59 | info_ptr->x_green = green_x;␍␊ |
60 | info_ptr->y_green = green_y;␍␊ |
61 | info_ptr->x_blue = blue_x;␍␊ |
62 | info_ptr->y_blue = blue_y;␍␊ |
63 | info_ptr->valid |= PNG_INFO_cHRM;␍␊ |
64 | }␍␊ |
65 | }␍␊ |
66 | ␍␊ |
67 | void PNGFAPI␍␊ |
68 | png_set_cHRM_XYZ_fixed(png_structp png_ptr, png_infop 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 | png_xy xy;␍␊ |
77 | ␍␊ |
78 | png_debug1(1, "in %s storage function", "cHRM XYZ fixed");␍␊ |
79 | ␍␊ |
80 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
81 | return;␍␊ |
82 | ␍␊ |
83 | XYZ.redX = int_red_X;␍␊ |
84 | XYZ.redY = int_red_Y;␍␊ |
85 | XYZ.redZ = int_red_Z;␍␊ |
86 | XYZ.greenX = int_green_X;␍␊ |
87 | XYZ.greenY = int_green_Y;␍␊ |
88 | XYZ.greenZ = int_green_Z;␍␊ |
89 | XYZ.blueX = int_blue_X;␍␊ |
90 | XYZ.blueY = int_blue_Y;␍␊ |
91 | XYZ.blueZ = int_blue_Z;␍␊ |
92 | ␍␊ |
93 | if (png_xy_from_XYZ(&xy, XYZ))␍␊ |
94 | png_error(png_ptr, "XYZ values out of representable range");␍␊ |
95 | ␍␊ |
96 | png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy,␍␊ |
97 | xy.greenx, xy.greeny, xy.bluex, xy.bluey);␍␊ |
98 | }␍␊ |
99 | ␍␊ |
100 | # ifdef PNG_FLOATING_POINT_SUPPORTED␍␊ |
101 | void PNGAPI␍␊ |
102 | png_set_cHRM(png_structp png_ptr, png_infop info_ptr,␍␊ |
103 | double white_x, double white_y, double red_x, double red_y,␍␊ |
104 | double green_x, double green_y, double blue_x, double blue_y)␍␊ |
105 | {␍␊ |
106 | png_set_cHRM_fixed(png_ptr, info_ptr,␍␊ |
107 | png_fixed(png_ptr, white_x, "cHRM White X"),␍␊ |
108 | png_fixed(png_ptr, white_y, "cHRM White Y"),␍␊ |
109 | png_fixed(png_ptr, red_x, "cHRM Red X"),␍␊ |
110 | png_fixed(png_ptr, red_y, "cHRM Red Y"),␍␊ |
111 | png_fixed(png_ptr, green_x, "cHRM Green X"),␍␊ |
112 | png_fixed(png_ptr, green_y, "cHRM Green Y"),␍␊ |
113 | png_fixed(png_ptr, blue_x, "cHRM Blue X"),␍␊ |
114 | png_fixed(png_ptr, blue_y, "cHRM Blue Y"));␍␊ |
115 | }␍␊ |
116 | ␍␊ |
117 | void PNGAPI␍␊ |
118 | png_set_cHRM_XYZ(png_structp png_ptr, png_infop info_ptr, double red_X,␍␊ |
119 | double red_Y, double red_Z, double green_X, double green_Y, double green_Z,␍␊ |
120 | double blue_X, double blue_Y, double blue_Z)␍␊ |
121 | {␍␊ |
122 | png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,␍␊ |
123 | png_fixed(png_ptr, red_X, "cHRM Red X"),␍␊ |
124 | png_fixed(png_ptr, red_Y, "cHRM Red Y"),␍␊ |
125 | png_fixed(png_ptr, red_Z, "cHRM Red Z"),␍␊ |
126 | png_fixed(png_ptr, green_X, "cHRM Red X"),␍␊ |
127 | png_fixed(png_ptr, green_Y, "cHRM Red Y"),␍␊ |
128 | png_fixed(png_ptr, green_Z, "cHRM Red Z"),␍␊ |
129 | png_fixed(png_ptr, blue_X, "cHRM Red X"),␍␊ |
130 | png_fixed(png_ptr, blue_Y, "cHRM Red Y"),␍␊ |
131 | png_fixed(png_ptr, blue_Z, "cHRM Red Z"));␍␊ |
132 | }␍␊ |
133 | # endif /* PNG_FLOATING_POINT_SUPPORTED */␍␊ |
134 | ␍␊ |
135 | #endif /* PNG_cHRM_SUPPORTED */␍␊ |
136 | ␍␊ |
137 | #ifdef PNG_gAMA_SUPPORTED␍␊ |
138 | void PNGFAPI␍␊ |
139 | png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point␍␊ |
140 | file_gamma)␍␊ |
141 | {␍␊ |
142 | png_debug1(1, "in %s storage function", "gAMA");␍␊ |
143 | ␍␊ |
144 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
145 | return;␍␊ |
146 | ␍␊ |
147 | /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't␍␊ |
148 | * occur. Since the fixed point representation is assymetrical it is␍␊ |
149 | * possible for 1/gamma to overflow the limit of 21474 and this means the␍␊ |
150 | * gamma value must be at least 5/100000 and hence at most 20000.0. For␍␊ |
151 | * safety the limits here are a little narrower. The values are 0.00016 to␍␊ |
152 | * 6250.0, which are truly ridiculous gamma values (and will produce␍␊ |
153 | * displays that are all black or all white.)␍␊ |
154 | */␍␊ |
155 | if (file_gamma < 16 || file_gamma > 625000000)␍␊ |
156 | png_warning(png_ptr, "Out of range gamma value ignored");␍␊ |
157 | ␍␊ |
158 | else␍␊ |
159 | {␍␊ |
160 | info_ptr->gamma = file_gamma;␍␊ |
161 | info_ptr->valid |= PNG_INFO_gAMA;␍␊ |
162 | }␍␊ |
163 | }␍␊ |
164 | ␍␊ |
165 | # ifdef PNG_FLOATING_POINT_SUPPORTED␍␊ |
166 | void PNGAPI␍␊ |
167 | png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)␍␊ |
168 | {␍␊ |
169 | png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,␍␊ |
170 | "png_set_gAMA"));␍␊ |
171 | }␍␊ |
172 | # endif␍␊ |
173 | #endif␍␊ |
174 | ␍␊ |
175 | #ifdef PNG_hIST_SUPPORTED␍␊ |
176 | void PNGAPI␍␊ |
177 | png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist)␍␊ |
178 | {␍␊ |
179 | int i;␍␊ |
180 | ␍␊ |
181 | png_debug1(1, "in %s storage function", "hIST");␍␊ |
182 | ␍␊ |
183 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
184 | return;␍␊ |
185 | ␍␊ |
186 | if (info_ptr->num_palette == 0 || info_ptr->num_palette␍␊ |
187 | > PNG_MAX_PALETTE_LENGTH)␍␊ |
188 | {␍␊ |
189 | png_warning(png_ptr,␍␊ |
190 | "Invalid palette size, hIST allocation skipped");␍␊ |
191 | ␍␊ |
192 | return;␍␊ |
193 | }␍␊ |
194 | ␍␊ |
195 | png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);␍␊ |
196 | ␍␊ |
197 | /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in␍␊ |
198 | * version 1.2.1␍␊ |
199 | */␍␊ |
200 | png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,␍␊ |
201 | PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16));␍␊ |
202 | ␍␊ |
203 | if (png_ptr->hist == NULL)␍␊ |
204 | {␍␊ |
205 | png_warning(png_ptr, "Insufficient memory for hIST chunk data");␍␊ |
206 | return;␍␊ |
207 | }␍␊ |
208 | ␍␊ |
209 | for (i = 0; i < info_ptr->num_palette; i++)␍␊ |
210 | png_ptr->hist[i] = hist[i];␍␊ |
211 | ␍␊ |
212 | info_ptr->hist = png_ptr->hist;␍␊ |
213 | info_ptr->valid |= PNG_INFO_hIST;␍␊ |
214 | info_ptr->free_me |= PNG_FREE_HIST;␍␊ |
215 | }␍␊ |
216 | #endif␍␊ |
217 | ␍␊ |
218 | void PNGAPI␍␊ |
219 | png_set_IHDR(png_structp png_ptr, png_infop info_ptr,␍␊ |
220 | png_uint_32 width, png_uint_32 height, int bit_depth,␍␊ |
221 | int color_type, int interlace_type, int compression_type,␍␊ |
222 | int filter_type)␍␊ |
223 | {␍␊ |
224 | png_debug1(1, "in %s storage function", "IHDR");␍␊ |
225 | ␍␊ |
226 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
227 | return;␍␊ |
228 | ␍␊ |
229 | info_ptr->width = width;␍␊ |
230 | info_ptr->height = height;␍␊ |
231 | info_ptr->bit_depth = (png_byte)bit_depth;␍␊ |
232 | info_ptr->color_type = (png_byte)color_type;␍␊ |
233 | info_ptr->compression_type = (png_byte)compression_type;␍␊ |
234 | info_ptr->filter_type = (png_byte)filter_type;␍␊ |
235 | info_ptr->interlace_type = (png_byte)interlace_type;␍␊ |
236 | ␍␊ |
237 | png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,␍␊ |
238 | info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,␍␊ |
239 | info_ptr->compression_type, info_ptr->filter_type);␍␊ |
240 | ␍␊ |
241 | if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)␍␊ |
242 | info_ptr->channels = 1;␍␊ |
243 | ␍␊ |
244 | else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)␍␊ |
245 | info_ptr->channels = 3;␍␊ |
246 | ␍␊ |
247 | else␍␊ |
248 | info_ptr->channels = 1;␍␊ |
249 | ␍␊ |
250 | if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)␍␊ |
251 | info_ptr->channels++;␍␊ |
252 | ␍␊ |
253 | info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);␍␊ |
254 | ␍␊ |
255 | /* Check for potential overflow */␍␊ |
256 | if (width >␍␊ |
257 | (PNG_UINT_32_MAX >> 3) /* 8-byte RRGGBBAA pixels */␍␊ |
258 | - 48 /* bigrowbuf hack */␍␊ |
259 | - 1 /* filter byte */␍␊ |
260 | - 7*8 /* rounding of width to multiple of 8 pixels */␍␊ |
261 | - 8) /* extra max_pixel_depth pad */␍␊ |
262 | info_ptr->rowbytes = 0;␍␊ |
263 | else␍␊ |
264 | info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);␍␊ |
265 | }␍␊ |
266 | ␍␊ |
267 | #ifdef PNG_oFFs_SUPPORTED␍␊ |
268 | void PNGAPI␍␊ |
269 | png_set_oFFs(png_structp png_ptr, png_infop info_ptr,␍␊ |
270 | png_int_32 offset_x, png_int_32 offset_y, int unit_type)␍␊ |
271 | {␍␊ |
272 | png_debug1(1, "in %s storage function", "oFFs");␍␊ |
273 | ␍␊ |
274 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
275 | return;␍␊ |
276 | ␍␊ |
277 | info_ptr->x_offset = offset_x;␍␊ |
278 | info_ptr->y_offset = offset_y;␍␊ |
279 | info_ptr->offset_unit_type = (png_byte)unit_type;␍␊ |
280 | info_ptr->valid |= PNG_INFO_oFFs;␍␊ |
281 | }␍␊ |
282 | #endif␍␊ |
283 | ␍␊ |
284 | #ifdef PNG_pCAL_SUPPORTED␍␊ |
285 | void PNGAPI␍␊ |
286 | png_set_pCAL(png_structp png_ptr, png_infop info_ptr,␍␊ |
287 | png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,␍␊ |
288 | int nparams, png_const_charp units, png_charpp params)␍␊ |
289 | {␍␊ |
290 | png_size_t length;␍␊ |
291 | int i;␍␊ |
292 | ␍␊ |
293 | png_debug1(1, "in %s storage function", "pCAL");␍␊ |
294 | ␍␊ |
295 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
296 | return;␍␊ |
297 | ␍␊ |
298 | length = png_strlen(purpose) + 1;␍␊ |
299 | png_debug1(3, "allocating purpose for info (%lu bytes)",␍␊ |
300 | (unsigned long)length);␍␊ |
301 | ␍␊ |
302 | /* TODO: validate format of calibration name and unit name */␍␊ |
303 | ␍␊ |
304 | /* Check that the type matches the specification. */␍␊ |
305 | if (type < 0 || type > 3)␍␊ |
306 | png_error(png_ptr, "Invalid pCAL equation type");␍␊ |
307 | ␍␊ |
308 | /* Validate params[nparams] */␍␊ |
309 | for (i=0; i<nparams; ++i)␍␊ |
310 | if (!png_check_fp_string(params[i], png_strlen(params[i])))␍␊ |
311 | png_error(png_ptr, "Invalid format for pCAL parameter");␍␊ |
312 | ␍␊ |
313 | info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);␍␊ |
314 | ␍␊ |
315 | if (info_ptr->pcal_purpose == NULL)␍␊ |
316 | {␍␊ |
317 | png_warning(png_ptr, "Insufficient memory for pCAL purpose");␍␊ |
318 | return;␍␊ |
319 | }␍␊ |
320 | ␍␊ |
321 | png_memcpy(info_ptr->pcal_purpose, purpose, length);␍␊ |
322 | ␍␊ |
323 | png_debug(3, "storing X0, X1, type, and nparams in info");␍␊ |
324 | info_ptr->pcal_X0 = X0;␍␊ |
325 | info_ptr->pcal_X1 = X1;␍␊ |
326 | info_ptr->pcal_type = (png_byte)type;␍␊ |
327 | info_ptr->pcal_nparams = (png_byte)nparams;␍␊ |
328 | ␍␊ |
329 | length = png_strlen(units) + 1;␍␊ |
330 | png_debug1(3, "allocating units for info (%lu bytes)",␍␊ |
331 | (unsigned long)length);␍␊ |
332 | ␍␊ |
333 | info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);␍␊ |
334 | ␍␊ |
335 | if (info_ptr->pcal_units == NULL)␍␊ |
336 | {␍␊ |
337 | png_warning(png_ptr, "Insufficient memory for pCAL units");␍␊ |
338 | return;␍␊ |
339 | }␍␊ |
340 | ␍␊ |
341 | png_memcpy(info_ptr->pcal_units, units, length);␍␊ |
342 | ␍␊ |
343 | info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,␍␊ |
344 | (png_size_t)((nparams + 1) * png_sizeof(png_charp)));␍␊ |
345 | ␍␊ |
346 | if (info_ptr->pcal_params == NULL)␍␊ |
347 | {␍␊ |
348 | png_warning(png_ptr, "Insufficient memory for pCAL params");␍␊ |
349 | return;␍␊ |
350 | }␍␊ |
351 | ␍␊ |
352 | png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));␍␊ |
353 | ␍␊ |
354 | for (i = 0; i < nparams; i++)␍␊ |
355 | {␍␊ |
356 | length = png_strlen(params[i]) + 1;␍␊ |
357 | png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,␍␊ |
358 | (unsigned long)length);␍␊ |
359 | ␍␊ |
360 | info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);␍␊ |
361 | ␍␊ |
362 | if (info_ptr->pcal_params[i] == NULL)␍␊ |
363 | {␍␊ |
364 | png_warning(png_ptr, "Insufficient memory for pCAL parameter");␍␊ |
365 | return;␍␊ |
366 | }␍␊ |
367 | ␍␊ |
368 | png_memcpy(info_ptr->pcal_params[i], params[i], length);␍␊ |
369 | }␍␊ |
370 | ␍␊ |
371 | info_ptr->valid |= PNG_INFO_pCAL;␍␊ |
372 | info_ptr->free_me |= PNG_FREE_PCAL;␍␊ |
373 | }␍␊ |
374 | #endif␍␊ |
375 | ␍␊ |
376 | #ifdef PNG_sCAL_SUPPORTED␍␊ |
377 | void PNGAPI␍␊ |
378 | png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,␍␊ |
379 | int unit, png_const_charp swidth, png_const_charp sheight)␍␊ |
380 | {␍␊ |
381 | png_size_t lengthw = 0, lengthh = 0;␍␊ |
382 | ␍␊ |
383 | png_debug1(1, "in %s storage function", "sCAL");␍␊ |
384 | ␍␊ |
385 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
386 | return;␍␊ |
387 | ␍␊ |
388 | /* Double check the unit (should never get here with an invalid␍␊ |
389 | * unit unless this is an API call.)␍␊ |
390 | */␍␊ |
391 | if (unit != 1 && unit != 2)␍␊ |
392 | png_error(png_ptr, "Invalid sCAL unit");␍␊ |
393 | ␍␊ |
394 | if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 ||␍␊ |
395 | swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))␍␊ |
396 | png_error(png_ptr, "Invalid sCAL width");␍␊ |
397 | ␍␊ |
398 | if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 ||␍␊ |
399 | sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))␍␊ |
400 | png_error(png_ptr, "Invalid sCAL height");␍␊ |
401 | ␍␊ |
402 | info_ptr->scal_unit = (png_byte)unit;␍␊ |
403 | ␍␊ |
404 | ++lengthw;␍␊ |
405 | ␍␊ |
406 | png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);␍␊ |
407 | ␍␊ |
408 | info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw);␍␊ |
409 | ␍␊ |
410 | if (info_ptr->scal_s_width == NULL)␍␊ |
411 | {␍␊ |
412 | png_warning(png_ptr, "Memory allocation failed while processing sCAL");␍␊ |
413 | return;␍␊ |
414 | }␍␊ |
415 | ␍␊ |
416 | png_memcpy(info_ptr->scal_s_width, swidth, lengthw);␍␊ |
417 | ␍␊ |
418 | ++lengthh;␍␊ |
419 | ␍␊ |
420 | png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);␍␊ |
421 | ␍␊ |
422 | info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh);␍␊ |
423 | ␍␊ |
424 | if (info_ptr->scal_s_height == NULL)␍␊ |
425 | {␍␊ |
426 | png_free (png_ptr, info_ptr->scal_s_width);␍␊ |
427 | info_ptr->scal_s_width = NULL;␍␊ |
428 | ␍␊ |
429 | png_warning(png_ptr, "Memory allocation failed while processing sCAL");␍␊ |
430 | return;␍␊ |
431 | }␍␊ |
432 | ␍␊ |
433 | png_memcpy(info_ptr->scal_s_height, sheight, lengthh);␍␊ |
434 | ␍␊ |
435 | info_ptr->valid |= PNG_INFO_sCAL;␍␊ |
436 | info_ptr->free_me |= PNG_FREE_SCAL;␍␊ |
437 | }␍␊ |
438 | ␍␊ |
439 | # ifdef PNG_FLOATING_POINT_SUPPORTED␍␊ |
440 | void PNGAPI␍␊ |
441 | png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width,␍␊ |
442 | double height)␍␊ |
443 | {␍␊ |
444 | png_debug1(1, "in %s storage function", "sCAL");␍␊ |
445 | ␍␊ |
446 | /* Check the arguments. */␍␊ |
447 | if (width <= 0)␍␊ |
448 | png_warning(png_ptr, "Invalid sCAL width ignored");␍␊ |
449 | ␍␊ |
450 | else if (height <= 0)␍␊ |
451 | png_warning(png_ptr, "Invalid sCAL height ignored");␍␊ |
452 | ␍␊ |
453 | else␍␊ |
454 | {␍␊ |
455 | /* Convert 'width' and 'height' to ASCII. */␍␊ |
456 | char swidth[PNG_sCAL_MAX_DIGITS+1];␍␊ |
457 | char sheight[PNG_sCAL_MAX_DIGITS+1];␍␊ |
458 | ␍␊ |
459 | png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width,␍␊ |
460 | PNG_sCAL_PRECISION);␍␊ |
461 | png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height,␍␊ |
462 | PNG_sCAL_PRECISION);␍␊ |
463 | ␍␊ |
464 | png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);␍␊ |
465 | }␍␊ |
466 | }␍␊ |
467 | # endif␍␊ |
468 | ␍␊ |
469 | # ifdef PNG_FIXED_POINT_SUPPORTED␍␊ |
470 | void PNGAPI␍␊ |
471 | png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit,␍␊ |
472 | png_fixed_point width, png_fixed_point height)␍␊ |
473 | {␍␊ |
474 | png_debug1(1, "in %s storage function", "sCAL");␍␊ |
475 | ␍␊ |
476 | /* Check the arguments. */␍␊ |
477 | if (width <= 0)␍␊ |
478 | png_warning(png_ptr, "Invalid sCAL width ignored");␍␊ |
479 | ␍␊ |
480 | else if (height <= 0)␍␊ |
481 | png_warning(png_ptr, "Invalid sCAL height ignored");␍␊ |
482 | ␍␊ |
483 | else␍␊ |
484 | {␍␊ |
485 | /* Convert 'width' and 'height' to ASCII. */␍␊ |
486 | char swidth[PNG_sCAL_MAX_DIGITS+1];␍␊ |
487 | char sheight[PNG_sCAL_MAX_DIGITS+1];␍␊ |
488 | ␍␊ |
489 | png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width);␍␊ |
490 | png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height);␍␊ |
491 | ␍␊ |
492 | png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);␍␊ |
493 | }␍␊ |
494 | }␍␊ |
495 | # endif␍␊ |
496 | #endif␍␊ |
497 | ␍␊ |
498 | #ifdef PNG_pHYs_SUPPORTED␍␊ |
499 | void PNGAPI␍␊ |
500 | png_set_pHYs(png_structp png_ptr, png_infop info_ptr,␍␊ |
501 | png_uint_32 res_x, png_uint_32 res_y, int unit_type)␍␊ |
502 | {␍␊ |
503 | png_debug1(1, "in %s storage function", "pHYs");␍␊ |
504 | ␍␊ |
505 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
506 | return;␍␊ |
507 | ␍␊ |
508 | info_ptr->x_pixels_per_unit = res_x;␍␊ |
509 | info_ptr->y_pixels_per_unit = res_y;␍␊ |
510 | info_ptr->phys_unit_type = (png_byte)unit_type;␍␊ |
511 | info_ptr->valid |= PNG_INFO_pHYs;␍␊ |
512 | }␍␊ |
513 | #endif␍␊ |
514 | ␍␊ |
515 | void PNGAPI␍␊ |
516 | png_set_PLTE(png_structp png_ptr, png_infop info_ptr,␍␊ |
517 | png_const_colorp palette, int num_palette)␍␊ |
518 | {␍␊ |
519 | ␍␊ |
520 | png_debug1(1, "in %s storage function", "PLTE");␍␊ |
521 | ␍␊ |
522 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
523 | return;␍␊ |
524 | ␍␊ |
525 | if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)␍␊ |
526 | {␍␊ |
527 | if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)␍␊ |
528 | png_error(png_ptr, "Invalid palette length");␍␊ |
529 | ␍␊ |
530 | else␍␊ |
531 | {␍␊ |
532 | png_warning(png_ptr, "Invalid palette length");␍␊ |
533 | return;␍␊ |
534 | }␍␊ |
535 | }␍␊ |
536 | ␍␊ |
537 | /* It may not actually be necessary to set png_ptr->palette here;␍␊ |
538 | * we do it for backward compatibility with the way the png_handle_tRNS␍␊ |
539 | * function used to do the allocation.␍␊ |
540 | */␍␊ |
541 | png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);␍␊ |
542 | ␍␊ |
543 | /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead␍␊ |
544 | * of num_palette entries, in case of an invalid PNG file that has␍␊ |
545 | * too-large sample values.␍␊ |
546 | */␍␊ |
547 | png_ptr->palette = (png_colorp)png_calloc(png_ptr,␍␊ |
548 | PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));␍␊ |
549 | ␍␊ |
550 | png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));␍␊ |
551 | info_ptr->palette = png_ptr->palette;␍␊ |
552 | info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;␍␊ |
553 | ␍␊ |
554 | info_ptr->free_me |= PNG_FREE_PLTE;␍␊ |
555 | ␍␊ |
556 | info_ptr->valid |= PNG_INFO_PLTE;␍␊ |
557 | }␍␊ |
558 | ␍␊ |
559 | #ifdef PNG_sBIT_SUPPORTED␍␊ |
560 | void PNGAPI␍␊ |
561 | png_set_sBIT(png_structp png_ptr, png_infop info_ptr,␍␊ |
562 | png_const_color_8p sig_bit)␍␊ |
563 | {␍␊ |
564 | png_debug1(1, "in %s storage function", "sBIT");␍␊ |
565 | ␍␊ |
566 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
567 | return;␍␊ |
568 | ␍␊ |
569 | png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));␍␊ |
570 | info_ptr->valid |= PNG_INFO_sBIT;␍␊ |
571 | }␍␊ |
572 | #endif␍␊ |
573 | ␍␊ |
574 | #ifdef PNG_sRGB_SUPPORTED␍␊ |
575 | void PNGAPI␍␊ |
576 | png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent)␍␊ |
577 | {␍␊ |
578 | png_debug1(1, "in %s storage function", "sRGB");␍␊ |
579 | ␍␊ |
580 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
581 | return;␍␊ |
582 | ␍␊ |
583 | info_ptr->srgb_intent = (png_byte)srgb_intent;␍␊ |
584 | info_ptr->valid |= PNG_INFO_sRGB;␍␊ |
585 | }␍␊ |
586 | ␍␊ |
587 | void PNGAPI␍␊ |
588 | png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,␍␊ |
589 | int srgb_intent)␍␊ |
590 | {␍␊ |
591 | png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");␍␊ |
592 | ␍␊ |
593 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
594 | return;␍␊ |
595 | ␍␊ |
596 | png_set_sRGB(png_ptr, info_ptr, srgb_intent);␍␊ |
597 | ␍␊ |
598 | # ifdef PNG_gAMA_SUPPORTED␍␊ |
599 | png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);␍␊ |
600 | # endif␍␊ |
601 | ␍␊ |
602 | # ifdef PNG_cHRM_SUPPORTED␍␊ |
603 | png_set_cHRM_fixed(png_ptr, info_ptr,␍␊ |
604 | /* color x y */␍␊ |
605 | /* white */ 31270, 32900,␍␊ |
606 | /* red */ 64000, 33000,␍␊ |
607 | /* green */ 30000, 60000,␍␊ |
608 | /* blue */ 15000, 6000␍␊ |
609 | );␍␊ |
610 | # endif /* cHRM */␍␊ |
611 | }␍␊ |
612 | #endif /* sRGB */␍␊ |
613 | ␍␊ |
614 | ␍␊ |
615 | #ifdef PNG_iCCP_SUPPORTED␍␊ |
616 | void PNGAPI␍␊ |
617 | png_set_iCCP(png_structp png_ptr, png_infop info_ptr,␍␊ |
618 | png_const_charp name, int compression_type,␍␊ |
619 | png_const_bytep profile, png_uint_32 proflen)␍␊ |
620 | {␍␊ |
621 | png_charp new_iccp_name;␍␊ |
622 | png_bytep new_iccp_profile;␍␊ |
623 | png_size_t length;␍␊ |
624 | ␍␊ |
625 | png_debug1(1, "in %s storage function", "iCCP");␍␊ |
626 | ␍␊ |
627 | if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)␍␊ |
628 | return;␍␊ |
629 | ␍␊ |
630 | length = png_strlen(name)+1;␍␊ |
631 | new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);␍␊ |
632 | ␍␊ |
633 | if (new_iccp_name == NULL)␍␊ |
634 | {␍␊ |
635 | png_warning(png_ptr, "Insufficient memory to process iCCP chunk");␍␊ |
636 | return;␍␊ |
637 | }␍␊ |
638 | ␍␊ |
639 | png_memcpy(new_iccp_name, name, length);␍␊ |
640 | new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen);␍␊ |
641 | ␍␊ |
642 | if (new_iccp_profile == NULL)␍␊ |
643 | {␍␊ |
644 | png_free (png_ptr, new_iccp_name);␍␊ |
645 | png_warning(png_ptr,␍␊ |
646 | "Insufficient memory to process iCCP profile");␍␊ |
647 | return;␍␊ |
648 | }␍␊ |
649 | ␍␊ |
650 | png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);␍␊ |
651 | ␍␊ |
652 | png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);␍␊ |
653 | ␍␊ |
654 | info_ptr->iccp_proflen = proflen;␍␊ |
655 | info_ptr->iccp_name = new_iccp_name;␍␊ |
656 | info_ptr->iccp_profile = new_iccp_profile;␍␊ |
657 | /* Compression is always zero but is here so the API and info structure␍␊ |
658 | * does not have to change if we introduce multiple compression types␍␊ |
659 | */␍␊ |
660 | info_ptr->iccp_compression = (png_byte)compression_type;␍␊ |
661 | info_ptr->free_me |= PNG_FREE_ICCP;␍␊ |
662 | info_ptr->valid |= PNG_INFO_iCCP;␍␊ |
663 | }␍␊ |
664 | #endif␍␊ |
665 | ␍␊ |
666 | #ifdef PNG_TEXT_SUPPORTED␍␊ |
667 | void PNGAPI␍␊ |
668 | png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr,␍␊ |
669 | int num_text)␍␊ |
670 | {␍␊ |
671 | int ret;␍␊ |
672 | ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);␍␊ |
673 | ␍␊ |
674 | if (ret)␍␊ |
675 | png_error(png_ptr, "Insufficient memory to store text");␍␊ |
676 | }␍␊ |
677 | ␍␊ |
678 | int /* PRIVATE */␍␊ |
679 | png_set_text_2(png_structp png_ptr, png_infop info_ptr,␍␊ |
680 | png_const_textp text_ptr, int num_text)␍␊ |
681 | {␍␊ |
682 | int i;␍␊ |
683 | ␍␊ |
684 | png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :␍␊ |
685 | (unsigned long)png_ptr->chunk_name);␍␊ |
686 | ␍␊ |
687 | if (png_ptr == NULL || info_ptr == NULL || num_text == 0)␍␊ |
688 | return(0);␍␊ |
689 | ␍␊ |
690 | /* Make sure we have enough space in the "text" array in info_struct␍␊ |
691 | * to hold all of the incoming text_ptr objects.␍␊ |
692 | */␍␊ |
693 | if (info_ptr->num_text + num_text > info_ptr->max_text)␍␊ |
694 | {␍␊ |
695 | int old_max_text = info_ptr->max_text;␍␊ |
696 | int old_num_text = info_ptr->num_text;␍␊ |
697 | ␍␊ |
698 | if (info_ptr->text != NULL)␍␊ |
699 | {␍␊ |
700 | png_textp old_text;␍␊ |
701 | ␍␊ |
702 | info_ptr->max_text = info_ptr->num_text + num_text + 8;␍␊ |
703 | old_text = info_ptr->text;␍␊ |
704 | ␍␊ |
705 | info_ptr->text = (png_textp)png_malloc_warn(png_ptr,␍␊ |
706 | (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));␍␊ |
707 | ␍␊ |
708 | if (info_ptr->text == NULL)␍␊ |
709 | {␍␊ |
710 | /* Restore to previous condition */␍␊ |
711 | info_ptr->max_text = old_max_text;␍␊ |
712 | info_ptr->text = old_text;␍␊ |
713 | return(1);␍␊ |
714 | }␍␊ |
715 | ␍␊ |
716 | png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max_text *␍␊ |
717 | png_sizeof(png_text)));␍␊ |
718 | png_free(png_ptr, old_text);␍␊ |
719 | }␍␊ |
720 | ␍␊ |
721 | else␍␊ |
722 | {␍␊ |
723 | info_ptr->max_text = num_text + 8;␍␊ |
724 | info_ptr->num_text = 0;␍␊ |
725 | info_ptr->text = (png_textp)png_malloc_warn(png_ptr,␍␊ |
726 | (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));␍␊ |
727 | if (info_ptr->text == NULL)␍␊ |
728 | {␍␊ |
729 | /* Restore to previous condition */␍␊ |
730 | info_ptr->num_text = old_num_text;␍␊ |
731 | info_ptr->max_text = old_max_text;␍␊ |
732 | return(1);␍␊ |
733 | }␍␊ |
734 | info_ptr->free_me |= PNG_FREE_TEXT;␍␊ |
735 | }␍␊ |
736 | ␍␊ |
737 | png_debug1(3, "allocated %d entries for info_ptr->text",␍␊ |
738 | info_ptr->max_text);␍␊ |
739 | }␍␊ |
740 | for (i = 0; i < num_text; i++)␍␊ |
741 | {␍␊ |
742 | png_size_t text_length, key_len;␍␊ |
743 | png_size_t lang_len, lang_key_len;␍␊ |
744 | png_textp textp = &(info_ptr->text[info_ptr->num_text]);␍␊ |
745 | ␍␊ |
746 | if (text_ptr[i].key == NULL)␍␊ |
747 | continue;␍␊ |
748 | ␍␊ |
749 | if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||␍␊ |
750 | text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)␍␊ |
751 | {␍␊ |
752 | png_warning(png_ptr, "text compression mode is out of range");␍␊ |
753 | continue;␍␊ |
754 | }␍␊ |
755 | ␍␊ |
756 | key_len = png_strlen(text_ptr[i].key);␍␊ |
757 | ␍␊ |
758 | if (text_ptr[i].compression <= 0)␍␊ |
759 | {␍␊ |
760 | lang_len = 0;␍␊ |
761 | lang_key_len = 0;␍␊ |
762 | }␍␊ |
763 | ␍␊ |
764 | else␍␊ |
765 | # ifdef PNG_iTXt_SUPPORTED␍␊ |
766 | {␍␊ |
767 | /* Set iTXt data */␍␊ |
768 | ␍␊ |
769 | if (text_ptr[i].lang != NULL)␍␊ |
770 | lang_len = png_strlen(text_ptr[i].lang);␍␊ |
771 | ␍␊ |
772 | else␍␊ |
773 | lang_len = 0;␍␊ |
774 | ␍␊ |
775 | if (text_ptr[i].lang_key != NULL)␍␊ |
776 | lang_key_len = png_strlen(text_ptr[i].lang_key);␍␊ |
777 | ␍␊ |
778 | else␍␊ |
779 | lang_key_len = 0;␍␊ |
780 | }␍␊ |
781 | # else /* PNG_iTXt_SUPPORTED */␍␊ |
782 | {␍␊ |
783 | png_warning(png_ptr, "iTXt chunk not supported");␍␊ |
784 | continue;␍␊ |
785 | }␍␊ |
786 | # endif␍␊ |
787 | ␍␊ |
788 | if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')␍␊ |
789 | {␍␊ |
790 | text_length = 0;␍␊ |
791 | # ifdef PNG_iTXt_SUPPORTED␍␊ |
792 | if (text_ptr[i].compression > 0)␍␊ |
793 | textp->compression = PNG_ITXT_COMPRESSION_NONE;␍␊ |
794 | ␍␊ |
795 | else␍␊ |
796 | # endif␍␊ |
797 | textp->compression = PNG_TEXT_COMPRESSION_NONE;␍␊ |
798 | }␍␊ |
799 | ␍␊ |
800 | else␍␊ |
801 | {␍␊ |
802 | text_length = png_strlen(text_ptr[i].text);␍␊ |
803 | textp->compression = text_ptr[i].compression;␍␊ |
804 | }␍␊ |
805 | ␍␊ |
806 | textp->key = (png_charp)png_malloc_warn(png_ptr,␍␊ |
807 | (png_size_t)␍␊ |
808 | (key_len + text_length + lang_len + lang_key_len + 4));␍␊ |
809 | ␍␊ |
810 | if (textp->key == NULL)␍␊ |
811 | return(1);␍␊ |
812 | ␍␊ |
813 | png_debug2(2, "Allocated %lu bytes at %p in png_set_text",␍␊ |
814 | (unsigned long)(png_uint_32)␍␊ |
815 | (key_len + lang_len + lang_key_len + text_length + 4),␍␊ |
816 | textp->key);␍␊ |
817 | ␍␊ |
818 | png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));␍␊ |
819 | *(textp->key + key_len) = '\0';␍␊ |
820 | ␍␊ |
821 | if (text_ptr[i].compression > 0)␍␊ |
822 | {␍␊ |
823 | textp->lang = textp->key + key_len + 1;␍␊ |
824 | png_memcpy(textp->lang, text_ptr[i].lang, lang_len);␍␊ |
825 | *(textp->lang + lang_len) = '\0';␍␊ |
826 | textp->lang_key = textp->lang + lang_len + 1;␍␊ |
827 | png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);␍␊ |
828 | *(textp->lang_key + lang_key_len) = '\0';␍␊ |
829 | textp->text = textp->lang_key + lang_key_len + 1;␍␊ |
830 | }␍␊ |
831 | ␍␊ |
832 | else␍␊ |
833 | {␍␊ |
834 | textp->lang=NULL;␍␊ |
835 | textp->lang_key=NULL;␍␊ |
836 | textp->text = textp->key + key_len + 1;␍␊ |
837 | }␍␊ |
838 | ␍␊ |
839 | if (text_length)␍␊ |
840 | png_memcpy(textp->text, text_ptr[i].text,␍␊ |
841 | (png_size_t)(text_length));␍␊ |
842 | ␍␊ |
843 | *(textp->text + text_length) = '\0';␍␊ |
844 | ␍␊ |
845 | # ifdef PNG_iTXt_SUPPORTED␍␊ |
846 | if (textp->compression > 0)␍␊ |
847 | {␍␊ |
848 | textp->text_length = 0;␍␊ |
849 | textp->itxt_length = text_length;␍␊ |
850 | }␍␊ |
851 | ␍␊ |
852 | else␍␊ |
853 | # endif␍␊ |
854 | {␍␊ |
855 | textp->text_length = text_length;␍␊ |
856 | textp->itxt_length = 0;␍␊ |
857 | }␍␊ |
858 | ␍␊ |
859 | info_ptr->num_text++;␍␊ |
860 | png_debug1(3, "transferred text chunk %d", info_ptr->num_text);␍␊ |
861 | }␍␊ |
862 | return(0);␍␊ |
863 | }␍␊ |
864 | #endif␍␊ |
865 | ␍␊ |
866 | #ifdef PNG_tIME_SUPPORTED␍␊ |
867 | void PNGAPI␍␊ |
868 | png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)␍␊ |
869 | {␍␊ |
870 | png_debug1(1, "in %s storage function", "tIME");␍␊ |
871 | ␍␊ |
872 | if (png_ptr == NULL || info_ptr == NULL ||␍␊ |
873 | (png_ptr->mode & PNG_WROTE_tIME))␍␊ |
874 | return;␍␊ |
875 | ␍␊ |
876 | if (mod_time->month == 0 || mod_time->month > 12 ||␍␊ |
877 | mod_time->day == 0 || mod_time->day > 31 ||␍␊ |
878 | mod_time->hour > 23 || mod_time->minute > 59 ||␍␊ |
879 | mod_time->second > 60)␍␊ |
880 | {␍␊ |
881 | png_warning(png_ptr, "Ignoring invalid time value");␍␊ |
882 | return;␍␊ |
883 | }␍␊ |
884 | ␍␊ |
885 | png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));␍␊ |
886 | info_ptr->valid |= PNG_INFO_tIME;␍␊ |
887 | }␍␊ |
888 | #endif␍␊ |
889 | ␍␊ |
890 | #ifdef PNG_tRNS_SUPPORTED␍␊ |
891 | void PNGAPI␍␊ |
892 | png_set_tRNS(png_structp png_ptr, png_infop info_ptr,␍␊ |
893 | png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)␍␊ |
894 | {␍␊ |
895 | png_debug1(1, "in %s storage function", "tRNS");␍␊ |
896 | ␍␊ |
897 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
898 | return;␍␊ |
899 | ␍␊ |
900 | if (trans_alpha != NULL)␍␊ |
901 | {␍␊ |
902 | /* It may not actually be necessary to set png_ptr->trans_alpha here;␍␊ |
903 | * we do it for backward compatibility with the way the png_handle_tRNS␍␊ |
904 | * function used to do the allocation.␍␊ |
905 | */␍␊ |
906 | ␍␊ |
907 | png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);␍␊ |
908 | ␍␊ |
909 | /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */␍␊ |
910 | png_ptr->trans_alpha = info_ptr->trans_alpha =␍␊ |
911 | (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH);␍␊ |
912 | ␍␊ |
913 | if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)␍␊ |
914 | png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);␍␊ |
915 | }␍␊ |
916 | ␍␊ |
917 | if (trans_color != NULL)␍␊ |
918 | {␍␊ |
919 | int sample_max = (1 << info_ptr->bit_depth);␍␊ |
920 | ␍␊ |
921 | if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&␍␊ |
922 | (int)trans_color->gray > sample_max) ||␍␊ |
923 | (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&␍␊ |
924 | ((int)trans_color->red > sample_max ||␍␊ |
925 | (int)trans_color->green > sample_max ||␍␊ |
926 | (int)trans_color->blue > sample_max)))␍␊ |
927 | png_warning(png_ptr,␍␊ |
928 | "tRNS chunk has out-of-range samples for bit_depth");␍␊ |
929 | ␍␊ |
930 | png_memcpy(&(info_ptr->trans_color), trans_color,␍␊ |
931 | png_sizeof(png_color_16));␍␊ |
932 | ␍␊ |
933 | if (num_trans == 0)␍␊ |
934 | num_trans = 1;␍␊ |
935 | }␍␊ |
936 | ␍␊ |
937 | info_ptr->num_trans = (png_uint_16)num_trans;␍␊ |
938 | ␍␊ |
939 | if (num_trans != 0)␍␊ |
940 | {␍␊ |
941 | info_ptr->valid |= PNG_INFO_tRNS;␍␊ |
942 | info_ptr->free_me |= PNG_FREE_TRNS;␍␊ |
943 | }␍␊ |
944 | }␍␊ |
945 | #endif␍␊ |
946 | ␍␊ |
947 | #ifdef PNG_sPLT_SUPPORTED␍␊ |
948 | void PNGAPI␍␊ |
949 | png_set_sPLT(png_structp png_ptr,␍␊ |
950 | png_infop info_ptr, png_const_sPLT_tp entries, int nentries)␍␊ |
951 | /*␍␊ |
952 | * entries - array of png_sPLT_t structures␍␊ |
953 | * to be added to the list of palettes␍␊ |
954 | * in the info structure.␍␊ |
955 | *␍␊ |
956 | * nentries - number of palette structures to be␍␊ |
957 | * added.␍␊ |
958 | */␍␊ |
959 | {␍␊ |
960 | png_sPLT_tp np;␍␊ |
961 | int i;␍␊ |
962 | ␍␊ |
963 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
964 | return;␍␊ |
965 | ␍␊ |
966 | np = (png_sPLT_tp)png_malloc_warn(png_ptr,␍␊ |
967 | (info_ptr->splt_palettes_num + nentries) *␍␊ |
968 | (png_size_t)png_sizeof(png_sPLT_t));␍␊ |
969 | ␍␊ |
970 | if (np == NULL)␍␊ |
971 | {␍␊ |
972 | png_warning(png_ptr, "No memory for sPLT palettes");␍␊ |
973 | return;␍␊ |
974 | }␍␊ |
975 | ␍␊ |
976 | png_memcpy(np, info_ptr->splt_palettes,␍␊ |
977 | info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));␍␊ |
978 | ␍␊ |
979 | png_free(png_ptr, info_ptr->splt_palettes);␍␊ |
980 | info_ptr->splt_palettes=NULL;␍␊ |
981 | ␍␊ |
982 | for (i = 0; i < nentries; i++)␍␊ |
983 | {␍␊ |
984 | png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;␍␊ |
985 | png_const_sPLT_tp from = entries + i;␍␊ |
986 | png_size_t length;␍␊ |
987 | ␍␊ |
988 | length = png_strlen(from->name) + 1;␍␊ |
989 | to->name = (png_charp)png_malloc_warn(png_ptr, length);␍␊ |
990 | ␍␊ |
991 | if (to->name == NULL)␍␊ |
992 | {␍␊ |
993 | png_warning(png_ptr,␍␊ |
994 | "Out of memory while processing sPLT chunk");␍␊ |
995 | continue;␍␊ |
996 | }␍␊ |
997 | ␍␊ |
998 | png_memcpy(to->name, from->name, length);␍␊ |
999 | to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,␍␊ |
1000 | from->nentries * png_sizeof(png_sPLT_entry));␍␊ |
1001 | ␍␊ |
1002 | if (to->entries == NULL)␍␊ |
1003 | {␍␊ |
1004 | png_warning(png_ptr,␍␊ |
1005 | "Out of memory while processing sPLT chunk");␍␊ |
1006 | png_free(png_ptr, to->name);␍␊ |
1007 | to->name = NULL;␍␊ |
1008 | continue;␍␊ |
1009 | }␍␊ |
1010 | ␍␊ |
1011 | png_memcpy(to->entries, from->entries,␍␊ |
1012 | from->nentries * png_sizeof(png_sPLT_entry));␍␊ |
1013 | ␍␊ |
1014 | to->nentries = from->nentries;␍␊ |
1015 | to->depth = from->depth;␍␊ |
1016 | }␍␊ |
1017 | ␍␊ |
1018 | info_ptr->splt_palettes = np;␍␊ |
1019 | info_ptr->splt_palettes_num += nentries;␍␊ |
1020 | info_ptr->valid |= PNG_INFO_sPLT;␍␊ |
1021 | info_ptr->free_me |= PNG_FREE_SPLT;␍␊ |
1022 | }␍␊ |
1023 | #endif /* PNG_sPLT_SUPPORTED */␍␊ |
1024 | ␍␊ |
1025 | #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED␍␊ |
1026 | void PNGAPI␍␊ |
1027 | png_set_unknown_chunks(png_structp png_ptr,␍␊ |
1028 | png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)␍␊ |
1029 | {␍␊ |
1030 | png_unknown_chunkp np;␍␊ |
1031 | int i;␍␊ |
1032 | ␍␊ |
1033 | if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)␍␊ |
1034 | return;␍␊ |
1035 | ␍␊ |
1036 | np = (png_unknown_chunkp)png_malloc_warn(png_ptr,␍␊ |
1037 | (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) *␍␊ |
1038 | png_sizeof(png_unknown_chunk));␍␊ |
1039 | ␍␊ |
1040 | if (np == NULL)␍␊ |
1041 | {␍␊ |
1042 | png_warning(png_ptr,␍␊ |
1043 | "Out of memory while processing unknown chunk");␍␊ |
1044 | return;␍␊ |
1045 | }␍␊ |
1046 | ␍␊ |
1047 | png_memcpy(np, info_ptr->unknown_chunks,␍␊ |
1048 | (png_size_t)info_ptr->unknown_chunks_num *␍␊ |
1049 | png_sizeof(png_unknown_chunk));␍␊ |
1050 | ␍␊ |
1051 | png_free(png_ptr, info_ptr->unknown_chunks);␍␊ |
1052 | info_ptr->unknown_chunks = NULL;␍␊ |
1053 | ␍␊ |
1054 | for (i = 0; i < num_unknowns; i++)␍␊ |
1055 | {␍␊ |
1056 | png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;␍␊ |
1057 | png_const_unknown_chunkp from = unknowns + i;␍␊ |
1058 | ␍␊ |
1059 | png_memcpy(to->name, from->name, png_sizeof(from->name));␍␊ |
1060 | to->name[png_sizeof(to->name)-1] = '\0';␍␊ |
1061 | to->size = from->size;␍␊ |
1062 | ␍␊ |
1063 | /* Note our location in the read or write sequence */␍␊ |
1064 | to->location = (png_byte)(png_ptr->mode & 0xff);␍␊ |
1065 | ␍␊ |
1066 | if (from->size == 0)␍␊ |
1067 | to->data=NULL;␍␊ |
1068 | ␍␊ |
1069 | else␍␊ |
1070 | {␍␊ |
1071 | to->data = (png_bytep)png_malloc_warn(png_ptr,␍␊ |
1072 | (png_size_t)from->size);␍␊ |
1073 | ␍␊ |
1074 | if (to->data == NULL)␍␊ |
1075 | {␍␊ |
1076 | png_warning(png_ptr,␍␊ |
1077 | "Out of memory while processing unknown chunk");␍␊ |
1078 | to->size = 0;␍␊ |
1079 | }␍␊ |
1080 | ␍␊ |
1081 | else␍␊ |
1082 | png_memcpy(to->data, from->data, from->size);␍␊ |
1083 | }␍␊ |
1084 | }␍␊ |
1085 | ␍␊ |
1086 | info_ptr->unknown_chunks = np;␍␊ |
1087 | info_ptr->unknown_chunks_num += num_unknowns;␍␊ |
1088 | info_ptr->free_me |= PNG_FREE_UNKN;␍␊ |
1089 | }␍␊ |
1090 | ␍␊ |
1091 | void PNGAPI␍␊ |
1092 | png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,␍␊ |
1093 | int chunk, int location)␍␊ |
1094 | {␍␊ |
1095 | if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <␍␊ |
1096 | info_ptr->unknown_chunks_num)␍␊ |
1097 | info_ptr->unknown_chunks[chunk].location = (png_byte)location;␍␊ |
1098 | }␍␊ |
1099 | #endif␍␊ |
1100 | ␍␊ |
1101 | ␍␊ |
1102 | #ifdef PNG_MNG_FEATURES_SUPPORTED␍␊ |
1103 | png_uint_32 PNGAPI␍␊ |
1104 | png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)␍␊ |
1105 | {␍␊ |
1106 | png_debug(1, "in png_permit_mng_features");␍␊ |
1107 | ␍␊ |
1108 | if (png_ptr == NULL)␍␊ |
1109 | return (png_uint_32)0;␍␊ |
1110 | ␍␊ |
1111 | png_ptr->mng_features_permitted =␍␊ |
1112 | (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);␍␊ |
1113 | ␍␊ |
1114 | return (png_uint_32)png_ptr->mng_features_permitted;␍␊ |
1115 | }␍␊ |
1116 | #endif␍␊ |
1117 | ␍␊ |
1118 | #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED␍␊ |
1119 | void PNGAPI␍␊ |
1120 | png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep␍␊ |
1121 | chunk_list, int num_chunks)␍␊ |
1122 | {␍␊ |
1123 | png_bytep new_list, p;␍␊ |
1124 | int i, old_num_chunks;␍␊ |
1125 | if (png_ptr == NULL)␍␊ |
1126 | return;␍␊ |
1127 | ␍␊ |
1128 | if (num_chunks == 0)␍␊ |
1129 | {␍␊ |
1130 | if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)␍␊ |
1131 | png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;␍␊ |
1132 | ␍␊ |
1133 | else␍␊ |
1134 | png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;␍␊ |
1135 | ␍␊ |
1136 | if (keep == PNG_HANDLE_CHUNK_ALWAYS)␍␊ |
1137 | png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;␍␊ |
1138 | ␍␊ |
1139 | else␍␊ |
1140 | png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;␍␊ |
1141 | ␍␊ |
1142 | return;␍␊ |
1143 | }␍␊ |
1144 | ␍␊ |
1145 | if (chunk_list == NULL)␍␊ |
1146 | return;␍␊ |
1147 | ␍␊ |
1148 | old_num_chunks = png_ptr->num_chunk_list;␍␊ |
1149 | new_list=(png_bytep)png_malloc(png_ptr,␍␊ |
1150 | (png_size_t)(5*(num_chunks + old_num_chunks)));␍␊ |
1151 | ␍␊ |
1152 | if (png_ptr->chunk_list != NULL)␍␊ |
1153 | {␍␊ |
1154 | png_memcpy(new_list, png_ptr->chunk_list,␍␊ |
1155 | (png_size_t)(5*old_num_chunks));␍␊ |
1156 | png_free(png_ptr, png_ptr->chunk_list);␍␊ |
1157 | png_ptr->chunk_list=NULL;␍␊ |
1158 | }␍␊ |
1159 | ␍␊ |
1160 | png_memcpy(new_list + 5*old_num_chunks, chunk_list,␍␊ |
1161 | (png_size_t)(5*num_chunks));␍␊ |
1162 | ␍␊ |
1163 | for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5)␍␊ |
1164 | *p=(png_byte)keep;␍␊ |
1165 | ␍␊ |
1166 | png_ptr->num_chunk_list = old_num_chunks + num_chunks;␍␊ |
1167 | png_ptr->chunk_list = new_list;␍␊ |
1168 | png_ptr->free_me |= PNG_FREE_LIST;␍␊ |
1169 | }␍␊ |
1170 | #endif␍␊ |
1171 | ␍␊ |
1172 | #ifdef PNG_READ_USER_CHUNKS_SUPPORTED␍␊ |
1173 | void PNGAPI␍␊ |
1174 | png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,␍␊ |
1175 | png_user_chunk_ptr read_user_chunk_fn)␍␊ |
1176 | {␍␊ |
1177 | png_debug(1, "in png_set_read_user_chunk_fn");␍␊ |
1178 | ␍␊ |
1179 | if (png_ptr == NULL)␍␊ |
1180 | return;␍␊ |
1181 | ␍␊ |
1182 | png_ptr->read_user_chunk_fn = read_user_chunk_fn;␍␊ |
1183 | png_ptr->user_chunk_ptr = user_chunk_ptr;␍␊ |
1184 | }␍␊ |
1185 | #endif␍␊ |
1186 | ␍␊ |
1187 | #ifdef PNG_INFO_IMAGE_SUPPORTED␍␊ |
1188 | void PNGAPI␍␊ |
1189 | png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)␍␊ |
1190 | {␍␊ |
1191 | png_debug1(1, "in %s storage function", "rows");␍␊ |
1192 | ␍␊ |
1193 | if (png_ptr == NULL || info_ptr == NULL)␍␊ |
1194 | return;␍␊ |
1195 | ␍␊ |
1196 | if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))␍␊ |
1197 | png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);␍␊ |
1198 | ␍␊ |
1199 | info_ptr->row_pointers = row_pointers;␍␊ |
1200 | ␍␊ |
1201 | if (row_pointers)␍␊ |
1202 | info_ptr->valid |= PNG_INFO_IDAT;␍␊ |
1203 | }␍␊ |
1204 | #endif␍␊ |
1205 | ␍␊ |
1206 | void PNGAPI␍␊ |
1207 | png_set_compression_buffer_size(png_structp png_ptr, png_size_t size)␍␊ |
1208 | {␍␊ |
1209 | if (png_ptr == NULL)␍␊ |
1210 | return;␍␊ |
1211 | ␍␊ |
1212 | png_free(png_ptr, png_ptr->zbuf);␍␊ |
1213 | ␍␊ |
1214 | if (size > ZLIB_IO_MAX)␍␊ |
1215 | {␍␊ |
1216 | png_warning(png_ptr, "Attempt to set buffer size beyond max ignored");␍␊ |
1217 | png_ptr->zbuf_size = ZLIB_IO_MAX;␍␊ |
1218 | size = ZLIB_IO_MAX; /* must fit */␍␊ |
1219 | }␍␊ |
1220 | ␍␊ |
1221 | else␍␊ |
1222 | png_ptr->zbuf_size = (uInt)size;␍␊ |
1223 | ␍␊ |
1224 | png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);␍␊ |
1225 | ␍␊ |
1226 | /* The following ensures a relatively safe failure if this gets called while␍␊ |
1227 | * the buffer is actually in use.␍␊ |
1228 | */␍␊ |
1229 | png_ptr->zstream.next_out = png_ptr->zbuf;␍␊ |
1230 | png_ptr->zstream.avail_out = 0;␍␊ |
1231 | png_ptr->zstream.avail_in = 0;␍␊ |
1232 | }␍␊ |
1233 | ␍␊ |
1234 | void PNGAPI␍␊ |
1235 | png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)␍␊ |
1236 | {␍␊ |
1237 | if (png_ptr && info_ptr)␍␊ |
1238 | info_ptr->valid &= ~mask;␍␊ |
1239 | }␍␊ |
1240 | ␍␊ |
1241 | ␍␊ |
1242 | ␍␊ |
1243 | #ifdef PNG_SET_USER_LIMITS_SUPPORTED␍␊ |
1244 | /* This function was added to libpng 1.2.6 */␍␊ |
1245 | void PNGAPI␍␊ |
1246 | png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,␍␊ |
1247 | png_uint_32 user_height_max)␍␊ |
1248 | {␍␊ |
1249 | /* Images with dimensions larger than these limits will be␍␊ |
1250 | * rejected by png_set_IHDR(). To accept any PNG datastream␍␊ |
1251 | * regardless of dimensions, set both limits to 0x7ffffffL.␍␊ |
1252 | */␍␊ |
1253 | if (png_ptr == NULL)␍␊ |
1254 | return;␍␊ |
1255 | ␍␊ |
1256 | png_ptr->user_width_max = user_width_max;␍␊ |
1257 | png_ptr->user_height_max = user_height_max;␍␊ |
1258 | }␍␊ |
1259 | ␍␊ |
1260 | /* This function was added to libpng 1.4.0 */␍␊ |
1261 | void PNGAPI␍␊ |
1262 | png_set_chunk_cache_max (png_structp png_ptr,␍␊ |
1263 | png_uint_32 user_chunk_cache_max)␍␊ |
1264 | {␍␊ |
1265 | if (png_ptr)␍␊ |
1266 | png_ptr->user_chunk_cache_max = user_chunk_cache_max;␍␊ |
1267 | }␍␊ |
1268 | ␍␊ |
1269 | /* This function was added to libpng 1.4.1 */␍␊ |
1270 | void PNGAPI␍␊ |
1271 | png_set_chunk_malloc_max (png_structp png_ptr,␍␊ |
1272 | png_alloc_size_t user_chunk_malloc_max)␍␊ |
1273 | {␍␊ |
1274 | if (png_ptr)␍␊ |
1275 | png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;␍␊ |
1276 | }␍␊ |
1277 | #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */␍␊ |
1278 | ␍␊ |
1279 | ␍␊ |
1280 | #ifdef PNG_BENIGN_ERRORS_SUPPORTED␍␊ |
1281 | void PNGAPI␍␊ |
1282 | png_set_benign_errors(png_structp png_ptr, int allowed)␍␊ |
1283 | {␍␊ |
1284 | png_debug(1, "in png_set_benign_errors");␍␊ |
1285 | ␍␊ |
1286 | if (allowed)␍␊ |
1287 | png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;␍␊ |
1288 | ␍␊ |
1289 | else␍␊ |
1290 | png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;␍␊ |
1291 | }␍␊ |
1292 | #endif /* PNG_BENIGN_ERRORS_SUPPORTED */␍␊ |
1293 | ␍␊ |
1294 | #ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED␍␊ |
1295 | /* Whether to report invalid palette index; added at libng-1.5.10␍␊ |
1296 | * allowed - one of 0: disable; 1: enable␍␊ |
1297 | */␍␊ |
1298 | void PNGAPI␍␊ |
1299 | png_set_check_for_invalid_index(png_structp png_ptr, int allowed)␍␊ |
1300 | {␍␊ |
1301 | png_debug(1, "in png_set_check_for_invalid_index");␍␊ |
1302 | ␍␊ |
1303 | if (allowed)␍␊ |
1304 | png_ptr->num_palette_max = 0;␍␊ |
1305 | ␍␊ |
1306 | else␍␊ |
1307 | png_ptr->num_palette_max = -1;␍␊ |
1308 | }␍␊ |
1309 | #endif␍␊ |
1310 | ␍␊ |
1311 | #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */␍␊ |
1312 | |