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