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