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

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