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