pngread.c revision 893912bfc2683463dc3e2c445336752d012563d3
1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian/* pngread.c - read a PNG file 38f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * 4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Last changed in libpng 1.2.25 [February 18, 2008] 5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * For conditions of distribution and use, see copyright notice in png.h 6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (c) 1998-2008 Glenn Randers-Pehrson 78f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * This file contains routines that an application calls directly to 11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * read a PNG file or stream. 12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */ 13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#define PNG_INTERNAL 15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "png.h" 16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if defined(PNG_READ_SUPPORTED) 18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/* Create a PNG structure for reading, and allocate any memory needed. */ 20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectpng_structp PNGAPI 21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectpng_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr, 22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project png_error_ptr error_fn, png_error_ptr warn_fn) 23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifdef PNG_USER_MEM_SUPPORTED 26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, 27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL)); 28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/* Alternate create PNG structure for reading, and allocate any memory needed. */ 31643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockpng_structp PNGAPI 32643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockpng_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, 33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, 34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block png_malloc_ptr malloc_fn, png_free_ptr free_fn) 35643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 36643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif /* PNG_USER_MEM_SUPPORTED */ 37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block png_structp png_ptr; 39635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#ifdef PNG_SETJMP_SUPPORTED 41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#ifdef USE_FAR_KEYWORD 42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block jmp_buf jmpbuf; 438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif 44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif 45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int i; 47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 48643ca7872b450ea4efacab6188849e5aac2ba161Steve Block png_debug(1, "in png_create_read_struct\n"); 49643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#ifdef PNG_USER_MEM_SUPPORTED 50635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, 51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); 528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#else 53643ca7872b450ea4efacab6188849e5aac2ba161Steve Block png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); 54#endif 55 if (png_ptr == NULL) 56 return (NULL); 57 58 /* added at libpng-1.2.6 */ 59#ifdef PNG_SET_USER_LIMITS_SUPPORTED 60 png_ptr->user_width_max=PNG_USER_WIDTH_MAX; 61 png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; 62#endif 63 64#ifdef PNG_SETJMP_SUPPORTED 65#ifdef USE_FAR_KEYWORD 66 if (setjmp(jmpbuf)) 67#else 68 if (setjmp(png_ptr->jmpbuf)) 69#endif 70 { 71 png_free(png_ptr, png_ptr->zbuf); 72 png_ptr->zbuf=NULL; 73#ifdef PNG_USER_MEM_SUPPORTED 74 png_destroy_struct_2((png_voidp)png_ptr, 75 (png_free_ptr)free_fn, (png_voidp)mem_ptr); 76#else 77 png_destroy_struct((png_voidp)png_ptr); 78#endif 79 return (NULL); 80 } 81#ifdef USE_FAR_KEYWORD 82 png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); 83#endif 84#endif 85 86#ifdef PNG_USER_MEM_SUPPORTED 87 png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); 88#endif 89 90 png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); 91 92 if(user_png_ver) 93 { 94 i=0; 95 do 96 { 97 if(user_png_ver[i] != png_libpng_ver[i]) 98 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 99 } while (png_libpng_ver[i++]); 100 } 101 else 102 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 103 104 105 if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) 106 { 107 /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so 108 * we must recompile any applications that use any older library version. 109 * For versions after libpng 1.0, we will be compatible, so we need 110 * only check the first digit. 111 */ 112 if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || 113 (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || 114 (user_png_ver[0] == '0' && user_png_ver[2] < '9')) 115 { 116#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) 117 char msg[80]; 118 if (user_png_ver) 119 { 120 png_snprintf(msg, 80, 121 "Application was compiled with png.h from libpng-%.20s", 122 user_png_ver); 123 png_warning(png_ptr, msg); 124 } 125 png_snprintf(msg, 80, 126 "Application is running with png.c from libpng-%.20s", 127 png_libpng_ver); 128 png_warning(png_ptr, msg); 129#endif 130#ifdef PNG_ERROR_NUMBERS_SUPPORTED 131 png_ptr->flags=0; 132#endif 133 png_error(png_ptr, 134 "Incompatible libpng version in application and library"); 135 } 136 } 137 138 /* initialize zbuf - compression buffer */ 139 png_ptr->zbuf_size = PNG_ZBUF_SIZE; 140 png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, 141 (png_uint_32)png_ptr->zbuf_size); 142 png_ptr->zstream.zalloc = png_zalloc; 143 png_ptr->zstream.zfree = png_zfree; 144 png_ptr->zstream.opaque = (voidpf)png_ptr; 145 146 switch (inflateInit(&png_ptr->zstream)) 147 { 148 case Z_OK: /* Do nothing */ break; 149 case Z_MEM_ERROR: 150 case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break; 151 case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break; 152 default: png_error(png_ptr, "Unknown zlib error"); 153 } 154 155 png_ptr->zstream.next_out = png_ptr->zbuf; 156 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 157 158 png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL); 159 160#ifdef PNG_SETJMP_SUPPORTED 161/* Applications that neglect to set up their own setjmp() and then encounter 162 a png_error() will longjmp here. Since the jmpbuf is then meaningless we 163 abort instead of returning. */ 164#ifdef USE_FAR_KEYWORD 165 if (setjmp(jmpbuf)) 166 PNG_ABORT(); 167 png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); 168#else 169 if (setjmp(png_ptr->jmpbuf)) 170 PNG_ABORT(); 171#endif 172#endif 173 return (png_ptr); 174} 175 176#if defined(PNG_1_0_X) || defined(PNG_1_2_X) 177/* Initialize PNG structure for reading, and allocate any memory needed. 178 This interface is deprecated in favour of the png_create_read_struct(), 179 and it will disappear as of libpng-1.3.0. */ 180#undef png_read_init 181void PNGAPI 182png_read_init(png_structp png_ptr) 183{ 184 /* We only come here via pre-1.0.7-compiled applications */ 185 png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0); 186} 187 188void PNGAPI 189png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver, 190 png_size_t png_struct_size, png_size_t png_info_size) 191{ 192 /* We only come here via pre-1.0.12-compiled applications */ 193 if(png_ptr == NULL) return; 194#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) 195 if(png_sizeof(png_struct) > png_struct_size || 196 png_sizeof(png_info) > png_info_size) 197 { 198 char msg[80]; 199 png_ptr->warning_fn=NULL; 200 if (user_png_ver) 201 { 202 png_snprintf(msg, 80, 203 "Application was compiled with png.h from libpng-%.20s", 204 user_png_ver); 205 png_warning(png_ptr, msg); 206 } 207 png_snprintf(msg, 80, 208 "Application is running with png.c from libpng-%.20s", 209 png_libpng_ver); 210 png_warning(png_ptr, msg); 211 } 212#endif 213 if(png_sizeof(png_struct) > png_struct_size) 214 { 215 png_ptr->error_fn=NULL; 216#ifdef PNG_ERROR_NUMBERS_SUPPORTED 217 png_ptr->flags=0; 218#endif 219 png_error(png_ptr, 220 "The png struct allocated by the application for reading is too small."); 221 } 222 if(png_sizeof(png_info) > png_info_size) 223 { 224 png_ptr->error_fn=NULL; 225#ifdef PNG_ERROR_NUMBERS_SUPPORTED 226 png_ptr->flags=0; 227#endif 228 png_error(png_ptr, 229 "The info struct allocated by application for reading is too small."); 230 } 231 png_read_init_3(&png_ptr, user_png_ver, png_struct_size); 232} 233#endif /* PNG_1_0_X || PNG_1_2_X */ 234 235void PNGAPI 236png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, 237 png_size_t png_struct_size) 238{ 239#ifdef PNG_SETJMP_SUPPORTED 240 jmp_buf tmp_jmp; /* to save current jump buffer */ 241#endif 242 243 int i=0; 244 245 png_structp png_ptr=*ptr_ptr; 246 247 if(png_ptr == NULL) return; 248 249 do 250 { 251 if(user_png_ver[i] != png_libpng_ver[i]) 252 { 253#ifdef PNG_LEGACY_SUPPORTED 254 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 255#else 256 png_ptr->warning_fn=NULL; 257 png_warning(png_ptr, 258 "Application uses deprecated png_read_init() and should be recompiled."); 259 break; 260#endif 261 } 262 } while (png_libpng_ver[i++]); 263 264 png_debug(1, "in png_read_init_3\n"); 265 266#ifdef PNG_SETJMP_SUPPORTED 267 /* save jump buffer and error functions */ 268 png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); 269#endif 270 271 if(png_sizeof(png_struct) > png_struct_size) 272 { 273 png_destroy_struct(png_ptr); 274 *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); 275 png_ptr = *ptr_ptr; 276 } 277 278 /* reset all variables to 0 */ 279 png_memset(png_ptr, 0, png_sizeof (png_struct)); 280 281#ifdef PNG_SETJMP_SUPPORTED 282 /* restore jump buffer */ 283 png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); 284#endif 285 286 /* added at libpng-1.2.6 */ 287#ifdef PNG_SET_USER_LIMITS_SUPPORTED 288 png_ptr->user_width_max=PNG_USER_WIDTH_MAX; 289 png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; 290#endif 291 292 /* initialize zbuf - compression buffer */ 293 png_ptr->zbuf_size = PNG_ZBUF_SIZE; 294 png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, 295 (png_uint_32)png_ptr->zbuf_size); 296 png_ptr->zstream.zalloc = png_zalloc; 297 png_ptr->zstream.zfree = png_zfree; 298 png_ptr->zstream.opaque = (voidpf)png_ptr; 299 300 switch (inflateInit(&png_ptr->zstream)) 301 { 302 case Z_OK: /* Do nothing */ break; 303 case Z_MEM_ERROR: 304 case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break; 305 case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break; 306 default: png_error(png_ptr, "Unknown zlib error"); 307 } 308 309 png_ptr->zstream.next_out = png_ptr->zbuf; 310 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 311 312 png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL); 313} 314 315#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED 316/* Read the information before the actual image data. This has been 317 * changed in v0.90 to allow reading a file that already has the magic 318 * bytes read from the stream. You can tell libpng how many bytes have 319 * been read from the beginning of the stream (up to the maximum of 8) 320 * via png_set_sig_bytes(), and we will only check the remaining bytes 321 * here. The application can then have access to the signature bytes we 322 * read if it is determined that this isn't a valid PNG file. 323 */ 324void PNGAPI 325png_read_info(png_structp png_ptr, png_infop info_ptr) 326{ 327 if(png_ptr == NULL || info_ptr == NULL) return; 328 png_debug(1, "in png_read_info\n"); 329 /* If we haven't checked all of the PNG signature bytes, do so now. */ 330 if (png_ptr->sig_bytes < 8) 331 { 332 png_size_t num_checked = png_ptr->sig_bytes, 333 num_to_check = 8 - num_checked; 334 335 png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); 336 png_ptr->sig_bytes = 8; 337 338 if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) 339 { 340 if (num_checked < 4 && 341 png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) 342 png_error(png_ptr, "Not a PNG file"); 343 else 344 png_error(png_ptr, "PNG file corrupted by ASCII conversion"); 345 } 346 if (num_checked < 3) 347 png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; 348 } 349 350 for(;;) 351 { 352#ifdef PNG_USE_LOCAL_ARRAYS 353 PNG_CONST PNG_IHDR; 354 PNG_CONST PNG_IDAT; 355 PNG_CONST PNG_IEND; 356 PNG_CONST PNG_PLTE; 357#if defined(PNG_READ_bKGD_SUPPORTED) 358 PNG_CONST PNG_bKGD; 359#endif 360#if defined(PNG_READ_cHRM_SUPPORTED) 361 PNG_CONST PNG_cHRM; 362#endif 363#if defined(PNG_READ_gAMA_SUPPORTED) 364 PNG_CONST PNG_gAMA; 365#endif 366#if defined(PNG_READ_hIST_SUPPORTED) 367 PNG_CONST PNG_hIST; 368#endif 369#if defined(PNG_READ_iCCP_SUPPORTED) 370 PNG_CONST PNG_iCCP; 371#endif 372#if defined(PNG_READ_iTXt_SUPPORTED) 373 PNG_CONST PNG_iTXt; 374#endif 375#if defined(PNG_READ_oFFs_SUPPORTED) 376 PNG_CONST PNG_oFFs; 377#endif 378#if defined(PNG_READ_pCAL_SUPPORTED) 379 PNG_CONST PNG_pCAL; 380#endif 381#if defined(PNG_READ_pHYs_SUPPORTED) 382 PNG_CONST PNG_pHYs; 383#endif 384#if defined(PNG_READ_sBIT_SUPPORTED) 385 PNG_CONST PNG_sBIT; 386#endif 387#if defined(PNG_READ_sCAL_SUPPORTED) 388 PNG_CONST PNG_sCAL; 389#endif 390#if defined(PNG_READ_sPLT_SUPPORTED) 391 PNG_CONST PNG_sPLT; 392#endif 393#if defined(PNG_READ_sRGB_SUPPORTED) 394 PNG_CONST PNG_sRGB; 395#endif 396#if defined(PNG_READ_tEXt_SUPPORTED) 397 PNG_CONST PNG_tEXt; 398#endif 399#if defined(PNG_READ_tIME_SUPPORTED) 400 PNG_CONST PNG_tIME; 401#endif 402#if defined(PNG_READ_tRNS_SUPPORTED) 403 PNG_CONST PNG_tRNS; 404#endif 405#if defined(PNG_READ_zTXt_SUPPORTED) 406 PNG_CONST PNG_zTXt; 407#endif 408#endif /* PNG_USE_LOCAL_ARRAYS */ 409 png_byte chunk_length[4]; 410 png_uint_32 length; 411 412 png_read_data(png_ptr, chunk_length, 4); 413 length = png_get_uint_31(png_ptr,chunk_length); 414 415 png_reset_crc(png_ptr); 416 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 417 418 png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name, 419 length); 420 421 /* This should be a binary subdivision search or a hash for 422 * matching the chunk name rather than a linear search. 423 */ 424 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 425 if(png_ptr->mode & PNG_AFTER_IDAT) 426 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; 427 428 if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) 429 png_handle_IHDR(png_ptr, info_ptr, length); 430 else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) 431 png_handle_IEND(png_ptr, info_ptr, length); 432#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 433 else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) 434 { 435 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 436 png_ptr->mode |= PNG_HAVE_IDAT; 437 png_handle_unknown(png_ptr, info_ptr, length); 438 if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) 439 png_ptr->mode |= PNG_HAVE_PLTE; 440 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 441 { 442 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 443 png_error(png_ptr, "Missing IHDR before IDAT"); 444 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 445 !(png_ptr->mode & PNG_HAVE_PLTE)) 446 png_error(png_ptr, "Missing PLTE before IDAT"); 447 break; 448 } 449 } 450#endif 451 else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) 452 png_handle_PLTE(png_ptr, info_ptr, length); 453 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 454 { 455 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 456 png_error(png_ptr, "Missing IHDR before IDAT"); 457 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 458 !(png_ptr->mode & PNG_HAVE_PLTE)) 459 png_error(png_ptr, "Missing PLTE before IDAT"); 460 461 png_ptr->idat_size = length; 462 png_ptr->mode |= PNG_HAVE_IDAT; 463 break; 464 } 465#if defined(PNG_READ_bKGD_SUPPORTED) 466 else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) 467 png_handle_bKGD(png_ptr, info_ptr, length); 468#endif 469#if defined(PNG_READ_cHRM_SUPPORTED) 470 else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) 471 png_handle_cHRM(png_ptr, info_ptr, length); 472#endif 473#if defined(PNG_READ_gAMA_SUPPORTED) 474 else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) 475 png_handle_gAMA(png_ptr, info_ptr, length); 476#endif 477#if defined(PNG_READ_hIST_SUPPORTED) 478 else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) 479 png_handle_hIST(png_ptr, info_ptr, length); 480#endif 481#if defined(PNG_READ_oFFs_SUPPORTED) 482 else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) 483 png_handle_oFFs(png_ptr, info_ptr, length); 484#endif 485#if defined(PNG_READ_pCAL_SUPPORTED) 486 else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) 487 png_handle_pCAL(png_ptr, info_ptr, length); 488#endif 489#if defined(PNG_READ_sCAL_SUPPORTED) 490 else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) 491 png_handle_sCAL(png_ptr, info_ptr, length); 492#endif 493#if defined(PNG_READ_pHYs_SUPPORTED) 494 else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) 495 png_handle_pHYs(png_ptr, info_ptr, length); 496#endif 497#if defined(PNG_READ_sBIT_SUPPORTED) 498 else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) 499 png_handle_sBIT(png_ptr, info_ptr, length); 500#endif 501#if defined(PNG_READ_sRGB_SUPPORTED) 502 else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) 503 png_handle_sRGB(png_ptr, info_ptr, length); 504#endif 505#if defined(PNG_READ_iCCP_SUPPORTED) 506 else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) 507 png_handle_iCCP(png_ptr, info_ptr, length); 508#endif 509#if defined(PNG_READ_sPLT_SUPPORTED) 510 else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) 511 png_handle_sPLT(png_ptr, info_ptr, length); 512#endif 513#if defined(PNG_READ_tEXt_SUPPORTED) 514 else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) 515 png_handle_tEXt(png_ptr, info_ptr, length); 516#endif 517#if defined(PNG_READ_tIME_SUPPORTED) 518 else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) 519 png_handle_tIME(png_ptr, info_ptr, length); 520#endif 521#if defined(PNG_READ_tRNS_SUPPORTED) 522 else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) 523 png_handle_tRNS(png_ptr, info_ptr, length); 524#endif 525#if defined(PNG_READ_zTXt_SUPPORTED) 526 else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) 527 png_handle_zTXt(png_ptr, info_ptr, length); 528#endif 529#if defined(PNG_READ_iTXt_SUPPORTED) 530 else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) 531 png_handle_iTXt(png_ptr, info_ptr, length); 532#endif 533 else 534 png_handle_unknown(png_ptr, info_ptr, length); 535 } 536} 537#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ 538 539/* optional call to update the users info_ptr structure */ 540void PNGAPI 541png_read_update_info(png_structp png_ptr, png_infop info_ptr) 542{ 543 png_debug(1, "in png_read_update_info\n"); 544 if(png_ptr == NULL) return; 545 if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) 546 png_read_start_row(png_ptr); 547 else 548 png_warning(png_ptr, 549 "Ignoring extra png_read_update_info() call; row buffer not reallocated"); 550 png_read_transform_info(png_ptr, info_ptr); 551} 552 553#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED 554/* Initialize palette, background, etc, after transformations 555 * are set, but before any reading takes place. This allows 556 * the user to obtain a gamma-corrected palette, for example. 557 * If the user doesn't call this, we will do it ourselves. 558 */ 559void PNGAPI 560png_start_read_image(png_structp png_ptr) 561{ 562 png_debug(1, "in png_start_read_image\n"); 563 if(png_ptr == NULL) return; 564 if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) 565 png_read_start_row(png_ptr); 566} 567#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ 568 569#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED 570void PNGAPI 571png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) 572{ 573#ifdef PNG_USE_LOCAL_ARRAYS 574 PNG_CONST PNG_IDAT; 575 PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 576 0xff}; 577 PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; 578#endif 579 int ret; 580 if(png_ptr == NULL) return; 581 png_debug2(1, "in png_read_row (row %lu, pass %d)\n", 582 png_ptr->row_number, png_ptr->pass); 583 if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) 584 png_read_start_row(png_ptr); 585 if (png_ptr->row_number == 0 && png_ptr->pass == 0) 586 { 587 /* check for transforms that have been set but were defined out */ 588#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) 589 if (png_ptr->transformations & PNG_INVERT_MONO) 590 png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined."); 591#endif 592#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) 593 if (png_ptr->transformations & PNG_FILLER) 594 png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined."); 595#endif 596#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED) 597 if (png_ptr->transformations & PNG_PACKSWAP) 598 png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined."); 599#endif 600#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) 601 if (png_ptr->transformations & PNG_PACK) 602 png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined."); 603#endif 604#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) 605 if (png_ptr->transformations & PNG_SHIFT) 606 png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined."); 607#endif 608#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) 609 if (png_ptr->transformations & PNG_BGR) 610 png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined."); 611#endif 612#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) 613 if (png_ptr->transformations & PNG_SWAP_BYTES) 614 png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined."); 615#endif 616 } 617 618#if defined(PNG_READ_INTERLACING_SUPPORTED) 619 /* if interlaced and we do not need a new row, combine row and return */ 620 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) 621 { 622 switch (png_ptr->pass) 623 { 624 case 0: 625 if (png_ptr->row_number & 0x07) 626 { 627 if (dsp_row != NULL) 628 png_combine_row(png_ptr, dsp_row, 629 png_pass_dsp_mask[png_ptr->pass]); 630 png_read_finish_row(png_ptr); 631 return; 632 } 633 break; 634 case 1: 635 if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) 636 { 637 if (dsp_row != NULL) 638 png_combine_row(png_ptr, dsp_row, 639 png_pass_dsp_mask[png_ptr->pass]); 640 png_read_finish_row(png_ptr); 641 return; 642 } 643 break; 644 case 2: 645 if ((png_ptr->row_number & 0x07) != 4) 646 { 647 if (dsp_row != NULL && (png_ptr->row_number & 4)) 648 png_combine_row(png_ptr, dsp_row, 649 png_pass_dsp_mask[png_ptr->pass]); 650 png_read_finish_row(png_ptr); 651 return; 652 } 653 break; 654 case 3: 655 if ((png_ptr->row_number & 3) || png_ptr->width < 3) 656 { 657 if (dsp_row != NULL) 658 png_combine_row(png_ptr, dsp_row, 659 png_pass_dsp_mask[png_ptr->pass]); 660 png_read_finish_row(png_ptr); 661 return; 662 } 663 break; 664 case 4: 665 if ((png_ptr->row_number & 3) != 2) 666 { 667 if (dsp_row != NULL && (png_ptr->row_number & 2)) 668 png_combine_row(png_ptr, dsp_row, 669 png_pass_dsp_mask[png_ptr->pass]); 670 png_read_finish_row(png_ptr); 671 return; 672 } 673 break; 674 case 5: 675 if ((png_ptr->row_number & 1) || png_ptr->width < 2) 676 { 677 if (dsp_row != NULL) 678 png_combine_row(png_ptr, dsp_row, 679 png_pass_dsp_mask[png_ptr->pass]); 680 png_read_finish_row(png_ptr); 681 return; 682 } 683 break; 684 case 6: 685 if (!(png_ptr->row_number & 1)) 686 { 687 png_read_finish_row(png_ptr); 688 return; 689 } 690 break; 691 } 692 } 693#endif 694 695 if (!(png_ptr->mode & PNG_HAVE_IDAT)) 696 png_error(png_ptr, "Invalid attempt to read row data"); 697 698 png_ptr->zstream.next_out = png_ptr->row_buf; 699 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; 700 do 701 { 702 if (!(png_ptr->zstream.avail_in)) 703 { 704 while (!png_ptr->idat_size) 705 { 706 png_byte chunk_length[4]; 707 708 png_crc_finish(png_ptr, 0); 709 710 png_read_data(png_ptr, chunk_length, 4); 711 png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length); 712 713 png_reset_crc(png_ptr); 714 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 715 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 716 png_error(png_ptr, "Not enough image data"); 717 } 718 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; 719 png_ptr->zstream.next_in = png_ptr->zbuf; 720 if (png_ptr->zbuf_size > png_ptr->idat_size) 721 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; 722 png_crc_read(png_ptr, png_ptr->zbuf, 723 (png_size_t)png_ptr->zstream.avail_in); 724 png_ptr->idat_size -= png_ptr->zstream.avail_in; 725 } 726 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 727 if (ret == Z_STREAM_END) 728 { 729 if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || 730 png_ptr->idat_size) 731 png_error(png_ptr, "Extra compressed data"); 732 png_ptr->mode |= PNG_AFTER_IDAT; 733 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 734 break; 735 } 736 if (ret != Z_OK) 737 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : 738 "Decompression error"); 739 740 } while (png_ptr->zstream.avail_out); 741 742 png_ptr->row_info.color_type = png_ptr->color_type; 743 png_ptr->row_info.width = png_ptr->iwidth; 744 png_ptr->row_info.channels = png_ptr->channels; 745 png_ptr->row_info.bit_depth = png_ptr->bit_depth; 746 png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; 747 png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, 748 png_ptr->row_info.width); 749 750 if(png_ptr->row_buf[0]) 751 png_read_filter_row(png_ptr, &(png_ptr->row_info), 752 png_ptr->row_buf + 1, png_ptr->prev_row + 1, 753 (int)(png_ptr->row_buf[0])); 754 755 png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, 756 png_ptr->rowbytes + 1); 757 758#if defined(PNG_MNG_FEATURES_SUPPORTED) 759 if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && 760 (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) 761 { 762 /* Intrapixel differencing */ 763 png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); 764 } 765#endif 766 767 768 if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) 769 png_do_read_transformations(png_ptr); 770 771#if defined(PNG_READ_INTERLACING_SUPPORTED) 772 /* blow up interlaced rows to full size */ 773 if (png_ptr->interlaced && 774 (png_ptr->transformations & PNG_INTERLACE)) 775 { 776 if (png_ptr->pass < 6) 777/* old interface (pre-1.0.9): 778 png_do_read_interlace(&(png_ptr->row_info), 779 png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); 780 */ 781 png_do_read_interlace(png_ptr); 782 783 if (dsp_row != NULL) 784 png_combine_row(png_ptr, dsp_row, 785 png_pass_dsp_mask[png_ptr->pass]); 786 if (row != NULL) 787 png_combine_row(png_ptr, row, 788 png_pass_mask[png_ptr->pass]); 789 } 790 else 791#endif 792 { 793 if (row != NULL) 794 png_combine_row(png_ptr, row, 0xff); 795 if (dsp_row != NULL) 796 png_combine_row(png_ptr, dsp_row, 0xff); 797 } 798 png_read_finish_row(png_ptr); 799 800 if (png_ptr->read_row_fn != NULL) 801 (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); 802} 803#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ 804 805#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED 806/* Read one or more rows of image data. If the image is interlaced, 807 * and png_set_interlace_handling() has been called, the rows need to 808 * contain the contents of the rows from the previous pass. If the 809 * image has alpha or transparency, and png_handle_alpha()[*] has been 810 * called, the rows contents must be initialized to the contents of the 811 * screen. 812 * 813 * "row" holds the actual image, and pixels are placed in it 814 * as they arrive. If the image is displayed after each pass, it will 815 * appear to "sparkle" in. "display_row" can be used to display a 816 * "chunky" progressive image, with finer detail added as it becomes 817 * available. If you do not want this "chunky" display, you may pass 818 * NULL for display_row. If you do not want the sparkle display, and 819 * you have not called png_handle_alpha(), you may pass NULL for rows. 820 * If you have called png_handle_alpha(), and the image has either an 821 * alpha channel or a transparency chunk, you must provide a buffer for 822 * rows. In this case, you do not have to provide a display_row buffer 823 * also, but you may. If the image is not interlaced, or if you have 824 * not called png_set_interlace_handling(), the display_row buffer will 825 * be ignored, so pass NULL to it. 826 * 827 * [*] png_handle_alpha() does not exist yet, as of this version of libpng 828 */ 829 830void PNGAPI 831png_read_rows(png_structp png_ptr, png_bytepp row, 832 png_bytepp display_row, png_uint_32 num_rows) 833{ 834 png_uint_32 i; 835 png_bytepp rp; 836 png_bytepp dp; 837 838 png_debug(1, "in png_read_rows\n"); 839 if(png_ptr == NULL) return; 840 rp = row; 841 dp = display_row; 842 if (rp != NULL && dp != NULL) 843 for (i = 0; i < num_rows; i++) 844 { 845 png_bytep rptr = *rp++; 846 png_bytep dptr = *dp++; 847 848 png_read_row(png_ptr, rptr, dptr); 849 } 850 else if(rp != NULL) 851 for (i = 0; i < num_rows; i++) 852 { 853 png_bytep rptr = *rp; 854 png_read_row(png_ptr, rptr, png_bytep_NULL); 855 rp++; 856 } 857 else if(dp != NULL) 858 for (i = 0; i < num_rows; i++) 859 { 860 png_bytep dptr = *dp; 861 png_read_row(png_ptr, png_bytep_NULL, dptr); 862 dp++; 863 } 864} 865#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ 866 867#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED 868/* Read the entire image. If the image has an alpha channel or a tRNS 869 * chunk, and you have called png_handle_alpha()[*], you will need to 870 * initialize the image to the current image that PNG will be overlaying. 871 * We set the num_rows again here, in case it was incorrectly set in 872 * png_read_start_row() by a call to png_read_update_info() or 873 * png_start_read_image() if png_set_interlace_handling() wasn't called 874 * prior to either of these functions like it should have been. You can 875 * only call this function once. If you desire to have an image for 876 * each pass of a interlaced image, use png_read_rows() instead. 877 * 878 * [*] png_handle_alpha() does not exist yet, as of this version of libpng 879 */ 880void PNGAPI 881png_read_image(png_structp png_ptr, png_bytepp image) 882{ 883 png_uint_32 i,image_height; 884 int pass, j; 885 png_bytepp rp; 886 887 png_debug(1, "in png_read_image\n"); 888 if(png_ptr == NULL) return; 889 890#ifdef PNG_READ_INTERLACING_SUPPORTED 891 pass = png_set_interlace_handling(png_ptr); 892#else 893 if (png_ptr->interlaced) 894 png_error(png_ptr, 895 "Cannot read interlaced image -- interlace handler disabled."); 896 pass = 1; 897#endif 898 899 900 image_height=png_ptr->height; 901 png_ptr->num_rows = image_height; /* Make sure this is set correctly */ 902 903 for (j = 0; j < pass; j++) 904 { 905 rp = image; 906 for (i = 0; i < image_height; i++) 907 { 908 png_read_row(png_ptr, *rp, png_bytep_NULL); 909 rp++; 910 } 911 } 912} 913#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ 914 915#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED 916/* Read the end of the PNG file. Will not read past the end of the 917 * file, will verify the end is accurate, and will read any comments 918 * or time information at the end of the file, if info is not NULL. 919 */ 920void PNGAPI 921png_read_end(png_structp png_ptr, png_infop info_ptr) 922{ 923 png_byte chunk_length[4]; 924 png_uint_32 length; 925 926 png_debug(1, "in png_read_end\n"); 927 if(png_ptr == NULL) return; 928 png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ 929 930 do 931 { 932#ifdef PNG_USE_LOCAL_ARRAYS 933 PNG_CONST PNG_IHDR; 934 PNG_CONST PNG_IDAT; 935 PNG_CONST PNG_IEND; 936 PNG_CONST PNG_PLTE; 937#if defined(PNG_READ_bKGD_SUPPORTED) 938 PNG_CONST PNG_bKGD; 939#endif 940#if defined(PNG_READ_cHRM_SUPPORTED) 941 PNG_CONST PNG_cHRM; 942#endif 943#if defined(PNG_READ_gAMA_SUPPORTED) 944 PNG_CONST PNG_gAMA; 945#endif 946#if defined(PNG_READ_hIST_SUPPORTED) 947 PNG_CONST PNG_hIST; 948#endif 949#if defined(PNG_READ_iCCP_SUPPORTED) 950 PNG_CONST PNG_iCCP; 951#endif 952#if defined(PNG_READ_iTXt_SUPPORTED) 953 PNG_CONST PNG_iTXt; 954#endif 955#if defined(PNG_READ_oFFs_SUPPORTED) 956 PNG_CONST PNG_oFFs; 957#endif 958#if defined(PNG_READ_pCAL_SUPPORTED) 959 PNG_CONST PNG_pCAL; 960#endif 961#if defined(PNG_READ_pHYs_SUPPORTED) 962 PNG_CONST PNG_pHYs; 963#endif 964#if defined(PNG_READ_sBIT_SUPPORTED) 965 PNG_CONST PNG_sBIT; 966#endif 967#if defined(PNG_READ_sCAL_SUPPORTED) 968 PNG_CONST PNG_sCAL; 969#endif 970#if defined(PNG_READ_sPLT_SUPPORTED) 971 PNG_CONST PNG_sPLT; 972#endif 973#if defined(PNG_READ_sRGB_SUPPORTED) 974 PNG_CONST PNG_sRGB; 975#endif 976#if defined(PNG_READ_tEXt_SUPPORTED) 977 PNG_CONST PNG_tEXt; 978#endif 979#if defined(PNG_READ_tIME_SUPPORTED) 980 PNG_CONST PNG_tIME; 981#endif 982#if defined(PNG_READ_tRNS_SUPPORTED) 983 PNG_CONST PNG_tRNS; 984#endif 985#if defined(PNG_READ_zTXt_SUPPORTED) 986 PNG_CONST PNG_zTXt; 987#endif 988#endif /* PNG_USE_LOCAL_ARRAYS */ 989 990 png_read_data(png_ptr, chunk_length, 4); 991 length = png_get_uint_31(png_ptr,chunk_length); 992 993 png_reset_crc(png_ptr); 994 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 995 996 png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name); 997 998 if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) 999 png_handle_IHDR(png_ptr, info_ptr, length); 1000 else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) 1001 png_handle_IEND(png_ptr, info_ptr, length); 1002#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 1003 else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) 1004 { 1005 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 1006 { 1007 if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) 1008 png_error(png_ptr, "Too many IDAT's found"); 1009 } 1010 png_handle_unknown(png_ptr, info_ptr, length); 1011 if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) 1012 png_ptr->mode |= PNG_HAVE_PLTE; 1013 } 1014#endif 1015 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 1016 { 1017 /* Zero length IDATs are legal after the last IDAT has been 1018 * read, but not after other chunks have been read. 1019 */ 1020 if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) 1021 png_error(png_ptr, "Too many IDAT's found"); 1022 png_crc_finish(png_ptr, length); 1023 } 1024 else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) 1025 png_handle_PLTE(png_ptr, info_ptr, length); 1026#if defined(PNG_READ_bKGD_SUPPORTED) 1027 else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) 1028 png_handle_bKGD(png_ptr, info_ptr, length); 1029#endif 1030#if defined(PNG_READ_cHRM_SUPPORTED) 1031 else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) 1032 png_handle_cHRM(png_ptr, info_ptr, length); 1033#endif 1034#if defined(PNG_READ_gAMA_SUPPORTED) 1035 else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) 1036 png_handle_gAMA(png_ptr, info_ptr, length); 1037#endif 1038#if defined(PNG_READ_hIST_SUPPORTED) 1039 else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) 1040 png_handle_hIST(png_ptr, info_ptr, length); 1041#endif 1042#if defined(PNG_READ_oFFs_SUPPORTED) 1043 else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) 1044 png_handle_oFFs(png_ptr, info_ptr, length); 1045#endif 1046#if defined(PNG_READ_pCAL_SUPPORTED) 1047 else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) 1048 png_handle_pCAL(png_ptr, info_ptr, length); 1049#endif 1050#if defined(PNG_READ_sCAL_SUPPORTED) 1051 else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) 1052 png_handle_sCAL(png_ptr, info_ptr, length); 1053#endif 1054#if defined(PNG_READ_pHYs_SUPPORTED) 1055 else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) 1056 png_handle_pHYs(png_ptr, info_ptr, length); 1057#endif 1058#if defined(PNG_READ_sBIT_SUPPORTED) 1059 else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) 1060 png_handle_sBIT(png_ptr, info_ptr, length); 1061#endif 1062#if defined(PNG_READ_sRGB_SUPPORTED) 1063 else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) 1064 png_handle_sRGB(png_ptr, info_ptr, length); 1065#endif 1066#if defined(PNG_READ_iCCP_SUPPORTED) 1067 else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) 1068 png_handle_iCCP(png_ptr, info_ptr, length); 1069#endif 1070#if defined(PNG_READ_sPLT_SUPPORTED) 1071 else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) 1072 png_handle_sPLT(png_ptr, info_ptr, length); 1073#endif 1074#if defined(PNG_READ_tEXt_SUPPORTED) 1075 else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) 1076 png_handle_tEXt(png_ptr, info_ptr, length); 1077#endif 1078#if defined(PNG_READ_tIME_SUPPORTED) 1079 else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) 1080 png_handle_tIME(png_ptr, info_ptr, length); 1081#endif 1082#if defined(PNG_READ_tRNS_SUPPORTED) 1083 else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) 1084 png_handle_tRNS(png_ptr, info_ptr, length); 1085#endif 1086#if defined(PNG_READ_zTXt_SUPPORTED) 1087 else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) 1088 png_handle_zTXt(png_ptr, info_ptr, length); 1089#endif 1090#if defined(PNG_READ_iTXt_SUPPORTED) 1091 else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) 1092 png_handle_iTXt(png_ptr, info_ptr, length); 1093#endif 1094 else 1095 png_handle_unknown(png_ptr, info_ptr, length); 1096 } while (!(png_ptr->mode & PNG_HAVE_IEND)); 1097} 1098#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ 1099 1100/* free all memory used by the read */ 1101void PNGAPI 1102png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, 1103 png_infopp end_info_ptr_ptr) 1104{ 1105 png_structp png_ptr = NULL; 1106 png_infop info_ptr = NULL, end_info_ptr = NULL; 1107#ifdef PNG_USER_MEM_SUPPORTED 1108 png_free_ptr free_fn = NULL; 1109 png_voidp mem_ptr = NULL; 1110#endif 1111 1112 png_debug(1, "in png_destroy_read_struct\n"); 1113 if (png_ptr_ptr != NULL) 1114 { 1115 png_ptr = *png_ptr_ptr; 1116 } 1117 if (png_ptr == NULL) 1118 return; 1119 1120#ifdef PNG_USER_MEM_SUPPORTED 1121 free_fn = png_ptr->free_fn; 1122 mem_ptr = png_ptr->mem_ptr; 1123#endif 1124 1125 if (info_ptr_ptr != NULL) 1126 info_ptr = *info_ptr_ptr; 1127 1128 if (end_info_ptr_ptr != NULL) 1129 end_info_ptr = *end_info_ptr_ptr; 1130 1131 png_read_destroy(png_ptr, info_ptr, end_info_ptr); 1132 1133 if (info_ptr != NULL) 1134 { 1135#if defined(PNG_TEXT_SUPPORTED) 1136 png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); 1137#endif 1138 1139#ifdef PNG_USER_MEM_SUPPORTED 1140 png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, 1141 (png_voidp)mem_ptr); 1142#else 1143 png_destroy_struct((png_voidp)info_ptr); 1144#endif 1145 *info_ptr_ptr = NULL; 1146 } 1147 1148 if (end_info_ptr != NULL) 1149 { 1150#if defined(PNG_READ_TEXT_SUPPORTED) 1151 png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1); 1152#endif 1153#ifdef PNG_USER_MEM_SUPPORTED 1154 png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, 1155 (png_voidp)mem_ptr); 1156#else 1157 png_destroy_struct((png_voidp)end_info_ptr); 1158#endif 1159 *end_info_ptr_ptr = NULL; 1160 } 1161 1162#ifdef PNG_USER_MEM_SUPPORTED 1163 png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, 1164 (png_voidp)mem_ptr); 1165#else 1166 png_destroy_struct((png_voidp)png_ptr); 1167#endif 1168 *png_ptr_ptr = NULL; 1169} 1170 1171/* free all memory used by the read (old method) */ 1172void /* PRIVATE */ 1173png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr) 1174{ 1175#ifdef PNG_SETJMP_SUPPORTED 1176 jmp_buf tmp_jmp; 1177#endif 1178 png_error_ptr error_fn; 1179 png_error_ptr warning_fn; 1180 png_voidp error_ptr; 1181#ifdef PNG_USER_MEM_SUPPORTED 1182 png_free_ptr free_fn; 1183#endif 1184 1185 png_debug(1, "in png_read_destroy\n"); 1186 if (info_ptr != NULL) 1187 png_info_destroy(png_ptr, info_ptr); 1188 1189 if (end_info_ptr != NULL) 1190 png_info_destroy(png_ptr, end_info_ptr); 1191 1192 png_free(png_ptr, png_ptr->zbuf); 1193 png_free(png_ptr, png_ptr->big_row_buf); 1194 png_free(png_ptr, png_ptr->prev_row); 1195#if defined(PNG_READ_DITHER_SUPPORTED) 1196 png_free(png_ptr, png_ptr->palette_lookup); 1197 png_free(png_ptr, png_ptr->dither_index); 1198#endif 1199#if defined(PNG_READ_GAMMA_SUPPORTED) 1200 png_free(png_ptr, png_ptr->gamma_table); 1201#endif 1202#if defined(PNG_READ_BACKGROUND_SUPPORTED) 1203 png_free(png_ptr, png_ptr->gamma_from_1); 1204 png_free(png_ptr, png_ptr->gamma_to_1); 1205#endif 1206#ifdef PNG_FREE_ME_SUPPORTED 1207 if (png_ptr->free_me & PNG_FREE_PLTE) 1208 png_zfree(png_ptr, png_ptr->palette); 1209 png_ptr->free_me &= ~PNG_FREE_PLTE; 1210#else 1211 if (png_ptr->flags & PNG_FLAG_FREE_PLTE) 1212 png_zfree(png_ptr, png_ptr->palette); 1213 png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; 1214#endif 1215#if defined(PNG_tRNS_SUPPORTED) || \ 1216 defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) 1217#ifdef PNG_FREE_ME_SUPPORTED 1218 if (png_ptr->free_me & PNG_FREE_TRNS) 1219 png_free(png_ptr, png_ptr->trans); 1220 png_ptr->free_me &= ~PNG_FREE_TRNS; 1221#else 1222 if (png_ptr->flags & PNG_FLAG_FREE_TRNS) 1223 png_free(png_ptr, png_ptr->trans); 1224 png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; 1225#endif 1226#endif 1227#if defined(PNG_READ_hIST_SUPPORTED) 1228#ifdef PNG_FREE_ME_SUPPORTED 1229 if (png_ptr->free_me & PNG_FREE_HIST) 1230 png_free(png_ptr, png_ptr->hist); 1231 png_ptr->free_me &= ~PNG_FREE_HIST; 1232#else 1233 if (png_ptr->flags & PNG_FLAG_FREE_HIST) 1234 png_free(png_ptr, png_ptr->hist); 1235 png_ptr->flags &= ~PNG_FLAG_FREE_HIST; 1236#endif 1237#endif 1238#if defined(PNG_READ_GAMMA_SUPPORTED) 1239 if (png_ptr->gamma_16_table != NULL) 1240 { 1241 int i; 1242 int istop = (1 << (8 - png_ptr->gamma_shift)); 1243 for (i = 0; i < istop; i++) 1244 { 1245 png_free(png_ptr, png_ptr->gamma_16_table[i]); 1246 } 1247 png_free(png_ptr, png_ptr->gamma_16_table); 1248 } 1249#if defined(PNG_READ_BACKGROUND_SUPPORTED) 1250 if (png_ptr->gamma_16_from_1 != NULL) 1251 { 1252 int i; 1253 int istop = (1 << (8 - png_ptr->gamma_shift)); 1254 for (i = 0; i < istop; i++) 1255 { 1256 png_free(png_ptr, png_ptr->gamma_16_from_1[i]); 1257 } 1258 png_free(png_ptr, png_ptr->gamma_16_from_1); 1259 } 1260 if (png_ptr->gamma_16_to_1 != NULL) 1261 { 1262 int i; 1263 int istop = (1 << (8 - png_ptr->gamma_shift)); 1264 for (i = 0; i < istop; i++) 1265 { 1266 png_free(png_ptr, png_ptr->gamma_16_to_1[i]); 1267 } 1268 png_free(png_ptr, png_ptr->gamma_16_to_1); 1269 } 1270#endif 1271#endif 1272#if defined(PNG_TIME_RFC1123_SUPPORTED) 1273 png_free(png_ptr, png_ptr->time_buffer); 1274#endif 1275 1276 inflateEnd(&png_ptr->zstream); 1277#ifdef PNG_PROGRESSIVE_READ_SUPPORTED 1278 png_free(png_ptr, png_ptr->save_buffer); 1279#endif 1280 1281#ifdef PNG_PROGRESSIVE_READ_SUPPORTED 1282#ifdef PNG_TEXT_SUPPORTED 1283 png_free(png_ptr, png_ptr->current_text); 1284#endif /* PNG_TEXT_SUPPORTED */ 1285#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ 1286 1287 /* Save the important info out of the png_struct, in case it is 1288 * being used again. 1289 */ 1290#ifdef PNG_SETJMP_SUPPORTED 1291 png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); 1292#endif 1293 1294 error_fn = png_ptr->error_fn; 1295 warning_fn = png_ptr->warning_fn; 1296 error_ptr = png_ptr->error_ptr; 1297#ifdef PNG_USER_MEM_SUPPORTED 1298 free_fn = png_ptr->free_fn; 1299#endif 1300 1301 png_memset(png_ptr, 0, png_sizeof (png_struct)); 1302 1303 png_ptr->error_fn = error_fn; 1304 png_ptr->warning_fn = warning_fn; 1305 png_ptr->error_ptr = error_ptr; 1306#ifdef PNG_USER_MEM_SUPPORTED 1307 png_ptr->free_fn = free_fn; 1308#endif 1309 1310#ifdef PNG_SETJMP_SUPPORTED 1311 png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); 1312#endif 1313 1314} 1315 1316void PNGAPI 1317png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) 1318{ 1319 if(png_ptr == NULL) return; 1320 png_ptr->read_row_fn = read_row_fn; 1321} 1322 1323 1324#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED 1325#if defined(PNG_INFO_IMAGE_SUPPORTED) 1326void PNGAPI 1327png_read_png(png_structp png_ptr, png_infop info_ptr, 1328 int transforms, 1329 voidp params) 1330{ 1331 int row; 1332 1333 if(png_ptr == NULL) return; 1334#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) 1335 /* invert the alpha channel from opacity to transparency 1336 */ 1337 if (transforms & PNG_TRANSFORM_INVERT_ALPHA) 1338 png_set_invert_alpha(png_ptr); 1339#endif 1340 1341 /* png_read_info() gives us all of the information from the 1342 * PNG file before the first IDAT (image data chunk). 1343 */ 1344 png_read_info(png_ptr, info_ptr); 1345 if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) 1346 png_error(png_ptr,"Image is too high to process with png_read_png()"); 1347 1348 /* -------------- image transformations start here ------------------- */ 1349 1350#if defined(PNG_READ_16_TO_8_SUPPORTED) 1351 /* tell libpng to strip 16 bit/color files down to 8 bits per color 1352 */ 1353 if (transforms & PNG_TRANSFORM_STRIP_16) 1354 png_set_strip_16(png_ptr); 1355#endif 1356 1357#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) 1358 /* Strip alpha bytes from the input data without combining with 1359 * the background (not recommended). 1360 */ 1361 if (transforms & PNG_TRANSFORM_STRIP_ALPHA) 1362 png_set_strip_alpha(png_ptr); 1363#endif 1364 1365#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) 1366 /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single 1367 * byte into separate bytes (useful for paletted and grayscale images). 1368 */ 1369 if (transforms & PNG_TRANSFORM_PACKING) 1370 png_set_packing(png_ptr); 1371#endif 1372 1373#if defined(PNG_READ_PACKSWAP_SUPPORTED) 1374 /* Change the order of packed pixels to least significant bit first 1375 * (not useful if you are using png_set_packing). 1376 */ 1377 if (transforms & PNG_TRANSFORM_PACKSWAP) 1378 png_set_packswap(png_ptr); 1379#endif 1380 1381#if defined(PNG_READ_EXPAND_SUPPORTED) 1382 /* Expand paletted colors into true RGB triplets 1383 * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel 1384 * Expand paletted or RGB images with transparency to full alpha 1385 * channels so the data will be available as RGBA quartets. 1386 */ 1387 if (transforms & PNG_TRANSFORM_EXPAND) 1388 if ((png_ptr->bit_depth < 8) || 1389 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || 1390 (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) 1391 png_set_expand(png_ptr); 1392#endif 1393 1394 /* We don't handle background color or gamma transformation or dithering. 1395 */ 1396 1397#if defined(PNG_READ_INVERT_SUPPORTED) 1398 /* invert monochrome files to have 0 as white and 1 as black 1399 */ 1400 if (transforms & PNG_TRANSFORM_INVERT_MONO) 1401 png_set_invert_mono(png_ptr); 1402#endif 1403 1404#if defined(PNG_READ_SHIFT_SUPPORTED) 1405 /* If you want to shift the pixel values from the range [0,255] or 1406 * [0,65535] to the original [0,7] or [0,31], or whatever range the 1407 * colors were originally in: 1408 */ 1409 if ((transforms & PNG_TRANSFORM_SHIFT) 1410 && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) 1411 { 1412 png_color_8p sig_bit; 1413 1414 png_get_sBIT(png_ptr, info_ptr, &sig_bit); 1415 png_set_shift(png_ptr, sig_bit); 1416 } 1417#endif 1418 1419#if defined(PNG_READ_BGR_SUPPORTED) 1420 /* flip the RGB pixels to BGR (or RGBA to BGRA) 1421 */ 1422 if (transforms & PNG_TRANSFORM_BGR) 1423 png_set_bgr(png_ptr); 1424#endif 1425 1426#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) 1427 /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) 1428 */ 1429 if (transforms & PNG_TRANSFORM_SWAP_ALPHA) 1430 png_set_swap_alpha(png_ptr); 1431#endif 1432 1433#if defined(PNG_READ_SWAP_SUPPORTED) 1434 /* swap bytes of 16 bit files to least significant byte first 1435 */ 1436 if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) 1437 png_set_swap(png_ptr); 1438#endif 1439 1440 /* We don't handle adding filler bytes */ 1441 1442 /* Optional call to gamma correct and add the background to the palette 1443 * and update info structure. REQUIRED if you are expecting libpng to 1444 * update the palette for you (i.e., you selected such a transform above). 1445 */ 1446 png_read_update_info(png_ptr, info_ptr); 1447 1448 /* -------------- image transformations end here ------------------- */ 1449 1450#ifdef PNG_FREE_ME_SUPPORTED 1451 png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); 1452#endif 1453 if(info_ptr->row_pointers == NULL) 1454 { 1455 info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, 1456 info_ptr->height * png_sizeof(png_bytep)); 1457#ifdef PNG_FREE_ME_SUPPORTED 1458 info_ptr->free_me |= PNG_FREE_ROWS; 1459#endif 1460 for (row = 0; row < (int)info_ptr->height; row++) 1461 { 1462 info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, 1463 png_get_rowbytes(png_ptr, info_ptr)); 1464 } 1465 } 1466 1467 png_read_image(png_ptr, info_ptr->row_pointers); 1468 info_ptr->valid |= PNG_INFO_IDAT; 1469 1470 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ 1471 png_read_end(png_ptr, info_ptr); 1472 1473 transforms = transforms; /* quiet compiler warnings */ 1474 params = params; 1475 1476} 1477#endif /* PNG_INFO_IMAGE_SUPPORTED */ 1478#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ 1479#endif /* PNG_READ_SUPPORTED */ 1480