21
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
23
#ifdef PNG_bKGD_SUPPORTED
25
png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
26
png_const_color_16p background)
28
png_debug1(1, "in %s storage function", "bKGD");
30
if (png_ptr == NULL || info_ptr == NULL || background == NULL)
33
info_ptr->background = *background;
34
info_ptr->valid |= PNG_INFO_bKGD;
38
#ifdef PNG_cHRM_SUPPORTED
40
png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp 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)
47
png_debug1(1, "in %s storage function", "cHRM fixed");
49
if (png_ptr == NULL || info_ptr == NULL)
61
if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy,
63
info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
65
png_colorspace_sync_info(png_ptr, info_ptr);
69
png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
70
png_fixed_point int_red_X, png_fixed_point int_red_Y,
71
png_fixed_point int_red_Z, png_fixed_point int_green_X,
72
png_fixed_point int_green_Y, png_fixed_point int_green_Z,
73
png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
74
png_fixed_point int_blue_Z)
78
png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
80
if (png_ptr == NULL || info_ptr == NULL)
83
XYZ.red_X = int_red_X;
84
XYZ.red_Y = int_red_Y;
85
XYZ.red_Z = int_red_Z;
86
XYZ.green_X = int_green_X;
87
XYZ.green_Y = int_green_Y;
88
XYZ.green_Z = int_green_Z;
89
XYZ.blue_X = int_blue_X;
90
XYZ.blue_Y = int_blue_Y;
91
XYZ.blue_Z = int_blue_Z;
93
if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace,
95
info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
97
png_colorspace_sync_info(png_ptr, info_ptr);
100
# ifdef PNG_FLOATING_POINT_SUPPORTED
102
png_set_cHRM(png_const_structrp png_ptr, png_inforp 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)
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"));
118
png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp 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)
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 Green X"),
127
png_fixed(png_ptr, green_Y, "cHRM Green Y"),
128
png_fixed(png_ptr, green_Z, "cHRM Green Z"),
129
png_fixed(png_ptr, blue_X, "cHRM Blue X"),
130
png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
131
png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
137
#ifdef PNG_eXIf_SUPPORTED
139
png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
142
png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
148
png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
149
png_uint_32 num_exif, png_bytep exif)
153
png_debug1(1, "in %s storage function", "eXIf");
155
if (png_ptr == NULL || info_ptr == NULL ||
156
(png_ptr->mode & PNG_WROTE_eXIf) != 0)
159
new_exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr, num_exif));
161
if (new_exif == NULL)
163
png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
167
memcpy(new_exif, exif, (size_t)num_exif);
169
png_free_data(png_ptr, info_ptr, PNG_FREE_EXIF, 0);
171
info_ptr->num_exif = num_exif;
172
info_ptr->exif = new_exif;
173
info_ptr->free_me |= PNG_FREE_EXIF;
174
info_ptr->valid |= PNG_INFO_eXIf;
178
#ifdef PNG_gAMA_SUPPORTED
180
png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
181
png_fixed_point file_gamma)
183
png_debug1(1, "in %s storage function", "gAMA");
185
if (png_ptr == NULL || info_ptr == NULL)
188
png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);
189
png_colorspace_sync_info(png_ptr, info_ptr);
192
# ifdef PNG_FLOATING_POINT_SUPPORTED
194
png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma)
196
png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
202
#ifdef PNG_hIST_SUPPORTED
204
png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
205
png_const_uint_16p hist)
209
png_debug1(1, "in %s storage function", "hIST");
211
if (png_ptr == NULL || info_ptr == NULL)
214
if (info_ptr->num_palette == 0 || info_ptr->num_palette
215
> PNG_MAX_PALETTE_LENGTH)
218
"Invalid palette size, hIST allocation skipped");
223
png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
228
info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr,
229
PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16))));
231
if (info_ptr->hist == NULL)
233
png_warning(png_ptr, "Insufficient memory for hIST chunk data");
237
for (i = 0; i < info_ptr->num_palette; i++)
238
info_ptr->hist[i] = hist[i];
240
info_ptr->free_me |= PNG_FREE_HIST;
241
info_ptr->valid |= PNG_INFO_hIST;
246
png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
247
png_uint_32 width, png_uint_32 height, int bit_depth,
248
int color_type, int interlace_type, int compression_type,
251
png_debug1(1, "in %s storage function", "IHDR");
253
if (png_ptr == NULL || info_ptr == NULL)
256
info_ptr->width = width;
257
info_ptr->height = height;
258
info_ptr->bit_depth = (png_byte)bit_depth;
259
info_ptr->color_type = (png_byte)color_type;
260
info_ptr->compression_type = (png_byte)compression_type;
261
info_ptr->filter_type = (png_byte)filter_type;
262
info_ptr->interlace_type = (png_byte)interlace_type;
264
png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
265
info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
266
info_ptr->compression_type, info_ptr->filter_type);
268
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
269
info_ptr->channels = 1;
271
else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
272
info_ptr->channels = 3;
275
info_ptr->channels = 1;
277
if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
278
info_ptr->channels++;
280
info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
282
info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
285
#ifdef PNG_oFFs_SUPPORTED
287
png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr,
288
png_int_32 offset_x, png_int_32 offset_y, int unit_type)
290
png_debug1(1, "in %s storage function", "oFFs");
292
if (png_ptr == NULL || info_ptr == NULL)
295
info_ptr->x_offset = offset_x;
296
info_ptr->y_offset = offset_y;
297
info_ptr->offset_unit_type = (png_byte)unit_type;
298
info_ptr->valid |= PNG_INFO_oFFs;
302
#ifdef PNG_pCAL_SUPPORTED
304
png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
305
png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
306
int nparams, png_const_charp units, png_charpp params)
311
png_debug1(1, "in %s storage function", "pCAL");
313
if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL
314
|| (nparams > 0 && params == NULL))
317
length = strlen(purpose) + 1;
318
png_debug1(3, "allocating purpose for info (%lu bytes)",
319
(unsigned long)length);
324
if (type < 0 || type > 3)
326
png_chunk_report(png_ptr, "Invalid pCAL equation type",
327
PNG_CHUNK_WRITE_ERROR);
331
if (nparams < 0 || nparams > 255)
333
png_chunk_report(png_ptr, "Invalid pCAL parameter count",
334
PNG_CHUNK_WRITE_ERROR);
339
for (i=0; i<nparams; ++i)
341
if (params[i] == NULL ||
342
!png_check_fp_string(params[i], strlen(params[i])))
344
png_chunk_report(png_ptr, "Invalid format for pCAL parameter",
345
PNG_CHUNK_WRITE_ERROR);
350
info_ptr->pcal_purpose = png_voidcast(png_charp,
351
png_malloc_warn(png_ptr, length));
353
if (info_ptr->pcal_purpose == NULL)
355
png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose",
356
PNG_CHUNK_WRITE_ERROR);
360
memcpy(info_ptr->pcal_purpose, purpose, length);
362
info_ptr->free_me |= PNG_FREE_PCAL;
364
png_debug(3, "storing X0, X1, type, and nparams in info");
365
info_ptr->pcal_X0 = X0;
366
info_ptr->pcal_X1 = X1;
367
info_ptr->pcal_type = (png_byte)type;
368
info_ptr->pcal_nparams = (png_byte)nparams;
370
length = strlen(units) + 1;
371
png_debug1(3, "allocating units for info (%lu bytes)",
372
(unsigned long)length);
374
info_ptr->pcal_units = png_voidcast(png_charp,
375
png_malloc_warn(png_ptr, length));
377
if (info_ptr->pcal_units == NULL)
379
png_warning(png_ptr, "Insufficient memory for pCAL units");
383
memcpy(info_ptr->pcal_units, units, length);
385
info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
386
(size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp)))));
388
if (info_ptr->pcal_params == NULL)
390
png_warning(png_ptr, "Insufficient memory for pCAL params");
394
memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) *
395
(sizeof (png_charp)));
397
for (i = 0; i < nparams; i++)
399
length = strlen(params[i]) + 1;
400
png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
401
(unsigned long)length);
403
info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
405
if (info_ptr->pcal_params[i] == NULL)
407
png_warning(png_ptr, "Insufficient memory for pCAL parameter");
411
memcpy(info_ptr->pcal_params[i], params[i], length);
414
info_ptr->valid |= PNG_INFO_pCAL;
418
#ifdef PNG_sCAL_SUPPORTED
420
png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
421
int unit, png_const_charp swidth, png_const_charp sheight)
423
size_t lengthw = 0, lengthh = 0;
425
png_debug1(1, "in %s storage function", "sCAL");
427
if (png_ptr == NULL || info_ptr == NULL)
433
if (unit != 1 && unit != 2)
434
png_error(png_ptr, "Invalid sCAL unit");
436
if (swidth == NULL || (lengthw = strlen(swidth)) == 0 ||
437
swidth[0] == 45 || !png_check_fp_string(swidth, lengthw))
438
png_error(png_ptr, "Invalid sCAL width");
440
if (sheight == NULL || (lengthh = strlen(sheight)) == 0 ||
441
sheight[0] == 45 || !png_check_fp_string(sheight, lengthh))
442
png_error(png_ptr, "Invalid sCAL height");
444
info_ptr->scal_unit = (png_byte)unit;
448
png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
450
info_ptr->scal_s_width = png_voidcast(png_charp,
451
png_malloc_warn(png_ptr, lengthw));
453
if (info_ptr->scal_s_width == NULL)
455
png_warning(png_ptr, "Memory allocation failed while processing sCAL");
460
memcpy(info_ptr->scal_s_width, swidth, lengthw);
464
png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
466
info_ptr->scal_s_height = png_voidcast(png_charp,
467
png_malloc_warn(png_ptr, lengthh));
469
if (info_ptr->scal_s_height == NULL)
471
png_free(png_ptr, info_ptr->scal_s_width);
472
info_ptr->scal_s_width = NULL;
474
png_warning(png_ptr, "Memory allocation failed while processing sCAL");
478
memcpy(info_ptr->scal_s_height, sheight, lengthh);
480
info_ptr->free_me |= PNG_FREE_SCAL;
481
info_ptr->valid |= PNG_INFO_sCAL;
484
# ifdef PNG_FLOATING_POINT_SUPPORTED
486
png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
487
double width, double height)
489
png_debug1(1, "in %s storage function", "sCAL");
493
png_warning(png_ptr, "Invalid sCAL width ignored");
495
else if (height <= 0)
496
png_warning(png_ptr, "Invalid sCAL height ignored");
501
char swidth[PNG_sCAL_MAX_DIGITS+1];
502
char sheight[PNG_sCAL_MAX_DIGITS+1];
504
png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
506
png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
509
png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
514
# ifdef PNG_FIXED_POINT_SUPPORTED
516
png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
517
png_fixed_point width, png_fixed_point height)
519
png_debug1(1, "in %s storage function", "sCAL");
523
png_warning(png_ptr, "Invalid sCAL width ignored");
525
else if (height <= 0)
526
png_warning(png_ptr, "Invalid sCAL height ignored");
531
char swidth[PNG_sCAL_MAX_DIGITS+1];
532
char sheight[PNG_sCAL_MAX_DIGITS+1];
534
png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width);
535
png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height);
537
png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
543
#ifdef PNG_pHYs_SUPPORTED
545
png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr,
546
png_uint_32 res_x, png_uint_32 res_y, int unit_type)
548
png_debug1(1, "in %s storage function", "pHYs");
550
if (png_ptr == NULL || info_ptr == NULL)
553
info_ptr->x_pixels_per_unit = res_x;
554
info_ptr->y_pixels_per_unit = res_y;
555
info_ptr->phys_unit_type = (png_byte)unit_type;
556
info_ptr->valid |= PNG_INFO_pHYs;
561
png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
562
png_const_colorp palette, int num_palette)
565
png_uint_32 max_palette_length;
567
png_debug1(1, "in %s storage function", "PLTE");
569
if (png_ptr == NULL || info_ptr == NULL)
572
max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
573
(1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
575
if (num_palette < 0 || num_palette > (int) max_palette_length)
577
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
578
png_error(png_ptr, "Invalid palette length");
582
png_warning(png_ptr, "Invalid palette length");
588
if ((num_palette > 0 && palette == NULL) ||
590
# ifdef PNG_MNG_FEATURES_SUPPORTED
591
&& (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
595
png_error(png_ptr, "Invalid palette");
605
png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
611
png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
612
PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
615
memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
616
(sizeof (png_color)));
618
info_ptr->palette = png_ptr->palette;
619
info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
620
info_ptr->free_me |= PNG_FREE_PLTE;
621
info_ptr->valid |= PNG_INFO_PLTE;
624
#ifdef PNG_sBIT_SUPPORTED
626
png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
627
png_const_color_8p sig_bit)
629
png_debug1(1, "in %s storage function", "sBIT");
631
if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL)
634
info_ptr->sig_bit = *sig_bit;
635
info_ptr->valid |= PNG_INFO_sBIT;
639
#ifdef PNG_sRGB_SUPPORTED
641
png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)
643
png_debug1(1, "in %s storage function", "sRGB");
645
if (png_ptr == NULL || info_ptr == NULL)
648
(void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);
649
png_colorspace_sync_info(png_ptr, info_ptr);
653
png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
656
png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
658
if (png_ptr == NULL || info_ptr == NULL)
661
if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace,
665
info_ptr->colorspace.flags |=
666
PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
669
png_colorspace_sync_info(png_ptr, info_ptr);
674
#ifdef PNG_iCCP_SUPPORTED
676
png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
677
png_const_charp name, int compression_type,
678
png_const_bytep profile, png_uint_32 proflen)
680
png_charp new_iccp_name;
681
png_bytep new_iccp_profile;
684
png_debug1(1, "in %s storage function", "iCCP");
686
if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
689
if (compression_type != PNG_COMPRESSION_TYPE_BASE)
690
png_app_error(png_ptr, "Invalid iCCP compression method");
699
int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
700
proflen, profile, info_ptr->color_type);
702
png_colorspace_sync_info(png_ptr, info_ptr);
709
info_ptr->colorspace.flags |=
710
PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
713
length = strlen(name)+1;
714
new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length));
716
if (new_iccp_name == NULL)
718
png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
723
memcpy(new_iccp_name, name, length);
724
new_iccp_profile = png_voidcast(png_bytep,
725
png_malloc_warn(png_ptr, proflen));
727
if (new_iccp_profile == NULL)
729
png_free(png_ptr, new_iccp_name);
730
png_benign_error(png_ptr,
731
"Insufficient memory to process iCCP profile");
736
memcpy(new_iccp_profile, profile, proflen);
738
png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
740
info_ptr->iccp_proflen = proflen;
741
info_ptr->iccp_name = new_iccp_name;
742
info_ptr->iccp_profile = new_iccp_profile;
743
info_ptr->free_me |= PNG_FREE_ICCP;
744
info_ptr->valid |= PNG_INFO_iCCP;
748
#ifdef PNG_TEXT_SUPPORTED
750
png_set_text(png_const_structrp png_ptr, png_inforp info_ptr,
751
png_const_textp text_ptr, int num_text)
754
ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
757
png_error(png_ptr, "Insufficient memory to store text");
761
png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
762
png_const_textp text_ptr, int num_text)
766
png_debug1(1, "in text storage function, chunk typeid = 0x%lx",
767
png_ptr == NULL ? 0xabadca11UL : (unsigned long)png_ptr->chunk_name);
769
if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
777
if (num_text > info_ptr->max_text - info_ptr->num_text)
779
int old_num_text = info_ptr->num_text;
781
png_textp new_text = NULL;
784
max_text = old_num_text;
785
if (num_text <= INT_MAX - max_text)
787
max_text += num_text;
790
if (max_text < INT_MAX-8)
791
max_text = (max_text + 8) & ~0x7;
799
new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
800
info_ptr->text, old_num_text, max_text-old_num_text,
804
if (new_text == NULL)
806
png_chunk_report(png_ptr, "too many text chunks",
807
PNG_CHUNK_WRITE_ERROR);
812
png_free(png_ptr, info_ptr->text);
814
info_ptr->text = new_text;
815
info_ptr->free_me |= PNG_FREE_TEXT;
816
info_ptr->max_text = max_text;
819
png_debug1(3, "allocated %d entries for info_ptr->text", max_text);
822
for (i = 0; i < num_text; i++)
824
size_t text_length, key_len;
825
size_t lang_len, lang_key_len;
826
png_textp textp = &(info_ptr->text[info_ptr->num_text]);
828
if (text_ptr[i].key == NULL)
831
if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
832
text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
834
png_chunk_report(png_ptr, "text compression mode is out of range",
835
PNG_CHUNK_WRITE_ERROR);
839
key_len = strlen(text_ptr[i].key);
841
if (text_ptr[i].compression <= 0)
848
# ifdef PNG_iTXt_SUPPORTED
852
if (text_ptr[i].lang != NULL)
853
lang_len = strlen(text_ptr[i].lang);
858
if (text_ptr[i].lang_key != NULL)
859
lang_key_len = strlen(text_ptr[i].lang_key);
866
png_chunk_report(png_ptr, "iTXt chunk not supported",
867
PNG_CHUNK_WRITE_ERROR);
872
if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
875
# ifdef PNG_iTXt_SUPPORTED
876
if (text_ptr[i].compression > 0)
877
textp->compression = PNG_ITXT_COMPRESSION_NONE;
881
textp->compression = PNG_TEXT_COMPRESSION_NONE;
886
text_length = strlen(text_ptr[i].text);
887
textp->compression = text_ptr[i].compression;
890
textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr,
891
key_len + text_length + lang_len + lang_key_len + 4));
893
if (textp->key == NULL)
895
png_chunk_report(png_ptr, "text chunk: out of memory",
896
PNG_CHUNK_WRITE_ERROR);
901
png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
902
(unsigned long)(png_uint_32)
903
(key_len + lang_len + lang_key_len + text_length + 4),
906
memcpy(textp->key, text_ptr[i].key, key_len);
907
*(textp->key + key_len) = '\0';
909
if (text_ptr[i].compression > 0)
911
textp->lang = textp->key + key_len + 1;
912
memcpy(textp->lang, text_ptr[i].lang, lang_len);
913
*(textp->lang + lang_len) = '\0';
914
textp->lang_key = textp->lang + lang_len + 1;
915
memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
916
*(textp->lang_key + lang_key_len) = '\0';
917
textp->text = textp->lang_key + lang_key_len + 1;
923
textp->lang_key=NULL;
924
textp->text = textp->key + key_len + 1;
927
if (text_length != 0)
928
memcpy(textp->text, text_ptr[i].text, text_length);
930
*(textp->text + text_length) = '\0';
932
# ifdef PNG_iTXt_SUPPORTED
933
if (textp->compression > 0)
935
textp->text_length = 0;
936
textp->itxt_length = text_length;
942
textp->text_length = text_length;
943
textp->itxt_length = 0;
946
info_ptr->num_text++;
947
png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
954
#ifdef PNG_tIME_SUPPORTED
956
png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
957
png_const_timep mod_time)
959
png_debug1(1, "in %s storage function", "tIME");
961
if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL ||
962
(png_ptr->mode & PNG_WROTE_tIME) != 0)
965
if (mod_time->month == 0 || mod_time->month > 12 ||
966
mod_time->day == 0 || mod_time->day > 31 ||
967
mod_time->hour > 23 || mod_time->minute > 59 ||
968
mod_time->second > 60)
970
png_warning(png_ptr, "Ignoring invalid time value");
975
info_ptr->mod_time = *mod_time;
976
info_ptr->valid |= PNG_INFO_tIME;
980
#ifdef PNG_tRNS_SUPPORTED
982
png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
983
png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
985
png_debug1(1, "in %s storage function", "tRNS");
987
if (png_ptr == NULL || info_ptr == NULL)
991
if (trans_alpha != NULL)
1002
png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
1004
if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
1007
info_ptr->trans_alpha = png_voidcast(png_bytep,
1008
png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
1009
memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
1011
info_ptr->free_me |= PNG_FREE_TRNS;
1012
info_ptr->valid |= PNG_INFO_tRNS;
1014
png_ptr->trans_alpha = info_ptr->trans_alpha;
1017
if (trans_color != NULL)
1019
#ifdef PNG_WARNINGS_SUPPORTED
1020
if (info_ptr->bit_depth < 16)
1022
int sample_max = (1 << info_ptr->bit_depth) - 1;
1024
if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
1025
trans_color->gray > sample_max) ||
1026
(info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
1027
(trans_color->red > sample_max ||
1028
trans_color->green > sample_max ||
1029
trans_color->blue > sample_max)))
1030
png_warning(png_ptr,
1031
"tRNS chunk has out-of-range samples for bit_depth");
1035
info_ptr->trans_color = *trans_color;
1041
info_ptr->num_trans = (png_uint_16)num_trans;
1045
info_ptr->free_me |= PNG_FREE_TRNS;
1046
info_ptr->valid |= PNG_INFO_tRNS;
1051
#ifdef PNG_sPLT_SUPPORTED
1053
png_set_sPLT(png_const_structrp png_ptr,
1054
png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)
1066
png_debug1(1, "in %s storage function", "sPLT");
1068
if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
1074
np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
1075
info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
1081
png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
1085
png_free(png_ptr, info_ptr->splt_palettes);
1087
info_ptr->splt_palettes = np;
1088
info_ptr->free_me |= PNG_FREE_SPLT;
1090
np += info_ptr->splt_palettes_num;
1097
if (entries->name == NULL || entries->entries == NULL)
1100
png_app_error(png_ptr, "png_set_sPLT: invalid sPLT");
1105
np->depth = entries->depth;
1110
length = strlen(entries->name) + 1;
1111
np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length));
1113
if (np->name == NULL)
1116
memcpy(np->name, entries->name, length);
1122
np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr,
1123
entries->nentries, sizeof (png_sPLT_entry)));
1125
if (np->entries == NULL)
1127
png_free(png_ptr, np->name);
1132
np->nentries = entries->nentries;
1136
memcpy(np->entries, entries->entries,
1137
(unsigned int)entries->nentries * sizeof (png_sPLT_entry));
1142
info_ptr->valid |= PNG_INFO_sPLT;
1143
++(info_ptr->splt_palettes_num);
1150
png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
1154
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1156
check_location(png_const_structrp png_ptr, int location)
1158
location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
1164
if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
1167
png_app_warning(png_ptr,
1168
"png_set_unknown_chunks now expects a valid location");
1170
location = (png_byte)(png_ptr->mode &
1171
(PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
1178
png_error(png_ptr, "invalid location in png_set_unknown_chunks");
1183
while (location != (location & -location))
1184
location &= ~(location & -location);
1189
return (png_byte)location;
1193
png_set_unknown_chunks(png_const_structrp png_ptr,
1194
png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
1196
png_unknown_chunkp np;
1198
if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||
1208
# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \
1209
defined(PNG_READ_SUPPORTED)
1210
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1212
png_app_error(png_ptr, "no unknown chunk support on read");
1217
# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \
1218
defined(PNG_WRITE_SUPPORTED)
1219
if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
1221
png_app_error(png_ptr, "no unknown chunk support on write");
1232
np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
1233
info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
1238
png_chunk_report(png_ptr, "too many unknown chunks",
1239
PNG_CHUNK_WRITE_ERROR);
1243
png_free(png_ptr, info_ptr->unknown_chunks);
1245
info_ptr->unknown_chunks = np;
1246
info_ptr->free_me |= PNG_FREE_UNKN;
1248
np += info_ptr->unknown_chunks_num;
1253
for (; num_unknowns > 0; --num_unknowns, ++unknowns)
1255
memcpy(np->name, unknowns->name, (sizeof np->name));
1256
np->name[(sizeof np->name)-1] = '\0';
1257
np->location = check_location(png_ptr, unknowns->location);
1259
if (unknowns->size == 0)
1267
np->data = png_voidcast(png_bytep,
1268
png_malloc_base(png_ptr, unknowns->size));
1270
if (np->data == NULL)
1272
png_chunk_report(png_ptr, "unknown chunk: out of memory",
1273
PNG_CHUNK_WRITE_ERROR);
1278
memcpy(np->data, unknowns->data, unknowns->size);
1279
np->size = unknowns->size;
1287
++(info_ptr->unknown_chunks_num);
1292
png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
1293
int chunk, int location)
1300
if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 &&
1301
chunk < info_ptr->unknown_chunks_num)
1303
if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0)
1305
png_app_error(png_ptr, "invalid unknown chunk location");
1307
if (((unsigned int)location & PNG_HAVE_IDAT) != 0)
1308
location = PNG_AFTER_IDAT;
1311
location = PNG_HAVE_IHDR;
1314
info_ptr->unknown_chunks[chunk].location =
1315
check_location(png_ptr, location);
1320
#ifdef PNG_MNG_FEATURES_SUPPORTED
1322
png_permit_mng_features(png_structrp png_ptr, png_uint_32 mng_features)
1324
png_debug(1, "in png_permit_mng_features");
1326
if (png_ptr == NULL)
1329
png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES;
1331
return png_ptr->mng_features_permitted;
1335
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1337
add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
1344
for (i=0; i<count; ++i, list += 5)
1346
if (memcmp(list, add, 4) == 0)
1348
list[4] = (png_byte)keep;
1354
if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)
1357
memcpy(list, add, 4);
1358
list[4] = (png_byte)keep;
1365
png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
1366
png_const_bytep chunk_list, int num_chunks_in)
1369
unsigned int num_chunks, old_num_chunks;
1371
if (png_ptr == NULL)
1374
if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST)
1376
png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
1381
if (num_chunks_in <= 0)
1383
png_ptr->unknown_default = keep;
1386
if (num_chunks_in == 0)
1390
if (num_chunks_in < 0)
1395
static const png_byte chunks_to_ignore[] = {
1396
98, 75, 71, 68, '\0',
1397
99, 72, 82, 77, '\0',
1398
101, 88, 73, 102, '\0',
1399
103, 65, 77, 65, '\0',
1400
104, 73, 83, 84, '\0',
1401
105, 67, 67, 80, '\0',
1402
105, 84, 88, 116, '\0',
1403
111, 70, 70, 115, '\0',
1404
112, 67, 65, 76, '\0',
1405
112, 72, 89, 115, '\0',
1406
115, 66, 73, 84, '\0',
1407
115, 67, 65, 76, '\0',
1408
115, 80, 76, 84, '\0',
1409
115, 84, 69, 82, '\0',
1410
115, 82, 71, 66, '\0',
1411
116, 69, 88, 116, '\0',
1412
116, 73, 77, 69, '\0',
1413
122, 84, 88, 116, '\0'
1416
chunk_list = chunks_to_ignore;
1417
num_chunks = (unsigned int)(sizeof chunks_to_ignore)/5U;
1422
if (chunk_list == NULL)
1427
png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list");
1432
num_chunks = (unsigned int)num_chunks_in;
1435
old_num_chunks = png_ptr->num_chunk_list;
1436
if (png_ptr->chunk_list == NULL)
1441
if (num_chunks + old_num_chunks > UINT_MAX/5)
1443
png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
1454
new_list = png_voidcast(png_bytep, png_malloc(png_ptr,
1455
5 * (num_chunks + old_num_chunks)));
1457
if (old_num_chunks > 0)
1458
memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
1461
else if (old_num_chunks > 0)
1462
new_list = png_ptr->chunk_list;
1472
if (new_list != NULL)
1474
png_const_bytep inlist;
1478
for (i=0; i<num_chunks; ++i)
1480
old_num_chunks = add_one_chunk(new_list, old_num_chunks,
1481
chunk_list+5*i, keep);
1486
for (i=0, inlist=outlist=new_list; i<old_num_chunks; ++i, inlist += 5)
1490
if (outlist != inlist)
1491
memcpy(outlist, inlist, 5);
1498
if (num_chunks == 0)
1500
if (png_ptr->chunk_list != new_list)
1501
png_free(png_ptr, new_list);
1510
png_ptr->num_chunk_list = num_chunks;
1512
if (png_ptr->chunk_list != new_list)
1514
if (png_ptr->chunk_list != NULL)
1515
png_free(png_ptr, png_ptr->chunk_list);
1517
png_ptr->chunk_list = new_list;
1522
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1524
png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr,
1525
png_user_chunk_ptr read_user_chunk_fn)
1527
png_debug(1, "in png_set_read_user_chunk_fn");
1529
if (png_ptr == NULL)
1532
png_ptr->read_user_chunk_fn = read_user_chunk_fn;
1533
png_ptr->user_chunk_ptr = user_chunk_ptr;
1537
#ifdef PNG_INFO_IMAGE_SUPPORTED
1539
png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
1540
png_bytepp row_pointers)
1542
png_debug(1, "in png_set_rows");
1544
if (png_ptr == NULL || info_ptr == NULL)
1547
if (info_ptr->row_pointers != NULL &&
1548
(info_ptr->row_pointers != row_pointers))
1549
png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1551
info_ptr->row_pointers = row_pointers;
1553
if (row_pointers != NULL)
1554
info_ptr->valid |= PNG_INFO_IDAT;
1559
png_set_compression_buffer_size(png_structrp png_ptr, size_t size)
1561
png_debug(1, "in png_set_compression_buffer_size");
1563
if (png_ptr == NULL)
1566
if (size == 0 || size > PNG_UINT_31_MAX)
1567
png_error(png_ptr, "invalid compression buffer size");
1569
# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1570
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1572
png_ptr->IDAT_read_size = (png_uint_32)size;
1577
# ifdef PNG_WRITE_SUPPORTED
1578
if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
1580
if (png_ptr->zowner != 0)
1582
png_warning(png_ptr,
1583
"Compression buffer size cannot be changed because it is in use");
1592
if (size > ZLIB_IO_MAX)
1594
png_warning(png_ptr,
1595
"Compression buffer size limited to system maximum");
1605
png_warning(png_ptr,
1606
"Compression buffer size cannot be reduced below 6");
1611
if (png_ptr->zbuffer_size != size)
1613
png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
1614
png_ptr->zbuffer_size = (uInt)size;
1621
png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
1623
if (png_ptr != NULL && info_ptr != NULL)
1624
info_ptr->valid &= (unsigned int)(~mask);
1628
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
1631
png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max,
1632
png_uint_32 user_height_max)
1634
png_debug(1, "in png_set_user_limits");
1640
if (png_ptr == NULL)
1643
png_ptr->user_width_max = user_width_max;
1644
png_ptr->user_height_max = user_height_max;
1649
png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
1651
png_debug(1, "in png_set_chunk_cache_max");
1653
if (png_ptr != NULL)
1654
png_ptr->user_chunk_cache_max = user_chunk_cache_max;
1659
png_set_chunk_malloc_max(png_structrp png_ptr,
1660
png_alloc_size_t user_chunk_malloc_max)
1662
png_debug(1, "in png_set_chunk_malloc_max");
1664
if (png_ptr != NULL)
1665
png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
1670
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
1672
png_set_benign_errors(png_structrp png_ptr, int allowed)
1674
png_debug(1, "in png_set_benign_errors");
1683
png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN |
1684
PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN;
1687
png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN |
1688
PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN);
1692
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
1702
png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
1704
png_debug(1, "in png_set_check_for_invalid_index");
1707
png_ptr->num_palette_max = 0;
1710
png_ptr->num_palette_max = -1;
1714
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \
1715
defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
1727
png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
1729
#ifdef PNG_WARNINGS_SUPPORTED
1730
png_const_charp orig_key = key;
1732
png_uint_32 key_len = 0;
1733
int bad_character = 0;
1736
png_debug(1, "in png_check_keyword");
1744
while (*key && key_len < 79)
1746
png_byte ch = (png_byte)*key++;
1748
if ((ch > 32 && ch <= 126) || (ch >= 161 ))
1750
*new_key++ = ch; ++key_len; space = 0;
1753
else if (space == 0)
1758
*new_key++ = 32; ++key_len; space = 1;
1765
else if (bad_character == 0)
1769
if (key_len > 0 && space != 0)
1771
--key_len; --new_key;
1772
if (bad_character == 0)
1782
#ifdef PNG_WARNINGS_SUPPORTED
1785
png_warning(png_ptr, "keyword truncated");
1787
else if (bad_character != 0)
1789
PNG_WARNING_PARAMETERS(p)
1791
png_warning_parameter(p, 1, orig_key);
1792
png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
1794
png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");