Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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