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