|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 00002 /* pngpread.c - read a png file in push mode 00003 * 00004 * Last changed in libpng 1.2.38 [July 16, 2009] 00005 * Copyright (c) 1998-2009 Glenn Randers-Pehrson 00006 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 00007 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 00008 * 00009 * This code is released under the libpng license. 00010 * For conditions of distribution and use, see the disclaimer 00011 * and license in png.h 00012 */ 00013 00014 #define PNG_INTERNAL 00015 #include "png.h" 00016 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED 00017 00018 /* Push model modes */ 00019 #define PNG_READ_SIG_MODE 0 00020 #define PNG_READ_CHUNK_MODE 1 00021 #define PNG_READ_IDAT_MODE 2 00022 #define PNG_SKIP_MODE 3 00023 #define PNG_READ_tEXt_MODE 4 00024 #define PNG_READ_zTXt_MODE 5 00025 #define PNG_READ_DONE_MODE 6 00026 #define PNG_READ_iTXt_MODE 7 00027 #define PNG_ERROR_MODE 8 00028 00029 void PNGAPI 00030 png_process_data(png_structp png_ptr, png_infop info_ptr, 00031 png_bytep buffer, png_size_t buffer_size) 00032 { 00033 if (png_ptr == NULL || info_ptr == NULL) 00034 return; 00035 00036 png_push_restore_buffer(png_ptr, buffer, buffer_size); 00037 00038 while (png_ptr->buffer_size) 00039 { 00040 png_process_some_data(png_ptr, info_ptr); 00041 } 00042 } 00043 00044 /* What we do with the incoming data depends on what we were previously 00045 * doing before we ran out of data... 00046 */ 00047 void /* PRIVATE */ 00048 png_process_some_data(png_structp png_ptr, png_infop info_ptr) 00049 { 00050 if (png_ptr == NULL) 00051 return; 00052 00053 switch (png_ptr->process_mode) 00054 { 00055 case PNG_READ_SIG_MODE: 00056 { 00057 png_push_read_sig(png_ptr, info_ptr); 00058 break; 00059 } 00060 00061 case PNG_READ_CHUNK_MODE: 00062 { 00063 png_push_read_chunk(png_ptr, info_ptr); 00064 break; 00065 } 00066 00067 case PNG_READ_IDAT_MODE: 00068 { 00069 png_push_read_IDAT(png_ptr); 00070 break; 00071 } 00072 00073 #if defined(PNG_READ_tEXt_SUPPORTED) 00074 case PNG_READ_tEXt_MODE: 00075 { 00076 png_push_read_tEXt(png_ptr, info_ptr); 00077 break; 00078 } 00079 00080 #endif 00081 #if defined(PNG_READ_zTXt_SUPPORTED) 00082 case PNG_READ_zTXt_MODE: 00083 { 00084 png_push_read_zTXt(png_ptr, info_ptr); 00085 break; 00086 } 00087 00088 #endif 00089 #if defined(PNG_READ_iTXt_SUPPORTED) 00090 case PNG_READ_iTXt_MODE: 00091 { 00092 png_push_read_iTXt(png_ptr, info_ptr); 00093 break; 00094 } 00095 00096 #endif 00097 case PNG_SKIP_MODE: 00098 { 00099 png_push_crc_finish(png_ptr); 00100 break; 00101 } 00102 00103 default: 00104 { 00105 png_ptr->buffer_size = 0; 00106 break; 00107 } 00108 } 00109 } 00110 00111 /* Read any remaining signature bytes from the stream and compare them with 00112 * the correct PNG signature. It is possible that this routine is called 00113 * with bytes already read from the signature, either because they have been 00114 * checked by the calling application, or because of multiple calls to this 00115 * routine. 00116 */ 00117 void /* PRIVATE */ 00118 png_push_read_sig(png_structp png_ptr, png_infop info_ptr) 00119 { 00120 png_size_t num_checked = png_ptr->sig_bytes, 00121 num_to_check = 8 - num_checked; 00122 00123 if (png_ptr->buffer_size < num_to_check) 00124 { 00125 num_to_check = png_ptr->buffer_size; 00126 } 00127 00128 png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), 00129 num_to_check); 00130 png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); 00131 00132 if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) 00133 { 00134 if (num_checked < 4 && 00135 png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) 00136 png_error(png_ptr, "Not a PNG file"); 00137 else 00138 png_error(png_ptr, "PNG file corrupted by ASCII conversion"); 00139 } 00140 else 00141 { 00142 if (png_ptr->sig_bytes >= 8) 00143 { 00144 png_ptr->process_mode = PNG_READ_CHUNK_MODE; 00145 } 00146 } 00147 } 00148 00149 void /* PRIVATE */ 00150 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) 00151 { 00152 #ifdef PNG_USE_LOCAL_ARRAYS 00153 PNG_CONST PNG_IHDR; 00154 PNG_CONST PNG_IDAT; 00155 PNG_CONST PNG_IEND; 00156 PNG_CONST PNG_PLTE; 00157 #if defined(PNG_READ_bKGD_SUPPORTED) 00158 PNG_CONST PNG_bKGD; 00159 #endif 00160 #if defined(PNG_READ_cHRM_SUPPORTED) 00161 PNG_CONST PNG_cHRM; 00162 #endif 00163 #if defined(PNG_READ_gAMA_SUPPORTED) 00164 PNG_CONST PNG_gAMA; 00165 #endif 00166 #if defined(PNG_READ_hIST_SUPPORTED) 00167 PNG_CONST PNG_hIST; 00168 #endif 00169 #if defined(PNG_READ_iCCP_SUPPORTED) 00170 PNG_CONST PNG_iCCP; 00171 #endif 00172 #if defined(PNG_READ_iTXt_SUPPORTED) 00173 PNG_CONST PNG_iTXt; 00174 #endif 00175 #if defined(PNG_READ_oFFs_SUPPORTED) 00176 PNG_CONST PNG_oFFs; 00177 #endif 00178 #if defined(PNG_READ_pCAL_SUPPORTED) 00179 PNG_CONST PNG_pCAL; 00180 #endif 00181 #if defined(PNG_READ_pHYs_SUPPORTED) 00182 PNG_CONST PNG_pHYs; 00183 #endif 00184 #if defined(PNG_READ_sBIT_SUPPORTED) 00185 PNG_CONST PNG_sBIT; 00186 #endif 00187 #if defined(PNG_READ_sCAL_SUPPORTED) 00188 PNG_CONST PNG_sCAL; 00189 #endif 00190 #if defined(PNG_READ_sRGB_SUPPORTED) 00191 PNG_CONST PNG_sRGB; 00192 #endif 00193 #if defined(PNG_READ_sPLT_SUPPORTED) 00194 PNG_CONST PNG_sPLT; 00195 #endif 00196 #if defined(PNG_READ_tEXt_SUPPORTED) 00197 PNG_CONST PNG_tEXt; 00198 #endif 00199 #if defined(PNG_READ_tIME_SUPPORTED) 00200 PNG_CONST PNG_tIME; 00201 #endif 00202 #if defined(PNG_READ_tRNS_SUPPORTED) 00203 PNG_CONST PNG_tRNS; 00204 #endif 00205 #if defined(PNG_READ_zTXt_SUPPORTED) 00206 PNG_CONST PNG_zTXt; 00207 #endif 00208 #endif /* PNG_USE_LOCAL_ARRAYS */ 00209 /* First we make sure we have enough data for the 4 byte chunk name 00210 * and the 4 byte chunk length before proceeding with decoding the 00211 * chunk data. To fully decode each of these chunks, we also make 00212 * sure we have enough data in the buffer for the 4 byte CRC at the 00213 * end of every chunk (except IDAT, which is handled separately). 00214 */ 00215 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) 00216 { 00217 png_byte chunk_length[4]; 00218 00219 if (png_ptr->buffer_size < 8) 00220 { 00221 png_push_save_buffer(png_ptr); 00222 return; 00223 } 00224 00225 png_push_fill_buffer(png_ptr, chunk_length, 4); 00226 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); 00227 png_reset_crc(png_ptr); 00228 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 00229 png_check_chunk_name(png_ptr, png_ptr->chunk_name); 00230 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; 00231 } 00232 00233 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 00234 if (png_ptr->mode & PNG_AFTER_IDAT) 00235 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; 00236 00237 if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) 00238 { 00239 if (png_ptr->push_length != 13) 00240 png_error(png_ptr, "Invalid IHDR length"); 00241 00242 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00243 { 00244 png_push_save_buffer(png_ptr); 00245 return; 00246 } 00247 00248 png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); 00249 } 00250 00251 else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) 00252 { 00253 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00254 { 00255 png_push_save_buffer(png_ptr); 00256 return; 00257 } 00258 00259 png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); 00260 00261 png_ptr->process_mode = PNG_READ_DONE_MODE; 00262 png_push_have_end(png_ptr, info_ptr); 00263 } 00264 00265 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 00266 else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) 00267 { 00268 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00269 { 00270 png_push_save_buffer(png_ptr); 00271 return; 00272 } 00273 00274 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 00275 png_ptr->mode |= PNG_HAVE_IDAT; 00276 00277 png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); 00278 00279 if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) 00280 png_ptr->mode |= PNG_HAVE_PLTE; 00281 00282 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 00283 { 00284 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 00285 png_error(png_ptr, "Missing IHDR before IDAT"); 00286 00287 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 00288 !(png_ptr->mode & PNG_HAVE_PLTE)) 00289 png_error(png_ptr, "Missing PLTE before IDAT"); 00290 } 00291 } 00292 00293 #endif 00294 else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) 00295 { 00296 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00297 { 00298 png_push_save_buffer(png_ptr); 00299 return; 00300 } 00301 png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); 00302 } 00303 00304 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 00305 { 00306 /* If we reach an IDAT chunk, this means we have read all of the 00307 * header chunks, and we can start reading the image (or if this 00308 * is called after the image has been read - we have an error). 00309 */ 00310 00311 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 00312 png_error(png_ptr, "Missing IHDR before IDAT"); 00313 00314 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 00315 !(png_ptr->mode & PNG_HAVE_PLTE)) 00316 png_error(png_ptr, "Missing PLTE before IDAT"); 00317 00318 if (png_ptr->mode & PNG_HAVE_IDAT) 00319 { 00320 if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) 00321 if (png_ptr->push_length == 0) 00322 return; 00323 00324 if (png_ptr->mode & PNG_AFTER_IDAT) 00325 png_error(png_ptr, "Too many IDAT's found"); 00326 } 00327 00328 png_ptr->idat_size = png_ptr->push_length; 00329 png_ptr->mode |= PNG_HAVE_IDAT; 00330 png_ptr->process_mode = PNG_READ_IDAT_MODE; 00331 png_push_have_info(png_ptr, info_ptr); 00332 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; 00333 png_ptr->zstream.next_out = png_ptr->row_buf; 00334 return; 00335 } 00336 00337 #if defined(PNG_READ_gAMA_SUPPORTED) 00338 else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) 00339 { 00340 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00341 { 00342 png_push_save_buffer(png_ptr); 00343 return; 00344 } 00345 00346 png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); 00347 } 00348 00349 #endif 00350 #if defined(PNG_READ_sBIT_SUPPORTED) 00351 else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) 00352 { 00353 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00354 { 00355 png_push_save_buffer(png_ptr); 00356 return; 00357 } 00358 00359 png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); 00360 } 00361 00362 #endif 00363 #if defined(PNG_READ_cHRM_SUPPORTED) 00364 else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) 00365 { 00366 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00367 { 00368 png_push_save_buffer(png_ptr); 00369 return; 00370 } 00371 00372 png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); 00373 } 00374 00375 #endif 00376 #if defined(PNG_READ_sRGB_SUPPORTED) 00377 else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) 00378 { 00379 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00380 { 00381 png_push_save_buffer(png_ptr); 00382 return; 00383 } 00384 00385 png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); 00386 } 00387 00388 #endif 00389 #if defined(PNG_READ_iCCP_SUPPORTED) 00390 else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) 00391 { 00392 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00393 { 00394 png_push_save_buffer(png_ptr); 00395 return; 00396 } 00397 00398 png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); 00399 } 00400 00401 #endif 00402 #if defined(PNG_READ_sPLT_SUPPORTED) 00403 else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) 00404 { 00405 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00406 { 00407 png_push_save_buffer(png_ptr); 00408 return; 00409 } 00410 00411 png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); 00412 } 00413 00414 #endif 00415 #if defined(PNG_READ_tRNS_SUPPORTED) 00416 else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) 00417 { 00418 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00419 { 00420 png_push_save_buffer(png_ptr); 00421 return; 00422 } 00423 00424 png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); 00425 } 00426 00427 #endif 00428 #if defined(PNG_READ_bKGD_SUPPORTED) 00429 else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) 00430 { 00431 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00432 { 00433 png_push_save_buffer(png_ptr); 00434 return; 00435 } 00436 00437 png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); 00438 } 00439 00440 #endif 00441 #if defined(PNG_READ_hIST_SUPPORTED) 00442 else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) 00443 { 00444 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00445 { 00446 png_push_save_buffer(png_ptr); 00447 return; 00448 } 00449 00450 png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); 00451 } 00452 00453 #endif 00454 #if defined(PNG_READ_pHYs_SUPPORTED) 00455 else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) 00456 { 00457 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00458 { 00459 png_push_save_buffer(png_ptr); 00460 return; 00461 } 00462 00463 png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); 00464 } 00465 00466 #endif 00467 #if defined(PNG_READ_oFFs_SUPPORTED) 00468 else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) 00469 { 00470 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00471 { 00472 png_push_save_buffer(png_ptr); 00473 return; 00474 } 00475 00476 png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); 00477 } 00478 #endif 00479 00480 #if defined(PNG_READ_pCAL_SUPPORTED) 00481 else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) 00482 { 00483 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00484 { 00485 png_push_save_buffer(png_ptr); 00486 return; 00487 } 00488 00489 png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); 00490 } 00491 00492 #endif 00493 #if defined(PNG_READ_sCAL_SUPPORTED) 00494 else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) 00495 { 00496 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00497 { 00498 png_push_save_buffer(png_ptr); 00499 return; 00500 } 00501 00502 png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); 00503 } 00504 00505 #endif 00506 #if defined(PNG_READ_tIME_SUPPORTED) 00507 else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) 00508 { 00509 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00510 { 00511 png_push_save_buffer(png_ptr); 00512 return; 00513 } 00514 00515 png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); 00516 } 00517 00518 #endif 00519 #if defined(PNG_READ_tEXt_SUPPORTED) 00520 else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) 00521 { 00522 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00523 { 00524 png_push_save_buffer(png_ptr); 00525 return; 00526 } 00527 00528 png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); 00529 } 00530 00531 #endif 00532 #if defined(PNG_READ_zTXt_SUPPORTED) 00533 else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) 00534 { 00535 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00536 { 00537 png_push_save_buffer(png_ptr); 00538 return; 00539 } 00540 00541 png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); 00542 } 00543 00544 #endif 00545 #if defined(PNG_READ_iTXt_SUPPORTED) 00546 else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) 00547 { 00548 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00549 { 00550 png_push_save_buffer(png_ptr); 00551 return; 00552 } 00553 00554 png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); 00555 } 00556 00557 #endif 00558 else 00559 { 00560 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 00561 { 00562 png_push_save_buffer(png_ptr); 00563 return; 00564 } 00565 png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); 00566 } 00567 00568 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; 00569 } 00570 00571 void /* PRIVATE */ 00572 png_push_crc_skip(png_structp png_ptr, png_uint_32 skip) 00573 { 00574 png_ptr->process_mode = PNG_SKIP_MODE; 00575 png_ptr->skip_length = skip; 00576 } 00577 00578 void /* PRIVATE */ 00579 png_push_crc_finish(png_structp png_ptr) 00580 { 00581 if (png_ptr->skip_length && png_ptr->save_buffer_size) 00582 { 00583 png_size_t save_size; 00584 00585 if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size) 00586 save_size = (png_size_t)png_ptr->skip_length; 00587 else 00588 save_size = png_ptr->save_buffer_size; 00589 00590 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); 00591 00592 png_ptr->skip_length -= save_size; 00593 png_ptr->buffer_size -= save_size; 00594 png_ptr->save_buffer_size -= save_size; 00595 png_ptr->save_buffer_ptr += save_size; 00596 } 00597 if (png_ptr->skip_length && png_ptr->current_buffer_size) 00598 { 00599 png_size_t save_size; 00600 00601 if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size) 00602 save_size = (png_size_t)png_ptr->skip_length; 00603 else 00604 save_size = png_ptr->current_buffer_size; 00605 00606 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); 00607 00608 png_ptr->skip_length -= save_size; 00609 png_ptr->buffer_size -= save_size; 00610 png_ptr->current_buffer_size -= save_size; 00611 png_ptr->current_buffer_ptr += save_size; 00612 } 00613 if (!png_ptr->skip_length) 00614 { 00615 if (png_ptr->buffer_size < 4) 00616 { 00617 png_push_save_buffer(png_ptr); 00618 return; 00619 } 00620 00621 png_crc_finish(png_ptr, 0); 00622 png_ptr->process_mode = PNG_READ_CHUNK_MODE; 00623 } 00624 } 00625 00626 void PNGAPI 00627 png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) 00628 { 00629 png_bytep ptr; 00630 00631 if (png_ptr == NULL) 00632 return; 00633 00634 ptr = buffer; 00635 if (png_ptr->save_buffer_size) 00636 { 00637 png_size_t save_size; 00638 00639 if (length < png_ptr->save_buffer_size) 00640 save_size = length; 00641 else 00642 save_size = png_ptr->save_buffer_size; 00643 00644 png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size); 00645 length -= save_size; 00646 ptr += save_size; 00647 png_ptr->buffer_size -= save_size; 00648 png_ptr->save_buffer_size -= save_size; 00649 png_ptr->save_buffer_ptr += save_size; 00650 } 00651 if (length && png_ptr->current_buffer_size) 00652 { 00653 png_size_t save_size; 00654 00655 if (length < png_ptr->current_buffer_size) 00656 save_size = length; 00657 00658 else 00659 save_size = png_ptr->current_buffer_size; 00660 00661 png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size); 00662 png_ptr->buffer_size -= save_size; 00663 png_ptr->current_buffer_size -= save_size; 00664 png_ptr->current_buffer_ptr += save_size; 00665 } 00666 } 00667 00668 void /* PRIVATE */ 00669 png_push_save_buffer(png_structp png_ptr) 00670 { 00671 if (png_ptr->save_buffer_size) 00672 { 00673 if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) 00674 { 00675 png_size_t i, istop; 00676 png_bytep sp; 00677 png_bytep dp; 00678 00679 istop = png_ptr->save_buffer_size; 00680 for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; 00681 i < istop; i++, sp++, dp++) 00682 { 00683 *dp = *sp; 00684 } 00685 } 00686 } 00687 if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > 00688 png_ptr->save_buffer_max) 00689 { 00690 png_size_t new_max; 00691 png_bytep old_buffer; 00692 00693 if (png_ptr->save_buffer_size > PNG_SIZE_MAX - 00694 (png_ptr->current_buffer_size + 256)) 00695 { 00696 png_error(png_ptr, "Potential overflow of save_buffer"); 00697 } 00698 00699 new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; 00700 old_buffer = png_ptr->save_buffer; 00701 png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, 00702 (png_uint_32)new_max); 00703 png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); 00704 png_free(png_ptr, old_buffer); 00705 png_ptr->save_buffer_max = new_max; 00706 } 00707 if (png_ptr->current_buffer_size) 00708 { 00709 png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, 00710 png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); 00711 png_ptr->save_buffer_size += png_ptr->current_buffer_size; 00712 png_ptr->current_buffer_size = 0; 00713 } 00714 png_ptr->save_buffer_ptr = png_ptr->save_buffer; 00715 png_ptr->buffer_size = 0; 00716 } 00717 00718 void /* PRIVATE */ 00719 png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, 00720 png_size_t buffer_length) 00721 { 00722 png_ptr->current_buffer = buffer; 00723 png_ptr->current_buffer_size = buffer_length; 00724 png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; 00725 png_ptr->current_buffer_ptr = png_ptr->current_buffer; 00726 } 00727 00728 void /* PRIVATE */ 00729 png_push_read_IDAT(png_structp png_ptr) 00730 { 00731 #ifdef PNG_USE_LOCAL_ARRAYS 00732 PNG_CONST PNG_IDAT; 00733 #endif 00734 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) 00735 { 00736 png_byte chunk_length[4]; 00737 00738 if (png_ptr->buffer_size < 8) 00739 { 00740 png_push_save_buffer(png_ptr); 00741 return; 00742 } 00743 00744 png_push_fill_buffer(png_ptr, chunk_length, 4); 00745 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); 00746 png_reset_crc(png_ptr); 00747 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 00748 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; 00749 00750 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 00751 { 00752 png_ptr->process_mode = PNG_READ_CHUNK_MODE; 00753 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 00754 png_error(png_ptr, "Not enough compressed data"); 00755 return; 00756 } 00757 00758 png_ptr->idat_size = png_ptr->push_length; 00759 } 00760 if (png_ptr->idat_size && png_ptr->save_buffer_size) 00761 { 00762 png_size_t save_size; 00763 00764 if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size) 00765 { 00766 save_size = (png_size_t)png_ptr->idat_size; 00767 00768 /* Check for overflow */ 00769 if ((png_uint_32)save_size != png_ptr->idat_size) 00770 png_error(png_ptr, "save_size overflowed in pngpread"); 00771 } 00772 else 00773 save_size = png_ptr->save_buffer_size; 00774 00775 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); 00776 00777 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 00778 png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); 00779 00780 png_ptr->idat_size -= save_size; 00781 png_ptr->buffer_size -= save_size; 00782 png_ptr->save_buffer_size -= save_size; 00783 png_ptr->save_buffer_ptr += save_size; 00784 } 00785 if (png_ptr->idat_size && png_ptr->current_buffer_size) 00786 { 00787 png_size_t save_size; 00788 00789 if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size) 00790 { 00791 save_size = (png_size_t)png_ptr->idat_size; 00792 00793 /* Check for overflow */ 00794 if ((png_uint_32)save_size != png_ptr->idat_size) 00795 png_error(png_ptr, "save_size overflowed in pngpread"); 00796 } 00797 else 00798 save_size = png_ptr->current_buffer_size; 00799 00800 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); 00801 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 00802 png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); 00803 00804 png_ptr->idat_size -= save_size; 00805 png_ptr->buffer_size -= save_size; 00806 png_ptr->current_buffer_size -= save_size; 00807 png_ptr->current_buffer_ptr += save_size; 00808 } 00809 if (!png_ptr->idat_size) 00810 { 00811 if (png_ptr->buffer_size < 4) 00812 { 00813 png_push_save_buffer(png_ptr); 00814 return; 00815 } 00816 00817 png_crc_finish(png_ptr, 0); 00818 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; 00819 png_ptr->mode |= PNG_AFTER_IDAT; 00820 } 00821 } 00822 00823 void /* PRIVATE */ 00824 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, 00825 png_size_t buffer_length) 00826 { 00827 int ret; 00828 00829 if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length) 00830 png_error(png_ptr, "Extra compression data"); 00831 00832 png_ptr->zstream.next_in = buffer; 00833 png_ptr->zstream.avail_in = (uInt)buffer_length; 00834 for (;;) 00835 { 00836 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 00837 if (ret != Z_OK) 00838 { 00839 if (ret == Z_STREAM_END) 00840 { 00841 if (png_ptr->zstream.avail_in) 00842 png_error(png_ptr, "Extra compressed data"); 00843 00844 if (!(png_ptr->zstream.avail_out)) 00845 { 00846 png_push_process_row(png_ptr); 00847 } 00848 00849 png_ptr->mode |= PNG_AFTER_IDAT; 00850 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 00851 break; 00852 } 00853 else if (ret == Z_BUF_ERROR) 00854 break; 00855 00856 else 00857 png_error(png_ptr, "Decompression Error"); 00858 } 00859 if (!(png_ptr->zstream.avail_out)) 00860 { 00861 if (( 00862 #if defined(PNG_READ_INTERLACING_SUPPORTED) 00863 png_ptr->interlaced && png_ptr->pass > 6) || 00864 (!png_ptr->interlaced && 00865 #endif 00866 png_ptr->row_number == png_ptr->num_rows)) 00867 { 00868 if (png_ptr->zstream.avail_in) 00869 png_warning(png_ptr, "Too much data in IDAT chunks"); 00870 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 00871 break; 00872 } 00873 png_push_process_row(png_ptr); 00874 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; 00875 png_ptr->zstream.next_out = png_ptr->row_buf; 00876 } 00877 00878 else 00879 break; 00880 } 00881 } 00882 00883 void /* PRIVATE */ 00884 png_push_process_row(png_structp png_ptr) 00885 { 00886 png_ptr->row_info.color_type = png_ptr->color_type; 00887 png_ptr->row_info.width = png_ptr->iwidth; 00888 png_ptr->row_info.channels = png_ptr->channels; 00889 png_ptr->row_info.bit_depth = png_ptr->bit_depth; 00890 png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; 00891 00892 png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, 00893 png_ptr->row_info.width); 00894 00895 png_read_filter_row(png_ptr, &(png_ptr->row_info), 00896 png_ptr->row_buf + 1, png_ptr->prev_row + 1, 00897 (int)(png_ptr->row_buf[0])); 00898 00899 png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, 00900 png_ptr->rowbytes + 1); 00901 00902 if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) 00903 png_do_read_transformations(png_ptr); 00904 00905 #if defined(PNG_READ_INTERLACING_SUPPORTED) 00906 /* Blow up interlaced rows to full size */ 00907 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) 00908 { 00909 if (png_ptr->pass < 6) 00910 /* old interface (pre-1.0.9): 00911 png_do_read_interlace(&(png_ptr->row_info), 00912 png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); 00913 */ 00914 png_do_read_interlace(png_ptr); 00915 00916 switch (png_ptr->pass) 00917 { 00918 case 0: 00919 { 00920 int i; 00921 for (i = 0; i < 8 && png_ptr->pass == 0; i++) 00922 { 00923 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 00924 png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ 00925 } 00926 00927 if (png_ptr->pass == 2) /* Pass 1 might be empty */ 00928 { 00929 for (i = 0; i < 4 && png_ptr->pass == 2; i++) 00930 { 00931 png_push_have_row(png_ptr, png_bytep_NULL); 00932 png_read_push_finish_row(png_ptr); 00933 } 00934 } 00935 00936 if (png_ptr->pass == 4 && png_ptr->height <= 4) 00937 { 00938 for (i = 0; i < 2 && png_ptr->pass == 4; i++) 00939 { 00940 png_push_have_row(png_ptr, png_bytep_NULL); 00941 png_read_push_finish_row(png_ptr); 00942 } 00943 } 00944 00945 if (png_ptr->pass == 6 && png_ptr->height <= 4) 00946 { 00947 png_push_have_row(png_ptr, png_bytep_NULL); 00948 png_read_push_finish_row(png_ptr); 00949 } 00950 00951 break; 00952 } 00953 00954 case 1: 00955 { 00956 int i; 00957 for (i = 0; i < 8 && png_ptr->pass == 1; i++) 00958 { 00959 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 00960 png_read_push_finish_row(png_ptr); 00961 } 00962 00963 if (png_ptr->pass == 2) /* Skip top 4 generated rows */ 00964 { 00965 for (i = 0; i < 4 && png_ptr->pass == 2; i++) 00966 { 00967 png_push_have_row(png_ptr, png_bytep_NULL); 00968 png_read_push_finish_row(png_ptr); 00969 } 00970 } 00971 00972 break; 00973 } 00974 00975 case 2: 00976 { 00977 int i; 00978 00979 for (i = 0; i < 4 && png_ptr->pass == 2; i++) 00980 { 00981 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 00982 png_read_push_finish_row(png_ptr); 00983 } 00984 00985 for (i = 0; i < 4 && png_ptr->pass == 2; i++) 00986 { 00987 png_push_have_row(png_ptr, png_bytep_NULL); 00988 png_read_push_finish_row(png_ptr); 00989 } 00990 00991 if (png_ptr->pass == 4) /* Pass 3 might be empty */ 00992 { 00993 for (i = 0; i < 2 && png_ptr->pass == 4; i++) 00994 { 00995 png_push_have_row(png_ptr, png_bytep_NULL); 00996 png_read_push_finish_row(png_ptr); 00997 } 00998 } 00999 01000 break; 01001 } 01002 01003 case 3: 01004 { 01005 int i; 01006 01007 for (i = 0; i < 4 && png_ptr->pass == 3; i++) 01008 { 01009 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 01010 png_read_push_finish_row(png_ptr); 01011 } 01012 01013 if (png_ptr->pass == 4) /* Skip top two generated rows */ 01014 { 01015 for (i = 0; i < 2 && png_ptr->pass == 4; i++) 01016 { 01017 png_push_have_row(png_ptr, png_bytep_NULL); 01018 png_read_push_finish_row(png_ptr); 01019 } 01020 } 01021 01022 break; 01023 } 01024 01025 case 4: 01026 { 01027 int i; 01028 01029 for (i = 0; i < 2 && png_ptr->pass == 4; i++) 01030 { 01031 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 01032 png_read_push_finish_row(png_ptr); 01033 } 01034 01035 for (i = 0; i < 2 && png_ptr->pass == 4; i++) 01036 { 01037 png_push_have_row(png_ptr, png_bytep_NULL); 01038 png_read_push_finish_row(png_ptr); 01039 } 01040 01041 if (png_ptr->pass == 6) /* Pass 5 might be empty */ 01042 { 01043 png_push_have_row(png_ptr, png_bytep_NULL); 01044 png_read_push_finish_row(png_ptr); 01045 } 01046 01047 break; 01048 } 01049 01050 case 5: 01051 { 01052 int i; 01053 01054 for (i = 0; i < 2 && png_ptr->pass == 5; i++) 01055 { 01056 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 01057 png_read_push_finish_row(png_ptr); 01058 } 01059 01060 if (png_ptr->pass == 6) /* Skip top generated row */ 01061 { 01062 png_push_have_row(png_ptr, png_bytep_NULL); 01063 png_read_push_finish_row(png_ptr); 01064 } 01065 01066 break; 01067 } 01068 case 6: 01069 { 01070 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 01071 png_read_push_finish_row(png_ptr); 01072 01073 if (png_ptr->pass != 6) 01074 break; 01075 01076 png_push_have_row(png_ptr, png_bytep_NULL); 01077 png_read_push_finish_row(png_ptr); 01078 } 01079 } 01080 } 01081 else 01082 #endif 01083 { 01084 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 01085 png_read_push_finish_row(png_ptr); 01086 } 01087 } 01088 01089 void /* PRIVATE */ 01090 png_read_push_finish_row(png_structp png_ptr) 01091 { 01092 #ifdef PNG_USE_LOCAL_ARRAYS 01093 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 01094 01095 /* Start of interlace block */ 01096 PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; 01097 01098 /* Offset to next interlace block */ 01099 PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; 01100 01101 /* Start of interlace block in the y direction */ 01102 PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; 01103 01104 /* Offset to next interlace block in the y direction */ 01105 PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; 01106 01107 /* Height of interlace block. This is not currently used - if you need 01108 * it, uncomment it here and in png.h 01109 PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; 01110 */ 01111 #endif 01112 01113 png_ptr->row_number++; 01114 if (png_ptr->row_number < png_ptr->num_rows) 01115 return; 01116 01117 #if defined(PNG_READ_INTERLACING_SUPPORTED) 01118 if (png_ptr->interlaced) 01119 { 01120 png_ptr->row_number = 0; 01121 png_memset_check(png_ptr, png_ptr->prev_row, 0, 01122 png_ptr->rowbytes + 1); 01123 do 01124 { 01125 png_ptr->pass++; 01126 if ((png_ptr->pass == 1 && png_ptr->width < 5) || 01127 (png_ptr->pass == 3 && png_ptr->width < 3) || 01128 (png_ptr->pass == 5 && png_ptr->width < 2)) 01129 png_ptr->pass++; 01130 01131 if (png_ptr->pass > 7) 01132 png_ptr->pass--; 01133 01134 if (png_ptr->pass >= 7) 01135 break; 01136 01137 png_ptr->iwidth = (png_ptr->width + 01138 png_pass_inc[png_ptr->pass] - 1 - 01139 png_pass_start[png_ptr->pass]) / 01140 png_pass_inc[png_ptr->pass]; 01141 01142 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, 01143 png_ptr->iwidth) + 1; 01144 01145 if (png_ptr->transformations & PNG_INTERLACE) 01146 break; 01147 01148 png_ptr->num_rows = (png_ptr->height + 01149 png_pass_yinc[png_ptr->pass] - 1 - 01150 png_pass_ystart[png_ptr->pass]) / 01151 png_pass_yinc[png_ptr->pass]; 01152 01153 } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); 01154 } 01155 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 01156 } 01157 01158 #if defined(PNG_READ_tEXt_SUPPORTED) 01159 void /* PRIVATE */ 01160 png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 01161 length) 01162 { 01163 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) 01164 { 01165 png_error(png_ptr, "Out of place tEXt"); 01166 info_ptr = info_ptr; /* To quiet some compiler warnings */ 01167 } 01168 01169 #ifdef PNG_MAX_MALLOC_64K 01170 png_ptr->skip_length = 0; /* This may not be necessary */ 01171 01172 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ 01173 { 01174 png_warning(png_ptr, "tEXt chunk too large to fit in memory"); 01175 png_ptr->skip_length = length - (png_uint_32)65535L; 01176 length = (png_uint_32)65535L; 01177 } 01178 #endif 01179 01180 png_ptr->current_text = (png_charp)png_malloc(png_ptr, 01181 (png_uint_32)(length + 1)); 01182 png_ptr->current_text[length] = '\0'; 01183 png_ptr->current_text_ptr = png_ptr->current_text; 01184 png_ptr->current_text_size = (png_size_t)length; 01185 png_ptr->current_text_left = (png_size_t)length; 01186 png_ptr->process_mode = PNG_READ_tEXt_MODE; 01187 } 01188 01189 void /* PRIVATE */ 01190 png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) 01191 { 01192 if (png_ptr->buffer_size && png_ptr->current_text_left) 01193 { 01194 png_size_t text_size; 01195 01196 if (png_ptr->buffer_size < png_ptr->current_text_left) 01197 text_size = png_ptr->buffer_size; 01198 01199 else 01200 text_size = png_ptr->current_text_left; 01201 01202 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); 01203 png_ptr->current_text_left -= text_size; 01204 png_ptr->current_text_ptr += text_size; 01205 } 01206 if (!(png_ptr->current_text_left)) 01207 { 01208 png_textp text_ptr; 01209 png_charp text; 01210 png_charp key; 01211 int ret; 01212 01213 if (png_ptr->buffer_size < 4) 01214 { 01215 png_push_save_buffer(png_ptr); 01216 return; 01217 } 01218 01219 png_push_crc_finish(png_ptr); 01220 01221 #if defined(PNG_MAX_MALLOC_64K) 01222 if (png_ptr->skip_length) 01223 return; 01224 #endif 01225 01226 key = png_ptr->current_text; 01227 01228 for (text = key; *text; text++) 01229 /* Empty loop */ ; 01230 01231 if (text < key + png_ptr->current_text_size) 01232 text++; 01233 01234 text_ptr = (png_textp)png_malloc(png_ptr, 01235 (png_uint_32)png_sizeof(png_text)); 01236 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; 01237 text_ptr->key = key; 01238 #ifdef PNG_iTXt_SUPPORTED 01239 text_ptr->lang = NULL; 01240 text_ptr->lang_key = NULL; 01241 #endif 01242 text_ptr->text = text; 01243 01244 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 01245 01246 png_free(png_ptr, key); 01247 png_free(png_ptr, text_ptr); 01248 png_ptr->current_text = NULL; 01249 01250 if (ret) 01251 png_warning(png_ptr, "Insufficient memory to store text chunk."); 01252 } 01253 } 01254 #endif 01255 01256 #if defined(PNG_READ_zTXt_SUPPORTED) 01257 void /* PRIVATE */ 01258 png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 01259 length) 01260 { 01261 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) 01262 { 01263 png_error(png_ptr, "Out of place zTXt"); 01264 info_ptr = info_ptr; /* To quiet some compiler warnings */ 01265 } 01266 01267 #ifdef PNG_MAX_MALLOC_64K 01268 /* We can't handle zTXt chunks > 64K, since we don't have enough space 01269 * to be able to store the uncompressed data. Actually, the threshold 01270 * is probably around 32K, but it isn't as definite as 64K is. 01271 */ 01272 if (length > (png_uint_32)65535L) 01273 { 01274 png_warning(png_ptr, "zTXt chunk too large to fit in memory"); 01275 png_push_crc_skip(png_ptr, length); 01276 return; 01277 } 01278 #endif 01279 01280 png_ptr->current_text = (png_charp)png_malloc(png_ptr, 01281 (png_uint_32)(length + 1)); 01282 png_ptr->current_text[length] = '\0'; 01283 png_ptr->current_text_ptr = png_ptr->current_text; 01284 png_ptr->current_text_size = (png_size_t)length; 01285 png_ptr->current_text_left = (png_size_t)length; 01286 png_ptr->process_mode = PNG_READ_zTXt_MODE; 01287 } 01288 01289 void /* PRIVATE */ 01290 png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) 01291 { 01292 if (png_ptr->buffer_size && png_ptr->current_text_left) 01293 { 01294 png_size_t text_size; 01295 01296 if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) 01297 text_size = png_ptr->buffer_size; 01298 01299 else 01300 text_size = png_ptr->current_text_left; 01301 01302 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); 01303 png_ptr->current_text_left -= text_size; 01304 png_ptr->current_text_ptr += text_size; 01305 } 01306 if (!(png_ptr->current_text_left)) 01307 { 01308 png_textp text_ptr; 01309 png_charp text; 01310 png_charp key; 01311 int ret; 01312 png_size_t text_size, key_size; 01313 01314 if (png_ptr->buffer_size < 4) 01315 { 01316 png_push_save_buffer(png_ptr); 01317 return; 01318 } 01319 01320 png_push_crc_finish(png_ptr); 01321 01322 key = png_ptr->current_text; 01323 01324 for (text = key; *text; text++) 01325 /* Empty loop */ ; 01326 01327 /* zTXt can't have zero text */ 01328 if (text >= key + png_ptr->current_text_size) 01329 { 01330 png_ptr->current_text = NULL; 01331 png_free(png_ptr, key); 01332 return; 01333 } 01334 01335 text++; 01336 01337 if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */ 01338 { 01339 png_ptr->current_text = NULL; 01340 png_free(png_ptr, key); 01341 return; 01342 } 01343 01344 text++; 01345 01346 png_ptr->zstream.next_in = (png_bytep )text; 01347 png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - 01348 (text - key)); 01349 png_ptr->zstream.next_out = png_ptr->zbuf; 01350 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 01351 01352 key_size = text - key; 01353 text_size = 0; 01354 text = NULL; 01355 ret = Z_STREAM_END; 01356 01357 while (png_ptr->zstream.avail_in) 01358 { 01359 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 01360 if (ret != Z_OK && ret != Z_STREAM_END) 01361 { 01362 inflateReset(&png_ptr->zstream); 01363 png_ptr->zstream.avail_in = 0; 01364 png_ptr->current_text = NULL; 01365 png_free(png_ptr, key); 01366 png_free(png_ptr, text); 01367 return; 01368 } 01369 if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) 01370 { 01371 if (text == NULL) 01372 { 01373 text = (png_charp)png_malloc(png_ptr, 01374 (png_uint_32)(png_ptr->zbuf_size 01375 - png_ptr->zstream.avail_out + key_size + 1)); 01376 01377 png_memcpy(text + key_size, png_ptr->zbuf, 01378 png_ptr->zbuf_size - png_ptr->zstream.avail_out); 01379 01380 png_memcpy(text, key, key_size); 01381 01382 text_size = key_size + png_ptr->zbuf_size - 01383 png_ptr->zstream.avail_out; 01384 01385 *(text + text_size) = '\0'; 01386 } 01387 else 01388 { 01389 png_charp tmp; 01390 01391 tmp = text; 01392 text = (png_charp)png_malloc(png_ptr, text_size + 01393 (png_uint_32)(png_ptr->zbuf_size 01394 - png_ptr->zstream.avail_out + 1)); 01395 01396 png_memcpy(text, tmp, text_size); 01397 png_free(png_ptr, tmp); 01398 01399 png_memcpy(text + text_size, png_ptr->zbuf, 01400 png_ptr->zbuf_size - png_ptr->zstream.avail_out); 01401 01402 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; 01403 *(text + text_size) = '\0'; 01404 } 01405 if (ret != Z_STREAM_END) 01406 { 01407 png_ptr->zstream.next_out = png_ptr->zbuf; 01408 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 01409 } 01410 } 01411 else 01412 { 01413 break; 01414 } 01415 01416 if (ret == Z_STREAM_END) 01417 break; 01418 } 01419 01420 inflateReset(&png_ptr->zstream); 01421 png_ptr->zstream.avail_in = 0; 01422 01423 if (ret != Z_STREAM_END) 01424 { 01425 png_ptr->current_text = NULL; 01426 png_free(png_ptr, key); 01427 png_free(png_ptr, text); 01428 return; 01429 } 01430 01431 png_ptr->current_text = NULL; 01432 png_free(png_ptr, key); 01433 key = text; 01434 text += key_size; 01435 01436 text_ptr = (png_textp)png_malloc(png_ptr, 01437 (png_uint_32)png_sizeof(png_text)); 01438 text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; 01439 text_ptr->key = key; 01440 #ifdef PNG_iTXt_SUPPORTED 01441 text_ptr->lang = NULL; 01442 text_ptr->lang_key = NULL; 01443 #endif 01444 text_ptr->text = text; 01445 01446 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 01447 01448 png_free(png_ptr, key); 01449 png_free(png_ptr, text_ptr); 01450 01451 if (ret) 01452 png_warning(png_ptr, "Insufficient memory to store text chunk."); 01453 } 01454 } 01455 #endif 01456 01457 #if defined(PNG_READ_iTXt_SUPPORTED) 01458 void /* PRIVATE */ 01459 png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 01460 length) 01461 { 01462 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) 01463 { 01464 png_error(png_ptr, "Out of place iTXt"); 01465 info_ptr = info_ptr; /* To quiet some compiler warnings */ 01466 } 01467 01468 #ifdef PNG_MAX_MALLOC_64K 01469 png_ptr->skip_length = 0; /* This may not be necessary */ 01470 01471 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ 01472 { 01473 png_warning(png_ptr, "iTXt chunk too large to fit in memory"); 01474 png_ptr->skip_length = length - (png_uint_32)65535L; 01475 length = (png_uint_32)65535L; 01476 } 01477 #endif 01478 01479 png_ptr->current_text = (png_charp)png_malloc(png_ptr, 01480 (png_uint_32)(length + 1)); 01481 png_ptr->current_text[length] = '\0'; 01482 png_ptr->current_text_ptr = png_ptr->current_text; 01483 png_ptr->current_text_size = (png_size_t)length; 01484 png_ptr->current_text_left = (png_size_t)length; 01485 png_ptr->process_mode = PNG_READ_iTXt_MODE; 01486 } 01487 01488 void /* PRIVATE */ 01489 png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) 01490 { 01491 01492 if (png_ptr->buffer_size && png_ptr->current_text_left) 01493 { 01494 png_size_t text_size; 01495 01496 if (png_ptr->buffer_size < png_ptr->current_text_left) 01497 text_size = png_ptr->buffer_size; 01498 01499 else 01500 text_size = png_ptr->current_text_left; 01501 01502 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); 01503 png_ptr->current_text_left -= text_size; 01504 png_ptr->current_text_ptr += text_size; 01505 } 01506 if (!(png_ptr->current_text_left)) 01507 { 01508 png_textp text_ptr; 01509 png_charp key; 01510 int comp_flag; 01511 png_charp lang; 01512 png_charp lang_key; 01513 png_charp text; 01514 int ret; 01515 01516 if (png_ptr->buffer_size < 4) 01517 { 01518 png_push_save_buffer(png_ptr); 01519 return; 01520 } 01521 01522 png_push_crc_finish(png_ptr); 01523 01524 #if defined(PNG_MAX_MALLOC_64K) 01525 if (png_ptr->skip_length) 01526 return; 01527 #endif 01528 01529 key = png_ptr->current_text; 01530 01531 for (lang = key; *lang; lang++) 01532 /* Empty loop */ ; 01533 01534 if (lang < key + png_ptr->current_text_size - 3) 01535 lang++; 01536 01537 comp_flag = *lang++; 01538 lang++; /* Skip comp_type, always zero */ 01539 01540 for (lang_key = lang; *lang_key; lang_key++) 01541 /* Empty loop */ ; 01542 01543 lang_key++; /* Skip NUL separator */ 01544 01545 text=lang_key; 01546 01547 if (lang_key < key + png_ptr->current_text_size - 1) 01548 { 01549 for (; *text; text++) 01550 /* Empty loop */ ; 01551 } 01552 01553 if (text < key + png_ptr->current_text_size) 01554 text++; 01555 01556 text_ptr = (png_textp)png_malloc(png_ptr, 01557 (png_uint_32)png_sizeof(png_text)); 01558 01559 text_ptr->compression = comp_flag + 2; 01560 text_ptr->key = key; 01561 text_ptr->lang = lang; 01562 text_ptr->lang_key = lang_key; 01563 text_ptr->text = text; 01564 text_ptr->text_length = 0; 01565 text_ptr->itxt_length = png_strlen(text); 01566 01567 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 01568 01569 png_ptr->current_text = NULL; 01570 01571 png_free(png_ptr, text_ptr); 01572 if (ret) 01573 png_warning(png_ptr, "Insufficient memory to store iTXt chunk."); 01574 } 01575 } 01576 #endif 01577 01578 /* This function is called when we haven't found a handler for this 01579 * chunk. If there isn't a problem with the chunk itself (ie a bad chunk 01580 * name or a critical chunk), the chunk is (currently) silently ignored. 01581 */ 01582 void /* PRIVATE */ 01583 png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 01584 length) 01585 { 01586 png_uint_32 skip = 0; 01587 01588 if (!(png_ptr->chunk_name[0] & 0x20)) 01589 { 01590 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 01591 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 01592 PNG_HANDLE_CHUNK_ALWAYS 01593 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) 01594 && png_ptr->read_user_chunk_fn == NULL 01595 #endif 01596 ) 01597 #endif 01598 png_chunk_error(png_ptr, "unknown critical chunk"); 01599 01600 info_ptr = info_ptr; /* To quiet some compiler warnings */ 01601 } 01602 01603 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 01604 if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) 01605 { 01606 #ifdef PNG_MAX_MALLOC_64K 01607 if (length > (png_uint_32)65535L) 01608 { 01609 png_warning(png_ptr, "unknown chunk too large to fit in memory"); 01610 skip = length - (png_uint_32)65535L; 01611 length = (png_uint_32)65535L; 01612 } 01613 #endif 01614 png_memcpy((png_charp)png_ptr->unknown_chunk.name, 01615 (png_charp)png_ptr->chunk_name, 01616 png_sizeof(png_ptr->unknown_chunk.name)); 01617 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1] 01618 = '\0'; 01619 01620 png_ptr->unknown_chunk.size = (png_size_t)length; 01621 01622 if (length == 0) 01623 png_ptr->unknown_chunk.data = NULL; 01624 01625 else 01626 { 01627 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, 01628 (png_uint_32)length); 01629 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); 01630 } 01631 01632 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) 01633 if (png_ptr->read_user_chunk_fn != NULL) 01634 { 01635 /* Callback to user unknown chunk handler */ 01636 int ret; 01637 ret = (*(png_ptr->read_user_chunk_fn)) 01638 (png_ptr, &png_ptr->unknown_chunk); 01639 01640 if (ret < 0) 01641 png_chunk_error(png_ptr, "error in user chunk"); 01642 01643 if (ret == 0) 01644 { 01645 if (!(png_ptr->chunk_name[0] & 0x20)) 01646 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 01647 PNG_HANDLE_CHUNK_ALWAYS) 01648 png_chunk_error(png_ptr, "unknown critical chunk"); 01649 png_set_unknown_chunks(png_ptr, info_ptr, 01650 &png_ptr->unknown_chunk, 1); 01651 } 01652 } 01653 01654 else 01655 #endif 01656 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); 01657 png_free(png_ptr, png_ptr->unknown_chunk.data); 01658 png_ptr->unknown_chunk.data = NULL; 01659 } 01660 01661 else 01662 #endif 01663 skip=length; 01664 png_push_crc_skip(png_ptr, skip); 01665 } 01666 01667 void /* PRIVATE */ 01668 png_push_have_info(png_structp png_ptr, png_infop info_ptr) 01669 { 01670 if (png_ptr->info_fn != NULL) 01671 (*(png_ptr->info_fn))(png_ptr, info_ptr); 01672 } 01673 01674 void /* PRIVATE */ 01675 png_push_have_end(png_structp png_ptr, png_infop info_ptr) 01676 { 01677 if (png_ptr->end_fn != NULL) 01678 (*(png_ptr->end_fn))(png_ptr, info_ptr); 01679 } 01680 01681 void /* PRIVATE */ 01682 png_push_have_row(png_structp png_ptr, png_bytep row) 01683 { 01684 if (png_ptr->row_fn != NULL) 01685 (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, 01686 (int)png_ptr->pass); 01687 } 01688 01689 void PNGAPI 01690 png_progressive_combine_row (png_structp png_ptr, 01691 png_bytep old_row, png_bytep new_row) 01692 { 01693 #ifdef PNG_USE_LOCAL_ARRAYS 01694 PNG_CONST int FARDATA png_pass_dsp_mask[7] = 01695 {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; 01696 #endif 01697 if (png_ptr == NULL) 01698 return; 01699 01700 if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ 01701 png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); 01702 } 01703 01704 void PNGAPI 01705 png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, 01706 png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, 01707 png_progressive_end_ptr end_fn) 01708 { 01709 if (png_ptr == NULL) 01710 return; 01711 01712 png_ptr->info_fn = info_fn; 01713 png_ptr->row_fn = row_fn; 01714 png_ptr->end_fn = end_fn; 01715 01716 png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); 01717 } 01718 01719 png_voidp PNGAPI 01720 png_get_progressive_ptr(png_structp png_ptr) 01721 { 01722 if (png_ptr == NULL) 01723 return (NULL); 01724 01725 return png_ptr->io_ptr; 01726 } 01727 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */