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