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