initial import
[dosrtxon] / libs / imago / libpng / png.c
1 \r
2 /* png.c - location for general purpose libpng functions\r
3  *\r
4  * Last changed in libpng 1.2.30 [August 15, 2008]\r
5  * For conditions of distribution and use, see copyright notice in png.h\r
6  * Copyright (c) 1998-2008 Glenn Randers-Pehrson\r
7  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\r
8  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\r
9  */\r
10 \r
11 #define PNG_INTERNAL\r
12 #define PNG_NO_EXTERN\r
13 #include "png.h"\r
14 \r
15 /* Generate a compiler error if there is an old png.h in the search path. */\r
16 typedef version_1_2_33 Your_png_h_is_not_version_1_2_33;\r
17 \r
18 /* Version information for C files.  This had better match the version\r
19  * string defined in png.h.  */\r
20 \r
21 #ifdef PNG_USE_GLOBAL_ARRAYS\r
22 /* png_libpng_ver was changed to a function in version 1.0.5c */\r
23 PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;\r
24 \r
25 #ifdef PNG_READ_SUPPORTED\r
26 \r
27 /* png_sig was changed to a function in version 1.0.5c */\r
28 /* Place to hold the signature string for a PNG file. */\r
29 PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};\r
30 #endif /* PNG_READ_SUPPORTED */\r
31 \r
32 /* Invoke global declarations for constant strings for known chunk types */\r
33 PNG_IHDR;\r
34 PNG_IDAT;\r
35 PNG_IEND;\r
36 PNG_PLTE;\r
37 PNG_bKGD;\r
38 PNG_cHRM;\r
39 PNG_gAMA;\r
40 PNG_hIST;\r
41 PNG_iCCP;\r
42 PNG_iTXt;\r
43 PNG_oFFs;\r
44 PNG_pCAL;\r
45 PNG_sCAL;\r
46 PNG_pHYs;\r
47 PNG_sBIT;\r
48 PNG_sPLT;\r
49 PNG_sRGB;\r
50 PNG_tEXt;\r
51 PNG_tIME;\r
52 PNG_tRNS;\r
53 PNG_zTXt;\r
54 \r
55 #ifdef PNG_READ_SUPPORTED\r
56 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */\r
57 \r
58 /* start of interlace block */\r
59 PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};\r
60 \r
61 /* offset to next interlace block */\r
62 PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};\r
63 \r
64 /* start of interlace block in the y direction */\r
65 PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};\r
66 \r
67 /* offset to next interlace block in the y direction */\r
68 PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};\r
69 \r
70 /* Height of interlace block.  This is not currently used - if you need\r
71  * it, uncomment it here and in png.h\r
72 PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};\r
73 */\r
74 \r
75 /* Mask to determine which pixels are valid in a pass */\r
76 PNG_CONST int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};\r
77 \r
78 /* Mask to determine which pixels to overwrite while displaying */\r
79 PNG_CONST int FARDATA png_pass_dsp_mask[]\r
80    = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};\r
81 \r
82 #endif /* PNG_READ_SUPPORTED */\r
83 #endif /* PNG_USE_GLOBAL_ARRAYS */\r
84 \r
85 /* Tells libpng that we have already handled the first "num_bytes" bytes\r
86  * of the PNG file signature.  If the PNG data is embedded into another\r
87  * stream we can set num_bytes = 8 so that libpng will not attempt to read\r
88  * or write any of the magic bytes before it starts on the IHDR.\r
89  */\r
90 \r
91 #ifdef PNG_READ_SUPPORTED\r
92 void PNGAPI\r
93 png_set_sig_bytes(png_structp png_ptr, int num_bytes)\r
94 {\r
95    if (png_ptr == NULL) return;\r
96    png_debug(1, "in png_set_sig_bytes\n");\r
97    if (num_bytes > 8)\r
98       png_error(png_ptr, "Too many bytes for PNG signature.");\r
99 \r
100    png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);\r
101 }\r
102 \r
103 /* Checks whether the supplied bytes match the PNG signature.  We allow\r
104  * checking less than the full 8-byte signature so that those apps that\r
105  * already read the first few bytes of a file to determine the file type\r
106  * can simply check the remaining bytes for extra assurance.  Returns\r
107  * an integer less than, equal to, or greater than zero if sig is found,\r
108  * respectively, to be less than, to match, or be greater than the correct\r
109  * PNG signature (this is the same behaviour as strcmp, memcmp, etc).\r
110  */\r
111 int PNGAPI\r
112 png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)\r
113 {\r
114    png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};\r
115    if (num_to_check > 8)\r
116       num_to_check = 8;\r
117    else if (num_to_check < 1)\r
118       return (-1);\r
119 \r
120    if (start > 7)\r
121       return (-1);\r
122 \r
123    if (start + num_to_check > 8)\r
124       num_to_check = 8 - start;\r
125 \r
126    return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));\r
127 }\r
128 \r
129 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)\r
130 /* (Obsolete) function to check signature bytes.  It does not allow one\r
131  * to check a partial signature.  This function might be removed in the\r
132  * future - use png_sig_cmp().  Returns true (nonzero) if the file is PNG.\r
133  */\r
134 int PNGAPI\r
135 png_check_sig(png_bytep sig, int num)\r
136 {\r
137   return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));\r
138 }\r
139 #endif\r
140 #endif /* PNG_READ_SUPPORTED */\r
141 \r
142 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\r
143 /* Function to allocate memory for zlib and clear it to 0. */\r
144 #ifdef PNG_1_0_X\r
145 voidpf PNGAPI\r
146 #else\r
147 voidpf /* private */\r
148 #endif\r
149 png_zalloc(voidpf png_ptr, uInt items, uInt size)\r
150 {\r
151    png_voidp ptr;\r
152    png_structp p=(png_structp)png_ptr;\r
153    png_uint_32 save_flags=p->flags;\r
154    png_uint_32 num_bytes;\r
155 \r
156    if (png_ptr == NULL) return (NULL);\r
157    if (items > PNG_UINT_32_MAX/size)\r
158    {\r
159      png_warning (p, "Potential overflow in png_zalloc()");\r
160      return (NULL);\r
161    }\r
162    num_bytes = (png_uint_32)items * size;\r
163 \r
164    p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;\r
165    ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);\r
166    p->flags=save_flags;\r
167 \r
168 #if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)\r
169    if (ptr == NULL)\r
170        return ((voidpf)ptr);\r
171 \r
172    if (num_bytes > (png_uint_32)0x8000L)\r
173    {\r
174       png_memset(ptr, 0, (png_size_t)0x8000L);\r
175       png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,\r
176          (png_size_t)(num_bytes - (png_uint_32)0x8000L));\r
177    }\r
178    else\r
179    {\r
180       png_memset(ptr, 0, (png_size_t)num_bytes);\r
181    }\r
182 #endif\r
183    return ((voidpf)ptr);\r
184 }\r
185 \r
186 /* function to free memory for zlib */\r
187 #ifdef PNG_1_0_X\r
188 void PNGAPI\r
189 #else\r
190 void /* private */\r
191 #endif\r
192 png_zfree(voidpf png_ptr, voidpf ptr)\r
193 {\r
194    png_free((png_structp)png_ptr, (png_voidp)ptr);\r
195 }\r
196 \r
197 /* Reset the CRC variable to 32 bits of 1's.  Care must be taken\r
198  * in case CRC is > 32 bits to leave the top bits 0.\r
199  */\r
200 void /* PRIVATE */\r
201 png_reset_crc(png_structp png_ptr)\r
202 {\r
203    png_ptr->crc = crc32(0, Z_NULL, 0);\r
204 }\r
205 \r
206 /* Calculate the CRC over a section of data.  We can only pass as\r
207  * much data to this routine as the largest single buffer size.  We\r
208  * also check that this data will actually be used before going to the\r
209  * trouble of calculating it.\r
210  */\r
211 void /* PRIVATE */\r
212 png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)\r
213 {\r
214    int need_crc = 1;\r
215 \r
216    if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */\r
217    {\r
218       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==\r
219           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))\r
220          need_crc = 0;\r
221    }\r
222    else                                                    /* critical */\r
223    {\r
224       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)\r
225          need_crc = 0;\r
226    }\r
227 \r
228    if (need_crc)\r
229       png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);\r
230 }\r
231 \r
232 /* Allocate the memory for an info_struct for the application.  We don't\r
233  * really need the png_ptr, but it could potentially be useful in the\r
234  * future.  This should be used in favour of malloc(png_sizeof(png_info))\r
235  * and png_info_init() so that applications that want to use a shared\r
236  * libpng don't have to be recompiled if png_info changes size.\r
237  */\r
238 png_infop PNGAPI\r
239 png_create_info_struct(png_structp png_ptr)\r
240 {\r
241    png_infop info_ptr;\r
242 \r
243    png_debug(1, "in png_create_info_struct\n");\r
244    if (png_ptr == NULL) return (NULL);\r
245 #ifdef PNG_USER_MEM_SUPPORTED\r
246    info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,\r
247       png_ptr->malloc_fn, png_ptr->mem_ptr);\r
248 #else\r
249    info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);\r
250 #endif\r
251    if (info_ptr != NULL)\r
252       png_info_init_3(&info_ptr, png_sizeof(png_info));\r
253 \r
254    return (info_ptr);\r
255 }\r
256 \r
257 /* This function frees the memory associated with a single info struct.\r
258  * Normally, one would use either png_destroy_read_struct() or\r
259  * png_destroy_write_struct() to free an info struct, but this may be\r
260  * useful for some applications.\r
261  */\r
262 void PNGAPI\r
263 png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)\r
264 {\r
265    png_infop info_ptr = NULL;\r
266    if (png_ptr == NULL) return;\r
267 \r
268    png_debug(1, "in png_destroy_info_struct\n");\r
269    if (info_ptr_ptr != NULL)\r
270       info_ptr = *info_ptr_ptr;\r
271 \r
272    if (info_ptr != NULL)\r
273    {\r
274       png_info_destroy(png_ptr, info_ptr);\r
275 \r
276 #ifdef PNG_USER_MEM_SUPPORTED\r
277       png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,\r
278           png_ptr->mem_ptr);\r
279 #else\r
280       png_destroy_struct((png_voidp)info_ptr);\r
281 #endif\r
282       *info_ptr_ptr = NULL;\r
283    }\r
284 }\r
285 \r
286 /* Initialize the info structure.  This is now an internal function (0.89)\r
287  * and applications using it are urged to use png_create_info_struct()\r
288  * instead.\r
289  */\r
290 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)\r
291 #undef png_info_init\r
292 void PNGAPI\r
293 png_info_init(png_infop info_ptr)\r
294 {\r
295    /* We only come here via pre-1.0.12-compiled applications */\r
296    png_info_init_3(&info_ptr, 0);\r
297 }\r
298 #endif\r
299 \r
300 void PNGAPI\r
301 png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)\r
302 {\r
303    png_infop info_ptr = *ptr_ptr;\r
304 \r
305    if (info_ptr == NULL) return;\r
306 \r
307    png_debug(1, "in png_info_init_3\n");\r
308 \r
309    if (png_sizeof(png_info) > png_info_struct_size)\r
310      {\r
311        png_destroy_struct(info_ptr);\r
312        info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);\r
313        *ptr_ptr = info_ptr;\r
314      }\r
315 \r
316    /* set everything to 0 */\r
317    png_memset(info_ptr, 0, png_sizeof(png_info));\r
318 }\r
319 \r
320 #ifdef PNG_FREE_ME_SUPPORTED\r
321 void PNGAPI\r
322 png_data_freer(png_structp png_ptr, png_infop info_ptr,\r
323    int freer, png_uint_32 mask)\r
324 {\r
325    png_debug(1, "in png_data_freer\n");\r
326    if (png_ptr == NULL || info_ptr == NULL)\r
327       return;\r
328    if (freer == PNG_DESTROY_WILL_FREE_DATA)\r
329       info_ptr->free_me |= mask;\r
330    else if (freer == PNG_USER_WILL_FREE_DATA)\r
331       info_ptr->free_me &= ~mask;\r
332    else\r
333       png_warning(png_ptr,\r
334          "Unknown freer parameter in png_data_freer.");\r
335 }\r
336 #endif\r
337 \r
338 void PNGAPI\r
339 png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,\r
340    int num)\r
341 {\r
342    png_debug(1, "in png_free_data\n");\r
343    if (png_ptr == NULL || info_ptr == NULL)\r
344       return;\r
345 \r
346 #if defined(PNG_TEXT_SUPPORTED)\r
347 /* free text item num or (if num == -1) all text items */\r
348 #ifdef PNG_FREE_ME_SUPPORTED\r
349 if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)\r
350 #else\r
351 if (mask & PNG_FREE_TEXT)\r
352 #endif\r
353 {\r
354    if (num != -1)\r
355    {\r
356      if (info_ptr->text && info_ptr->text[num].key)\r
357      {\r
358          png_free(png_ptr, info_ptr->text[num].key);\r
359          info_ptr->text[num].key = NULL;\r
360      }\r
361    }\r
362    else\r
363    {\r
364        int i;\r
365        for (i = 0; i < info_ptr->num_text; i++)\r
366            png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);\r
367        png_free(png_ptr, info_ptr->text);\r
368        info_ptr->text = NULL;\r
369        info_ptr->num_text=0;\r
370    }\r
371 }\r
372 #endif\r
373 \r
374 #if defined(PNG_tRNS_SUPPORTED)\r
375 /* free any tRNS entry */\r
376 #ifdef PNG_FREE_ME_SUPPORTED\r
377 if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)\r
378 #else\r
379 if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))\r
380 #endif\r
381 {\r
382     png_free(png_ptr, info_ptr->trans);\r
383     info_ptr->trans = NULL;\r
384     info_ptr->valid &= ~PNG_INFO_tRNS;\r
385 #ifndef PNG_FREE_ME_SUPPORTED\r
386     png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;\r
387 #endif\r
388 }\r
389 #endif\r
390 \r
391 #if defined(PNG_sCAL_SUPPORTED)\r
392 /* free any sCAL entry */\r
393 #ifdef PNG_FREE_ME_SUPPORTED\r
394 if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)\r
395 #else\r
396 if (mask & PNG_FREE_SCAL)\r
397 #endif\r
398 {\r
399 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)\r
400     png_free(png_ptr, info_ptr->scal_s_width);\r
401     png_free(png_ptr, info_ptr->scal_s_height);\r
402     info_ptr->scal_s_width = NULL;\r
403     info_ptr->scal_s_height = NULL;\r
404 #endif\r
405     info_ptr->valid &= ~PNG_INFO_sCAL;\r
406 }\r
407 #endif\r
408 \r
409 #if defined(PNG_pCAL_SUPPORTED)\r
410 /* free any pCAL entry */\r
411 #ifdef PNG_FREE_ME_SUPPORTED\r
412 if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)\r
413 #else\r
414 if (mask & PNG_FREE_PCAL)\r
415 #endif\r
416 {\r
417     png_free(png_ptr, info_ptr->pcal_purpose);\r
418     png_free(png_ptr, info_ptr->pcal_units);\r
419     info_ptr->pcal_purpose = NULL;\r
420     info_ptr->pcal_units = NULL;\r
421     if (info_ptr->pcal_params != NULL)\r
422     {\r
423         int i;\r
424         for (i = 0; i < (int)info_ptr->pcal_nparams; i++)\r
425         {\r
426           png_free(png_ptr, info_ptr->pcal_params[i]);\r
427           info_ptr->pcal_params[i]=NULL;\r
428         }\r
429         png_free(png_ptr, info_ptr->pcal_params);\r
430         info_ptr->pcal_params = NULL;\r
431     }\r
432     info_ptr->valid &= ~PNG_INFO_pCAL;\r
433 }\r
434 #endif\r
435 \r
436 #if defined(PNG_iCCP_SUPPORTED)\r
437 /* free any iCCP entry */\r
438 #ifdef PNG_FREE_ME_SUPPORTED\r
439 if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)\r
440 #else\r
441 if (mask & PNG_FREE_ICCP)\r
442 #endif\r
443 {\r
444     png_free(png_ptr, info_ptr->iccp_name);\r
445     png_free(png_ptr, info_ptr->iccp_profile);\r
446     info_ptr->iccp_name = NULL;\r
447     info_ptr->iccp_profile = NULL;\r
448     info_ptr->valid &= ~PNG_INFO_iCCP;\r
449 }\r
450 #endif\r
451 \r
452 #if defined(PNG_sPLT_SUPPORTED)\r
453 /* free a given sPLT entry, or (if num == -1) all sPLT entries */\r
454 #ifdef PNG_FREE_ME_SUPPORTED\r
455 if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)\r
456 #else\r
457 if (mask & PNG_FREE_SPLT)\r
458 #endif\r
459 {\r
460    if (num != -1)\r
461    {\r
462       if (info_ptr->splt_palettes)\r
463       {\r
464           png_free(png_ptr, info_ptr->splt_palettes[num].name);\r
465           png_free(png_ptr, info_ptr->splt_palettes[num].entries);\r
466           info_ptr->splt_palettes[num].name = NULL;\r
467           info_ptr->splt_palettes[num].entries = NULL;\r
468       }\r
469    }\r
470    else\r
471    {\r
472        if (info_ptr->splt_palettes_num)\r
473        {\r
474          int i;\r
475          for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)\r
476             png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);\r
477 \r
478          png_free(png_ptr, info_ptr->splt_palettes);\r
479          info_ptr->splt_palettes = NULL;\r
480          info_ptr->splt_palettes_num = 0;\r
481        }\r
482        info_ptr->valid &= ~PNG_INFO_sPLT;\r
483    }\r
484 }\r
485 #endif\r
486 \r
487 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)\r
488   if (png_ptr->unknown_chunk.data)\r
489   {\r
490     png_free(png_ptr, png_ptr->unknown_chunk.data);\r
491     png_ptr->unknown_chunk.data = NULL;\r
492   }\r
493 \r
494 #ifdef PNG_FREE_ME_SUPPORTED\r
495 if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)\r
496 #else\r
497 if (mask & PNG_FREE_UNKN)\r
498 #endif\r
499 {\r
500    if (num != -1)\r
501    {\r
502        if (info_ptr->unknown_chunks)\r
503        {\r
504           png_free(png_ptr, info_ptr->unknown_chunks[num].data);\r
505           info_ptr->unknown_chunks[num].data = NULL;\r
506        }\r
507    }\r
508    else\r
509    {\r
510        int i;\r
511 \r
512        if (info_ptr->unknown_chunks_num)\r
513        {\r
514          for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)\r
515             png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);\r
516 \r
517          png_free(png_ptr, info_ptr->unknown_chunks);\r
518          info_ptr->unknown_chunks = NULL;\r
519          info_ptr->unknown_chunks_num = 0;\r
520        }\r
521    }\r
522 }\r
523 #endif\r
524 \r
525 #if defined(PNG_hIST_SUPPORTED)\r
526 /* free any hIST entry */\r
527 #ifdef PNG_FREE_ME_SUPPORTED\r
528 if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)\r
529 #else\r
530 if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))\r
531 #endif\r
532 {\r
533     png_free(png_ptr, info_ptr->hist);\r
534     info_ptr->hist = NULL;\r
535     info_ptr->valid &= ~PNG_INFO_hIST;\r
536 #ifndef PNG_FREE_ME_SUPPORTED\r
537     png_ptr->flags &= ~PNG_FLAG_FREE_HIST;\r
538 #endif\r
539 }\r
540 #endif\r
541 \r
542 /* free any PLTE entry that was internally allocated */\r
543 #ifdef PNG_FREE_ME_SUPPORTED\r
544 if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)\r
545 #else\r
546 if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))\r
547 #endif\r
548 {\r
549     png_zfree(png_ptr, info_ptr->palette);\r
550     info_ptr->palette = NULL;\r
551     info_ptr->valid &= ~PNG_INFO_PLTE;\r
552 #ifndef PNG_FREE_ME_SUPPORTED\r
553     png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;\r
554 #endif\r
555     info_ptr->num_palette = 0;\r
556 }\r
557 \r
558 #if defined(PNG_INFO_IMAGE_SUPPORTED)\r
559 /* free any image bits attached to the info structure */\r
560 #ifdef PNG_FREE_ME_SUPPORTED\r
561 if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)\r
562 #else\r
563 if (mask & PNG_FREE_ROWS)\r
564 #endif\r
565 {\r
566     if (info_ptr->row_pointers)\r
567     {\r
568        int row;\r
569        for (row = 0; row < (int)info_ptr->height; row++)\r
570        {\r
571           png_free(png_ptr, info_ptr->row_pointers[row]);\r
572           info_ptr->row_pointers[row]=NULL;\r
573        }\r
574        png_free(png_ptr, info_ptr->row_pointers);\r
575        info_ptr->row_pointers=NULL;\r
576     }\r
577     info_ptr->valid &= ~PNG_INFO_IDAT;\r
578 }\r
579 #endif\r
580 \r
581 #ifdef PNG_FREE_ME_SUPPORTED\r
582    if (num == -1)\r
583      info_ptr->free_me &= ~mask;\r
584    else\r
585      info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);\r
586 #endif\r
587 }\r
588 \r
589 /* This is an internal routine to free any memory that the info struct is\r
590  * pointing to before re-using it or freeing the struct itself.  Recall\r
591  * that png_free() checks for NULL pointers for us.\r
592  */\r
593 void /* PRIVATE */\r
594 png_info_destroy(png_structp png_ptr, png_infop info_ptr)\r
595 {\r
596    png_debug(1, "in png_info_destroy\n");\r
597 \r
598    png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);\r
599 \r
600 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)\r
601    if (png_ptr->num_chunk_list)\r
602    {\r
603        png_free(png_ptr, png_ptr->chunk_list);\r
604        png_ptr->chunk_list=NULL;\r
605        png_ptr->num_chunk_list = 0;\r
606    }\r
607 #endif\r
608 \r
609    png_info_init_3(&info_ptr, png_sizeof(png_info));\r
610 }\r
611 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */\r
612 \r
613 /* This function returns a pointer to the io_ptr associated with the user\r
614  * functions.  The application should free any memory associated with this\r
615  * pointer before png_write_destroy() or png_read_destroy() are called.\r
616  */\r
617 png_voidp PNGAPI\r
618 png_get_io_ptr(png_structp png_ptr)\r
619 {\r
620    if (png_ptr == NULL) return (NULL);\r
621    return (png_ptr->io_ptr);\r
622 }\r
623 \r
624 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\r
625 #if !defined(PNG_NO_STDIO)\r
626 /* Initialize the default input/output functions for the PNG file.  If you\r
627  * use your own read or write routines, you can call either png_set_read_fn()\r
628  * or png_set_write_fn() instead of png_init_io().  If you have defined\r
629  * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't\r
630  * necessarily available.\r
631  */\r
632 void PNGAPI\r
633 png_init_io(png_structp png_ptr, png_FILE_p fp)\r
634 {\r
635    png_debug(1, "in png_init_io\n");\r
636    if (png_ptr == NULL) return;\r
637    png_ptr->io_ptr = (png_voidp)fp;\r
638 }\r
639 #endif\r
640 \r
641 #if defined(PNG_TIME_RFC1123_SUPPORTED)\r
642 /* Convert the supplied time into an RFC 1123 string suitable for use in\r
643  * a "Creation Time" or other text-based time string.\r
644  */\r
645 png_charp PNGAPI\r
646 png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)\r
647 {\r
648    static PNG_CONST char short_months[12][4] =\r
649         {"Jan", "Feb", "Mar", "Apr", "May", "Jun",\r
650          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};\r
651 \r
652    if (png_ptr == NULL) return (NULL);\r
653    if (png_ptr->time_buffer == NULL)\r
654    {\r
655       png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*\r
656          png_sizeof(char)));\r
657    }\r
658 \r
659 #if defined(_WIN32_WCE)\r
660    {\r
661       wchar_t time_buf[29];\r
662       wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),\r
663           ptime->day % 32, short_months[(ptime->month - 1) % 12],\r
664         ptime->year, ptime->hour % 24, ptime->minute % 60,\r
665           ptime->second % 61);\r
666       WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,\r
667           NULL, NULL);\r
668    }\r
669 #else\r
670 #ifdef USE_FAR_KEYWORD\r
671    {\r
672       char near_time_buf[29];\r
673       png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000",\r
674           ptime->day % 32, short_months[(ptime->month - 1) % 12],\r
675           ptime->year, ptime->hour % 24, ptime->minute % 60,\r
676           ptime->second % 61);\r
677       png_memcpy(png_ptr->time_buffer, near_time_buf,\r
678           29*png_sizeof(char));\r
679    }\r
680 #else\r
681    png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000",\r
682        ptime->day % 32, short_months[(ptime->month - 1) % 12],\r
683        ptime->year, ptime->hour % 24, ptime->minute % 60,\r
684        ptime->second % 61);\r
685 #endif\r
686 #endif /* _WIN32_WCE */\r
687    return ((png_charp)png_ptr->time_buffer);\r
688 }\r
689 #endif /* PNG_TIME_RFC1123_SUPPORTED */\r
690 \r
691 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */\r
692 \r
693 png_charp PNGAPI\r
694 png_get_copyright(png_structp png_ptr)\r
695 {\r
696    png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */\r
697    return ((png_charp) "\n libpng version 1.2.33 - October 31, 2008\n\\r
698    Copyright (c) 1998-2008 Glenn Randers-Pehrson\n\\r
699    Copyright (c) 1996-1997 Andreas Dilger\n\\r
700    Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");\r
701 }\r
702 \r
703 /* The following return the library version as a short string in the\r
704  * format 1.0.0 through 99.99.99zz.  To get the version of *.h files\r
705  * used with your application, print out PNG_LIBPNG_VER_STRING, which\r
706  * is defined in png.h.\r
707  * Note: now there is no difference between png_get_libpng_ver() and\r
708  * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,\r
709  * it is guaranteed that png.c uses the correct version of png.h.\r
710  */\r
711 png_charp PNGAPI\r
712 png_get_libpng_ver(png_structp png_ptr)\r
713 {\r
714    /* Version of *.c files used when building libpng */\r
715    png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */\r
716    return ((png_charp) PNG_LIBPNG_VER_STRING);\r
717 }\r
718 \r
719 png_charp PNGAPI\r
720 png_get_header_ver(png_structp png_ptr)\r
721 {\r
722    /* Version of *.h files used when building libpng */\r
723    png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */\r
724    return ((png_charp) PNG_LIBPNG_VER_STRING);\r
725 }\r
726 \r
727 png_charp PNGAPI\r
728 png_get_header_version(png_structp png_ptr)\r
729 {\r
730    /* Returns longer string containing both version and date */\r
731    png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */\r
732    return ((png_charp) PNG_HEADER_VERSION_STRING\r
733 #ifndef PNG_READ_SUPPORTED\r
734    "     (NO READ SUPPORT)"\r
735 #endif\r
736    "\n");\r
737 }\r
738 \r
739 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\r
740 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED\r
741 int PNGAPI\r
742 png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)\r
743 {\r
744    /* check chunk_name and return "keep" value if it's on the list, else 0 */\r
745    int i;\r
746    png_bytep p;\r
747    if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)\r
748       return 0;\r
749    p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5;\r
750    for (i = png_ptr->num_chunk_list; i; i--, p -= 5)\r
751       if (!png_memcmp(chunk_name, p, 4))\r
752         return ((int)*(p + 4));\r
753    return 0;\r
754 }\r
755 #endif\r
756 \r
757 /* This function, added to libpng-1.0.6g, is untested. */\r
758 int PNGAPI\r
759 png_reset_zstream(png_structp png_ptr)\r
760 {\r
761    if (png_ptr == NULL) return Z_STREAM_ERROR;\r
762    return (inflateReset(&png_ptr->zstream));\r
763 }\r
764 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */\r
765 \r
766 /* This function was added to libpng-1.0.7 */\r
767 png_uint_32 PNGAPI\r
768 png_access_version_number(void)\r
769 {\r
770    /* Version of *.c files used when building libpng */\r
771    return((png_uint_32) PNG_LIBPNG_VER);\r
772 }\r
773 \r
774 \r
775 #if defined(PNG_READ_SUPPORTED) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)\r
776 #if !defined(PNG_1_0_X)\r
777 /* this function was added to libpng 1.2.0 */\r
778 int PNGAPI\r
779 png_mmx_support(void)\r
780 {\r
781    /* obsolete, to be removed from libpng-1.4.0 */\r
782     return -1;\r
783 }\r
784 #endif /* PNG_1_0_X */\r
785 #endif /* PNG_READ_SUPPORTED && PNG_ASSEMBLER_CODE_SUPPORTED */\r
786 \r
787 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\r
788 #ifdef PNG_SIZE_T\r
789 /* Added at libpng version 1.2.6 */\r
790    PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));\r
791 png_size_t PNGAPI\r
792 png_convert_size(size_t size)\r
793 {\r
794   if (size > (png_size_t)-1)\r
795      PNG_ABORT();  /* We haven't got access to png_ptr, so no png_error() */\r
796   return ((png_size_t)size);\r
797 }\r
798 #endif /* PNG_SIZE_T */\r
799 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */\r