source: trunk/third/libpng/pngset.c @ 18166

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