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