Initial revision
[rrdtool.git] / libraries / libpng-1.0.9 / pngset.c
1
2 /* pngset.c - storage of image information into info struct
3  *
4  * libpng 1.0.9 - January 31, 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)
20 void PNGAPI
21 png_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
34 void PNGAPI
35 png_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
65 void PNGAPI
66 png_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
100 void PNGAPI
101 png_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 }
113 #endif
114 #endif
115 void PNGAPI
116 png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
117    int_gamma)
118 {
119    png_debug1(1, "in %s storage function\n", "gAMA");
120    if (png_ptr == NULL || info_ptr == NULL)
121       return;
122
123 #ifdef PNG_FLOATING_POINT_SUPPORTED
124    info_ptr->gamma = (float)(int_gamma/100000.);
125 #endif
126 #ifdef PNG_FIXED_POINT_SUPPORTED
127    info_ptr->int_gamma = int_gamma;
128 #endif
129    info_ptr->valid |= PNG_INFO_gAMA;
130 }
131
132 #if defined(PNG_hIST_SUPPORTED)
133 void PNGAPI
134 png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
135 {
136    int  i;
137
138    png_debug1(1, "in %s storage function\n", "hIST");
139    if (png_ptr == NULL || info_ptr == NULL)
140       return;
141    if (info_ptr->num_palette == 0)
142        png_warning(png_ptr,
143                    "Palette size 0, hIST allocation skipped.");
144
145 #ifdef PNG_FREE_ME_SUPPORTED
146    png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
147 #endif
148    png_ptr->hist = (png_uint_16p)png_malloc(png_ptr,
149       (png_uint_32)(info_ptr->num_palette * sizeof (png_uint_16)));
150
151    for (i = 0; i < info_ptr->num_palette; i++)
152        png_ptr->hist[i] = hist[i];
153    info_ptr->hist = png_ptr->hist;
154    info_ptr->valid |= PNG_INFO_hIST;
155
156 #ifdef PNG_FREE_ME_SUPPORTED
157    info_ptr->free_me |= PNG_FREE_HIST;
158 #else
159    png_ptr->flags |= PNG_FLAG_FREE_HIST;
160 #endif
161 }
162 #endif
163
164 void PNGAPI
165 png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
166    png_uint_32 width, png_uint_32 height, int bit_depth,
167    int color_type, int interlace_type, int compression_type,
168    int filter_type)
169 {
170    int rowbytes_per_pixel;
171    png_debug1(1, "in %s storage function\n", "IHDR");
172    if (png_ptr == NULL || info_ptr == NULL)
173       return;
174
175    info_ptr->width = width;
176    info_ptr->height = height;
177    info_ptr->bit_depth = (png_byte)bit_depth;
178    info_ptr->color_type =(png_byte) color_type;
179    info_ptr->compression_type = (png_byte)compression_type;
180    info_ptr->filter_type = (png_byte)filter_type;
181    info_ptr->interlace_type = (png_byte)interlace_type;
182    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
183       info_ptr->channels = 1;
184    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
185       info_ptr->channels = 3;
186    else
187       info_ptr->channels = 1;
188    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
189       info_ptr->channels++;
190    info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
191
192    /* check for overflow */
193    rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3;
194    if (( width > PNG_MAX_UINT/rowbytes_per_pixel))
195    {
196       png_warning(png_ptr,
197          "Width too large to process image data; rowbytes will overflow.");
198       info_ptr->rowbytes = (png_size_t)0;
199    }
200    else
201       info_ptr->rowbytes = (info_ptr->width * info_ptr->pixel_depth + 7) >> 3;
202 }
203
204 #if defined(PNG_oFFs_SUPPORTED)
205 void PNGAPI
206 png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
207    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
208 {
209    png_debug1(1, "in %s storage function\n", "oFFs");
210    if (png_ptr == NULL || info_ptr == NULL)
211       return;
212
213    info_ptr->x_offset = offset_x;
214    info_ptr->y_offset = offset_y;
215    info_ptr->offset_unit_type = (png_byte)unit_type;
216    info_ptr->valid |= PNG_INFO_oFFs;
217 }
218 #endif
219
220 #if defined(PNG_pCAL_SUPPORTED)
221 void PNGAPI
222 png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
223    png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
224    png_charp units, png_charpp params)
225 {
226    png_uint_32 length;
227    int i;
228
229    png_debug1(1, "in %s storage function\n", "pCAL");
230    if (png_ptr == NULL || info_ptr == NULL)
231       return;
232
233    length = png_strlen(purpose) + 1;
234    png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
235    info_ptr->pcal_purpose = (png_charp)png_malloc(png_ptr, length);
236    png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
237
238    png_debug(3, "storing X0, X1, type, and nparams in info\n");
239    info_ptr->pcal_X0 = X0;
240    info_ptr->pcal_X1 = X1;
241    info_ptr->pcal_type = (png_byte)type;
242    info_ptr->pcal_nparams = (png_byte)nparams;
243
244    length = png_strlen(units) + 1;
245    png_debug1(3, "allocating units for info (%lu bytes)\n", length);
246    info_ptr->pcal_units = (png_charp)png_malloc(png_ptr, length);
247    png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
248
249    info_ptr->pcal_params = (png_charpp)png_malloc(png_ptr,
250       (png_uint_32)((nparams + 1) * sizeof(png_charp)));
251    info_ptr->pcal_params[nparams] = NULL;
252
253    for (i = 0; i < nparams; i++)
254    {
255       length = png_strlen(params[i]) + 1;
256       png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
257       info_ptr->pcal_params[i] = (png_charp)png_malloc(png_ptr, length);
258       png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
259    }
260
261    info_ptr->valid |= PNG_INFO_pCAL;
262 #ifdef PNG_FREE_ME_SUPPORTED
263    info_ptr->free_me |= PNG_FREE_PCAL;
264 #endif
265 }
266 #endif
267
268 #if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
269 #ifdef PNG_FLOATING_POINT_SUPPORTED
270 void PNGAPI
271 png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
272              int unit, double width, double height)
273 {
274    png_debug1(1, "in %s storage function\n", "sCAL");
275    if (png_ptr == NULL || info_ptr == NULL)
276       return;
277
278    info_ptr->scal_unit = (png_byte)unit;
279    info_ptr->scal_pixel_width = width;
280    info_ptr->scal_pixel_height = height;
281
282    info_ptr->valid |= PNG_INFO_sCAL;
283 }
284 #else
285 #ifdef PNG_FIXED_POINT_SUPPORTED
286 void PNGAPI
287 png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
288              int unit, png_charp swidth, png_charp sheight)
289 {
290    png_uint_32 length;
291
292    png_debug1(1, "in %s storage function\n", "sCAL");
293    if (png_ptr == NULL || info_ptr == NULL)
294       return;
295
296    info_ptr->scal_unit = (png_byte)unit;
297
298    length = png_strlen(swidth) + 1;
299    png_debug1(3, "allocating unit for info (%d bytes)\n", length);
300    info_ptr->scal_s_width = (png_charp)png_malloc(png_ptr, length);
301    png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
302
303    length = png_strlen(sheight) + 1;
304    png_debug1(3, "allocating unit for info (%d bytes)\n", length);
305    info_ptr->scal_s_width = (png_charp)png_malloc(png_ptr, length);
306    png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
307
308    info_ptr->valid |= PNG_INFO_sCAL;
309 #ifdef PNG_FREE_ME_SUPPORTED
310    info_ptr->free_me |= PNG_FREE_SCAL;
311 #endif
312 }
313 #endif
314 #endif
315 #endif
316
317 #if defined(PNG_pHYs_SUPPORTED)
318 void PNGAPI
319 png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
320    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
321 {
322    png_debug1(1, "in %s storage function\n", "pHYs");
323    if (png_ptr == NULL || info_ptr == NULL)
324       return;
325
326    info_ptr->x_pixels_per_unit = res_x;
327    info_ptr->y_pixels_per_unit = res_y;
328    info_ptr->phys_unit_type = (png_byte)unit_type;
329    info_ptr->valid |= PNG_INFO_pHYs;
330 }
331 #endif
332
333 void PNGAPI
334 png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
335    png_colorp palette, int num_palette)
336 {
337
338    png_debug1(1, "in %s storage function\n", "PLTE");
339    if (png_ptr == NULL || info_ptr == NULL)
340       return;
341
342    /*
343     * It may not actually be necessary to set png_ptr->palette here;
344     * we do it for backward compatibility with the way the png_handle_tRNS
345     * function used to do the allocation.
346     */
347 #ifdef PNG_FREE_ME_SUPPORTED
348    png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
349 #endif
350    png_ptr->palette = (png_colorp)png_zalloc(png_ptr, (uInt)num_palette,
351       sizeof (png_color));
352    memcpy(png_ptr->palette, palette, num_palette * sizeof (png_color));
353    info_ptr->palette = png_ptr->palette;
354    info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
355
356 #ifdef PNG_FREE_ME_SUPPORTED
357    info_ptr->free_me |= PNG_FREE_PLTE;
358 #else
359    png_ptr->flags |= PNG_FLAG_FREE_PLTE;
360 #endif
361
362    info_ptr->valid |= PNG_INFO_PLTE;
363 }
364
365 #if defined(PNG_sBIT_SUPPORTED)
366 void PNGAPI
367 png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
368    png_color_8p sig_bit)
369 {
370    png_debug1(1, "in %s storage function\n", "sBIT");
371    if (png_ptr == NULL || info_ptr == NULL)
372       return;
373
374    png_memcpy(&(info_ptr->sig_bit), sig_bit, sizeof (png_color_8));
375    info_ptr->valid |= PNG_INFO_sBIT;
376 }
377 #endif
378
379 #if defined(PNG_sRGB_SUPPORTED)
380 void PNGAPI
381 png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
382 {
383    png_debug1(1, "in %s storage function\n", "sRGB");
384    if (png_ptr == NULL || info_ptr == NULL)
385       return;
386
387    info_ptr->srgb_intent = (png_byte)intent;
388    info_ptr->valid |= PNG_INFO_sRGB;
389 }
390
391 void PNGAPI
392 png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
393    int intent)
394 {
395 #if defined(PNG_gAMA_SUPPORTED)
396 #ifdef PNG_FLOATING_POINT_SUPPORTED
397    float file_gamma;
398 #endif
399 #ifdef PNG_FIXED_POINT_SUPPORTED
400    png_fixed_point int_file_gamma;
401 #endif
402 #endif
403 #if defined(PNG_cHRM_SUPPORTED)
404 #ifdef PNG_FLOATING_POINT_SUPPORTED
405    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
406 #endif
407 #ifdef PNG_FIXED_POINT_SUPPORTED
408    png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
409       int_green_y, int_blue_x, int_blue_y;
410 #endif
411 #endif
412    png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
413    if (png_ptr == NULL || info_ptr == NULL)
414       return;
415
416    png_set_sRGB(png_ptr, info_ptr, intent);
417
418 #if defined(PNG_gAMA_SUPPORTED)
419 #ifdef PNG_FLOATING_POINT_SUPPORTED
420    file_gamma = (float).45455;
421    png_set_gAMA(png_ptr, info_ptr, file_gamma);
422 #endif
423 #ifdef PNG_FIXED_POINT_SUPPORTED
424    int_file_gamma = 45455L;
425    png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
426 #endif
427 #endif
428
429 #if defined(PNG_cHRM_SUPPORTED)
430 #ifdef PNG_FIXED_POINT_SUPPORTED
431    int_white_x = 31270L;
432    int_white_y = 32900L;
433    int_red_x   = 64000L;
434    int_red_y   = 33000L;
435    int_green_x = 30000L;
436    int_green_y = 60000L;
437    int_blue_x  = 15000L;
438    int_blue_y  =  6000L;
439
440    png_set_cHRM_fixed(png_ptr, info_ptr,
441       int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y,
442       int_blue_x, int_blue_y);
443 #endif
444 #ifdef PNG_FLOATING_POINT_SUPPORTED
445    white_x = (float).3127;
446    white_y = (float).3290;
447    red_x   = (float).64;
448    red_y   = (float).33;
449    green_x = (float).30;
450    green_y = (float).60;
451    blue_x  = (float).15;
452    blue_y  = (float).06;
453
454    png_set_cHRM(png_ptr, info_ptr,
455       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
456 #endif
457 #endif
458 }
459 #endif
460
461
462 #if defined(PNG_iCCP_SUPPORTED)
463 void PNGAPI
464 png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
465              png_charp name, int compression_type,
466              png_charp profile, png_uint_32 proflen)
467 {
468    png_charp new_iccp_name;
469    png_charp new_iccp_profile;
470
471    png_debug1(1, "in %s storage function\n", "iCCP");
472    if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
473       return;
474
475    new_iccp_name = png_malloc(png_ptr, png_strlen(name)+1);
476    strcpy(new_iccp_name, name);
477    new_iccp_profile = png_malloc(png_ptr, proflen);
478    png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
479
480    png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
481
482    info_ptr->iccp_proflen = proflen;
483    info_ptr->iccp_name = new_iccp_name;
484    info_ptr->iccp_profile = new_iccp_profile;
485    /* Compression is always zero but is here so the API and info structure
486     * does not have to change if we introduce multiple compression types */
487    info_ptr->iccp_compression = (png_byte)compression_type;
488 #ifdef PNG_FREE_ME_SUPPORTED
489    info_ptr->free_me |= PNG_FREE_ICCP;
490 #endif
491    info_ptr->valid |= PNG_INFO_iCCP;
492 }
493 #endif
494
495 #if defined(PNG_TEXT_SUPPORTED)
496 void PNGAPI
497 png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
498    int num_text)
499 {
500    int i;
501
502    png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
503       "text" : (png_const_charp)png_ptr->chunk_name));
504
505    if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
506       return;
507
508    /* Make sure we have enough space in the "text" array in info_struct
509     * to hold all of the incoming text_ptr objects.
510     */
511    if (info_ptr->num_text + num_text > info_ptr->max_text)
512    {
513       if (info_ptr->text != NULL)
514       {
515          png_textp old_text;
516          int old_max;
517
518          old_max = info_ptr->max_text;
519          info_ptr->max_text = info_ptr->num_text + num_text + 8;
520          old_text = info_ptr->text;
521          info_ptr->text = (png_textp)png_malloc(png_ptr,
522             (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
523          png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
524             sizeof(png_text)));
525          png_free(png_ptr, old_text);
526       }
527       else
528       {
529          info_ptr->max_text = num_text + 8;
530          info_ptr->num_text = 0;
531          info_ptr->text = (png_textp)png_malloc(png_ptr,
532             (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
533 #ifdef PNG_FREE_ME_SUPPORTED
534          info_ptr->free_me |= PNG_FREE_TEXT;
535 #endif
536       }
537       png_debug1(3, "allocated %d entries for info_ptr->text\n",
538          info_ptr->max_text);
539    }
540    for (i = 0; i < num_text; i++)
541    {
542       png_size_t text_length,key_len;
543       png_size_t lang_len,lang_key_len;
544       png_textp textp = &(info_ptr->text[info_ptr->num_text]);
545
546       if (text_ptr[i].key == (png_charp)NULL)
547           continue;
548
549       key_len = png_strlen(text_ptr[i].key);
550
551       if(text_ptr[i].compression <= 0)
552       {
553         lang_len = 0;
554         lang_key_len = 0;
555       }
556       else
557 #ifdef PNG_iTXt_SUPPORTED
558       {
559         /* set iTXt data */
560         if (text_ptr[i].key != (png_charp)NULL)
561           lang_len = png_strlen(text_ptr[i].lang);
562         else
563           lang_len = 0;
564         if (text_ptr[i].lang_key != (png_charp)NULL)
565           lang_key_len = png_strlen(text_ptr[i].lang_key);
566         else
567           lang_key_len = 0;
568       }
569 #else
570       {
571         png_warning(png_ptr, "iTXt chunk not supported.");
572         continue;
573       }
574 #endif
575
576       if (text_ptr[i].text == (png_charp)NULL || text_ptr[i].text[0] == '\0')
577       {
578          text_length = 0;
579 #ifdef PNG_iTXt_SUPPORTED
580          if(text_ptr[i].compression > 0)
581             textp->compression = PNG_ITXT_COMPRESSION_NONE;
582          else
583 #endif
584             textp->compression = PNG_TEXT_COMPRESSION_NONE;
585       }
586       else
587       {
588          text_length = png_strlen(text_ptr[i].text);
589          textp->compression = text_ptr[i].compression;
590       }
591
592       textp->key = (png_charp)png_malloc(png_ptr,
593          (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
594       png_debug2(2, "Allocated %d bytes at %x in png_set_text\n",
595          key_len + lang_len + lang_key_len + text_length + 4, (int)textp->key);
596
597       png_memcpy(textp->key, text_ptr[i].key,
598          (png_size_t)(key_len));
599       *(textp->key+key_len) = '\0';
600 #ifdef PNG_iTXt_SUPPORTED
601       if (text_ptr[i].compression > 0)
602       {
603          textp->lang=textp->key + key_len + 1;
604          png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
605          *(textp->lang+lang_len) = '\0';
606          textp->lang_key=textp->lang + lang_len + 1;
607          png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
608          *(textp->lang_key+lang_key_len) = '\0';
609          textp->text=textp->lang_key + lang_key_len + 1;
610       }
611       else
612 #endif
613       {
614 #ifdef PNG_iTXt_SUPPORTED
615          textp->lang=(png_charp)NULL;
616          textp->lang_key=(png_charp)NULL;
617 #endif
618          textp->text=textp->key + key_len + 1;
619       }
620       if(text_length)
621          png_memcpy(textp->text, text_ptr[i].text,
622             (png_size_t)(text_length));
623       *(textp->text+text_length) = '\0';
624
625 #ifdef PNG_iTXt_SUPPORTED
626       if(textp->compression > 0)
627       {
628          textp->text_length = 0;
629          textp->itxt_length = text_length;
630       }
631       else
632 #endif
633       {
634          textp->text_length = text_length;
635 #ifdef PNG_iTXt_SUPPORTED
636          textp->itxt_length = 0;
637 #endif
638       }
639       info_ptr->text[info_ptr->num_text]= *textp;
640       info_ptr->num_text++;
641       png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
642    }
643 }
644 #endif
645
646 #if defined(PNG_tIME_SUPPORTED)
647 void PNGAPI
648 png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
649 {
650    png_debug1(1, "in %s storage function\n", "tIME");
651    if (png_ptr == NULL || info_ptr == NULL ||
652        (png_ptr->mode & PNG_WROTE_tIME))
653       return;
654
655    png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time));
656    info_ptr->valid |= PNG_INFO_tIME;
657 }
658 #endif
659
660 #if defined(PNG_tRNS_SUPPORTED)
661 void PNGAPI
662 png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
663    png_bytep trans, int num_trans, png_color_16p trans_values)
664 {
665    png_debug1(1, "in %s storage function\n", "tRNS");
666    if (png_ptr == NULL || info_ptr == NULL)
667       return;
668
669    if (trans != NULL)
670    {
671        /*
672         * It may not actually be necessary to set png_ptr->trans here;
673         * we do it for backward compatibility with the way the png_handle_tRNS
674         * function used to do the allocation.
675         */
676 #ifdef PNG_FREE_ME_SUPPORTED
677        png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
678 #endif
679        png_ptr->trans = info_ptr->trans = png_malloc(png_ptr, num_trans);
680        memcpy(info_ptr->trans, trans, num_trans);
681 #ifdef PNG_FREE_ME_SUPPORTED
682        info_ptr->free_me |= PNG_FREE_TRNS;
683 #else
684        png_ptr->flags |= PNG_FLAG_FREE_TRNS;
685 #endif
686    }
687
688    if (trans_values != NULL)
689    {
690       png_memcpy(&(info_ptr->trans_values), trans_values,
691          sizeof(png_color_16));
692       if (num_trans == 0)
693         num_trans = 1;
694    }
695    info_ptr->num_trans = (png_uint_16)num_trans;
696    info_ptr->valid |= PNG_INFO_tRNS;
697 }
698 #endif
699
700 #if defined(PNG_sPLT_SUPPORTED)
701 void PNGAPI
702 png_set_sPLT(png_structp png_ptr,
703              png_infop info_ptr, png_sPLT_tp entries, int nentries)
704 {
705     png_sPLT_tp np;
706     int i;
707
708     np = (png_sPLT_tp)png_malloc(png_ptr,
709         (info_ptr->splt_palettes_num + nentries) * sizeof(png_sPLT_t));
710
711     png_memcpy(np, info_ptr->splt_palettes,
712            info_ptr->splt_palettes_num * sizeof(png_sPLT_t));
713     png_free(png_ptr, info_ptr->splt_palettes);
714     info_ptr->splt_palettes=NULL;
715
716     for (i = 0; i < nentries; i++)
717     {
718         png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
719         png_sPLT_tp from = entries + i;
720
721         to->name = (png_charp)png_malloc(png_ptr,
722                                         png_strlen(from->name) + 1);
723         png_strcpy(to->name, from->name);
724         to->entries = (png_sPLT_entryp)png_malloc(png_ptr,
725                                  from->nentries * sizeof(png_sPLT_t));
726         png_memcpy(to->entries, from->entries,
727                from->nentries * sizeof(png_sPLT_t));
728         to->nentries = from->nentries;
729         to->depth = from->depth;
730     }
731
732     info_ptr->splt_palettes = np;
733     info_ptr->splt_palettes_num += nentries;
734     info_ptr->valid |= PNG_INFO_sPLT;
735 #ifdef PNG_FREE_ME_SUPPORTED
736     info_ptr->free_me |= PNG_FREE_SPLT;
737 #endif
738 }
739 #endif /* PNG_sPLT_SUPPORTED */
740
741 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
742 void PNGAPI
743 png_set_unknown_chunks(png_structp png_ptr,
744    png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
745 {
746     png_unknown_chunkp np;
747     int i;
748
749     if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
750         return;
751
752     np = (png_unknown_chunkp)png_malloc(png_ptr,
753         (info_ptr->unknown_chunks_num + num_unknowns) *
754         sizeof(png_unknown_chunk));
755
756     png_memcpy(np, info_ptr->unknown_chunks,
757            info_ptr->unknown_chunks_num * sizeof(png_unknown_chunk));
758     png_free(png_ptr, info_ptr->unknown_chunks);
759     info_ptr->unknown_chunks=NULL;
760
761     for (i = 0; i < num_unknowns; i++)
762     {
763         png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
764         png_unknown_chunkp from = unknowns + i;
765
766         png_strcpy((png_charp)to->name, (png_charp)from->name);
767         to->data = (png_bytep)png_malloc(png_ptr, from->size);
768         png_memcpy(to->data, from->data, from->size);
769         to->size = from->size;
770
771         /* note our location in the read or write sequence */
772         to->location = (png_byte)(png_ptr->mode & 0xff);
773     }
774
775     info_ptr->unknown_chunks = np;
776     info_ptr->unknown_chunks_num += num_unknowns;
777 #ifdef PNG_FREE_ME_SUPPORTED
778     info_ptr->free_me |= PNG_FREE_UNKN;
779 #endif
780 }
781 void PNGAPI
782 png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
783    int chunk, int location)
784 {
785    if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
786          (int)info_ptr->unknown_chunks_num)
787       info_ptr->unknown_chunks[chunk].location = (png_byte)location;
788 }
789 #endif
790
791 #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
792     defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
793 void PNGAPI
794 png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
795 {
796    /* This function is deprecated in favor of png_permit_mng_features()
797       and will be removed from libpng-2.0.0 */
798    png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n");
799    if (png_ptr == NULL)
800       return;
801    png_ptr->mng_features_permitted = (png_byte)
802      ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) |
803      ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
804 }
805 #endif
806
807 #if defined(PNG_MNG_FEATURES_SUPPORTED)
808 png_uint_32 PNGAPI
809 png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
810 {
811    png_debug(1, "in png_permit_mng_features\n");
812    if (png_ptr == NULL)
813       return (png_uint_32)0;
814    png_ptr->mng_features_permitted =
815      (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
816    return (png_uint_32)png_ptr->mng_features_permitted;
817 }
818 #endif
819
820 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
821 void PNGAPI
822 png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
823    chunk_list, int num_chunks)
824 {
825     png_bytep new_list, p;
826     int i, old_num_chunks;
827     if (num_chunks == 0)
828     {
829       if(keep == HANDLE_CHUNK_ALWAYS || keep == HANDLE_CHUNK_IF_SAFE)
830         png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
831       else
832         png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
833
834       if(keep == HANDLE_CHUNK_ALWAYS)
835         png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
836       else
837         png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
838       return;
839     }
840     if (chunk_list == NULL)
841       return;
842     old_num_chunks=png_ptr->num_chunk_list;
843     new_list=png_malloc(png_ptr,5*(num_chunks+old_num_chunks));
844     if(png_ptr->chunk_list != (png_bytep)NULL)
845     {
846        png_memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
847        png_free(png_ptr, png_ptr->chunk_list);
848        png_ptr->chunk_list=NULL;
849     }
850     png_memcpy(new_list+5*old_num_chunks, chunk_list, 5*num_chunks);
851     for (p=new_list+5*old_num_chunks+4, i=0; i<num_chunks; i++, p+=5)
852        *p=(png_byte)keep;
853     png_ptr->num_chunk_list=old_num_chunks+num_chunks;
854     png_ptr->chunk_list=new_list;
855 #ifdef PNG_FREE_ME_SUPPORTED
856     png_ptr->free_me |= PNG_FREE_LIST;
857 #endif
858 }
859 #endif
860
861 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
862 void PNGAPI
863 png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
864    png_user_chunk_ptr read_user_chunk_fn)
865 {
866    png_debug(1, "in png_set_read_user_chunk_fn\n");
867    png_ptr->read_user_chunk_fn = read_user_chunk_fn;
868    png_ptr->user_chunk_ptr = user_chunk_ptr;
869 }
870 #endif
871
872 #if defined(PNG_INFO_IMAGE_SUPPORTED)
873 void PNGAPI
874 png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
875 {
876    png_debug1(1, "in %s storage function\n", "rows");
877
878    if (png_ptr == NULL || info_ptr == NULL)
879       return;
880
881    if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
882       png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
883    info_ptr->row_pointers = row_pointers;
884    if(row_pointers)
885       info_ptr->valid |= PNG_INFO_IDAT;
886
887 }
888 #endif
889
890 void PNGAPI
891 png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
892 {
893     if(png_ptr->zbuf)
894        png_free(png_ptr, png_ptr->zbuf);
895     png_ptr->zbuf_size = (png_size_t)size;
896     png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
897     if(!png_ptr->zbuf)
898        png_error(png_ptr,"Unable to malloc zbuf");
899     png_ptr->zstream.next_out = png_ptr->zbuf;
900     png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
901 }
902
903 void PNGAPI
904 png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
905 {
906    if (png_ptr && info_ptr)
907       info_ptr->valid &= ~(mask);
908 }
909