xref: /plan9-contrib/sys/src/cmd/gs/libpng/pngset.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier 
27dd7cddfSDavid du Colombier /* pngset.c - storage of image information into info struct
37dd7cddfSDavid du Colombier  *
4*593dc095SDavid du Colombier  * libpng 1.2.8 - December 3, 2004
57dd7cddfSDavid du Colombier  * For conditions of distribution and use, see copyright notice in png.h
6*593dc095SDavid du Colombier  * Copyright (c) 1998-2004 Glenn Randers-Pehrson
7*593dc095SDavid du Colombier  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8*593dc095SDavid du Colombier  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
97dd7cddfSDavid du Colombier  *
107dd7cddfSDavid du Colombier  * The functions here are used during reads to store data from the file
117dd7cddfSDavid du Colombier  * into the info struct, and during writes to store application data
127dd7cddfSDavid du Colombier  * into the info struct for writing into the file.  This abstracts the
137dd7cddfSDavid du Colombier  * info struct and allows us to change the structure in the future.
147dd7cddfSDavid du Colombier  */
157dd7cddfSDavid du Colombier 
167dd7cddfSDavid du Colombier #define PNG_INTERNAL
177dd7cddfSDavid du Colombier #include "png.h"
187dd7cddfSDavid du Colombier 
19*593dc095SDavid du Colombier #if defined(PNG_bKGD_SUPPORTED)
20*593dc095SDavid du Colombier void PNGAPI
png_set_bKGD(png_structp png_ptr,png_infop info_ptr,png_color_16p background)217dd7cddfSDavid du Colombier png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
227dd7cddfSDavid du Colombier {
237dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "bKGD");
24*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
257dd7cddfSDavid du Colombier       return;
267dd7cddfSDavid du Colombier 
27*593dc095SDavid du Colombier    png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
287dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_bKGD;
297dd7cddfSDavid du Colombier }
307dd7cddfSDavid du Colombier #endif
317dd7cddfSDavid du Colombier 
32*593dc095SDavid du Colombier #if defined(PNG_cHRM_SUPPORTED)
33*593dc095SDavid du Colombier #ifdef PNG_FLOATING_POINT_SUPPORTED
34*593dc095SDavid du Colombier void PNGAPI
png_set_cHRM(png_structp png_ptr,png_infop info_ptr,double white_x,double white_y,double red_x,double red_y,double green_x,double green_y,double blue_x,double blue_y)357dd7cddfSDavid du Colombier png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
367dd7cddfSDavid du Colombier    double white_x, double white_y, double red_x, double red_y,
377dd7cddfSDavid du Colombier    double green_x, double green_y, double blue_x, double blue_y)
387dd7cddfSDavid du Colombier {
397dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "cHRM");
40*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
417dd7cddfSDavid du Colombier       return;
427dd7cddfSDavid du Colombier 
43*593dc095SDavid du Colombier    if (white_x < 0.0 || white_y < 0.0 ||
44*593dc095SDavid du Colombier          red_x < 0.0 ||   red_y < 0.0 ||
45*593dc095SDavid du Colombier        green_x < 0.0 || green_y < 0.0 ||
46*593dc095SDavid du Colombier         blue_x < 0.0 ||  blue_y < 0.0)
47*593dc095SDavid du Colombier    {
48*593dc095SDavid du Colombier       png_warning(png_ptr,
49*593dc095SDavid du Colombier         "Ignoring attempt to set negative chromaticity value");
50*593dc095SDavid du Colombier       return;
51*593dc095SDavid du Colombier    }
52*593dc095SDavid du Colombier    if (white_x > 21474.83 || white_y > 21474.83 ||
53*593dc095SDavid du Colombier          red_x > 21474.83 ||   red_y > 21474.83 ||
54*593dc095SDavid du Colombier        green_x > 21474.83 || green_y > 21474.83 ||
55*593dc095SDavid du Colombier         blue_x > 21474.83 ||  blue_y > 21474.83)
56*593dc095SDavid du Colombier    {
57*593dc095SDavid du Colombier       png_warning(png_ptr,
58*593dc095SDavid du Colombier         "Ignoring attempt to set chromaticity value exceeding 21474.83");
59*593dc095SDavid du Colombier       return;
60*593dc095SDavid du Colombier    }
61*593dc095SDavid du Colombier 
627dd7cddfSDavid du Colombier    info_ptr->x_white = (float)white_x;
637dd7cddfSDavid du Colombier    info_ptr->y_white = (float)white_y;
647dd7cddfSDavid du Colombier    info_ptr->x_red   = (float)red_x;
657dd7cddfSDavid du Colombier    info_ptr->y_red   = (float)red_y;
667dd7cddfSDavid du Colombier    info_ptr->x_green = (float)green_x;
677dd7cddfSDavid du Colombier    info_ptr->y_green = (float)green_y;
687dd7cddfSDavid du Colombier    info_ptr->x_blue  = (float)blue_x;
697dd7cddfSDavid du Colombier    info_ptr->y_blue  = (float)blue_y;
70*593dc095SDavid du Colombier #ifdef PNG_FIXED_POINT_SUPPORTED
71*593dc095SDavid du Colombier    info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
72*593dc095SDavid du Colombier    info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
73*593dc095SDavid du Colombier    info_ptr->int_x_red   = (png_fixed_point)(  red_x*100000.+0.5);
74*593dc095SDavid du Colombier    info_ptr->int_y_red   = (png_fixed_point)(  red_y*100000.+0.5);
75*593dc095SDavid du Colombier    info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
76*593dc095SDavid du Colombier    info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
77*593dc095SDavid du Colombier    info_ptr->int_x_blue  = (png_fixed_point)( blue_x*100000.+0.5);
78*593dc095SDavid du Colombier    info_ptr->int_y_blue  = (png_fixed_point)( blue_y*100000.+0.5);
79*593dc095SDavid du Colombier #endif
807dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_cHRM;
817dd7cddfSDavid du Colombier }
827dd7cddfSDavid du Colombier #endif
83*593dc095SDavid du Colombier #ifdef PNG_FIXED_POINT_SUPPORTED
84*593dc095SDavid du Colombier void PNGAPI
png_set_cHRM_fixed(png_structp png_ptr,png_infop info_ptr,png_fixed_point white_x,png_fixed_point white_y,png_fixed_point red_x,png_fixed_point red_y,png_fixed_point green_x,png_fixed_point green_y,png_fixed_point blue_x,png_fixed_point blue_y)85*593dc095SDavid du Colombier png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
86*593dc095SDavid du Colombier    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
87*593dc095SDavid du Colombier    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
88*593dc095SDavid du Colombier    png_fixed_point blue_x, png_fixed_point blue_y)
89*593dc095SDavid du Colombier {
90*593dc095SDavid du Colombier    png_debug1(1, "in %s storage function\n", "cHRM");
91*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
92*593dc095SDavid du Colombier       return;
937dd7cddfSDavid du Colombier 
94*593dc095SDavid du Colombier    if (white_x < 0 || white_y < 0 ||
95*593dc095SDavid du Colombier          red_x < 0 ||   red_y < 0 ||
96*593dc095SDavid du Colombier        green_x < 0 || green_y < 0 ||
97*593dc095SDavid du Colombier         blue_x < 0 ||  blue_y < 0)
98*593dc095SDavid du Colombier    {
99*593dc095SDavid du Colombier       png_warning(png_ptr,
100*593dc095SDavid du Colombier         "Ignoring attempt to set negative chromaticity value");
101*593dc095SDavid du Colombier       return;
102*593dc095SDavid du Colombier    }
103*593dc095SDavid du Colombier    if (white_x > (double) PNG_UINT_31_MAX ||
104*593dc095SDavid du Colombier        white_y > (double) PNG_UINT_31_MAX ||
105*593dc095SDavid du Colombier          red_x > (double) PNG_UINT_31_MAX ||
106*593dc095SDavid du Colombier          red_y > (double) PNG_UINT_31_MAX ||
107*593dc095SDavid du Colombier        green_x > (double) PNG_UINT_31_MAX ||
108*593dc095SDavid du Colombier        green_y > (double) PNG_UINT_31_MAX ||
109*593dc095SDavid du Colombier         blue_x > (double) PNG_UINT_31_MAX ||
110*593dc095SDavid du Colombier         blue_y > (double) PNG_UINT_31_MAX)
111*593dc095SDavid du Colombier    {
112*593dc095SDavid du Colombier       png_warning(png_ptr,
113*593dc095SDavid du Colombier         "Ignoring attempt to set chromaticity value exceeding 21474.83");
114*593dc095SDavid du Colombier       return;
115*593dc095SDavid du Colombier    }
116*593dc095SDavid du Colombier    info_ptr->int_x_white = white_x;
117*593dc095SDavid du Colombier    info_ptr->int_y_white = white_y;
118*593dc095SDavid du Colombier    info_ptr->int_x_red   = red_x;
119*593dc095SDavid du Colombier    info_ptr->int_y_red   = red_y;
120*593dc095SDavid du Colombier    info_ptr->int_x_green = green_x;
121*593dc095SDavid du Colombier    info_ptr->int_y_green = green_y;
122*593dc095SDavid du Colombier    info_ptr->int_x_blue  = blue_x;
123*593dc095SDavid du Colombier    info_ptr->int_y_blue  = blue_y;
124*593dc095SDavid du Colombier #ifdef PNG_FLOATING_POINT_SUPPORTED
125*593dc095SDavid du Colombier    info_ptr->x_white = (float)(white_x/100000.);
126*593dc095SDavid du Colombier    info_ptr->y_white = (float)(white_y/100000.);
127*593dc095SDavid du Colombier    info_ptr->x_red   = (float)(  red_x/100000.);
128*593dc095SDavid du Colombier    info_ptr->y_red   = (float)(  red_y/100000.);
129*593dc095SDavid du Colombier    info_ptr->x_green = (float)(green_x/100000.);
130*593dc095SDavid du Colombier    info_ptr->y_green = (float)(green_y/100000.);
131*593dc095SDavid du Colombier    info_ptr->x_blue  = (float)( blue_x/100000.);
132*593dc095SDavid du Colombier    info_ptr->y_blue  = (float)( blue_y/100000.);
133*593dc095SDavid du Colombier #endif
134*593dc095SDavid du Colombier    info_ptr->valid |= PNG_INFO_cHRM;
135*593dc095SDavid du Colombier }
136*593dc095SDavid du Colombier #endif
137*593dc095SDavid du Colombier #endif
138*593dc095SDavid du Colombier 
139*593dc095SDavid du Colombier #if defined(PNG_gAMA_SUPPORTED)
140*593dc095SDavid du Colombier #ifdef PNG_FLOATING_POINT_SUPPORTED
141*593dc095SDavid du Colombier void PNGAPI
png_set_gAMA(png_structp png_ptr,png_infop info_ptr,double file_gamma)1427dd7cddfSDavid du Colombier png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
1437dd7cddfSDavid du Colombier {
144*593dc095SDavid du Colombier    double gamma;
1457dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "gAMA");
146*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
1477dd7cddfSDavid du Colombier       return;
1487dd7cddfSDavid du Colombier 
149*593dc095SDavid du Colombier    /* Check for overflow */
150*593dc095SDavid du Colombier    if (file_gamma > 21474.83)
151*593dc095SDavid du Colombier    {
152*593dc095SDavid du Colombier       png_warning(png_ptr, "Limiting gamma to 21474.83");
153*593dc095SDavid du Colombier       gamma=21474.83;
154*593dc095SDavid du Colombier    }
155*593dc095SDavid du Colombier    else
156*593dc095SDavid du Colombier       gamma=file_gamma;
157*593dc095SDavid du Colombier    info_ptr->gamma = (float)gamma;
158*593dc095SDavid du Colombier #ifdef PNG_FIXED_POINT_SUPPORTED
159*593dc095SDavid du Colombier    info_ptr->int_gamma = (int)(gamma*100000.+.5);
160*593dc095SDavid du Colombier #endif
1617dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_gAMA;
162*593dc095SDavid du Colombier    if(gamma == 0.0)
163*593dc095SDavid du Colombier       png_warning(png_ptr, "Setting gamma=0");
164*593dc095SDavid du Colombier }
165*593dc095SDavid du Colombier #endif
166*593dc095SDavid du Colombier void PNGAPI
png_set_gAMA_fixed(png_structp png_ptr,png_infop info_ptr,png_fixed_point int_gamma)167*593dc095SDavid du Colombier png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
168*593dc095SDavid du Colombier    int_gamma)
169*593dc095SDavid du Colombier {
170*593dc095SDavid du Colombier    png_fixed_point gamma;
171*593dc095SDavid du Colombier 
172*593dc095SDavid du Colombier    png_debug1(1, "in %s storage function\n", "gAMA");
173*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
174*593dc095SDavid du Colombier       return;
175*593dc095SDavid du Colombier 
176*593dc095SDavid du Colombier    if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX)
177*593dc095SDavid du Colombier    {
178*593dc095SDavid du Colombier      png_warning(png_ptr, "Limiting gamma to 21474.83");
179*593dc095SDavid du Colombier      gamma=PNG_UINT_31_MAX;
180*593dc095SDavid du Colombier    }
181*593dc095SDavid du Colombier    else
182*593dc095SDavid du Colombier    {
183*593dc095SDavid du Colombier      if (int_gamma < 0)
184*593dc095SDavid du Colombier      {
185*593dc095SDavid du Colombier        png_warning(png_ptr, "Setting negative gamma to zero");
186*593dc095SDavid du Colombier        gamma=0;
187*593dc095SDavid du Colombier      }
188*593dc095SDavid du Colombier      else
189*593dc095SDavid du Colombier        gamma=int_gamma;
190*593dc095SDavid du Colombier    }
191*593dc095SDavid du Colombier #ifdef PNG_FLOATING_POINT_SUPPORTED
192*593dc095SDavid du Colombier    info_ptr->gamma = (float)(gamma/100000.);
193*593dc095SDavid du Colombier #endif
194*593dc095SDavid du Colombier #ifdef PNG_FIXED_POINT_SUPPORTED
195*593dc095SDavid du Colombier    info_ptr->int_gamma = gamma;
196*593dc095SDavid du Colombier #endif
197*593dc095SDavid du Colombier    info_ptr->valid |= PNG_INFO_gAMA;
198*593dc095SDavid du Colombier    if(gamma == 0)
199*593dc095SDavid du Colombier       png_warning(png_ptr, "Setting gamma=0");
2007dd7cddfSDavid du Colombier }
2017dd7cddfSDavid du Colombier #endif
2027dd7cddfSDavid du Colombier 
203*593dc095SDavid du Colombier #if defined(PNG_hIST_SUPPORTED)
204*593dc095SDavid du Colombier void PNGAPI
png_set_hIST(png_structp png_ptr,png_infop info_ptr,png_uint_16p hist)2057dd7cddfSDavid du Colombier png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
2067dd7cddfSDavid du Colombier {
207*593dc095SDavid du Colombier    int i;
2087dd7cddfSDavid du Colombier 
209*593dc095SDavid du Colombier    png_debug1(1, "in %s storage function\n", "hIST");
210*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
211*593dc095SDavid du Colombier       return;
212*593dc095SDavid du Colombier    if (info_ptr->num_palette == 0)
213*593dc095SDavid du Colombier    {
214*593dc095SDavid du Colombier        png_warning(png_ptr,
215*593dc095SDavid du Colombier           "Palette size 0, hIST allocation skipped.");
216*593dc095SDavid du Colombier        return;
217*593dc095SDavid du Colombier    }
218*593dc095SDavid du Colombier 
219*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
220*593dc095SDavid du Colombier    png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
221*593dc095SDavid du Colombier #endif
222*593dc095SDavid du Colombier    /* Changed from info->num_palette to 256 in version 1.2.1 */
223*593dc095SDavid du Colombier    png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
224*593dc095SDavid du Colombier       (png_uint_32)(256 * png_sizeof (png_uint_16)));
225*593dc095SDavid du Colombier    if (png_ptr->hist == NULL)
226*593dc095SDavid du Colombier      {
227*593dc095SDavid du Colombier        png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
228*593dc095SDavid du Colombier        return;
229*593dc095SDavid du Colombier      }
230*593dc095SDavid du Colombier 
231*593dc095SDavid du Colombier    for (i = 0; i < info_ptr->num_palette; i++)
232*593dc095SDavid du Colombier        png_ptr->hist[i] = hist[i];
233*593dc095SDavid du Colombier    info_ptr->hist = png_ptr->hist;
2347dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_hIST;
235*593dc095SDavid du Colombier 
236*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
237*593dc095SDavid du Colombier    info_ptr->free_me |= PNG_FREE_HIST;
238*593dc095SDavid du Colombier #else
239*593dc095SDavid du Colombier    png_ptr->flags |= PNG_FLAG_FREE_HIST;
240*593dc095SDavid du Colombier #endif
2417dd7cddfSDavid du Colombier }
2427dd7cddfSDavid du Colombier #endif
2437dd7cddfSDavid du Colombier 
244*593dc095SDavid du Colombier void PNGAPI
png_set_IHDR(png_structp png_ptr,png_infop info_ptr,png_uint_32 width,png_uint_32 height,int bit_depth,int color_type,int interlace_type,int compression_type,int filter_type)2457dd7cddfSDavid du Colombier png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
2467dd7cddfSDavid du Colombier    png_uint_32 width, png_uint_32 height, int bit_depth,
2477dd7cddfSDavid du Colombier    int color_type, int interlace_type, int compression_type,
2487dd7cddfSDavid du Colombier    int filter_type)
2497dd7cddfSDavid du Colombier {
2507dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "IHDR");
251*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
2527dd7cddfSDavid du Colombier       return;
2537dd7cddfSDavid du Colombier 
254*593dc095SDavid du Colombier    /* check for width and height valid values */
255*593dc095SDavid du Colombier    if (width == 0 || height == 0)
256*593dc095SDavid du Colombier       png_error(png_ptr, "Image width or height is zero in IHDR");
257*593dc095SDavid du Colombier #ifdef PNG_SET_USER_LIMITS_SUPPORTED
258*593dc095SDavid du Colombier    if (width > png_ptr->user_width_max || height > png_ptr->user_height_max)
259*593dc095SDavid du Colombier       png_error(png_ptr, "image size exceeds user limits in IHDR");
260*593dc095SDavid du Colombier #else
261*593dc095SDavid du Colombier    if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX)
262*593dc095SDavid du Colombier       png_error(png_ptr, "image size exceeds user limits in IHDR");
263*593dc095SDavid du Colombier #endif
264*593dc095SDavid du Colombier    if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX)
265*593dc095SDavid du Colombier       png_error(png_ptr, "Invalid image size in IHDR");
266*593dc095SDavid du Colombier    if ( width > (PNG_UINT_32_MAX
267*593dc095SDavid du Colombier                  >> 3)      /* 8-byte RGBA pixels */
268*593dc095SDavid du Colombier                  - 64       /* bigrowbuf hack */
269*593dc095SDavid du Colombier                  - 1        /* filter byte */
270*593dc095SDavid du Colombier                  - 7*8      /* rounding of width to multiple of 8 pixels */
271*593dc095SDavid du Colombier                  - 8)       /* extra max_pixel_depth pad */
272*593dc095SDavid du Colombier       png_warning(png_ptr, "Width is too large for libpng to process pixels");
273*593dc095SDavid du Colombier 
274*593dc095SDavid du Colombier    /* check other values */
275*593dc095SDavid du Colombier    if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
276*593dc095SDavid du Colombier       bit_depth != 8 && bit_depth != 16)
277*593dc095SDavid du Colombier       png_error(png_ptr, "Invalid bit depth in IHDR");
278*593dc095SDavid du Colombier 
279*593dc095SDavid du Colombier    if (color_type < 0 || color_type == 1 ||
280*593dc095SDavid du Colombier       color_type == 5 || color_type > 6)
281*593dc095SDavid du Colombier       png_error(png_ptr, "Invalid color type in IHDR");
282*593dc095SDavid du Colombier 
283*593dc095SDavid du Colombier    if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
284*593dc095SDavid du Colombier        ((color_type == PNG_COLOR_TYPE_RGB ||
285*593dc095SDavid du Colombier          color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
286*593dc095SDavid du Colombier          color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
287*593dc095SDavid du Colombier       png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
288*593dc095SDavid du Colombier 
289*593dc095SDavid du Colombier    if (interlace_type >= PNG_INTERLACE_LAST)
290*593dc095SDavid du Colombier       png_error(png_ptr, "Unknown interlace method in IHDR");
291*593dc095SDavid du Colombier 
292*593dc095SDavid du Colombier    if (compression_type != PNG_COMPRESSION_TYPE_BASE)
293*593dc095SDavid du Colombier       png_error(png_ptr, "Unknown compression method in IHDR");
294*593dc095SDavid du Colombier 
295*593dc095SDavid du Colombier #if defined(PNG_MNG_FEATURES_SUPPORTED)
296*593dc095SDavid du Colombier    /* Accept filter_method 64 (intrapixel differencing) only if
297*593dc095SDavid du Colombier     * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
298*593dc095SDavid du Colombier     * 2. Libpng did not read a PNG signature (this filter_method is only
299*593dc095SDavid du Colombier     *    used in PNG datastreams that are embedded in MNG datastreams) and
300*593dc095SDavid du Colombier     * 3. The application called png_permit_mng_features with a mask that
301*593dc095SDavid du Colombier     *    included PNG_FLAG_MNG_FILTER_64 and
302*593dc095SDavid du Colombier     * 4. The filter_method is 64 and
303*593dc095SDavid du Colombier     * 5. The color_type is RGB or RGBA
304*593dc095SDavid du Colombier     */
305*593dc095SDavid du Colombier    if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted)
306*593dc095SDavid du Colombier       png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n");
307*593dc095SDavid du Colombier    if(filter_type != PNG_FILTER_TYPE_BASE)
308*593dc095SDavid du Colombier    {
309*593dc095SDavid du Colombier      if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
310*593dc095SDavid du Colombier         (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
311*593dc095SDavid du Colombier         ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
312*593dc095SDavid du Colombier         (color_type == PNG_COLOR_TYPE_RGB ||
313*593dc095SDavid du Colombier          color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
314*593dc095SDavid du Colombier         png_error(png_ptr, "Unknown filter method in IHDR");
315*593dc095SDavid du Colombier      if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)
316*593dc095SDavid du Colombier         png_warning(png_ptr, "Invalid filter method in IHDR");
317*593dc095SDavid du Colombier    }
318*593dc095SDavid du Colombier #else
319*593dc095SDavid du Colombier    if(filter_type != PNG_FILTER_TYPE_BASE)
320*593dc095SDavid du Colombier       png_error(png_ptr, "Unknown filter method in IHDR");
321*593dc095SDavid du Colombier #endif
322*593dc095SDavid du Colombier 
3237dd7cddfSDavid du Colombier    info_ptr->width = width;
3247dd7cddfSDavid du Colombier    info_ptr->height = height;
3257dd7cddfSDavid du Colombier    info_ptr->bit_depth = (png_byte)bit_depth;
3267dd7cddfSDavid du Colombier    info_ptr->color_type =(png_byte) color_type;
3277dd7cddfSDavid du Colombier    info_ptr->compression_type = (png_byte)compression_type;
3287dd7cddfSDavid du Colombier    info_ptr->filter_type = (png_byte)filter_type;
3297dd7cddfSDavid du Colombier    info_ptr->interlace_type = (png_byte)interlace_type;
3307dd7cddfSDavid du Colombier    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3317dd7cddfSDavid du Colombier       info_ptr->channels = 1;
3327dd7cddfSDavid du Colombier    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
3337dd7cddfSDavid du Colombier       info_ptr->channels = 3;
3347dd7cddfSDavid du Colombier    else
3357dd7cddfSDavid du Colombier       info_ptr->channels = 1;
3367dd7cddfSDavid du Colombier    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
3377dd7cddfSDavid du Colombier       info_ptr->channels++;
3387dd7cddfSDavid du Colombier    info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
3397dd7cddfSDavid du Colombier 
340*593dc095SDavid du Colombier    /* check for potential overflow */
341*593dc095SDavid du Colombier    if ( width > (PNG_UINT_32_MAX
342*593dc095SDavid du Colombier                  >> 3)      /* 8-byte RGBA pixels */
343*593dc095SDavid du Colombier                  - 64       /* bigrowbuf hack */
344*593dc095SDavid du Colombier                  - 1        /* filter byte */
345*593dc095SDavid du Colombier                  - 7*8      /* rounding of width to multiple of 8 pixels */
346*593dc095SDavid du Colombier                  - 8)       /* extra max_pixel_depth pad */
3477dd7cddfSDavid du Colombier       info_ptr->rowbytes = (png_size_t)0;
348*593dc095SDavid du Colombier    else
349*593dc095SDavid du Colombier       info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width);
3507dd7cddfSDavid du Colombier }
3517dd7cddfSDavid du Colombier 
352*593dc095SDavid du Colombier #if defined(PNG_oFFs_SUPPORTED)
353*593dc095SDavid du Colombier void PNGAPI
png_set_oFFs(png_structp png_ptr,png_infop info_ptr,png_int_32 offset_x,png_int_32 offset_y,int unit_type)3547dd7cddfSDavid du Colombier png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
355*593dc095SDavid du Colombier    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
3567dd7cddfSDavid du Colombier {
3577dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "oFFs");
358*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
3597dd7cddfSDavid du Colombier       return;
3607dd7cddfSDavid du Colombier 
3617dd7cddfSDavid du Colombier    info_ptr->x_offset = offset_x;
3627dd7cddfSDavid du Colombier    info_ptr->y_offset = offset_y;
3637dd7cddfSDavid du Colombier    info_ptr->offset_unit_type = (png_byte)unit_type;
3647dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_oFFs;
3657dd7cddfSDavid du Colombier }
3667dd7cddfSDavid du Colombier #endif
3677dd7cddfSDavid du Colombier 
368*593dc095SDavid du Colombier #if defined(PNG_pCAL_SUPPORTED)
369*593dc095SDavid du Colombier void PNGAPI
png_set_pCAL(png_structp png_ptr,png_infop info_ptr,png_charp purpose,png_int_32 X0,png_int_32 X1,int type,int nparams,png_charp units,png_charpp params)3707dd7cddfSDavid du Colombier png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
3717dd7cddfSDavid du Colombier    png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
3727dd7cddfSDavid du Colombier    png_charp units, png_charpp params)
3737dd7cddfSDavid du Colombier {
3747dd7cddfSDavid du Colombier    png_uint_32 length;
3757dd7cddfSDavid du Colombier    int i;
3767dd7cddfSDavid du Colombier 
3777dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "pCAL");
378*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
3797dd7cddfSDavid du Colombier       return;
3807dd7cddfSDavid du Colombier 
3817dd7cddfSDavid du Colombier    length = png_strlen(purpose) + 1;
382*593dc095SDavid du Colombier    png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
383*593dc095SDavid du Colombier    info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
384*593dc095SDavid du Colombier    if (info_ptr->pcal_purpose == NULL)
385*593dc095SDavid du Colombier      {
386*593dc095SDavid du Colombier        png_warning(png_ptr, "Insufficient memory for pCAL purpose.");
387*593dc095SDavid du Colombier        return;
388*593dc095SDavid du Colombier      }
3897dd7cddfSDavid du Colombier    png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
3907dd7cddfSDavid du Colombier 
3917dd7cddfSDavid du Colombier    png_debug(3, "storing X0, X1, type, and nparams in info\n");
3927dd7cddfSDavid du Colombier    info_ptr->pcal_X0 = X0;
3937dd7cddfSDavid du Colombier    info_ptr->pcal_X1 = X1;
3947dd7cddfSDavid du Colombier    info_ptr->pcal_type = (png_byte)type;
3957dd7cddfSDavid du Colombier    info_ptr->pcal_nparams = (png_byte)nparams;
3967dd7cddfSDavid du Colombier 
3977dd7cddfSDavid du Colombier    length = png_strlen(units) + 1;
398*593dc095SDavid du Colombier    png_debug1(3, "allocating units for info (%lu bytes)\n", length);
399*593dc095SDavid du Colombier    info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
400*593dc095SDavid du Colombier    if (info_ptr->pcal_units == NULL)
401*593dc095SDavid du Colombier      {
402*593dc095SDavid du Colombier        png_warning(png_ptr, "Insufficient memory for pCAL units.");
403*593dc095SDavid du Colombier        return;
404*593dc095SDavid du Colombier      }
4057dd7cddfSDavid du Colombier    png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
4067dd7cddfSDavid du Colombier 
407*593dc095SDavid du Colombier    info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
408*593dc095SDavid du Colombier       (png_uint_32)((nparams + 1) * png_sizeof(png_charp)));
409*593dc095SDavid du Colombier    if (info_ptr->pcal_params == NULL)
410*593dc095SDavid du Colombier      {
411*593dc095SDavid du Colombier        png_warning(png_ptr, "Insufficient memory for pCAL params.");
412*593dc095SDavid du Colombier        return;
413*593dc095SDavid du Colombier      }
414*593dc095SDavid du Colombier 
4157dd7cddfSDavid du Colombier    info_ptr->pcal_params[nparams] = NULL;
4167dd7cddfSDavid du Colombier 
4177dd7cddfSDavid du Colombier    for (i = 0; i < nparams; i++)
4187dd7cddfSDavid du Colombier    {
4197dd7cddfSDavid du Colombier       length = png_strlen(params[i]) + 1;
420*593dc095SDavid du Colombier       png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
421*593dc095SDavid du Colombier       info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
422*593dc095SDavid du Colombier       if (info_ptr->pcal_params[i] == NULL)
423*593dc095SDavid du Colombier         {
424*593dc095SDavid du Colombier           png_warning(png_ptr, "Insufficient memory for pCAL parameter.");
425*593dc095SDavid du Colombier           return;
426*593dc095SDavid du Colombier         }
4277dd7cddfSDavid du Colombier       png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
4287dd7cddfSDavid du Colombier    }
4297dd7cddfSDavid du Colombier 
4307dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_pCAL;
431*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
432*593dc095SDavid du Colombier    info_ptr->free_me |= PNG_FREE_PCAL;
433*593dc095SDavid du Colombier #endif
4347dd7cddfSDavid du Colombier }
4357dd7cddfSDavid du Colombier #endif
4367dd7cddfSDavid du Colombier 
437*593dc095SDavid du Colombier #if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
438*593dc095SDavid du Colombier #ifdef PNG_FLOATING_POINT_SUPPORTED
439*593dc095SDavid du Colombier void PNGAPI
png_set_sCAL(png_structp png_ptr,png_infop info_ptr,int unit,double width,double height)440*593dc095SDavid du Colombier png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
441*593dc095SDavid du Colombier              int unit, double width, double height)
442*593dc095SDavid du Colombier {
443*593dc095SDavid du Colombier    png_debug1(1, "in %s storage function\n", "sCAL");
444*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
445*593dc095SDavid du Colombier       return;
446*593dc095SDavid du Colombier 
447*593dc095SDavid du Colombier    info_ptr->scal_unit = (png_byte)unit;
448*593dc095SDavid du Colombier    info_ptr->scal_pixel_width = width;
449*593dc095SDavid du Colombier    info_ptr->scal_pixel_height = height;
450*593dc095SDavid du Colombier 
451*593dc095SDavid du Colombier    info_ptr->valid |= PNG_INFO_sCAL;
452*593dc095SDavid du Colombier }
453*593dc095SDavid du Colombier #else
454*593dc095SDavid du Colombier #ifdef PNG_FIXED_POINT_SUPPORTED
455*593dc095SDavid du Colombier void PNGAPI
png_set_sCAL_s(png_structp png_ptr,png_infop info_ptr,int unit,png_charp swidth,png_charp sheight)456*593dc095SDavid du Colombier png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
457*593dc095SDavid du Colombier              int unit, png_charp swidth, png_charp sheight)
458*593dc095SDavid du Colombier {
459*593dc095SDavid du Colombier    png_uint_32 length;
460*593dc095SDavid du Colombier 
461*593dc095SDavid du Colombier    png_debug1(1, "in %s storage function\n", "sCAL");
462*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
463*593dc095SDavid du Colombier       return;
464*593dc095SDavid du Colombier 
465*593dc095SDavid du Colombier    info_ptr->scal_unit = (png_byte)unit;
466*593dc095SDavid du Colombier 
467*593dc095SDavid du Colombier    length = png_strlen(swidth) + 1;
468*593dc095SDavid du Colombier    png_debug1(3, "allocating unit for info (%d bytes)\n", length);
469*593dc095SDavid du Colombier    info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
470*593dc095SDavid du Colombier    if (info_ptr->scal_s_width == NULL)
471*593dc095SDavid du Colombier    {
472*593dc095SDavid du Colombier       png_warning(png_ptr, "Memory allocation failed while processing sCAL.");
473*593dc095SDavid du Colombier    }
474*593dc095SDavid du Colombier    png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
475*593dc095SDavid du Colombier 
476*593dc095SDavid du Colombier    length = png_strlen(sheight) + 1;
477*593dc095SDavid du Colombier    png_debug1(3, "allocating unit for info (%d bytes)\n", length);
478*593dc095SDavid du Colombier    info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
479*593dc095SDavid du Colombier    if (info_ptr->scal_s_height == NULL)
480*593dc095SDavid du Colombier    {
481*593dc095SDavid du Colombier       png_free (png_ptr, info_ptr->scal_s_width);
482*593dc095SDavid du Colombier       png_warning(png_ptr, "Memory allocation failed while processing sCAL.");
483*593dc095SDavid du Colombier    }
484*593dc095SDavid du Colombier    png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
485*593dc095SDavid du Colombier 
486*593dc095SDavid du Colombier    info_ptr->valid |= PNG_INFO_sCAL;
487*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
488*593dc095SDavid du Colombier    info_ptr->free_me |= PNG_FREE_SCAL;
489*593dc095SDavid du Colombier #endif
490*593dc095SDavid du Colombier }
491*593dc095SDavid du Colombier #endif
492*593dc095SDavid du Colombier #endif
493*593dc095SDavid du Colombier #endif
494*593dc095SDavid du Colombier 
495*593dc095SDavid du Colombier #if defined(PNG_pHYs_SUPPORTED)
496*593dc095SDavid du Colombier void PNGAPI
png_set_pHYs(png_structp png_ptr,png_infop info_ptr,png_uint_32 res_x,png_uint_32 res_y,int unit_type)4977dd7cddfSDavid du Colombier png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
4987dd7cddfSDavid du Colombier    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
4997dd7cddfSDavid du Colombier {
5007dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "pHYs");
501*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
5027dd7cddfSDavid du Colombier       return;
5037dd7cddfSDavid du Colombier 
5047dd7cddfSDavid du Colombier    info_ptr->x_pixels_per_unit = res_x;
5057dd7cddfSDavid du Colombier    info_ptr->y_pixels_per_unit = res_y;
5067dd7cddfSDavid du Colombier    info_ptr->phys_unit_type = (png_byte)unit_type;
5077dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_pHYs;
5087dd7cddfSDavid du Colombier }
5097dd7cddfSDavid du Colombier #endif
5107dd7cddfSDavid du Colombier 
511*593dc095SDavid du Colombier void PNGAPI
png_set_PLTE(png_structp png_ptr,png_infop info_ptr,png_colorp palette,int num_palette)5127dd7cddfSDavid du Colombier png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
5137dd7cddfSDavid du Colombier    png_colorp palette, int num_palette)
5147dd7cddfSDavid du Colombier {
515*593dc095SDavid du Colombier 
5167dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "PLTE");
517*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
5187dd7cddfSDavid du Colombier       return;
5197dd7cddfSDavid du Colombier 
520*593dc095SDavid du Colombier    /*
521*593dc095SDavid du Colombier     * It may not actually be necessary to set png_ptr->palette here;
522*593dc095SDavid du Colombier     * we do it for backward compatibility with the way the png_handle_tRNS
523*593dc095SDavid du Colombier     * function used to do the allocation.
524*593dc095SDavid du Colombier     */
525*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
526*593dc095SDavid du Colombier    png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
527*593dc095SDavid du Colombier #endif
528*593dc095SDavid du Colombier 
529*593dc095SDavid du Colombier    /* Changed in libpng-1.2.1 to allocate 256 instead of num_palette entries,
530*593dc095SDavid du Colombier       in case of an invalid PNG file that has too-large sample values. */
531*593dc095SDavid du Colombier    png_ptr->palette = (png_colorp)png_malloc(png_ptr,
532*593dc095SDavid du Colombier       256 * png_sizeof(png_color));
533*593dc095SDavid du Colombier    png_memset(png_ptr->palette, 0, 256 * png_sizeof(png_color));
534*593dc095SDavid du Colombier    png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color));
535*593dc095SDavid du Colombier    info_ptr->palette = png_ptr->palette;
536*593dc095SDavid du Colombier    info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
537*593dc095SDavid du Colombier 
538*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
539*593dc095SDavid du Colombier    info_ptr->free_me |= PNG_FREE_PLTE;
540*593dc095SDavid du Colombier #else
541*593dc095SDavid du Colombier    png_ptr->flags |= PNG_FLAG_FREE_PLTE;
542*593dc095SDavid du Colombier #endif
543*593dc095SDavid du Colombier 
5447dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_PLTE;
5457dd7cddfSDavid du Colombier }
5467dd7cddfSDavid du Colombier 
547*593dc095SDavid du Colombier #if defined(PNG_sBIT_SUPPORTED)
548*593dc095SDavid du Colombier void PNGAPI
png_set_sBIT(png_structp png_ptr,png_infop info_ptr,png_color_8p sig_bit)5497dd7cddfSDavid du Colombier png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
5507dd7cddfSDavid du Colombier    png_color_8p sig_bit)
5517dd7cddfSDavid du Colombier {
5527dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "sBIT");
553*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
5547dd7cddfSDavid du Colombier       return;
5557dd7cddfSDavid du Colombier 
556*593dc095SDavid du Colombier    png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8));
5577dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_sBIT;
5587dd7cddfSDavid du Colombier }
5597dd7cddfSDavid du Colombier #endif
5607dd7cddfSDavid du Colombier 
561*593dc095SDavid du Colombier #if defined(PNG_sRGB_SUPPORTED)
562*593dc095SDavid du Colombier void PNGAPI
png_set_sRGB(png_structp png_ptr,png_infop info_ptr,int intent)5637dd7cddfSDavid du Colombier png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
5647dd7cddfSDavid du Colombier {
5657dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "sRGB");
566*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
5677dd7cddfSDavid du Colombier       return;
5687dd7cddfSDavid du Colombier 
5697dd7cddfSDavid du Colombier    info_ptr->srgb_intent = (png_byte)intent;
5707dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_sRGB;
5717dd7cddfSDavid du Colombier }
572*593dc095SDavid du Colombier 
573*593dc095SDavid du Colombier void PNGAPI
png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr,png_infop info_ptr,int intent)5747dd7cddfSDavid du Colombier png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
5757dd7cddfSDavid du Colombier    int intent)
5767dd7cddfSDavid du Colombier {
577*593dc095SDavid du Colombier #if defined(PNG_gAMA_SUPPORTED)
578*593dc095SDavid du Colombier #ifdef PNG_FLOATING_POINT_SUPPORTED
5797dd7cddfSDavid du Colombier    float file_gamma;
5807dd7cddfSDavid du Colombier #endif
581*593dc095SDavid du Colombier #ifdef PNG_FIXED_POINT_SUPPORTED
582*593dc095SDavid du Colombier    png_fixed_point int_file_gamma;
583*593dc095SDavid du Colombier #endif
584*593dc095SDavid du Colombier #endif
585*593dc095SDavid du Colombier #if defined(PNG_cHRM_SUPPORTED)
586*593dc095SDavid du Colombier #ifdef PNG_FLOATING_POINT_SUPPORTED
5877dd7cddfSDavid du Colombier    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
5887dd7cddfSDavid du Colombier #endif
589*593dc095SDavid du Colombier #ifdef PNG_FIXED_POINT_SUPPORTED
590*593dc095SDavid du Colombier    png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
591*593dc095SDavid du Colombier       int_green_y, int_blue_x, int_blue_y;
592*593dc095SDavid du Colombier #endif
593*593dc095SDavid du Colombier #endif
5947dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
595*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
5967dd7cddfSDavid du Colombier       return;
5977dd7cddfSDavid du Colombier 
5987dd7cddfSDavid du Colombier    png_set_sRGB(png_ptr, info_ptr, intent);
5997dd7cddfSDavid du Colombier 
600*593dc095SDavid du Colombier #if defined(PNG_gAMA_SUPPORTED)
601*593dc095SDavid du Colombier #ifdef PNG_FLOATING_POINT_SUPPORTED
602*593dc095SDavid du Colombier    file_gamma = (float).45455;
6037dd7cddfSDavid du Colombier    png_set_gAMA(png_ptr, info_ptr, file_gamma);
6047dd7cddfSDavid du Colombier #endif
605*593dc095SDavid du Colombier #ifdef PNG_FIXED_POINT_SUPPORTED
606*593dc095SDavid du Colombier    int_file_gamma = 45455L;
607*593dc095SDavid du Colombier    png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
608*593dc095SDavid du Colombier #endif
609*593dc095SDavid du Colombier #endif
6107dd7cddfSDavid du Colombier 
611*593dc095SDavid du Colombier #if defined(PNG_cHRM_SUPPORTED)
612*593dc095SDavid du Colombier #ifdef PNG_FIXED_POINT_SUPPORTED
613*593dc095SDavid du Colombier    int_white_x = 31270L;
614*593dc095SDavid du Colombier    int_white_y = 32900L;
615*593dc095SDavid du Colombier    int_red_x   = 64000L;
616*593dc095SDavid du Colombier    int_red_y   = 33000L;
617*593dc095SDavid du Colombier    int_green_x = 30000L;
618*593dc095SDavid du Colombier    int_green_y = 60000L;
619*593dc095SDavid du Colombier    int_blue_x  = 15000L;
620*593dc095SDavid du Colombier    int_blue_y  =  6000L;
621*593dc095SDavid du Colombier 
622*593dc095SDavid du Colombier    png_set_cHRM_fixed(png_ptr, info_ptr,
623*593dc095SDavid du Colombier       int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y,
624*593dc095SDavid du Colombier       int_blue_x, int_blue_y);
625*593dc095SDavid du Colombier #endif
626*593dc095SDavid du Colombier #ifdef PNG_FLOATING_POINT_SUPPORTED
6277dd7cddfSDavid du Colombier    white_x = (float).3127;
6287dd7cddfSDavid du Colombier    white_y = (float).3290;
6297dd7cddfSDavid du Colombier    red_x   = (float).64;
6307dd7cddfSDavid du Colombier    red_y   = (float).33;
6317dd7cddfSDavid du Colombier    green_x = (float).30;
6327dd7cddfSDavid du Colombier    green_y = (float).60;
6337dd7cddfSDavid du Colombier    blue_x  = (float).15;
6347dd7cddfSDavid du Colombier    blue_y  = (float).06;
6357dd7cddfSDavid du Colombier 
6367dd7cddfSDavid du Colombier    png_set_cHRM(png_ptr, info_ptr,
6377dd7cddfSDavid du Colombier       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
638*593dc095SDavid du Colombier #endif
6397dd7cddfSDavid du Colombier #endif
6407dd7cddfSDavid du Colombier }
6417dd7cddfSDavid du Colombier #endif
6427dd7cddfSDavid du Colombier 
643*593dc095SDavid du Colombier 
644*593dc095SDavid du Colombier #if defined(PNG_iCCP_SUPPORTED)
645*593dc095SDavid du Colombier void PNGAPI
png_set_iCCP(png_structp png_ptr,png_infop info_ptr,png_charp name,int compression_type,png_charp profile,png_uint_32 proflen)646*593dc095SDavid du Colombier png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
647*593dc095SDavid du Colombier              png_charp name, int compression_type,
648*593dc095SDavid du Colombier              png_charp profile, png_uint_32 proflen)
649*593dc095SDavid du Colombier {
650*593dc095SDavid du Colombier    png_charp new_iccp_name;
651*593dc095SDavid du Colombier    png_charp new_iccp_profile;
652*593dc095SDavid du Colombier 
653*593dc095SDavid du Colombier    png_debug1(1, "in %s storage function\n", "iCCP");
654*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
655*593dc095SDavid du Colombier       return;
656*593dc095SDavid du Colombier 
657*593dc095SDavid du Colombier    new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1);
658*593dc095SDavid du Colombier    if (new_iccp_name == NULL)
659*593dc095SDavid du Colombier    {
660*593dc095SDavid du Colombier       png_warning(png_ptr, "Insufficient memory to process iCCP chunk.");
661*593dc095SDavid du Colombier       return;
662*593dc095SDavid du Colombier    }
663*593dc095SDavid du Colombier    png_strcpy(new_iccp_name, name);
664*593dc095SDavid du Colombier    new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
665*593dc095SDavid du Colombier    if (new_iccp_profile == NULL)
666*593dc095SDavid du Colombier    {
667*593dc095SDavid du Colombier       png_free (png_ptr, new_iccp_name);
668*593dc095SDavid du Colombier       png_warning(png_ptr, "Insufficient memory to process iCCP profile.");
669*593dc095SDavid du Colombier       return;
670*593dc095SDavid du Colombier    }
671*593dc095SDavid du Colombier    png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
672*593dc095SDavid du Colombier 
673*593dc095SDavid du Colombier    png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
674*593dc095SDavid du Colombier 
675*593dc095SDavid du Colombier    info_ptr->iccp_proflen = proflen;
676*593dc095SDavid du Colombier    info_ptr->iccp_name = new_iccp_name;
677*593dc095SDavid du Colombier    info_ptr->iccp_profile = new_iccp_profile;
678*593dc095SDavid du Colombier    /* Compression is always zero but is here so the API and info structure
679*593dc095SDavid du Colombier     * does not have to change if we introduce multiple compression types */
680*593dc095SDavid du Colombier    info_ptr->iccp_compression = (png_byte)compression_type;
681*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
682*593dc095SDavid du Colombier    info_ptr->free_me |= PNG_FREE_ICCP;
683*593dc095SDavid du Colombier #endif
684*593dc095SDavid du Colombier    info_ptr->valid |= PNG_INFO_iCCP;
685*593dc095SDavid du Colombier }
686*593dc095SDavid du Colombier #endif
687*593dc095SDavid du Colombier 
688*593dc095SDavid du Colombier #if defined(PNG_TEXT_SUPPORTED)
689*593dc095SDavid du Colombier void PNGAPI
png_set_text(png_structp png_ptr,png_infop info_ptr,png_textp text_ptr,int num_text)6907dd7cddfSDavid du Colombier png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
6917dd7cddfSDavid du Colombier    int num_text)
6927dd7cddfSDavid du Colombier {
693*593dc095SDavid du Colombier    int ret;
694*593dc095SDavid du Colombier    ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
695*593dc095SDavid du Colombier    if (ret)
696*593dc095SDavid du Colombier      png_error(png_ptr, "Insufficient memory to store text");
697*593dc095SDavid du Colombier }
698*593dc095SDavid du Colombier 
699*593dc095SDavid du Colombier int /* PRIVATE */
png_set_text_2(png_structp png_ptr,png_infop info_ptr,png_textp text_ptr,int num_text)700*593dc095SDavid du Colombier png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
701*593dc095SDavid du Colombier    int num_text)
702*593dc095SDavid du Colombier {
7037dd7cddfSDavid du Colombier    int i;
7047dd7cddfSDavid du Colombier 
7057dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
7067dd7cddfSDavid du Colombier       "text" : (png_const_charp)png_ptr->chunk_name));
7077dd7cddfSDavid du Colombier 
708*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
709*593dc095SDavid du Colombier       return(0);
7107dd7cddfSDavid du Colombier 
7117dd7cddfSDavid du Colombier    /* Make sure we have enough space in the "text" array in info_struct
7127dd7cddfSDavid du Colombier     * to hold all of the incoming text_ptr objects.
7137dd7cddfSDavid du Colombier     */
7147dd7cddfSDavid du Colombier    if (info_ptr->num_text + num_text > info_ptr->max_text)
7157dd7cddfSDavid du Colombier    {
7167dd7cddfSDavid du Colombier       if (info_ptr->text != NULL)
7177dd7cddfSDavid du Colombier       {
7187dd7cddfSDavid du Colombier          png_textp old_text;
7197dd7cddfSDavid du Colombier          int old_max;
7207dd7cddfSDavid du Colombier 
7217dd7cddfSDavid du Colombier          old_max = info_ptr->max_text;
7227dd7cddfSDavid du Colombier          info_ptr->max_text = info_ptr->num_text + num_text + 8;
7237dd7cddfSDavid du Colombier          old_text = info_ptr->text;
724*593dc095SDavid du Colombier          info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
725*593dc095SDavid du Colombier             (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
726*593dc095SDavid du Colombier          if (info_ptr->text == NULL)
727*593dc095SDavid du Colombier            {
728*593dc095SDavid du Colombier              png_free(png_ptr, old_text);
729*593dc095SDavid du Colombier              return(1);
730*593dc095SDavid du Colombier            }
731*593dc095SDavid du Colombier          png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
732*593dc095SDavid du Colombier             png_sizeof(png_text)));
7337dd7cddfSDavid du Colombier          png_free(png_ptr, old_text);
7347dd7cddfSDavid du Colombier       }
7357dd7cddfSDavid du Colombier       else
7367dd7cddfSDavid du Colombier       {
7377dd7cddfSDavid du Colombier          info_ptr->max_text = num_text + 8;
7387dd7cddfSDavid du Colombier          info_ptr->num_text = 0;
739*593dc095SDavid du Colombier          info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
740*593dc095SDavid du Colombier             (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
741*593dc095SDavid du Colombier          if (info_ptr->text == NULL)
742*593dc095SDavid du Colombier            return(1);
743*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
744*593dc095SDavid du Colombier          info_ptr->free_me |= PNG_FREE_TEXT;
745*593dc095SDavid du Colombier #endif
7467dd7cddfSDavid du Colombier       }
7477dd7cddfSDavid du Colombier       png_debug1(3, "allocated %d entries for info_ptr->text\n",
7487dd7cddfSDavid du Colombier          info_ptr->max_text);
7497dd7cddfSDavid du Colombier    }
7507dd7cddfSDavid du Colombier    for (i = 0; i < num_text; i++)
7517dd7cddfSDavid du Colombier    {
752*593dc095SDavid du Colombier       png_size_t text_length,key_len;
753*593dc095SDavid du Colombier       png_size_t lang_len,lang_key_len;
7547dd7cddfSDavid du Colombier       png_textp textp = &(info_ptr->text[info_ptr->num_text]);
7557dd7cddfSDavid du Colombier 
756*593dc095SDavid du Colombier       if (text_ptr[i].key == NULL)
757*593dc095SDavid du Colombier           continue;
7587dd7cddfSDavid du Colombier 
759*593dc095SDavid du Colombier       key_len = png_strlen(text_ptr[i].key);
760*593dc095SDavid du Colombier 
761*593dc095SDavid du Colombier       if(text_ptr[i].compression <= 0)
7627dd7cddfSDavid du Colombier       {
763*593dc095SDavid du Colombier         lang_len = 0;
764*593dc095SDavid du Colombier         lang_key_len = 0;
765*593dc095SDavid du Colombier       }
766*593dc095SDavid du Colombier       else
767*593dc095SDavid du Colombier #ifdef PNG_iTXt_SUPPORTED
768*593dc095SDavid du Colombier       {
769*593dc095SDavid du Colombier         /* set iTXt data */
770*593dc095SDavid du Colombier         if (text_ptr[i].lang != NULL)
771*593dc095SDavid du Colombier           lang_len = png_strlen(text_ptr[i].lang);
772*593dc095SDavid du Colombier         else
773*593dc095SDavid du Colombier           lang_len = 0;
774*593dc095SDavid du Colombier         if (text_ptr[i].lang_key != NULL)
775*593dc095SDavid du Colombier           lang_key_len = png_strlen(text_ptr[i].lang_key);
776*593dc095SDavid du Colombier         else
777*593dc095SDavid du Colombier           lang_key_len = 0;
778*593dc095SDavid du Colombier       }
779*593dc095SDavid du Colombier #else
780*593dc095SDavid du Colombier       {
781*593dc095SDavid du Colombier         png_warning(png_ptr, "iTXt chunk not supported.");
782*593dc095SDavid du Colombier         continue;
783*593dc095SDavid du Colombier       }
784*593dc095SDavid du Colombier #endif
785*593dc095SDavid du Colombier 
786*593dc095SDavid du Colombier       if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
787*593dc095SDavid du Colombier       {
788*593dc095SDavid du Colombier          text_length = 0;
789*593dc095SDavid du Colombier #ifdef PNG_iTXt_SUPPORTED
790*593dc095SDavid du Colombier          if(text_ptr[i].compression > 0)
791*593dc095SDavid du Colombier             textp->compression = PNG_ITXT_COMPRESSION_NONE;
792*593dc095SDavid du Colombier          else
793*593dc095SDavid du Colombier #endif
7947dd7cddfSDavid du Colombier             textp->compression = PNG_TEXT_COMPRESSION_NONE;
7957dd7cddfSDavid du Colombier       }
7967dd7cddfSDavid du Colombier       else
7977dd7cddfSDavid du Colombier       {
798*593dc095SDavid du Colombier          text_length = png_strlen(text_ptr[i].text);
7997dd7cddfSDavid du Colombier          textp->compression = text_ptr[i].compression;
8007dd7cddfSDavid du Colombier       }
801*593dc095SDavid du Colombier 
802*593dc095SDavid du Colombier       textp->key = (png_charp)png_malloc_warn(png_ptr,
803*593dc095SDavid du Colombier          (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
804*593dc095SDavid du Colombier       if (textp->key == NULL)
805*593dc095SDavid du Colombier         return(1);
806*593dc095SDavid du Colombier       png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n",
807*593dc095SDavid du Colombier          (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4),
808*593dc095SDavid du Colombier          (int)textp->key);
809*593dc095SDavid du Colombier 
810*593dc095SDavid du Colombier       png_memcpy(textp->key, text_ptr[i].key,
811*593dc095SDavid du Colombier          (png_size_t)(key_len));
812*593dc095SDavid du Colombier       *(textp->key+key_len) = '\0';
813*593dc095SDavid du Colombier #ifdef PNG_iTXt_SUPPORTED
814*593dc095SDavid du Colombier       if (text_ptr[i].compression > 0)
815*593dc095SDavid du Colombier       {
816*593dc095SDavid du Colombier          textp->lang=textp->key + key_len + 1;
817*593dc095SDavid du Colombier          png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
818*593dc095SDavid du Colombier          *(textp->lang+lang_len) = '\0';
819*593dc095SDavid du Colombier          textp->lang_key=textp->lang + lang_len + 1;
820*593dc095SDavid du Colombier          png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
821*593dc095SDavid du Colombier          *(textp->lang_key+lang_key_len) = '\0';
822*593dc095SDavid du Colombier          textp->text=textp->lang_key + lang_key_len + 1;
823*593dc095SDavid du Colombier       }
824*593dc095SDavid du Colombier       else
825*593dc095SDavid du Colombier #endif
826*593dc095SDavid du Colombier       {
827*593dc095SDavid du Colombier #ifdef PNG_iTXt_SUPPORTED
828*593dc095SDavid du Colombier          textp->lang=NULL;
829*593dc095SDavid du Colombier          textp->lang_key=NULL;
830*593dc095SDavid du Colombier #endif
831*593dc095SDavid du Colombier          textp->text=textp->key + key_len + 1;
832*593dc095SDavid du Colombier       }
833*593dc095SDavid du Colombier       if(text_length)
834*593dc095SDavid du Colombier          png_memcpy(textp->text, text_ptr[i].text,
835*593dc095SDavid du Colombier             (png_size_t)(text_length));
836*593dc095SDavid du Colombier       *(textp->text+text_length) = '\0';
837*593dc095SDavid du Colombier 
838*593dc095SDavid du Colombier #ifdef PNG_iTXt_SUPPORTED
839*593dc095SDavid du Colombier       if(textp->compression > 0)
840*593dc095SDavid du Colombier       {
841*593dc095SDavid du Colombier          textp->text_length = 0;
842*593dc095SDavid du Colombier          textp->itxt_length = text_length;
843*593dc095SDavid du Colombier       }
844*593dc095SDavid du Colombier       else
845*593dc095SDavid du Colombier #endif
846*593dc095SDavid du Colombier       {
847*593dc095SDavid du Colombier          textp->text_length = text_length;
848*593dc095SDavid du Colombier #ifdef PNG_iTXt_SUPPORTED
849*593dc095SDavid du Colombier          textp->itxt_length = 0;
850*593dc095SDavid du Colombier #endif
851*593dc095SDavid du Colombier       }
852*593dc095SDavid du Colombier       info_ptr->text[info_ptr->num_text]= *textp;
8537dd7cddfSDavid du Colombier       info_ptr->num_text++;
8547dd7cddfSDavid du Colombier       png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
8557dd7cddfSDavid du Colombier    }
856*593dc095SDavid du Colombier    return(0);
8577dd7cddfSDavid du Colombier }
8587dd7cddfSDavid du Colombier #endif
8597dd7cddfSDavid du Colombier 
860*593dc095SDavid du Colombier #if defined(PNG_tIME_SUPPORTED)
861*593dc095SDavid du Colombier void PNGAPI
png_set_tIME(png_structp png_ptr,png_infop info_ptr,png_timep mod_time)8627dd7cddfSDavid du Colombier png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
8637dd7cddfSDavid du Colombier {
8647dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "tIME");
865*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL ||
866*593dc095SDavid du Colombier        (png_ptr->mode & PNG_WROTE_tIME))
8677dd7cddfSDavid du Colombier       return;
8687dd7cddfSDavid du Colombier 
869*593dc095SDavid du Colombier    png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time));
8707dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_tIME;
8717dd7cddfSDavid du Colombier }
8727dd7cddfSDavid du Colombier #endif
8737dd7cddfSDavid du Colombier 
874*593dc095SDavid du Colombier #if defined(PNG_tRNS_SUPPORTED)
875*593dc095SDavid du Colombier void PNGAPI
png_set_tRNS(png_structp png_ptr,png_infop info_ptr,png_bytep trans,int num_trans,png_color_16p trans_values)8767dd7cddfSDavid du Colombier png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
8777dd7cddfSDavid du Colombier    png_bytep trans, int num_trans, png_color_16p trans_values)
8787dd7cddfSDavid du Colombier {
8797dd7cddfSDavid du Colombier    png_debug1(1, "in %s storage function\n", "tRNS");
880*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
8817dd7cddfSDavid du Colombier       return;
8827dd7cddfSDavid du Colombier 
8837dd7cddfSDavid du Colombier    if (trans != NULL)
8847dd7cddfSDavid du Colombier    {
885*593dc095SDavid du Colombier        /*
886*593dc095SDavid du Colombier         * It may not actually be necessary to set png_ptr->trans here;
887*593dc095SDavid du Colombier         * we do it for backward compatibility with the way the png_handle_tRNS
888*593dc095SDavid du Colombier         * function used to do the allocation.
889*593dc095SDavid du Colombier         */
890*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
891*593dc095SDavid du Colombier        png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
892*593dc095SDavid du Colombier #endif
893*593dc095SDavid du Colombier        /* Changed from num_trans to 256 in version 1.2.1 */
894*593dc095SDavid du Colombier        png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
895*593dc095SDavid du Colombier            (png_uint_32)256);
896*593dc095SDavid du Colombier        png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
897*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
898*593dc095SDavid du Colombier        info_ptr->free_me |= PNG_FREE_TRNS;
899*593dc095SDavid du Colombier #else
900*593dc095SDavid du Colombier        png_ptr->flags |= PNG_FLAG_FREE_TRNS;
901*593dc095SDavid du Colombier #endif
9027dd7cddfSDavid du Colombier    }
9037dd7cddfSDavid du Colombier 
9047dd7cddfSDavid du Colombier    if (trans_values != NULL)
9057dd7cddfSDavid du Colombier    {
9067dd7cddfSDavid du Colombier       png_memcpy(&(info_ptr->trans_values), trans_values,
907*593dc095SDavid du Colombier          png_sizeof(png_color_16));
9087dd7cddfSDavid du Colombier       if (num_trans == 0)
9097dd7cddfSDavid du Colombier         num_trans = 1;
9107dd7cddfSDavid du Colombier    }
9117dd7cddfSDavid du Colombier    info_ptr->num_trans = (png_uint_16)num_trans;
9127dd7cddfSDavid du Colombier    info_ptr->valid |= PNG_INFO_tRNS;
9137dd7cddfSDavid du Colombier }
9147dd7cddfSDavid du Colombier #endif
9157dd7cddfSDavid du Colombier 
916*593dc095SDavid du Colombier #if defined(PNG_sPLT_SUPPORTED)
917*593dc095SDavid du Colombier void PNGAPI
png_set_sPLT(png_structp png_ptr,png_infop info_ptr,png_sPLT_tp entries,int nentries)918*593dc095SDavid du Colombier png_set_sPLT(png_structp png_ptr,
919*593dc095SDavid du Colombier              png_infop info_ptr, png_sPLT_tp entries, int nentries)
920*593dc095SDavid du Colombier {
921*593dc095SDavid du Colombier     png_sPLT_tp np;
922*593dc095SDavid du Colombier     int i;
923*593dc095SDavid du Colombier 
924*593dc095SDavid du Colombier     np = (png_sPLT_tp)png_malloc_warn(png_ptr,
925*593dc095SDavid du Colombier         (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t));
926*593dc095SDavid du Colombier     if (np == NULL)
927*593dc095SDavid du Colombier     {
928*593dc095SDavid du Colombier       png_warning(png_ptr, "No memory for sPLT palettes.");
929*593dc095SDavid du Colombier       return;
930*593dc095SDavid du Colombier     }
931*593dc095SDavid du Colombier 
932*593dc095SDavid du Colombier     png_memcpy(np, info_ptr->splt_palettes,
933*593dc095SDavid du Colombier            info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
934*593dc095SDavid du Colombier     png_free(png_ptr, info_ptr->splt_palettes);
935*593dc095SDavid du Colombier     info_ptr->splt_palettes=NULL;
936*593dc095SDavid du Colombier 
937*593dc095SDavid du Colombier     for (i = 0; i < nentries; i++)
938*593dc095SDavid du Colombier     {
939*593dc095SDavid du Colombier         png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
940*593dc095SDavid du Colombier         png_sPLT_tp from = entries + i;
941*593dc095SDavid du Colombier 
942*593dc095SDavid du Colombier         to->name = (png_charp)png_malloc(png_ptr,
943*593dc095SDavid du Colombier             png_strlen(from->name) + 1);
944*593dc095SDavid du Colombier         /* TODO: use png_malloc_warn */
945*593dc095SDavid du Colombier         png_strcpy(to->name, from->name);
946*593dc095SDavid du Colombier         to->entries = (png_sPLT_entryp)png_malloc(png_ptr,
947*593dc095SDavid du Colombier             from->nentries * png_sizeof(png_sPLT_t));
948*593dc095SDavid du Colombier         /* TODO: use png_malloc_warn */
949*593dc095SDavid du Colombier         png_memcpy(to->entries, from->entries,
950*593dc095SDavid du Colombier             from->nentries * png_sizeof(png_sPLT_t));
951*593dc095SDavid du Colombier         to->nentries = from->nentries;
952*593dc095SDavid du Colombier         to->depth = from->depth;
953*593dc095SDavid du Colombier     }
954*593dc095SDavid du Colombier 
955*593dc095SDavid du Colombier     info_ptr->splt_palettes = np;
956*593dc095SDavid du Colombier     info_ptr->splt_palettes_num += nentries;
957*593dc095SDavid du Colombier     info_ptr->valid |= PNG_INFO_sPLT;
958*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
959*593dc095SDavid du Colombier     info_ptr->free_me |= PNG_FREE_SPLT;
960*593dc095SDavid du Colombier #endif
961*593dc095SDavid du Colombier }
962*593dc095SDavid du Colombier #endif /* PNG_sPLT_SUPPORTED */
963*593dc095SDavid du Colombier 
964*593dc095SDavid du Colombier #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
965*593dc095SDavid du Colombier void PNGAPI
png_set_unknown_chunks(png_structp png_ptr,png_infop info_ptr,png_unknown_chunkp unknowns,int num_unknowns)966*593dc095SDavid du Colombier png_set_unknown_chunks(png_structp png_ptr,
967*593dc095SDavid du Colombier    png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
968*593dc095SDavid du Colombier {
969*593dc095SDavid du Colombier     png_unknown_chunkp np;
970*593dc095SDavid du Colombier     int i;
971*593dc095SDavid du Colombier 
972*593dc095SDavid du Colombier     if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
973*593dc095SDavid du Colombier         return;
974*593dc095SDavid du Colombier 
975*593dc095SDavid du Colombier     np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
976*593dc095SDavid du Colombier         (info_ptr->unknown_chunks_num + num_unknowns) *
977*593dc095SDavid du Colombier         png_sizeof(png_unknown_chunk));
978*593dc095SDavid du Colombier     if (np == NULL)
979*593dc095SDavid du Colombier     {
980*593dc095SDavid du Colombier        png_warning(png_ptr, "Out of memory while processing unknown chunk.");
981*593dc095SDavid du Colombier        return;
982*593dc095SDavid du Colombier     }
983*593dc095SDavid du Colombier 
984*593dc095SDavid du Colombier     png_memcpy(np, info_ptr->unknown_chunks,
985*593dc095SDavid du Colombier            info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
986*593dc095SDavid du Colombier     png_free(png_ptr, info_ptr->unknown_chunks);
987*593dc095SDavid du Colombier     info_ptr->unknown_chunks=NULL;
988*593dc095SDavid du Colombier 
989*593dc095SDavid du Colombier     for (i = 0; i < num_unknowns; i++)
990*593dc095SDavid du Colombier     {
991*593dc095SDavid du Colombier         png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
992*593dc095SDavid du Colombier         png_unknown_chunkp from = unknowns + i;
993*593dc095SDavid du Colombier 
994*593dc095SDavid du Colombier         png_strncpy((png_charp)to->name, (png_charp)from->name, 5);
995*593dc095SDavid du Colombier         to->data = (png_bytep)png_malloc_warn(png_ptr, from->size);
996*593dc095SDavid du Colombier         if (to->data == NULL)
997*593dc095SDavid du Colombier         {
998*593dc095SDavid du Colombier            png_warning(png_ptr, "Out of memory processing unknown chunk.");
999*593dc095SDavid du Colombier         }
1000*593dc095SDavid du Colombier         else
1001*593dc095SDavid du Colombier         {
1002*593dc095SDavid du Colombier            png_memcpy(to->data, from->data, from->size);
1003*593dc095SDavid du Colombier            to->size = from->size;
1004*593dc095SDavid du Colombier 
1005*593dc095SDavid du Colombier            /* note our location in the read or write sequence */
1006*593dc095SDavid du Colombier            to->location = (png_byte)(png_ptr->mode & 0xff);
1007*593dc095SDavid du Colombier         }
1008*593dc095SDavid du Colombier     }
1009*593dc095SDavid du Colombier 
1010*593dc095SDavid du Colombier     info_ptr->unknown_chunks = np;
1011*593dc095SDavid du Colombier     info_ptr->unknown_chunks_num += num_unknowns;
1012*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
1013*593dc095SDavid du Colombier     info_ptr->free_me |= PNG_FREE_UNKN;
1014*593dc095SDavid du Colombier #endif
1015*593dc095SDavid du Colombier }
1016*593dc095SDavid du Colombier void PNGAPI
png_set_unknown_chunk_location(png_structp png_ptr,png_infop info_ptr,int chunk,int location)1017*593dc095SDavid du Colombier png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
1018*593dc095SDavid du Colombier    int chunk, int location)
1019*593dc095SDavid du Colombier {
1020*593dc095SDavid du Colombier    if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
1021*593dc095SDavid du Colombier          (int)info_ptr->unknown_chunks_num)
1022*593dc095SDavid du Colombier       info_ptr->unknown_chunks[chunk].location = (png_byte)location;
1023*593dc095SDavid du Colombier }
1024*593dc095SDavid du Colombier #endif
1025*593dc095SDavid du Colombier 
1026*593dc095SDavid du Colombier #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
1027*593dc095SDavid du Colombier     defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
1028*593dc095SDavid du Colombier void PNGAPI
png_permit_empty_plte(png_structp png_ptr,int empty_plte_permitted)1029*593dc095SDavid du Colombier png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
1030*593dc095SDavid du Colombier {
1031*593dc095SDavid du Colombier    /* This function is deprecated in favor of png_permit_mng_features()
1032*593dc095SDavid du Colombier       and will be removed from libpng-2.0.0 */
1033*593dc095SDavid du Colombier    png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n");
1034*593dc095SDavid du Colombier    if (png_ptr == NULL)
1035*593dc095SDavid du Colombier       return;
1036*593dc095SDavid du Colombier    png_ptr->mng_features_permitted = (png_byte)
1037*593dc095SDavid du Colombier      ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) |
1038*593dc095SDavid du Colombier      ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
1039*593dc095SDavid du Colombier }
1040*593dc095SDavid du Colombier #endif
1041*593dc095SDavid du Colombier 
1042*593dc095SDavid du Colombier #if defined(PNG_MNG_FEATURES_SUPPORTED)
1043*593dc095SDavid du Colombier png_uint_32 PNGAPI
png_permit_mng_features(png_structp png_ptr,png_uint_32 mng_features)1044*593dc095SDavid du Colombier png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
1045*593dc095SDavid du Colombier {
1046*593dc095SDavid du Colombier    png_debug(1, "in png_permit_mng_features\n");
1047*593dc095SDavid du Colombier    if (png_ptr == NULL)
1048*593dc095SDavid du Colombier       return (png_uint_32)0;
1049*593dc095SDavid du Colombier    png_ptr->mng_features_permitted =
1050*593dc095SDavid du Colombier      (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
1051*593dc095SDavid du Colombier    return (png_uint_32)png_ptr->mng_features_permitted;
1052*593dc095SDavid du Colombier }
1053*593dc095SDavid du Colombier #endif
1054*593dc095SDavid du Colombier 
1055*593dc095SDavid du Colombier #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
1056*593dc095SDavid du Colombier void PNGAPI
png_set_keep_unknown_chunks(png_structp png_ptr,int keep,png_bytep chunk_list,int num_chunks)1057*593dc095SDavid du Colombier png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
1058*593dc095SDavid du Colombier    chunk_list, int num_chunks)
1059*593dc095SDavid du Colombier {
1060*593dc095SDavid du Colombier     png_bytep new_list, p;
1061*593dc095SDavid du Colombier     int i, old_num_chunks;
1062*593dc095SDavid du Colombier     if (num_chunks == 0)
1063*593dc095SDavid du Colombier     {
1064*593dc095SDavid du Colombier       if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
1065*593dc095SDavid du Colombier         png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
1066*593dc095SDavid du Colombier       else
1067*593dc095SDavid du Colombier         png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
1068*593dc095SDavid du Colombier 
1069*593dc095SDavid du Colombier       if(keep == PNG_HANDLE_CHUNK_ALWAYS)
1070*593dc095SDavid du Colombier         png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
1071*593dc095SDavid du Colombier       else
1072*593dc095SDavid du Colombier         png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
1073*593dc095SDavid du Colombier       return;
1074*593dc095SDavid du Colombier     }
1075*593dc095SDavid du Colombier     if (chunk_list == NULL)
1076*593dc095SDavid du Colombier       return;
1077*593dc095SDavid du Colombier     old_num_chunks=png_ptr->num_chunk_list;
1078*593dc095SDavid du Colombier     new_list=(png_bytep)png_malloc(png_ptr,
1079*593dc095SDavid du Colombier        (png_uint_32)(5*(num_chunks+old_num_chunks)));
1080*593dc095SDavid du Colombier     if(png_ptr->chunk_list != NULL)
1081*593dc095SDavid du Colombier     {
1082*593dc095SDavid du Colombier        png_memcpy(new_list, png_ptr->chunk_list,
1083*593dc095SDavid du Colombier           (png_size_t)(5*old_num_chunks));
1084*593dc095SDavid du Colombier        png_free(png_ptr, png_ptr->chunk_list);
1085*593dc095SDavid du Colombier        png_ptr->chunk_list=NULL;
1086*593dc095SDavid du Colombier     }
1087*593dc095SDavid du Colombier     png_memcpy(new_list+5*old_num_chunks, chunk_list,
1088*593dc095SDavid du Colombier        (png_size_t)(5*num_chunks));
1089*593dc095SDavid du Colombier     for (p=new_list+5*old_num_chunks+4, i=0; i<num_chunks; i++, p+=5)
1090*593dc095SDavid du Colombier        *p=(png_byte)keep;
1091*593dc095SDavid du Colombier     png_ptr->num_chunk_list=old_num_chunks+num_chunks;
1092*593dc095SDavid du Colombier     png_ptr->chunk_list=new_list;
1093*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
1094*593dc095SDavid du Colombier     png_ptr->free_me |= PNG_FREE_LIST;
1095*593dc095SDavid du Colombier #endif
1096*593dc095SDavid du Colombier }
1097*593dc095SDavid du Colombier #endif
1098*593dc095SDavid du Colombier 
1099*593dc095SDavid du Colombier #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
1100*593dc095SDavid du Colombier void PNGAPI
png_set_read_user_chunk_fn(png_structp png_ptr,png_voidp user_chunk_ptr,png_user_chunk_ptr read_user_chunk_fn)1101*593dc095SDavid du Colombier png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
1102*593dc095SDavid du Colombier    png_user_chunk_ptr read_user_chunk_fn)
1103*593dc095SDavid du Colombier {
1104*593dc095SDavid du Colombier    png_debug(1, "in png_set_read_user_chunk_fn\n");
1105*593dc095SDavid du Colombier    png_ptr->read_user_chunk_fn = read_user_chunk_fn;
1106*593dc095SDavid du Colombier    png_ptr->user_chunk_ptr = user_chunk_ptr;
1107*593dc095SDavid du Colombier }
1108*593dc095SDavid du Colombier #endif
1109*593dc095SDavid du Colombier 
1110*593dc095SDavid du Colombier #if defined(PNG_INFO_IMAGE_SUPPORTED)
1111*593dc095SDavid du Colombier void PNGAPI
png_set_rows(png_structp png_ptr,png_infop info_ptr,png_bytepp row_pointers)1112*593dc095SDavid du Colombier png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
1113*593dc095SDavid du Colombier {
1114*593dc095SDavid du Colombier    png_debug1(1, "in %s storage function\n", "rows");
1115*593dc095SDavid du Colombier 
1116*593dc095SDavid du Colombier    if (png_ptr == NULL || info_ptr == NULL)
1117*593dc095SDavid du Colombier       return;
1118*593dc095SDavid du Colombier 
1119*593dc095SDavid du Colombier    if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
1120*593dc095SDavid du Colombier       png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1121*593dc095SDavid du Colombier    info_ptr->row_pointers = row_pointers;
1122*593dc095SDavid du Colombier    if(row_pointers)
1123*593dc095SDavid du Colombier       info_ptr->valid |= PNG_INFO_IDAT;
1124*593dc095SDavid du Colombier }
1125*593dc095SDavid du Colombier #endif
1126*593dc095SDavid du Colombier 
1127*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
1128*593dc095SDavid du Colombier void PNGAPI
png_set_compression_buffer_size(png_structp png_ptr,png_uint_32 size)1129*593dc095SDavid du Colombier png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
1130*593dc095SDavid du Colombier {
1131*593dc095SDavid du Colombier     if(png_ptr->zbuf)
1132*593dc095SDavid du Colombier        png_free(png_ptr, png_ptr->zbuf);
1133*593dc095SDavid du Colombier     png_ptr->zbuf_size = (png_size_t)size;
1134*593dc095SDavid du Colombier     png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
1135*593dc095SDavid du Colombier     png_ptr->zstream.next_out = png_ptr->zbuf;
1136*593dc095SDavid du Colombier     png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1137*593dc095SDavid du Colombier }
1138*593dc095SDavid du Colombier #endif
1139*593dc095SDavid du Colombier 
1140*593dc095SDavid du Colombier void PNGAPI
png_set_invalid(png_structp png_ptr,png_infop info_ptr,int mask)1141*593dc095SDavid du Colombier png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
1142*593dc095SDavid du Colombier {
1143*593dc095SDavid du Colombier    if (png_ptr && info_ptr)
1144*593dc095SDavid du Colombier       info_ptr->valid &= ~(mask);
1145*593dc095SDavid du Colombier }
1146*593dc095SDavid du Colombier 
1147*593dc095SDavid du Colombier 
1148*593dc095SDavid du Colombier #ifndef PNG_1_0_X
1149*593dc095SDavid du Colombier #ifdef PNG_ASSEMBLER_CODE_SUPPORTED
1150*593dc095SDavid du Colombier /* this function was added to libpng 1.2.0 and should always exist by default */
1151*593dc095SDavid du Colombier void PNGAPI
png_set_asm_flags(png_structp png_ptr,png_uint_32 asm_flags)1152*593dc095SDavid du Colombier png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags)
1153*593dc095SDavid du Colombier {
1154*593dc095SDavid du Colombier     png_uint_32 settable_asm_flags;
1155*593dc095SDavid du Colombier     png_uint_32 settable_mmx_flags;
1156*593dc095SDavid du Colombier 
1157*593dc095SDavid du Colombier     settable_mmx_flags =
1158*593dc095SDavid du Colombier #ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
1159*593dc095SDavid du Colombier                          PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  |
1160*593dc095SDavid du Colombier #endif
1161*593dc095SDavid du Colombier #ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
1162*593dc095SDavid du Colombier                          PNG_ASM_FLAG_MMX_READ_INTERLACE    |
1163*593dc095SDavid du Colombier #endif
1164*593dc095SDavid du Colombier #ifdef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
1165*593dc095SDavid du Colombier                          PNG_ASM_FLAG_MMX_READ_FILTER_SUB   |
1166*593dc095SDavid du Colombier                          PNG_ASM_FLAG_MMX_READ_FILTER_UP    |
1167*593dc095SDavid du Colombier                          PNG_ASM_FLAG_MMX_READ_FILTER_AVG   |
1168*593dc095SDavid du Colombier                          PNG_ASM_FLAG_MMX_READ_FILTER_PAETH |
1169*593dc095SDavid du Colombier #endif
1170*593dc095SDavid du Colombier                          0;
1171*593dc095SDavid du Colombier 
1172*593dc095SDavid du Colombier     /* could be some non-MMX ones in the future, but not currently: */
1173*593dc095SDavid du Colombier     settable_asm_flags = settable_mmx_flags;
1174*593dc095SDavid du Colombier 
1175*593dc095SDavid du Colombier     if (!(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED) ||
1176*593dc095SDavid du Colombier         !(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU))
1177*593dc095SDavid du Colombier     {
1178*593dc095SDavid du Colombier         /* clear all MMX flags if MMX isn't supported */
1179*593dc095SDavid du Colombier         settable_asm_flags &= ~settable_mmx_flags;
1180*593dc095SDavid du Colombier         png_ptr->asm_flags &= ~settable_mmx_flags;
1181*593dc095SDavid du Colombier     }
1182*593dc095SDavid du Colombier 
1183*593dc095SDavid du Colombier     /* we're replacing the settable bits with those passed in by the user,
1184*593dc095SDavid du Colombier      * so first zero them out of the master copy, then logical-OR in the
1185*593dc095SDavid du Colombier      * allowed subset that was requested */
1186*593dc095SDavid du Colombier 
1187*593dc095SDavid du Colombier     png_ptr->asm_flags &= ~settable_asm_flags;               /* zero them */
1188*593dc095SDavid du Colombier     png_ptr->asm_flags |= (asm_flags & settable_asm_flags);  /* set them */
1189*593dc095SDavid du Colombier }
1190*593dc095SDavid du Colombier #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
1191*593dc095SDavid du Colombier 
1192*593dc095SDavid du Colombier #ifdef PNG_ASSEMBLER_CODE_SUPPORTED
1193*593dc095SDavid du Colombier /* this function was added to libpng 1.2.0 */
1194*593dc095SDavid du Colombier void PNGAPI
png_set_mmx_thresholds(png_structp png_ptr,png_byte mmx_bitdepth_threshold,png_uint_32 mmx_rowbytes_threshold)1195*593dc095SDavid du Colombier png_set_mmx_thresholds (png_structp png_ptr,
1196*593dc095SDavid du Colombier                         png_byte mmx_bitdepth_threshold,
1197*593dc095SDavid du Colombier                         png_uint_32 mmx_rowbytes_threshold)
1198*593dc095SDavid du Colombier {
1199*593dc095SDavid du Colombier     png_ptr->mmx_bitdepth_threshold = mmx_bitdepth_threshold;
1200*593dc095SDavid du Colombier     png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold;
1201*593dc095SDavid du Colombier }
1202*593dc095SDavid du Colombier #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
1203*593dc095SDavid du Colombier 
1204*593dc095SDavid du Colombier #ifdef PNG_SET_USER_LIMITS_SUPPORTED
1205*593dc095SDavid du Colombier /* this function was added to libpng 1.2.6 */
1206*593dc095SDavid du Colombier void PNGAPI
png_set_user_limits(png_structp png_ptr,png_uint_32 user_width_max,png_uint_32 user_height_max)1207*593dc095SDavid du Colombier png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
1208*593dc095SDavid du Colombier     png_uint_32 user_height_max)
1209*593dc095SDavid du Colombier {
1210*593dc095SDavid du Colombier     /* Images with dimensions larger than these limits will be
1211*593dc095SDavid du Colombier      * rejected by png_set_IHDR().  To accept any PNG datastream
1212*593dc095SDavid du Colombier      * regardless of dimensions, set both limits to 0x7ffffffL.
1213*593dc095SDavid du Colombier      */
1214*593dc095SDavid du Colombier     png_ptr->user_width_max = user_width_max;
1215*593dc095SDavid du Colombier     png_ptr->user_height_max = user_height_max;
1216*593dc095SDavid du Colombier }
1217*593dc095SDavid du Colombier #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
1218*593dc095SDavid du Colombier 
1219*593dc095SDavid du Colombier #endif /* ?PNG_1_0_X */
1220