00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #define PNG_INTERNAL
00015 #include "png.h"
00016
00017 #if defined(PNG_READ_SUPPORTED)
00018
00019 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
00020 # define WIN32_WCE_OLD
00021 #endif
00022
00023 #ifdef PNG_FLOATING_POINT_SUPPORTED
00024 # if defined(WIN32_WCE_OLD)
00025
00026 __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr)
00027 {
00028 double result = 0;
00029 int len;
00030 wchar_t *str, *end;
00031
00032 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
00033 str = (wchar_t *)png_malloc(png_ptr, len * sizeof(wchar_t));
00034 if ( NULL != str )
00035 {
00036 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
00037 result = wcstod(str, &end);
00038 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
00039 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
00040 png_free(png_ptr, str);
00041 }
00042 return result;
00043 }
00044 # else
00045 # define png_strtod(p,a,b) strtod(a,b)
00046 # endif
00047 #endif
00048
00049 png_uint_32 PNGAPI
00050 png_get_uint_31(png_structp png_ptr, png_bytep buf)
00051 {
00052 png_uint_32 i = png_get_uint_32(buf);
00053 if (i > PNG_UINT_31_MAX)
00054 png_error(png_ptr, "PNG unsigned integer out of range.");
00055 return (i);
00056 }
00057 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
00058
00059 png_uint_32 PNGAPI
00060 png_get_uint_32(png_bytep buf)
00061 {
00062 png_uint_32 i = ((png_uint_32)(*buf) << 24) +
00063 ((png_uint_32)(*(buf + 1)) << 16) +
00064 ((png_uint_32)(*(buf + 2)) << 8) +
00065 (png_uint_32)(*(buf + 3));
00066
00067 return (i);
00068 }
00069
00070
00071
00072
00073 png_int_32 PNGAPI
00074 png_get_int_32(png_bytep buf)
00075 {
00076 png_int_32 i = ((png_int_32)(*buf) << 24) +
00077 ((png_int_32)(*(buf + 1)) << 16) +
00078 ((png_int_32)(*(buf + 2)) << 8) +
00079 (png_int_32)(*(buf + 3));
00080
00081 return (i);
00082 }
00083
00084
00085 png_uint_16 PNGAPI
00086 png_get_uint_16(png_bytep buf)
00087 {
00088 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
00089 (png_uint_16)(*(buf + 1)));
00090
00091 return (i);
00092 }
00093 #endif
00094
00095
00096 void
00097 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
00098 {
00099 if(png_ptr == NULL) return;
00100 png_read_data(png_ptr, buf, length);
00101 png_calculate_crc(png_ptr, buf, length);
00102 }
00103
00104
00105
00106
00107
00108 int
00109 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
00110 {
00111 png_size_t i;
00112 png_size_t istop = png_ptr->zbuf_size;
00113
00114 for (i = (png_size_t)skip; i > istop; i -= istop)
00115 {
00116 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
00117 }
00118 if (i)
00119 {
00120 png_crc_read(png_ptr, png_ptr->zbuf, i);
00121 }
00122
00123 if (png_crc_error(png_ptr))
00124 {
00125 if (((png_ptr->chunk_name[0] & 0x20) &&
00126 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
00127 (!(png_ptr->chunk_name[0] & 0x20) &&
00128 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
00129 {
00130 png_chunk_warning(png_ptr, "CRC error");
00131 }
00132 else
00133 {
00134 png_chunk_error(png_ptr, "CRC error");
00135 }
00136 return (1);
00137 }
00138
00139 return (0);
00140 }
00141
00142
00143
00144 int
00145 png_crc_error(png_structp png_ptr)
00146 {
00147 png_byte crc_bytes[4];
00148 png_uint_32 crc;
00149 int need_crc = 1;
00150
00151 if (png_ptr->chunk_name[0] & 0x20)
00152 {
00153 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
00154 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
00155 need_crc = 0;
00156 }
00157 else
00158 {
00159 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
00160 need_crc = 0;
00161 }
00162
00163 png_read_data(png_ptr, crc_bytes, 4);
00164
00165 if (need_crc)
00166 {
00167 crc = png_get_uint_32(crc_bytes);
00168 return ((int)(crc != png_ptr->crc));
00169 }
00170 else
00171 return (0);
00172 }
00173
00174 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
00175 defined(PNG_READ_iCCP_SUPPORTED)
00176
00177
00178
00179
00180
00181
00182
00183 png_charp
00184 png_decompress_chunk(png_structp png_ptr, int comp_type,
00185 png_charp chunkdata, png_size_t chunklength,
00186 png_size_t prefix_size, png_size_t *newlength)
00187 {
00188 static PNG_CONST char msg[] = "Error decoding compressed text";
00189 png_charp text;
00190 png_size_t text_size;
00191
00192 if (comp_type == PNG_COMPRESSION_TYPE_BASE)
00193 {
00194 int ret = Z_OK;
00195 png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
00196 png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
00197 png_ptr->zstream.next_out = png_ptr->zbuf;
00198 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
00199
00200 text_size = 0;
00201 text = NULL;
00202
00203 while (png_ptr->zstream.avail_in)
00204 {
00205 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
00206 if (ret != Z_OK && ret != Z_STREAM_END)
00207 {
00208 if (png_ptr->zstream.msg != NULL)
00209 png_warning(png_ptr, png_ptr->zstream.msg);
00210 else
00211 png_warning(png_ptr, msg);
00212 inflateReset(&png_ptr->zstream);
00213 png_ptr->zstream.avail_in = 0;
00214
00215 if (text == NULL)
00216 {
00217 text_size = prefix_size + png_sizeof(msg) + 1;
00218 text = (png_charp)png_malloc_warn(png_ptr, text_size);
00219 if (text == NULL)
00220 {
00221 png_free(png_ptr,chunkdata);
00222 png_error(png_ptr,"Not enough memory to decompress chunk");
00223 }
00224 png_memcpy(text, chunkdata, prefix_size);
00225 }
00226
00227 text[text_size - 1] = 0x00;
00228
00229
00230 text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
00231 text_size = png_sizeof(msg) > text_size ? text_size :
00232 png_sizeof(msg);
00233 png_memcpy(text + prefix_size, msg, text_size + 1);
00234 break;
00235 }
00236 if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
00237 {
00238 if (text == NULL)
00239 {
00240 text_size = prefix_size +
00241 png_ptr->zbuf_size - png_ptr->zstream.avail_out;
00242 text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
00243 if (text == NULL)
00244 {
00245 png_free(png_ptr,chunkdata);
00246 png_error(png_ptr,"Not enough memory to decompress chunk.");
00247 }
00248 png_memcpy(text + prefix_size, png_ptr->zbuf,
00249 text_size - prefix_size);
00250 png_memcpy(text, chunkdata, prefix_size);
00251 *(text + text_size) = 0x00;
00252 }
00253 else
00254 {
00255 png_charp tmp;
00256
00257 tmp = text;
00258 text = (png_charp)png_malloc_warn(png_ptr,
00259 (png_uint_32)(text_size +
00260 png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
00261 if (text == NULL)
00262 {
00263 png_free(png_ptr, tmp);
00264 png_free(png_ptr, chunkdata);
00265 png_error(png_ptr,"Not enough memory to decompress chunk..");
00266 }
00267 png_memcpy(text, tmp, text_size);
00268 png_free(png_ptr, tmp);
00269 png_memcpy(text + text_size, png_ptr->zbuf,
00270 (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
00271 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
00272 *(text + text_size) = 0x00;
00273 }
00274 if (ret == Z_STREAM_END)
00275 break;
00276 else
00277 {
00278 png_ptr->zstream.next_out = png_ptr->zbuf;
00279 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
00280 }
00281 }
00282 }
00283 if (ret != Z_STREAM_END)
00284 {
00285 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
00286 char umsg[52];
00287
00288 if (ret == Z_BUF_ERROR)
00289 png_snprintf(umsg, 52,
00290 "Buffer error in compressed datastream in %s chunk",
00291 png_ptr->chunk_name);
00292 else if (ret == Z_DATA_ERROR)
00293 png_snprintf(umsg, 52,
00294 "Data error in compressed datastream in %s chunk",
00295 png_ptr->chunk_name);
00296 else
00297 png_snprintf(umsg, 52,
00298 "Incomplete compressed datastream in %s chunk",
00299 png_ptr->chunk_name);
00300 png_warning(png_ptr, umsg);
00301 #else
00302 png_warning(png_ptr,
00303 "Incomplete compressed datastream in chunk other than IDAT");
00304 #endif
00305 text_size=prefix_size;
00306 if (text == NULL)
00307 {
00308 text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
00309 if (text == NULL)
00310 {
00311 png_free(png_ptr, chunkdata);
00312 png_error(png_ptr,"Not enough memory for text.");
00313 }
00314 png_memcpy(text, chunkdata, prefix_size);
00315 }
00316 *(text + text_size) = 0x00;
00317 }
00318
00319 inflateReset(&png_ptr->zstream);
00320 png_ptr->zstream.avail_in = 0;
00321
00322 png_free(png_ptr, chunkdata);
00323 chunkdata = text;
00324 *newlength=text_size;
00325 }
00326 else
00327 {
00328 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
00329 char umsg[50];
00330
00331 png_snprintf(umsg, 50,
00332 "Unknown zTXt compression type %d", comp_type);
00333 png_warning(png_ptr, umsg);
00334 #else
00335 png_warning(png_ptr, "Unknown zTXt compression type");
00336 #endif
00337
00338 *(chunkdata + prefix_size) = 0x00;
00339 *newlength=prefix_size;
00340 }
00341
00342 return chunkdata;
00343 }
00344 #endif
00345
00346
00347 void
00348 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
00349 {
00350 png_byte buf[13];
00351 png_uint_32 width, height;
00352 int bit_depth, color_type, compression_type, filter_type;
00353 int interlace_type;
00354
00355 png_debug(1, "in png_handle_IHDR\n");
00356
00357 if (png_ptr->mode & PNG_HAVE_IHDR)
00358 png_error(png_ptr, "Out of place IHDR");
00359
00360
00361 if (length != 13)
00362 png_error(png_ptr, "Invalid IHDR chunk");
00363
00364 png_ptr->mode |= PNG_HAVE_IHDR;
00365
00366 png_crc_read(png_ptr, buf, 13);
00367 png_crc_finish(png_ptr, 0);
00368
00369 width = png_get_uint_31(png_ptr, buf);
00370 height = png_get_uint_31(png_ptr, buf + 4);
00371 bit_depth = buf[8];
00372 color_type = buf[9];
00373 compression_type = buf[10];
00374 filter_type = buf[11];
00375 interlace_type = buf[12];
00376
00377
00378 png_ptr->width = width;
00379 png_ptr->height = height;
00380 png_ptr->bit_depth = (png_byte)bit_depth;
00381 png_ptr->interlaced = (png_byte)interlace_type;
00382 png_ptr->color_type = (png_byte)color_type;
00383 #if defined(PNG_MNG_FEATURES_SUPPORTED)
00384 png_ptr->filter_type = (png_byte)filter_type;
00385 #endif
00386 png_ptr->compression_type = (png_byte)compression_type;
00387
00388
00389 switch (png_ptr->color_type)
00390 {
00391 case PNG_COLOR_TYPE_GRAY:
00392 case PNG_COLOR_TYPE_PALETTE:
00393 png_ptr->channels = 1;
00394 break;
00395 case PNG_COLOR_TYPE_RGB:
00396 png_ptr->channels = 3;
00397 break;
00398 case PNG_COLOR_TYPE_GRAY_ALPHA:
00399 png_ptr->channels = 2;
00400 break;
00401 case PNG_COLOR_TYPE_RGB_ALPHA:
00402 png_ptr->channels = 4;
00403 break;
00404 }
00405
00406
00407 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
00408 png_ptr->channels);
00409 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
00410 png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
00411 png_debug1(3,"channels = %d\n", png_ptr->channels);
00412 png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
00413 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
00414 color_type, interlace_type, compression_type, filter_type);
00415 }
00416
00417
00418 void
00419 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
00420 {
00421 png_color palette[PNG_MAX_PALETTE_LENGTH];
00422 int num, i;
00423 #ifndef PNG_NO_POINTER_INDEXING
00424 png_colorp pal_ptr;
00425 #endif
00426
00427 png_debug(1, "in png_handle_PLTE\n");
00428
00429 if (!(png_ptr->mode & PNG_HAVE_IHDR))
00430 png_error(png_ptr, "Missing IHDR before PLTE");
00431 else if (png_ptr->mode & PNG_HAVE_IDAT)
00432 {
00433 png_warning(png_ptr, "Invalid PLTE after IDAT");
00434 png_crc_finish(png_ptr, length);
00435 return;
00436 }
00437 else if (png_ptr->mode & PNG_HAVE_PLTE)
00438 png_error(png_ptr, "Duplicate PLTE chunk");
00439
00440 png_ptr->mode |= PNG_HAVE_PLTE;
00441
00442 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
00443 {
00444 png_warning(png_ptr,
00445 "Ignoring PLTE chunk in grayscale PNG");
00446 png_crc_finish(png_ptr, length);
00447 return;
00448 }
00449 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
00450 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
00451 {
00452 png_crc_finish(png_ptr, length);
00453 return;
00454 }
00455 #endif
00456
00457 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
00458 {
00459 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
00460 {
00461 png_warning(png_ptr, "Invalid palette chunk");
00462 png_crc_finish(png_ptr, length);
00463 return;
00464 }
00465 else
00466 {
00467 png_error(png_ptr, "Invalid palette chunk");
00468 }
00469 }
00470
00471 num = (int)length / 3;
00472
00473 #ifndef PNG_NO_POINTER_INDEXING
00474 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
00475 {
00476 png_byte buf[3];
00477
00478 png_crc_read(png_ptr, buf, 3);
00479 pal_ptr->red = buf[0];
00480 pal_ptr->green = buf[1];
00481 pal_ptr->blue = buf[2];
00482 }
00483 #else
00484 for (i = 0; i < num; i++)
00485 {
00486 png_byte buf[3];
00487
00488 png_crc_read(png_ptr, buf, 3);
00489
00490 palette[i].red = buf[0];
00491 palette[i].green = buf[1];
00492 palette[i].blue = buf[2];
00493 }
00494 #endif
00495
00496
00497
00498
00499
00500 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
00501 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
00502 #endif
00503 {
00504 png_crc_finish(png_ptr, 0);
00505 }
00506 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
00507 else if (png_crc_error(png_ptr))
00508 {
00509
00510
00511
00512
00513 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
00514 {
00515 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
00516 {
00517 png_chunk_error(png_ptr, "CRC error");
00518 }
00519 else
00520 {
00521 png_chunk_warning(png_ptr, "CRC error");
00522 return;
00523 }
00524 }
00525
00526 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
00527 {
00528 png_chunk_warning(png_ptr, "CRC error");
00529 }
00530 }
00531 #endif
00532
00533 png_set_PLTE(png_ptr, info_ptr, palette, num);
00534
00535 #if defined(PNG_READ_tRNS_SUPPORTED)
00536 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
00537 {
00538 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
00539 {
00540 if (png_ptr->num_trans > (png_uint_16)num)
00541 {
00542 png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
00543 png_ptr->num_trans = (png_uint_16)num;
00544 }
00545 if (info_ptr->num_trans > (png_uint_16)num)
00546 {
00547 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
00548 info_ptr->num_trans = (png_uint_16)num;
00549 }
00550 }
00551 }
00552 #endif
00553
00554 }
00555
00556 void
00557 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
00558 {
00559 png_debug(1, "in png_handle_IEND\n");
00560
00561 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
00562 {
00563 png_error(png_ptr, "No image in file");
00564 }
00565
00566 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
00567
00568 if (length != 0)
00569 {
00570 png_warning(png_ptr, "Incorrect IEND chunk length");
00571 }
00572 png_crc_finish(png_ptr, length);
00573
00574 info_ptr =info_ptr;
00575 }
00576
00577 #if defined(PNG_READ_gAMA_SUPPORTED)
00578 void
00579 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
00580 {
00581 png_fixed_point igamma;
00582 #ifdef PNG_FLOATING_POINT_SUPPORTED
00583 float file_gamma;
00584 #endif
00585 png_byte buf[4];
00586
00587 png_debug(1, "in png_handle_gAMA\n");
00588
00589 if (!(png_ptr->mode & PNG_HAVE_IHDR))
00590 png_error(png_ptr, "Missing IHDR before gAMA");
00591 else if (png_ptr->mode & PNG_HAVE_IDAT)
00592 {
00593 png_warning(png_ptr, "Invalid gAMA after IDAT");
00594 png_crc_finish(png_ptr, length);
00595 return;
00596 }
00597 else if (png_ptr->mode & PNG_HAVE_PLTE)
00598
00599 png_warning(png_ptr, "Out of place gAMA chunk");
00600
00601 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
00602 #if defined(PNG_READ_sRGB_SUPPORTED)
00603 && !(info_ptr->valid & PNG_INFO_sRGB)
00604 #endif
00605 )
00606 {
00607 png_warning(png_ptr, "Duplicate gAMA chunk");
00608 png_crc_finish(png_ptr, length);
00609 return;
00610 }
00611
00612 if (length != 4)
00613 {
00614 png_warning(png_ptr, "Incorrect gAMA chunk length");
00615 png_crc_finish(png_ptr, length);
00616 return;
00617 }
00618
00619 png_crc_read(png_ptr, buf, 4);
00620 if (png_crc_finish(png_ptr, 0))
00621 return;
00622
00623 igamma = (png_fixed_point)png_get_uint_32(buf);
00624
00625 if (igamma == 0)
00626 {
00627 png_warning(png_ptr,
00628 "Ignoring gAMA chunk with gamma=0");
00629 return;
00630 }
00631
00632 #if defined(PNG_READ_sRGB_SUPPORTED)
00633 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
00634 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
00635 {
00636 png_warning(png_ptr,
00637 "Ignoring incorrect gAMA value when sRGB is also present");
00638 #ifndef PNG_NO_CONSOLE_IO
00639 fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
00640 #endif
00641 return;
00642 }
00643 #endif
00644
00645 #ifdef PNG_FLOATING_POINT_SUPPORTED
00646 file_gamma = (float)igamma / (float)100000.0;
00647 # ifdef PNG_READ_GAMMA_SUPPORTED
00648 png_ptr->gamma = file_gamma;
00649 # endif
00650 png_set_gAMA(png_ptr, info_ptr, file_gamma);
00651 #endif
00652 #ifdef PNG_FIXED_POINT_SUPPORTED
00653 png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
00654 #endif
00655 }
00656 #endif
00657
00658 #if defined(PNG_READ_sBIT_SUPPORTED)
00659 void
00660 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
00661 {
00662 png_size_t truelen;
00663 png_byte buf[4];
00664
00665 png_debug(1, "in png_handle_sBIT\n");
00666
00667 buf[0] = buf[1] = buf[2] = buf[3] = 0;
00668
00669 if (!(png_ptr->mode & PNG_HAVE_IHDR))
00670 png_error(png_ptr, "Missing IHDR before sBIT");
00671 else if (png_ptr->mode & PNG_HAVE_IDAT)
00672 {
00673 png_warning(png_ptr, "Invalid sBIT after IDAT");
00674 png_crc_finish(png_ptr, length);
00675 return;
00676 }
00677 else if (png_ptr->mode & PNG_HAVE_PLTE)
00678 {
00679
00680 png_warning(png_ptr, "Out of place sBIT chunk");
00681 }
00682 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
00683 {
00684 png_warning(png_ptr, "Duplicate sBIT chunk");
00685 png_crc_finish(png_ptr, length);
00686 return;
00687 }
00688
00689 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
00690 truelen = 3;
00691 else
00692 truelen = (png_size_t)png_ptr->channels;
00693
00694 if (length != truelen || length > 4)
00695 {
00696 png_warning(png_ptr, "Incorrect sBIT chunk length");
00697 png_crc_finish(png_ptr, length);
00698 return;
00699 }
00700
00701 png_crc_read(png_ptr, buf, truelen);
00702 if (png_crc_finish(png_ptr, 0))
00703 return;
00704
00705 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
00706 {
00707 png_ptr->sig_bit.red = buf[0];
00708 png_ptr->sig_bit.green = buf[1];
00709 png_ptr->sig_bit.blue = buf[2];
00710 png_ptr->sig_bit.alpha = buf[3];
00711 }
00712 else
00713 {
00714 png_ptr->sig_bit.gray = buf[0];
00715 png_ptr->sig_bit.red = buf[0];
00716 png_ptr->sig_bit.green = buf[0];
00717 png_ptr->sig_bit.blue = buf[0];
00718 png_ptr->sig_bit.alpha = buf[1];
00719 }
00720 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
00721 }
00722 #endif
00723
00724 #if defined(PNG_READ_cHRM_SUPPORTED)
00725 void
00726 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
00727 {
00728 png_byte buf[4];
00729 #ifdef PNG_FLOATING_POINT_SUPPORTED
00730 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
00731 #endif
00732 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
00733 int_y_green, int_x_blue, int_y_blue;
00734
00735 png_uint_32 uint_x, uint_y;
00736
00737 png_debug(1, "in png_handle_cHRM\n");
00738
00739 if (!(png_ptr->mode & PNG_HAVE_IHDR))
00740 png_error(png_ptr, "Missing IHDR before cHRM");
00741 else if (png_ptr->mode & PNG_HAVE_IDAT)
00742 {
00743 png_warning(png_ptr, "Invalid cHRM after IDAT");
00744 png_crc_finish(png_ptr, length);
00745 return;
00746 }
00747 else if (png_ptr->mode & PNG_HAVE_PLTE)
00748
00749 png_warning(png_ptr, "Missing PLTE before cHRM");
00750
00751 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
00752 #if defined(PNG_READ_sRGB_SUPPORTED)
00753 && !(info_ptr->valid & PNG_INFO_sRGB)
00754 #endif
00755 )
00756 {
00757 png_warning(png_ptr, "Duplicate cHRM chunk");
00758 png_crc_finish(png_ptr, length);
00759 return;
00760 }
00761
00762 if (length != 32)
00763 {
00764 png_warning(png_ptr, "Incorrect cHRM chunk length");
00765 png_crc_finish(png_ptr, length);
00766 return;
00767 }
00768
00769 png_crc_read(png_ptr, buf, 4);
00770 uint_x = png_get_uint_32(buf);
00771
00772 png_crc_read(png_ptr, buf, 4);
00773 uint_y = png_get_uint_32(buf);
00774
00775 if (uint_x > 80000L || uint_y > 80000L ||
00776 uint_x + uint_y > 100000L)
00777 {
00778 png_warning(png_ptr, "Invalid cHRM white point");
00779 png_crc_finish(png_ptr, 24);
00780 return;
00781 }
00782 int_x_white = (png_fixed_point)uint_x;
00783 int_y_white = (png_fixed_point)uint_y;
00784
00785 png_crc_read(png_ptr, buf, 4);
00786 uint_x = png_get_uint_32(buf);
00787
00788 png_crc_read(png_ptr, buf, 4);
00789 uint_y = png_get_uint_32(buf);
00790
00791 if (uint_x + uint_y > 100000L)
00792 {
00793 png_warning(png_ptr, "Invalid cHRM red point");
00794 png_crc_finish(png_ptr, 16);
00795 return;
00796 }
00797 int_x_red = (png_fixed_point)uint_x;
00798 int_y_red = (png_fixed_point)uint_y;
00799
00800 png_crc_read(png_ptr, buf, 4);
00801 uint_x = png_get_uint_32(buf);
00802
00803 png_crc_read(png_ptr, buf, 4);
00804 uint_y = png_get_uint_32(buf);
00805
00806 if (uint_x + uint_y > 100000L)
00807 {
00808 png_warning(png_ptr, "Invalid cHRM green point");
00809 png_crc_finish(png_ptr, 8);
00810 return;
00811 }
00812 int_x_green = (png_fixed_point)uint_x;
00813 int_y_green = (png_fixed_point)uint_y;
00814
00815 png_crc_read(png_ptr, buf, 4);
00816 uint_x = png_get_uint_32(buf);
00817
00818 png_crc_read(png_ptr, buf, 4);
00819 uint_y = png_get_uint_32(buf);
00820
00821 if (uint_x + uint_y > 100000L)
00822 {
00823 png_warning(png_ptr, "Invalid cHRM blue point");
00824 png_crc_finish(png_ptr, 0);
00825 return;
00826 }
00827 int_x_blue = (png_fixed_point)uint_x;
00828 int_y_blue = (png_fixed_point)uint_y;
00829
00830 #ifdef PNG_FLOATING_POINT_SUPPORTED
00831 white_x = (float)int_x_white / (float)100000.0;
00832 white_y = (float)int_y_white / (float)100000.0;
00833 red_x = (float)int_x_red / (float)100000.0;
00834 red_y = (float)int_y_red / (float)100000.0;
00835 green_x = (float)int_x_green / (float)100000.0;
00836 green_y = (float)int_y_green / (float)100000.0;
00837 blue_x = (float)int_x_blue / (float)100000.0;
00838 blue_y = (float)int_y_blue / (float)100000.0;
00839 #endif
00840
00841 #if defined(PNG_READ_sRGB_SUPPORTED)
00842 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
00843 {
00844 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
00845 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
00846 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
00847 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
00848 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
00849 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
00850 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
00851 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
00852 {
00853 png_warning(png_ptr,
00854 "Ignoring incorrect cHRM value when sRGB is also present");
00855 #ifndef PNG_NO_CONSOLE_IO
00856 #ifdef PNG_FLOATING_POINT_SUPPORTED
00857 fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
00858 white_x, white_y, red_x, red_y);
00859 fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
00860 green_x, green_y, blue_x, blue_y);
00861 #else
00862 fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
00863 int_x_white, int_y_white, int_x_red, int_y_red);
00864 fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
00865 int_x_green, int_y_green, int_x_blue, int_y_blue);
00866 #endif
00867 #endif
00868 }
00869 png_crc_finish(png_ptr, 0);
00870 return;
00871 }
00872 #endif
00873
00874 #ifdef PNG_FLOATING_POINT_SUPPORTED
00875 png_set_cHRM(png_ptr, info_ptr,
00876 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
00877 #endif
00878 #ifdef PNG_FIXED_POINT_SUPPORTED
00879 png_set_cHRM_fixed(png_ptr, info_ptr,
00880 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
00881 int_y_green, int_x_blue, int_y_blue);
00882 #endif
00883 if (png_crc_finish(png_ptr, 0))
00884 return;
00885 }
00886 #endif
00887
00888 #if defined(PNG_READ_sRGB_SUPPORTED)
00889 void
00890 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
00891 {
00892 int intent;
00893 png_byte buf[1];
00894
00895 png_debug(1, "in png_handle_sRGB\n");
00896
00897 if (!(png_ptr->mode & PNG_HAVE_IHDR))
00898 png_error(png_ptr, "Missing IHDR before sRGB");
00899 else if (png_ptr->mode & PNG_HAVE_IDAT)
00900 {
00901 png_warning(png_ptr, "Invalid sRGB after IDAT");
00902 png_crc_finish(png_ptr, length);
00903 return;
00904 }
00905 else if (png_ptr->mode & PNG_HAVE_PLTE)
00906
00907 png_warning(png_ptr, "Out of place sRGB chunk");
00908
00909 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
00910 {
00911 png_warning(png_ptr, "Duplicate sRGB chunk");
00912 png_crc_finish(png_ptr, length);
00913 return;
00914 }
00915
00916 if (length != 1)
00917 {
00918 png_warning(png_ptr, "Incorrect sRGB chunk length");
00919 png_crc_finish(png_ptr, length);
00920 return;
00921 }
00922
00923 png_crc_read(png_ptr, buf, 1);
00924 if (png_crc_finish(png_ptr, 0))
00925 return;
00926
00927 intent = buf[0];
00928
00929 if (intent >= PNG_sRGB_INTENT_LAST)
00930 {
00931 png_warning(png_ptr, "Unknown sRGB intent");
00932 return;
00933 }
00934
00935 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
00936 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
00937 {
00938 png_fixed_point igamma;
00939 #ifdef PNG_FIXED_POINT_SUPPORTED
00940 igamma=info_ptr->int_gamma;
00941 #else
00942 # ifdef PNG_FLOATING_POINT_SUPPORTED
00943 igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
00944 # endif
00945 #endif
00946 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
00947 {
00948 png_warning(png_ptr,
00949 "Ignoring incorrect gAMA value when sRGB is also present");
00950 #ifndef PNG_NO_CONSOLE_IO
00951 # ifdef PNG_FIXED_POINT_SUPPORTED
00952 fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
00953 # else
00954 # ifdef PNG_FLOATING_POINT_SUPPORTED
00955 fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
00956 # endif
00957 # endif
00958 #endif
00959 }
00960 }
00961 #endif
00962
00963 #ifdef PNG_READ_cHRM_SUPPORTED
00964 #ifdef PNG_FIXED_POINT_SUPPORTED
00965 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
00966 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
00967 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
00968 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
00969 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
00970 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
00971 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
00972 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
00973 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
00974 {
00975 png_warning(png_ptr,
00976 "Ignoring incorrect cHRM value when sRGB is also present");
00977 }
00978 #endif
00979 #endif
00980
00981 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
00982 }
00983 #endif
00984
00985 #if defined(PNG_READ_iCCP_SUPPORTED)
00986 void
00987 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
00988
00989 {
00990 png_charp chunkdata;
00991 png_byte compression_type;
00992 png_bytep pC;
00993 png_charp profile;
00994 png_uint_32 skip = 0;
00995 png_uint_32 profile_size, profile_length;
00996 png_size_t slength, prefix_length, data_length;
00997
00998 png_debug(1, "in png_handle_iCCP\n");
00999
01000 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01001 png_error(png_ptr, "Missing IHDR before iCCP");
01002 else if (png_ptr->mode & PNG_HAVE_IDAT)
01003 {
01004 png_warning(png_ptr, "Invalid iCCP after IDAT");
01005 png_crc_finish(png_ptr, length);
01006 return;
01007 }
01008 else if (png_ptr->mode & PNG_HAVE_PLTE)
01009
01010 png_warning(png_ptr, "Out of place iCCP chunk");
01011
01012 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
01013 {
01014 png_warning(png_ptr, "Duplicate iCCP chunk");
01015 png_crc_finish(png_ptr, length);
01016 return;
01017 }
01018
01019 #ifdef PNG_MAX_MALLOC_64K
01020 if (length > (png_uint_32)65535L)
01021 {
01022 png_warning(png_ptr, "iCCP chunk too large to fit in memory");
01023 skip = length - (png_uint_32)65535L;
01024 length = (png_uint_32)65535L;
01025 }
01026 #endif
01027
01028 chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
01029 slength = (png_size_t)length;
01030 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
01031
01032 if (png_crc_finish(png_ptr, skip))
01033 {
01034 png_free(png_ptr, chunkdata);
01035 return;
01036 }
01037
01038 chunkdata[slength] = 0x00;
01039
01040 for (profile = chunkdata; *profile; profile++)
01041 ;
01042
01043 ++profile;
01044
01045
01046
01047 if ( profile >= chunkdata + slength - 1)
01048 {
01049 png_free(png_ptr, chunkdata);
01050 png_warning(png_ptr, "Malformed iCCP chunk");
01051 return;
01052 }
01053
01054
01055 compression_type = *profile++;
01056 if (compression_type)
01057 {
01058 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
01059 compression_type=0x00;
01060
01061 }
01062
01063 prefix_length = profile - chunkdata;
01064 chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
01065 slength, prefix_length, &data_length);
01066
01067 profile_length = data_length - prefix_length;
01068
01069 if ( prefix_length > data_length || profile_length < 4)
01070 {
01071 png_free(png_ptr, chunkdata);
01072 png_warning(png_ptr, "Profile size field missing from iCCP chunk");
01073 return;
01074 }
01075
01076
01077 pC = (png_bytep)(chunkdata+prefix_length);
01078 profile_size = ((*(pC ))<<24) |
01079 ((*(pC+1))<<16) |
01080 ((*(pC+2))<< 8) |
01081 ((*(pC+3)) );
01082
01083 if(profile_size < profile_length)
01084 profile_length = profile_size;
01085
01086 if(profile_size > profile_length)
01087 {
01088 png_free(png_ptr, chunkdata);
01089 png_warning(png_ptr, "Ignoring truncated iCCP profile.");
01090 return;
01091 }
01092
01093 png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
01094 chunkdata + prefix_length, profile_length);
01095 png_free(png_ptr, chunkdata);
01096 }
01097 #endif
01098
01099 #if defined(PNG_READ_sPLT_SUPPORTED)
01100 void
01101 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01102
01103 {
01104 png_bytep chunkdata;
01105 png_bytep entry_start;
01106 png_sPLT_t new_palette;
01107 #ifdef PNG_NO_POINTER_INDEXING
01108 png_sPLT_entryp pp;
01109 #endif
01110 int data_length, entry_size, i;
01111 png_uint_32 skip = 0;
01112 png_size_t slength;
01113
01114 png_debug(1, "in png_handle_sPLT\n");
01115
01116 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01117 png_error(png_ptr, "Missing IHDR before sPLT");
01118 else if (png_ptr->mode & PNG_HAVE_IDAT)
01119 {
01120 png_warning(png_ptr, "Invalid sPLT after IDAT");
01121 png_crc_finish(png_ptr, length);
01122 return;
01123 }
01124
01125 #ifdef PNG_MAX_MALLOC_64K
01126 if (length > (png_uint_32)65535L)
01127 {
01128 png_warning(png_ptr, "sPLT chunk too large to fit in memory");
01129 skip = length - (png_uint_32)65535L;
01130 length = (png_uint_32)65535L;
01131 }
01132 #endif
01133
01134 chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
01135 slength = (png_size_t)length;
01136 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
01137
01138 if (png_crc_finish(png_ptr, skip))
01139 {
01140 png_free(png_ptr, chunkdata);
01141 return;
01142 }
01143
01144 chunkdata[slength] = 0x00;
01145
01146 for (entry_start = chunkdata; *entry_start; entry_start++)
01147 ;
01148 ++entry_start;
01149
01150
01151 if (entry_start > chunkdata + slength - 2)
01152 {
01153 png_free(png_ptr, chunkdata);
01154 png_warning(png_ptr, "malformed sPLT chunk");
01155 return;
01156 }
01157
01158 new_palette.depth = *entry_start++;
01159 entry_size = (new_palette.depth == 8 ? 6 : 10);
01160 data_length = (slength - (entry_start - chunkdata));
01161
01162
01163 if (data_length % entry_size)
01164 {
01165 png_free(png_ptr, chunkdata);
01166 png_warning(png_ptr, "sPLT chunk has bad length");
01167 return;
01168 }
01169
01170 new_palette.nentries = (png_int_32) ( data_length / entry_size);
01171 if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
01172 png_sizeof(png_sPLT_entry)))
01173 {
01174 png_warning(png_ptr, "sPLT chunk too long");
01175 return;
01176 }
01177 new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
01178 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
01179 if (new_palette.entries == NULL)
01180 {
01181 png_warning(png_ptr, "sPLT chunk requires too much memory");
01182 return;
01183 }
01184
01185 #ifndef PNG_NO_POINTER_INDEXING
01186 for (i = 0; i < new_palette.nentries; i++)
01187 {
01188 png_sPLT_entryp pp = new_palette.entries + i;
01189
01190 if (new_palette.depth == 8)
01191 {
01192 pp->red = *entry_start++;
01193 pp->green = *entry_start++;
01194 pp->blue = *entry_start++;
01195 pp->alpha = *entry_start++;
01196 }
01197 else
01198 {
01199 pp->red = png_get_uint_16(entry_start); entry_start += 2;
01200 pp->green = png_get_uint_16(entry_start); entry_start += 2;
01201 pp->blue = png_get_uint_16(entry_start); entry_start += 2;
01202 pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
01203 }
01204 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
01205 }
01206 #else
01207 pp = new_palette.entries;
01208 for (i = 0; i < new_palette.nentries; i++)
01209 {
01210
01211 if (new_palette.depth == 8)
01212 {
01213 pp[i].red = *entry_start++;
01214 pp[i].green = *entry_start++;
01215 pp[i].blue = *entry_start++;
01216 pp[i].alpha = *entry_start++;
01217 }
01218 else
01219 {
01220 pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
01221 pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
01222 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
01223 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
01224 }
01225 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
01226 }
01227 #endif
01228
01229
01230 new_palette.name = (png_charp)chunkdata;
01231
01232 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
01233
01234 png_free(png_ptr, chunkdata);
01235 png_free(png_ptr, new_palette.entries);
01236 }
01237 #endif
01238
01239 #if defined(PNG_READ_tRNS_SUPPORTED)
01240 void
01241 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01242 {
01243 png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
01244 int bit_mask;
01245
01246 png_debug(1, "in png_handle_tRNS\n");
01247
01248
01249
01250
01251 bit_mask = (1 << png_ptr->bit_depth) - 1;
01252
01253 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01254 png_error(png_ptr, "Missing IHDR before tRNS");
01255 else if (png_ptr->mode & PNG_HAVE_IDAT)
01256 {
01257 png_warning(png_ptr, "Invalid tRNS after IDAT");
01258 png_crc_finish(png_ptr, length);
01259 return;
01260 }
01261 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
01262 {
01263 png_warning(png_ptr, "Duplicate tRNS chunk");
01264 png_crc_finish(png_ptr, length);
01265 return;
01266 }
01267
01268 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
01269 {
01270 png_byte buf[2];
01271
01272 if (length != 2)
01273 {
01274 png_warning(png_ptr, "Incorrect tRNS chunk length");
01275 png_crc_finish(png_ptr, length);
01276 return;
01277 }
01278
01279 png_crc_read(png_ptr, buf, 2);
01280 png_ptr->num_trans = 1;
01281 png_ptr->trans_values.gray = png_get_uint_16(buf) & bit_mask;
01282 }
01283 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
01284 {
01285 png_byte buf[6];
01286
01287 if (length != 6)
01288 {
01289 png_warning(png_ptr, "Incorrect tRNS chunk length");
01290 png_crc_finish(png_ptr, length);
01291 return;
01292 }
01293 png_crc_read(png_ptr, buf, (png_size_t)length);
01294 png_ptr->num_trans = 1;
01295 png_ptr->trans_values.red = png_get_uint_16(buf) & bit_mask;
01296 png_ptr->trans_values.green = png_get_uint_16(buf + 2) & bit_mask;
01297 png_ptr->trans_values.blue = png_get_uint_16(buf + 4) & bit_mask;
01298 }
01299 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
01300 {
01301 if (!(png_ptr->mode & PNG_HAVE_PLTE))
01302 {
01303
01304 png_warning(png_ptr, "Missing PLTE before tRNS");
01305 }
01306 if (length > (png_uint_32)png_ptr->num_palette ||
01307 length > PNG_MAX_PALETTE_LENGTH)
01308 {
01309 png_warning(png_ptr, "Incorrect tRNS chunk length");
01310 png_crc_finish(png_ptr, length);
01311 return;
01312 }
01313 if (length == 0)
01314 {
01315 png_warning(png_ptr, "Zero length tRNS chunk");
01316 png_crc_finish(png_ptr, length);
01317 return;
01318 }
01319 png_crc_read(png_ptr, readbuf, (png_size_t)length);
01320 png_ptr->num_trans = (png_uint_16)length;
01321 }
01322 else
01323 {
01324 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
01325 png_crc_finish(png_ptr, length);
01326 return;
01327 }
01328
01329 if (png_crc_finish(png_ptr, 0))
01330 {
01331 png_ptr->num_trans = 0;
01332 return;
01333 }
01334
01335 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
01336 &(png_ptr->trans_values));
01337 }
01338 #endif
01339
01340 #if defined(PNG_READ_bKGD_SUPPORTED)
01341 void
01342 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01343 {
01344 png_size_t truelen;
01345 png_byte buf[6];
01346
01347 png_debug(1, "in png_handle_bKGD\n");
01348
01349 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01350 png_error(png_ptr, "Missing IHDR before bKGD");
01351 else if (png_ptr->mode & PNG_HAVE_IDAT)
01352 {
01353 png_warning(png_ptr, "Invalid bKGD after IDAT");
01354 png_crc_finish(png_ptr, length);
01355 return;
01356 }
01357 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
01358 !(png_ptr->mode & PNG_HAVE_PLTE))
01359 {
01360 png_warning(png_ptr, "Missing PLTE before bKGD");
01361 png_crc_finish(png_ptr, length);
01362 return;
01363 }
01364 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
01365 {
01366 png_warning(png_ptr, "Duplicate bKGD chunk");
01367 png_crc_finish(png_ptr, length);
01368 return;
01369 }
01370
01371 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
01372 truelen = 1;
01373 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
01374 truelen = 6;
01375 else
01376 truelen = 2;
01377
01378 if (length != truelen)
01379 {
01380 png_warning(png_ptr, "Incorrect bKGD chunk length");
01381 png_crc_finish(png_ptr, length);
01382 return;
01383 }
01384
01385 png_crc_read(png_ptr, buf, truelen);
01386 if (png_crc_finish(png_ptr, 0))
01387 return;
01388
01389
01390
01391
01392
01393 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
01394 {
01395 png_ptr->background.index = buf[0];
01396 if(info_ptr->num_palette)
01397 {
01398 if(buf[0] > info_ptr->num_palette)
01399 {
01400 png_warning(png_ptr, "Incorrect bKGD chunk index value");
01401 return;
01402 }
01403 png_ptr->background.red =
01404 (png_uint_16)png_ptr->palette[buf[0]].red;
01405 png_ptr->background.green =
01406 (png_uint_16)png_ptr->palette[buf[0]].green;
01407 png_ptr->background.blue =
01408 (png_uint_16)png_ptr->palette[buf[0]].blue;
01409 }
01410 }
01411 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
01412 {
01413 png_ptr->background.red =
01414 png_ptr->background.green =
01415 png_ptr->background.blue =
01416 png_ptr->background.gray = png_get_uint_16(buf);
01417 }
01418 else
01419 {
01420 png_ptr->background.red = png_get_uint_16(buf);
01421 png_ptr->background.green = png_get_uint_16(buf + 2);
01422 png_ptr->background.blue = png_get_uint_16(buf + 4);
01423 }
01424
01425 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
01426 }
01427 #endif
01428
01429 #if defined(PNG_READ_hIST_SUPPORTED)
01430 void
01431 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01432 {
01433 unsigned int num, i;
01434 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
01435
01436 png_debug(1, "in png_handle_hIST\n");
01437
01438 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01439 png_error(png_ptr, "Missing IHDR before hIST");
01440 else if (png_ptr->mode & PNG_HAVE_IDAT)
01441 {
01442 png_warning(png_ptr, "Invalid hIST after IDAT");
01443 png_crc_finish(png_ptr, length);
01444 return;
01445 }
01446 else if (!(png_ptr->mode & PNG_HAVE_PLTE))
01447 {
01448 png_warning(png_ptr, "Missing PLTE before hIST");
01449 png_crc_finish(png_ptr, length);
01450 return;
01451 }
01452 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
01453 {
01454 png_warning(png_ptr, "Duplicate hIST chunk");
01455 png_crc_finish(png_ptr, length);
01456 return;
01457 }
01458
01459 num = length / 2 ;
01460 if (num != (unsigned int) png_ptr->num_palette || num >
01461 (unsigned int) PNG_MAX_PALETTE_LENGTH)
01462 {
01463 png_warning(png_ptr, "Incorrect hIST chunk length");
01464 png_crc_finish(png_ptr, length);
01465 return;
01466 }
01467
01468 for (i = 0; i < num; i++)
01469 {
01470 png_byte buf[2];
01471
01472 png_crc_read(png_ptr, buf, 2);
01473 readbuf[i] = png_get_uint_16(buf);
01474 }
01475
01476 if (png_crc_finish(png_ptr, 0))
01477 return;
01478
01479 png_set_hIST(png_ptr, info_ptr, readbuf);
01480 }
01481 #endif
01482
01483 #if defined(PNG_READ_pHYs_SUPPORTED)
01484 void
01485 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01486 {
01487 png_byte buf[9];
01488 png_uint_32 res_x, res_y;
01489 int unit_type;
01490
01491 png_debug(1, "in png_handle_pHYs\n");
01492
01493 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01494 png_error(png_ptr, "Missing IHDR before pHYs");
01495 else if (png_ptr->mode & PNG_HAVE_IDAT)
01496 {
01497 png_warning(png_ptr, "Invalid pHYs after IDAT");
01498 png_crc_finish(png_ptr, length);
01499 return;
01500 }
01501 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
01502 {
01503 png_warning(png_ptr, "Duplicate pHYs chunk");
01504 png_crc_finish(png_ptr, length);
01505 return;
01506 }
01507
01508 if (length != 9)
01509 {
01510 png_warning(png_ptr, "Incorrect pHYs chunk length");
01511 png_crc_finish(png_ptr, length);
01512 return;
01513 }
01514
01515 png_crc_read(png_ptr, buf, 9);
01516 if (png_crc_finish(png_ptr, 0))
01517 return;
01518
01519 res_x = png_get_uint_32(buf);
01520 res_y = png_get_uint_32(buf + 4);
01521 unit_type = buf[8];
01522 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
01523 }
01524 #endif
01525
01526 #if defined(PNG_READ_oFFs_SUPPORTED)
01527 void
01528 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01529 {
01530 png_byte buf[9];
01531 png_int_32 offset_x, offset_y;
01532 int unit_type;
01533
01534 png_debug(1, "in png_handle_oFFs\n");
01535
01536 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01537 png_error(png_ptr, "Missing IHDR before oFFs");
01538 else if (png_ptr->mode & PNG_HAVE_IDAT)
01539 {
01540 png_warning(png_ptr, "Invalid oFFs after IDAT");
01541 png_crc_finish(png_ptr, length);
01542 return;
01543 }
01544 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
01545 {
01546 png_warning(png_ptr, "Duplicate oFFs chunk");
01547 png_crc_finish(png_ptr, length);
01548 return;
01549 }
01550
01551 if (length != 9)
01552 {
01553 png_warning(png_ptr, "Incorrect oFFs chunk length");
01554 png_crc_finish(png_ptr, length);
01555 return;
01556 }
01557
01558 png_crc_read(png_ptr, buf, 9);
01559 if (png_crc_finish(png_ptr, 0))
01560 return;
01561
01562 offset_x = png_get_int_32(buf);
01563 offset_y = png_get_int_32(buf + 4);
01564 unit_type = buf[8];
01565 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
01566 }
01567 #endif
01568
01569 #if defined(PNG_READ_pCAL_SUPPORTED)
01570
01571 void
01572 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01573 {
01574 png_charp purpose;
01575 png_int_32 X0, X1;
01576 png_byte type, nparams;
01577 png_charp buf, units, endptr;
01578 png_charpp params;
01579 png_size_t slength;
01580 int i;
01581
01582 png_debug(1, "in png_handle_pCAL\n");
01583
01584 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01585 png_error(png_ptr, "Missing IHDR before pCAL");
01586 else if (png_ptr->mode & PNG_HAVE_IDAT)
01587 {
01588 png_warning(png_ptr, "Invalid pCAL after IDAT");
01589 png_crc_finish(png_ptr, length);
01590 return;
01591 }
01592 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
01593 {
01594 png_warning(png_ptr, "Duplicate pCAL chunk");
01595 png_crc_finish(png_ptr, length);
01596 return;
01597 }
01598
01599 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
01600 length + 1);
01601 purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
01602 if (purpose == NULL)
01603 {
01604 png_warning(png_ptr, "No memory for pCAL purpose.");
01605 return;
01606 }
01607 slength = (png_size_t)length;
01608 png_crc_read(png_ptr, (png_bytep)purpose, slength);
01609
01610 if (png_crc_finish(png_ptr, 0))
01611 {
01612 png_free(png_ptr, purpose);
01613 return;
01614 }
01615
01616 purpose[slength] = 0x00;
01617
01618 png_debug(3, "Finding end of pCAL purpose string\n");
01619 for (buf = purpose; *buf; buf++)
01620 ;
01621
01622 endptr = purpose + slength;
01623
01624
01625
01626 if (endptr <= buf + 12)
01627 {
01628 png_warning(png_ptr, "Invalid pCAL data");
01629 png_free(png_ptr, purpose);
01630 return;
01631 }
01632
01633 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
01634 X0 = png_get_int_32((png_bytep)buf+1);
01635 X1 = png_get_int_32((png_bytep)buf+5);
01636 type = buf[9];
01637 nparams = buf[10];
01638 units = buf + 11;
01639
01640 png_debug(3, "Checking pCAL equation type and number of parameters\n");
01641
01642
01643 if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
01644 (type == PNG_EQUATION_BASE_E && nparams != 3) ||
01645 (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
01646 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
01647 {
01648 png_warning(png_ptr, "Invalid pCAL parameters for equation type");
01649 png_free(png_ptr, purpose);
01650 return;
01651 }
01652 else if (type >= PNG_EQUATION_LAST)
01653 {
01654 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
01655 }
01656
01657 for (buf = units; *buf; buf++)
01658 ;
01659
01660 png_debug(3, "Allocating pCAL parameters array\n");
01661 params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
01662 *png_sizeof(png_charp))) ;
01663 if (params == NULL)
01664 {
01665 png_free(png_ptr, purpose);
01666 png_warning(png_ptr, "No memory for pCAL params.");
01667 return;
01668 }
01669
01670
01671 for (i = 0; i < (int)nparams; i++)
01672 {
01673 buf++;
01674
01675 png_debug1(3, "Reading pCAL parameter %d\n", i);
01676 for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
01677 ;
01678
01679
01680 if (buf > endptr)
01681 {
01682 png_warning(png_ptr, "Invalid pCAL data");
01683 png_free(png_ptr, purpose);
01684 png_free(png_ptr, params);
01685 return;
01686 }
01687 }
01688
01689 png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
01690 units, params);
01691
01692 png_free(png_ptr, purpose);
01693 png_free(png_ptr, params);
01694 }
01695 #endif
01696
01697 #if defined(PNG_READ_sCAL_SUPPORTED)
01698
01699 void
01700 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01701 {
01702 png_charp buffer, ep;
01703 #ifdef PNG_FLOATING_POINT_SUPPORTED
01704 double width, height;
01705 png_charp vp;
01706 #else
01707 #ifdef PNG_FIXED_POINT_SUPPORTED
01708 png_charp swidth, sheight;
01709 #endif
01710 #endif
01711 png_size_t slength;
01712
01713 png_debug(1, "in png_handle_sCAL\n");
01714
01715 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01716 png_error(png_ptr, "Missing IHDR before sCAL");
01717 else if (png_ptr->mode & PNG_HAVE_IDAT)
01718 {
01719 png_warning(png_ptr, "Invalid sCAL after IDAT");
01720 png_crc_finish(png_ptr, length);
01721 return;
01722 }
01723 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
01724 {
01725 png_warning(png_ptr, "Duplicate sCAL chunk");
01726 png_crc_finish(png_ptr, length);
01727 return;
01728 }
01729
01730 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
01731 length + 1);
01732 buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
01733 if (buffer == NULL)
01734 {
01735 png_warning(png_ptr, "Out of memory while processing sCAL chunk");
01736 return;
01737 }
01738 slength = (png_size_t)length;
01739 png_crc_read(png_ptr, (png_bytep)buffer, slength);
01740
01741 if (png_crc_finish(png_ptr, 0))
01742 {
01743 png_free(png_ptr, buffer);
01744 return;
01745 }
01746
01747 buffer[slength] = 0x00;
01748
01749 ep = buffer + 1;
01750
01751 #ifdef PNG_FLOATING_POINT_SUPPORTED
01752 width = png_strtod(png_ptr, ep, &vp);
01753 if (*vp)
01754 {
01755 png_warning(png_ptr, "malformed width string in sCAL chunk");
01756 return;
01757 }
01758 #else
01759 #ifdef PNG_FIXED_POINT_SUPPORTED
01760 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
01761 if (swidth == NULL)
01762 {
01763 png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
01764 return;
01765 }
01766 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
01767 #endif
01768 #endif
01769
01770 for (ep = buffer; *ep; ep++)
01771 ;
01772 ep++;
01773
01774 if (buffer + slength < ep)
01775 {
01776 png_warning(png_ptr, "Truncated sCAL chunk");
01777 #if defined(PNG_FIXED_POINT_SUPPORTED) && \
01778 !defined(PNG_FLOATING_POINT_SUPPORTED)
01779 png_free(png_ptr, swidth);
01780 #endif
01781 png_free(png_ptr, buffer);
01782 return;
01783 }
01784
01785 #ifdef PNG_FLOATING_POINT_SUPPORTED
01786 height = png_strtod(png_ptr, ep, &vp);
01787 if (*vp)
01788 {
01789 png_warning(png_ptr, "malformed height string in sCAL chunk");
01790 return;
01791 }
01792 #else
01793 #ifdef PNG_FIXED_POINT_SUPPORTED
01794 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
01795 if (swidth == NULL)
01796 {
01797 png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
01798 return;
01799 }
01800 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
01801 #endif
01802 #endif
01803
01804 if (buffer + slength < ep
01805 #ifdef PNG_FLOATING_POINT_SUPPORTED
01806 || width <= 0. || height <= 0.
01807 #endif
01808 )
01809 {
01810 png_warning(png_ptr, "Invalid sCAL data");
01811 png_free(png_ptr, buffer);
01812 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
01813 png_free(png_ptr, swidth);
01814 png_free(png_ptr, sheight);
01815 #endif
01816 return;
01817 }
01818
01819
01820 #ifdef PNG_FLOATING_POINT_SUPPORTED
01821 png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
01822 #else
01823 #ifdef PNG_FIXED_POINT_SUPPORTED
01824 png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
01825 #endif
01826 #endif
01827
01828 png_free(png_ptr, buffer);
01829 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
01830 png_free(png_ptr, swidth);
01831 png_free(png_ptr, sheight);
01832 #endif
01833 }
01834 #endif
01835
01836 #if defined(PNG_READ_tIME_SUPPORTED)
01837 void
01838 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01839 {
01840 png_byte buf[7];
01841 png_time mod_time;
01842
01843 png_debug(1, "in png_handle_tIME\n");
01844
01845 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01846 png_error(png_ptr, "Out of place tIME chunk");
01847 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
01848 {
01849 png_warning(png_ptr, "Duplicate tIME chunk");
01850 png_crc_finish(png_ptr, length);
01851 return;
01852 }
01853
01854 if (png_ptr->mode & PNG_HAVE_IDAT)
01855 png_ptr->mode |= PNG_AFTER_IDAT;
01856
01857 if (length != 7)
01858 {
01859 png_warning(png_ptr, "Incorrect tIME chunk length");
01860 png_crc_finish(png_ptr, length);
01861 return;
01862 }
01863
01864 png_crc_read(png_ptr, buf, 7);
01865 if (png_crc_finish(png_ptr, 0))
01866 return;
01867
01868 mod_time.second = buf[6];
01869 mod_time.minute = buf[5];
01870 mod_time.hour = buf[4];
01871 mod_time.day = buf[3];
01872 mod_time.month = buf[2];
01873 mod_time.year = png_get_uint_16(buf);
01874
01875 png_set_tIME(png_ptr, info_ptr, &mod_time);
01876 }
01877 #endif
01878
01879 #if defined(PNG_READ_tEXt_SUPPORTED)
01880
01881 void
01882 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01883 {
01884 png_textp text_ptr;
01885 png_charp key;
01886 png_charp text;
01887 png_uint_32 skip = 0;
01888 png_size_t slength;
01889 int ret;
01890
01891 png_debug(1, "in png_handle_tEXt\n");
01892
01893 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01894 png_error(png_ptr, "Missing IHDR before tEXt");
01895
01896 if (png_ptr->mode & PNG_HAVE_IDAT)
01897 png_ptr->mode |= PNG_AFTER_IDAT;
01898
01899 #ifdef PNG_MAX_MALLOC_64K
01900 if (length > (png_uint_32)65535L)
01901 {
01902 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
01903 skip = length - (png_uint_32)65535L;
01904 length = (png_uint_32)65535L;
01905 }
01906 #endif
01907
01908 key = (png_charp)png_malloc_warn(png_ptr, length + 1);
01909 if (key == NULL)
01910 {
01911 png_warning(png_ptr, "No memory to process text chunk.");
01912 return;
01913 }
01914 slength = (png_size_t)length;
01915 png_crc_read(png_ptr, (png_bytep)key, slength);
01916
01917 if (png_crc_finish(png_ptr, skip))
01918 {
01919 png_free(png_ptr, key);
01920 return;
01921 }
01922
01923 key[slength] = 0x00;
01924
01925 for (text = key; *text; text++)
01926 ;
01927
01928 if (text != key + slength)
01929 text++;
01930
01931 text_ptr = (png_textp)png_malloc_warn(png_ptr,
01932 (png_uint_32)png_sizeof(png_text));
01933 if (text_ptr == NULL)
01934 {
01935 png_warning(png_ptr, "Not enough memory to process text chunk.");
01936 png_free(png_ptr, key);
01937 return;
01938 }
01939 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
01940 text_ptr->key = key;
01941 #ifdef PNG_iTXt_SUPPORTED
01942 text_ptr->lang = NULL;
01943 text_ptr->lang_key = NULL;
01944 text_ptr->itxt_length = 0;
01945 #endif
01946 text_ptr->text = text;
01947 text_ptr->text_length = png_strlen(text);
01948
01949 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
01950
01951 png_free(png_ptr, key);
01952 png_free(png_ptr, text_ptr);
01953 if (ret)
01954 png_warning(png_ptr, "Insufficient memory to process text chunk.");
01955 }
01956 #endif
01957
01958 #if defined(PNG_READ_zTXt_SUPPORTED)
01959
01960 void
01961 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
01962 {
01963 png_textp text_ptr;
01964 png_charp chunkdata;
01965 png_charp text;
01966 int comp_type;
01967 int ret;
01968 png_size_t slength, prefix_len, data_len;
01969
01970 png_debug(1, "in png_handle_zTXt\n");
01971 if (!(png_ptr->mode & PNG_HAVE_IHDR))
01972 png_error(png_ptr, "Missing IHDR before zTXt");
01973
01974 if (png_ptr->mode & PNG_HAVE_IDAT)
01975 png_ptr->mode |= PNG_AFTER_IDAT;
01976
01977 #ifdef PNG_MAX_MALLOC_64K
01978
01979
01980 if (length > (png_uint_32)65535L)
01981 {
01982 png_warning(png_ptr,"zTXt chunk too large to fit in memory");
01983 png_crc_finish(png_ptr, length);
01984 return;
01985 }
01986 #endif
01987
01988 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
01989 if (chunkdata == NULL)
01990 {
01991 png_warning(png_ptr,"Out of memory processing zTXt chunk.");
01992 return;
01993 }
01994 slength = (png_size_t)length;
01995 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
01996 if (png_crc_finish(png_ptr, 0))
01997 {
01998 png_free(png_ptr, chunkdata);
01999 return;
02000 }
02001
02002 chunkdata[slength] = 0x00;
02003
02004 for (text = chunkdata; *text; text++)
02005 ;
02006
02007
02008 if (text >= chunkdata + slength - 2)
02009 {
02010 png_warning(png_ptr, "Truncated zTXt chunk");
02011 png_free(png_ptr, chunkdata);
02012 return;
02013 }
02014 else
02015 {
02016 comp_type = *(++text);
02017 if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
02018 {
02019 png_warning(png_ptr, "Unknown compression type in zTXt chunk");
02020 comp_type = PNG_TEXT_COMPRESSION_zTXt;
02021 }
02022 text++;
02023 }
02024 prefix_len = text - chunkdata;
02025
02026 chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
02027 (png_size_t)length, prefix_len, &data_len);
02028
02029 text_ptr = (png_textp)png_malloc_warn(png_ptr,
02030 (png_uint_32)png_sizeof(png_text));
02031 if (text_ptr == NULL)
02032 {
02033 png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
02034 png_free(png_ptr, chunkdata);
02035 return;
02036 }
02037 text_ptr->compression = comp_type;
02038 text_ptr->key = chunkdata;
02039 #ifdef PNG_iTXt_SUPPORTED
02040 text_ptr->lang = NULL;
02041 text_ptr->lang_key = NULL;
02042 text_ptr->itxt_length = 0;
02043 #endif
02044 text_ptr->text = chunkdata + prefix_len;
02045 text_ptr->text_length = data_len;
02046
02047 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
02048
02049 png_free(png_ptr, text_ptr);
02050 png_free(png_ptr, chunkdata);
02051 if (ret)
02052 png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
02053 }
02054 #endif
02055
02056 #if defined(PNG_READ_iTXt_SUPPORTED)
02057
02058 void
02059 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
02060 {
02061 png_textp text_ptr;
02062 png_charp chunkdata;
02063 png_charp key, lang, text, lang_key;
02064 int comp_flag;
02065 int comp_type = 0;
02066 int ret;
02067 png_size_t slength, prefix_len, data_len;
02068
02069 png_debug(1, "in png_handle_iTXt\n");
02070
02071 if (!(png_ptr->mode & PNG_HAVE_IHDR))
02072 png_error(png_ptr, "Missing IHDR before iTXt");
02073
02074 if (png_ptr->mode & PNG_HAVE_IDAT)
02075 png_ptr->mode |= PNG_AFTER_IDAT;
02076
02077 #ifdef PNG_MAX_MALLOC_64K
02078
02079
02080 if (length > (png_uint_32)65535L)
02081 {
02082 png_warning(png_ptr,"iTXt chunk too large to fit in memory");
02083 png_crc_finish(png_ptr, length);
02084 return;
02085 }
02086 #endif
02087
02088 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
02089 if (chunkdata == NULL)
02090 {
02091 png_warning(png_ptr, "No memory to process iTXt chunk.");
02092 return;
02093 }
02094 slength = (png_size_t)length;
02095 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
02096 if (png_crc_finish(png_ptr, 0))
02097 {
02098 png_free(png_ptr, chunkdata);
02099 return;
02100 }
02101
02102 chunkdata[slength] = 0x00;
02103
02104 for (lang = chunkdata; *lang; lang++)
02105 ;
02106 lang++;
02107
02108
02109
02110
02111
02112 if (lang >= chunkdata + slength - 3)
02113 {
02114 png_warning(png_ptr, "Truncated iTXt chunk");
02115 png_free(png_ptr, chunkdata);
02116 return;
02117 }
02118 else
02119 {
02120 comp_flag = *lang++;
02121 comp_type = *lang++;
02122 }
02123
02124 for (lang_key = lang; *lang_key; lang_key++)
02125 ;
02126 lang_key++;
02127
02128 if (lang_key >= chunkdata + slength)
02129 {
02130 png_warning(png_ptr, "Truncated iTXt chunk");
02131 png_free(png_ptr, chunkdata);
02132 return;
02133 }
02134
02135 for (text = lang_key; *text; text++)
02136 ;
02137 text++;
02138 if (text >= chunkdata + slength)
02139 {
02140 png_warning(png_ptr, "Malformed iTXt chunk");
02141 png_free(png_ptr, chunkdata);
02142 return;
02143 }
02144
02145 prefix_len = text - chunkdata;
02146
02147 key=chunkdata;
02148 if (comp_flag)
02149 chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
02150 (size_t)length, prefix_len, &data_len);
02151 else
02152 data_len=png_strlen(chunkdata + prefix_len);
02153 text_ptr = (png_textp)png_malloc_warn(png_ptr,
02154 (png_uint_32)png_sizeof(png_text));
02155 if (text_ptr == NULL)
02156 {
02157 png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
02158 png_free(png_ptr, chunkdata);
02159 return;
02160 }
02161 text_ptr->compression = (int)comp_flag + 1;
02162 text_ptr->lang_key = chunkdata+(lang_key-key);
02163 text_ptr->lang = chunkdata+(lang-key);
02164 text_ptr->itxt_length = data_len;
02165 text_ptr->text_length = 0;
02166 text_ptr->key = chunkdata;
02167 text_ptr->text = chunkdata + prefix_len;
02168
02169 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
02170
02171 png_free(png_ptr, text_ptr);
02172 png_free(png_ptr, chunkdata);
02173 if (ret)
02174 png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
02175 }
02176 #endif
02177
02178
02179
02180
02181
02182
02183 void
02184 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
02185 {
02186 png_uint_32 skip = 0;
02187
02188 png_debug(1, "in png_handle_unknown\n");
02189
02190 if (png_ptr->mode & PNG_HAVE_IDAT)
02191 {
02192 #ifdef PNG_USE_LOCAL_ARRAYS
02193 PNG_CONST PNG_IDAT;
02194 #endif
02195 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
02196 png_ptr->mode |= PNG_AFTER_IDAT;
02197 }
02198
02199 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
02200
02201 if (!(png_ptr->chunk_name[0] & 0x20))
02202 {
02203 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
02204 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
02205 PNG_HANDLE_CHUNK_ALWAYS
02206 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
02207 && png_ptr->read_user_chunk_fn == NULL
02208 #endif
02209 )
02210 #endif
02211 png_chunk_error(png_ptr, "unknown critical chunk");
02212 }
02213
02214 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
02215 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) ||
02216 (png_ptr->read_user_chunk_fn != NULL))
02217 {
02218 #ifdef PNG_MAX_MALLOC_64K
02219 if (length > (png_uint_32)65535L)
02220 {
02221 png_warning(png_ptr, "unknown chunk too large to fit in memory");
02222 skip = length - (png_uint_32)65535L;
02223 length = (png_uint_32)65535L;
02224 }
02225 #endif
02226 png_memcpy((png_charp)png_ptr->unknown_chunk.name,
02227 (png_charp)png_ptr->chunk_name,
02228 png_sizeof(png_ptr->unknown_chunk.name));
02229 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] = '\0';
02230 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
02231 png_ptr->unknown_chunk.size = (png_size_t)length;
02232 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
02233 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
02234 if(png_ptr->read_user_chunk_fn != NULL)
02235 {
02236
02237 int ret;
02238 ret = (*(png_ptr->read_user_chunk_fn))
02239 (png_ptr, &png_ptr->unknown_chunk);
02240 if (ret < 0)
02241 png_chunk_error(png_ptr, "error in user chunk");
02242 if (ret == 0)
02243 {
02244 if (!(png_ptr->chunk_name[0] & 0x20))
02245 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
02246 PNG_HANDLE_CHUNK_ALWAYS)
02247 png_chunk_error(png_ptr, "unknown critical chunk");
02248 png_set_unknown_chunks(png_ptr, info_ptr,
02249 &png_ptr->unknown_chunk, 1);
02250 }
02251 }
02252 #else
02253 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
02254 #endif
02255 png_free(png_ptr, png_ptr->unknown_chunk.data);
02256 png_ptr->unknown_chunk.data = NULL;
02257 }
02258 else
02259 #endif
02260 skip = length;
02261
02262 png_crc_finish(png_ptr, skip);
02263
02264 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
02265 info_ptr = info_ptr;
02266 #endif
02267 }
02268
02269
02270
02271
02272
02273
02274
02275 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
02276
02277 void
02278 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
02279 {
02280 png_debug(1, "in png_check_chunk_name\n");
02281 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
02282 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
02283 {
02284 png_chunk_error(png_ptr, "invalid chunk type");
02285 }
02286 }
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299 void
02300 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
02301 {
02302 png_debug(1,"in png_combine_row\n");
02303 if (mask == 0xff)
02304 {
02305 png_memcpy(row, png_ptr->row_buf + 1,
02306 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
02307 }
02308 else
02309 {
02310 switch (png_ptr->row_info.pixel_depth)
02311 {
02312 case 1:
02313 {
02314 png_bytep sp = png_ptr->row_buf + 1;
02315 png_bytep dp = row;
02316 int s_inc, s_start, s_end;
02317 int m = 0x80;
02318 int shift;
02319 png_uint_32 i;
02320 png_uint_32 row_width = png_ptr->width;
02321
02322 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
02323 if (png_ptr->transformations & PNG_PACKSWAP)
02324 {
02325 s_start = 0;
02326 s_end = 7;
02327 s_inc = 1;
02328 }
02329 else
02330 #endif
02331 {
02332 s_start = 7;
02333 s_end = 0;
02334 s_inc = -1;
02335 }
02336
02337 shift = s_start;
02338
02339 for (i = 0; i < row_width; i++)
02340 {
02341 if (m & mask)
02342 {
02343 int value;
02344
02345 value = (*sp >> shift) & 0x01;
02346 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
02347 *dp |= (png_byte)(value << shift);
02348 }
02349
02350 if (shift == s_end)
02351 {
02352 shift = s_start;
02353 sp++;
02354 dp++;
02355 }
02356 else
02357 shift += s_inc;
02358
02359 if (m == 1)
02360 m = 0x80;
02361 else
02362 m >>= 1;
02363 }
02364 break;
02365 }
02366 case 2:
02367 {
02368 png_bytep sp = png_ptr->row_buf + 1;
02369 png_bytep dp = row;
02370 int s_start, s_end, s_inc;
02371 int m = 0x80;
02372 int shift;
02373 png_uint_32 i;
02374 png_uint_32 row_width = png_ptr->width;
02375 int value;
02376
02377 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
02378 if (png_ptr->transformations & PNG_PACKSWAP)
02379 {
02380 s_start = 0;
02381 s_end = 6;
02382 s_inc = 2;
02383 }
02384 else
02385 #endif
02386 {
02387 s_start = 6;
02388 s_end = 0;
02389 s_inc = -2;
02390 }
02391
02392 shift = s_start;
02393
02394 for (i = 0; i < row_width; i++)
02395 {
02396 if (m & mask)
02397 {
02398 value = (*sp >> shift) & 0x03;
02399 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
02400 *dp |= (png_byte)(value << shift);
02401 }
02402
02403 if (shift == s_end)
02404 {
02405 shift = s_start;
02406 sp++;
02407 dp++;
02408 }
02409 else
02410 shift += s_inc;
02411 if (m == 1)
02412 m = 0x80;
02413 else
02414 m >>= 1;
02415 }
02416 break;
02417 }
02418 case 4:
02419 {
02420 png_bytep sp = png_ptr->row_buf + 1;
02421 png_bytep dp = row;
02422 int s_start, s_end, s_inc;
02423 int m = 0x80;
02424 int shift;
02425 png_uint_32 i;
02426 png_uint_32 row_width = png_ptr->width;
02427 int value;
02428
02429 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
02430 if (png_ptr->transformations & PNG_PACKSWAP)
02431 {
02432 s_start = 0;
02433 s_end = 4;
02434 s_inc = 4;
02435 }
02436 else
02437 #endif
02438 {
02439 s_start = 4;
02440 s_end = 0;
02441 s_inc = -4;
02442 }
02443 shift = s_start;
02444
02445 for (i = 0; i < row_width; i++)
02446 {
02447 if (m & mask)
02448 {
02449 value = (*sp >> shift) & 0xf;
02450 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
02451 *dp |= (png_byte)(value << shift);
02452 }
02453
02454 if (shift == s_end)
02455 {
02456 shift = s_start;
02457 sp++;
02458 dp++;
02459 }
02460 else
02461 shift += s_inc;
02462 if (m == 1)
02463 m = 0x80;
02464 else
02465 m >>= 1;
02466 }
02467 break;
02468 }
02469 default:
02470 {
02471 png_bytep sp = png_ptr->row_buf + 1;
02472 png_bytep dp = row;
02473 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
02474 png_uint_32 i;
02475 png_uint_32 row_width = png_ptr->width;
02476 png_byte m = 0x80;
02477
02478
02479 for (i = 0; i < row_width; i++)
02480 {
02481 if (m & mask)
02482 {
02483 png_memcpy(dp, sp, pixel_bytes);
02484 }
02485
02486 sp += pixel_bytes;
02487 dp += pixel_bytes;
02488
02489 if (m == 1)
02490 m = 0x80;
02491 else
02492 m >>= 1;
02493 }
02494 break;
02495 }
02496 }
02497 }
02498 }
02499
02500 #ifdef PNG_READ_INTERLACING_SUPPORTED
02501
02502
02503
02504
02505 void
02506 png_do_read_interlace(png_structp png_ptr)
02507 {
02508 png_row_infop row_info = &(png_ptr->row_info);
02509 png_bytep row = png_ptr->row_buf + 1;
02510 int pass = png_ptr->pass;
02511 png_uint_32 transformations = png_ptr->transformations;
02512 #ifdef PNG_USE_LOCAL_ARRAYS
02513
02514
02515 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
02516 #endif
02517
02518 png_debug(1,"in png_do_read_interlace\n");
02519 if (row != NULL && row_info != NULL)
02520 {
02521 png_uint_32 final_width;
02522
02523 final_width = row_info->width * png_pass_inc[pass];
02524
02525 switch (row_info->pixel_depth)
02526 {
02527 case 1:
02528 {
02529 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
02530 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
02531 int sshift, dshift;
02532 int s_start, s_end, s_inc;
02533 int jstop = png_pass_inc[pass];
02534 png_byte v;
02535 png_uint_32 i;
02536 int j;
02537
02538 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
02539 if (transformations & PNG_PACKSWAP)
02540 {
02541 sshift = (int)((row_info->width + 7) & 0x07);
02542 dshift = (int)((final_width + 7) & 0x07);
02543 s_start = 7;
02544 s_end = 0;
02545 s_inc = -1;
02546 }
02547 else
02548 #endif
02549 {
02550 sshift = 7 - (int)((row_info->width + 7) & 0x07);
02551 dshift = 7 - (int)((final_width + 7) & 0x07);
02552 s_start = 0;
02553 s_end = 7;
02554 s_inc = 1;
02555 }
02556
02557 for (i = 0; i < row_info->width; i++)
02558 {
02559 v = (png_byte)((*sp >> sshift) & 0x01);
02560 for (j = 0; j < jstop; j++)
02561 {
02562 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
02563 *dp |= (png_byte)(v << dshift);
02564 if (dshift == s_end)
02565 {
02566 dshift = s_start;
02567 dp--;
02568 }
02569 else
02570 dshift += s_inc;
02571 }
02572 if (sshift == s_end)
02573 {
02574 sshift = s_start;
02575 sp--;
02576 }
02577 else
02578 sshift += s_inc;
02579 }
02580 break;
02581 }
02582 case 2:
02583 {
02584 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
02585 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
02586 int sshift, dshift;
02587 int s_start, s_end, s_inc;
02588 int jstop = png_pass_inc[pass];
02589 png_uint_32 i;
02590
02591 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
02592 if (transformations & PNG_PACKSWAP)
02593 {
02594 sshift = (int)(((row_info->width + 3) & 0x03) << 1);
02595 dshift = (int)(((final_width + 3) & 0x03) << 1);
02596 s_start = 6;
02597 s_end = 0;
02598 s_inc = -2;
02599 }
02600 else
02601 #endif
02602 {
02603 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
02604 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
02605 s_start = 0;
02606 s_end = 6;
02607 s_inc = 2;
02608 }
02609
02610 for (i = 0; i < row_info->width; i++)
02611 {
02612 png_byte v;
02613 int j;
02614
02615 v = (png_byte)((*sp >> sshift) & 0x03);
02616 for (j = 0; j < jstop; j++)
02617 {
02618 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
02619 *dp |= (png_byte)(v << dshift);
02620 if (dshift == s_end)
02621 {
02622 dshift = s_start;
02623 dp--;
02624 }
02625 else
02626 dshift += s_inc;
02627 }
02628 if (sshift == s_end)
02629 {
02630 sshift = s_start;
02631 sp--;
02632 }
02633 else
02634 sshift += s_inc;
02635 }
02636 break;
02637 }
02638 case 4:
02639 {
02640 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
02641 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
02642 int sshift, dshift;
02643 int s_start, s_end, s_inc;
02644 png_uint_32 i;
02645 int jstop = png_pass_inc[pass];
02646
02647 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
02648 if (transformations & PNG_PACKSWAP)
02649 {
02650 sshift = (int)(((row_info->width + 1) & 0x01) << 2);
02651 dshift = (int)(((final_width + 1) & 0x01) << 2);
02652 s_start = 4;
02653 s_end = 0;
02654 s_inc = -4;
02655 }
02656 else
02657 #endif
02658 {
02659 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
02660 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
02661 s_start = 0;
02662 s_end = 4;
02663 s_inc = 4;
02664 }
02665
02666 for (i = 0; i < row_info->width; i++)
02667 {
02668 png_byte v = (png_byte)((*sp >> sshift) & 0xf);
02669 int j;
02670
02671 for (j = 0; j < jstop; j++)
02672 {
02673 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
02674 *dp |= (png_byte)(v << dshift);
02675 if (dshift == s_end)
02676 {
02677 dshift = s_start;
02678 dp--;
02679 }
02680 else
02681 dshift += s_inc;
02682 }
02683 if (sshift == s_end)
02684 {
02685 sshift = s_start;
02686 sp--;
02687 }
02688 else
02689 sshift += s_inc;
02690 }
02691 break;
02692 }
02693 default:
02694 {
02695 png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
02696 png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
02697 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
02698
02699 int jstop = png_pass_inc[pass];
02700 png_uint_32 i;
02701
02702 for (i = 0; i < row_info->width; i++)
02703 {
02704 png_byte v[8];
02705 int j;
02706
02707 png_memcpy(v, sp, pixel_bytes);
02708 for (j = 0; j < jstop; j++)
02709 {
02710 png_memcpy(dp, v, pixel_bytes);
02711 dp -= pixel_bytes;
02712 }
02713 sp -= pixel_bytes;
02714 }
02715 break;
02716 }
02717 }
02718 row_info->width = final_width;
02719 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
02720 }
02721 #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
02722 transformations = transformations;
02723 #endif
02724 }
02725 #endif
02726
02727 void
02728 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
02729 png_bytep prev_row, int filter)
02730 {
02731 png_debug(1, "in png_read_filter_row\n");
02732 png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
02733 switch (filter)
02734 {
02735 case PNG_FILTER_VALUE_NONE:
02736 break;
02737 case PNG_FILTER_VALUE_SUB:
02738 {
02739 png_uint_32 i;
02740 png_uint_32 istop = row_info->rowbytes;
02741 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
02742 png_bytep rp = row + bpp;
02743 png_bytep lp = row;
02744
02745 for (i = bpp; i < istop; i++)
02746 {
02747 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
02748 rp++;
02749 }
02750 break;
02751 }
02752 case PNG_FILTER_VALUE_UP:
02753 {
02754 png_uint_32 i;
02755 png_uint_32 istop = row_info->rowbytes;
02756 png_bytep rp = row;
02757 png_bytep pp = prev_row;
02758
02759 for (i = 0; i < istop; i++)
02760 {
02761 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
02762 rp++;
02763 }
02764 break;
02765 }
02766 case PNG_FILTER_VALUE_AVG:
02767 {
02768 png_uint_32 i;
02769 png_bytep rp = row;
02770 png_bytep pp = prev_row;
02771 png_bytep lp = row;
02772 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
02773 png_uint_32 istop = row_info->rowbytes - bpp;
02774
02775 for (i = 0; i < bpp; i++)
02776 {
02777 *rp = (png_byte)(((int)(*rp) +
02778 ((int)(*pp++) / 2 )) & 0xff);
02779 rp++;
02780 }
02781
02782 for (i = 0; i < istop; i++)
02783 {
02784 *rp = (png_byte)(((int)(*rp) +
02785 (int)(*pp++ + *lp++) / 2 ) & 0xff);
02786 rp++;
02787 }
02788 break;
02789 }
02790 case PNG_FILTER_VALUE_PAETH:
02791 {
02792 png_uint_32 i;
02793 png_bytep rp = row;
02794 png_bytep pp = prev_row;
02795 png_bytep lp = row;
02796 png_bytep cp = prev_row;
02797 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
02798 png_uint_32 istop=row_info->rowbytes - bpp;
02799
02800 for (i = 0; i < bpp; i++)
02801 {
02802 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
02803 rp++;
02804 }
02805
02806 for (i = 0; i < istop; i++)
02807 {
02808 int a, b, c, pa, pb, pc, p;
02809
02810 a = *lp++;
02811 b = *pp++;
02812 c = *cp++;
02813
02814 p = b - c;
02815 pc = a - c;
02816
02817 #ifdef PNG_USE_ABS
02818 pa = abs(p);
02819 pb = abs(pc);
02820 pc = abs(p + pc);
02821 #else
02822 pa = p < 0 ? -p : p;
02823 pb = pc < 0 ? -pc : pc;
02824 pc = (p + pc) < 0 ? -(p + pc) : p + pc;
02825 #endif
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836 p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
02837
02838 *rp = (png_byte)(((int)(*rp) + p) & 0xff);
02839 rp++;
02840 }
02841 break;
02842 }
02843 default:
02844 png_warning(png_ptr, "Ignoring bad adaptive filter type");
02845 *row=0;
02846 break;
02847 }
02848 }
02849
02850 void
02851 png_read_finish_row(png_structp png_ptr)
02852 {
02853 #ifdef PNG_USE_LOCAL_ARRAYS
02854
02855
02856
02857 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
02858
02859
02860 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
02861
02862
02863 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
02864
02865
02866 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
02867 #endif
02868
02869 png_debug(1, "in png_read_finish_row\n");
02870 png_ptr->row_number++;
02871 if (png_ptr->row_number < png_ptr->num_rows)
02872 return;
02873
02874 if (png_ptr->interlaced)
02875 {
02876 png_ptr->row_number = 0;
02877 png_memset_check(png_ptr, png_ptr->prev_row, 0,
02878 png_ptr->rowbytes + 1);
02879 do
02880 {
02881 png_ptr->pass++;
02882 if (png_ptr->pass >= 7)
02883 break;
02884 png_ptr->iwidth = (png_ptr->width +
02885 png_pass_inc[png_ptr->pass] - 1 -
02886 png_pass_start[png_ptr->pass]) /
02887 png_pass_inc[png_ptr->pass];
02888
02889 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
02890 png_ptr->iwidth) + 1;
02891
02892 if (!(png_ptr->transformations & PNG_INTERLACE))
02893 {
02894 png_ptr->num_rows = (png_ptr->height +
02895 png_pass_yinc[png_ptr->pass] - 1 -
02896 png_pass_ystart[png_ptr->pass]) /
02897 png_pass_yinc[png_ptr->pass];
02898 if (!(png_ptr->num_rows))
02899 continue;
02900 }
02901 else
02902 break;
02903 } while (png_ptr->iwidth == 0);
02904
02905 if (png_ptr->pass < 7)
02906 return;
02907 }
02908
02909 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
02910 {
02911 #ifdef PNG_USE_LOCAL_ARRAYS
02912 PNG_CONST PNG_IDAT;
02913 #endif
02914 char extra;
02915 int ret;
02916
02917 png_ptr->zstream.next_out = (Byte *)&extra;
02918 png_ptr->zstream.avail_out = (uInt)1;
02919 for(;;)
02920 {
02921 if (!(png_ptr->zstream.avail_in))
02922 {
02923 while (!png_ptr->idat_size)
02924 {
02925 png_byte chunk_length[4];
02926
02927 png_crc_finish(png_ptr, 0);
02928
02929 png_read_data(png_ptr, chunk_length, 4);
02930 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
02931 png_reset_crc(png_ptr);
02932 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
02933 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
02934 png_error(png_ptr, "Not enough image data");
02935
02936 }
02937 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
02938 png_ptr->zstream.next_in = png_ptr->zbuf;
02939 if (png_ptr->zbuf_size > png_ptr->idat_size)
02940 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
02941 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
02942 png_ptr->idat_size -= png_ptr->zstream.avail_in;
02943 }
02944 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
02945 if (ret == Z_STREAM_END)
02946 {
02947 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
02948 png_ptr->idat_size)
02949 png_warning(png_ptr, "Extra compressed data");
02950 png_ptr->mode |= PNG_AFTER_IDAT;
02951 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
02952 break;
02953 }
02954 if (ret != Z_OK)
02955 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
02956 "Decompression Error");
02957
02958 if (!(png_ptr->zstream.avail_out))
02959 {
02960 png_warning(png_ptr, "Extra compressed data.");
02961 png_ptr->mode |= PNG_AFTER_IDAT;
02962 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
02963 break;
02964 }
02965
02966 }
02967 png_ptr->zstream.avail_out = 0;
02968 }
02969
02970 if (png_ptr->idat_size || png_ptr->zstream.avail_in)
02971 png_warning(png_ptr, "Extra compression data");
02972
02973 inflateReset(&png_ptr->zstream);
02974
02975 png_ptr->mode |= PNG_AFTER_IDAT;
02976 }
02977
02978 void
02979 png_read_start_row(png_structp png_ptr)
02980 {
02981 #ifdef PNG_USE_LOCAL_ARRAYS
02982
02983
02984
02985 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
02986
02987
02988 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
02989
02990
02991 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
02992
02993
02994 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
02995 #endif
02996
02997 int max_pixel_depth;
02998 png_uint_32 row_bytes;
02999
03000 png_debug(1, "in png_read_start_row\n");
03001 png_ptr->zstream.avail_in = 0;
03002 png_init_read_transformations(png_ptr);
03003 if (png_ptr->interlaced)
03004 {
03005 if (!(png_ptr->transformations & PNG_INTERLACE))
03006 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
03007 png_pass_ystart[0]) / png_pass_yinc[0];
03008 else
03009 png_ptr->num_rows = png_ptr->height;
03010
03011 png_ptr->iwidth = (png_ptr->width +
03012 png_pass_inc[png_ptr->pass] - 1 -
03013 png_pass_start[png_ptr->pass]) /
03014 png_pass_inc[png_ptr->pass];
03015
03016 row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
03017
03018 png_ptr->irowbytes = (png_size_t)row_bytes;
03019 if((png_uint_32)png_ptr->irowbytes != row_bytes)
03020 png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
03021 }
03022 else
03023 {
03024 png_ptr->num_rows = png_ptr->height;
03025 png_ptr->iwidth = png_ptr->width;
03026 png_ptr->irowbytes = png_ptr->rowbytes + 1;
03027 }
03028 max_pixel_depth = png_ptr->pixel_depth;
03029
03030 #if defined(PNG_READ_PACK_SUPPORTED)
03031 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
03032 max_pixel_depth = 8;
03033 #endif
03034
03035 #if defined(PNG_READ_EXPAND_SUPPORTED)
03036 if (png_ptr->transformations & PNG_EXPAND)
03037 {
03038 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
03039 {
03040 if (png_ptr->num_trans)
03041 max_pixel_depth = 32;
03042 else
03043 max_pixel_depth = 24;
03044 }
03045 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
03046 {
03047 if (max_pixel_depth < 8)
03048 max_pixel_depth = 8;
03049 if (png_ptr->num_trans)
03050 max_pixel_depth *= 2;
03051 }
03052 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
03053 {
03054 if (png_ptr->num_trans)
03055 {
03056 max_pixel_depth *= 4;
03057 max_pixel_depth /= 3;
03058 }
03059 }
03060 }
03061 #endif
03062
03063 #if defined(PNG_READ_FILLER_SUPPORTED)
03064 if (png_ptr->transformations & (PNG_FILLER))
03065 {
03066 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
03067 max_pixel_depth = 32;
03068 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
03069 {
03070 if (max_pixel_depth <= 8)
03071 max_pixel_depth = 16;
03072 else
03073 max_pixel_depth = 32;
03074 }
03075 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
03076 {
03077 if (max_pixel_depth <= 32)
03078 max_pixel_depth = 32;
03079 else
03080 max_pixel_depth = 64;
03081 }
03082 }
03083 #endif
03084
03085 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
03086 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
03087 {
03088 if (
03089 #if defined(PNG_READ_EXPAND_SUPPORTED)
03090 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
03091 #endif
03092 #if defined(PNG_READ_FILLER_SUPPORTED)
03093 (png_ptr->transformations & (PNG_FILLER)) ||
03094 #endif
03095 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
03096 {
03097 if (max_pixel_depth <= 16)
03098 max_pixel_depth = 32;
03099 else
03100 max_pixel_depth = 64;
03101 }
03102 else
03103 {
03104 if (max_pixel_depth <= 8)
03105 {
03106 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
03107 max_pixel_depth = 32;
03108 else
03109 max_pixel_depth = 24;
03110 }
03111 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
03112 max_pixel_depth = 64;
03113 else
03114 max_pixel_depth = 48;
03115 }
03116 }
03117 #endif
03118
03119 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
03120 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
03121 if(png_ptr->transformations & PNG_USER_TRANSFORM)
03122 {
03123 int user_pixel_depth=png_ptr->user_transform_depth*
03124 png_ptr->user_transform_channels;
03125 if(user_pixel_depth > max_pixel_depth)
03126 max_pixel_depth=user_pixel_depth;
03127 }
03128 #endif
03129
03130
03131
03132 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
03133
03134
03135 row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
03136 1 + ((max_pixel_depth + 7) >> 3);
03137 #ifdef PNG_MAX_MALLOC_64K
03138 if (row_bytes > (png_uint_32)65536L)
03139 png_error(png_ptr, "This image requires a row greater than 64KB");
03140 #endif
03141 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
03142 png_ptr->row_buf = png_ptr->big_row_buf+32;
03143
03144 #ifdef PNG_MAX_MALLOC_64K
03145 if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
03146 png_error(png_ptr, "This image requires a row greater than 64KB");
03147 #endif
03148 if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
03149 png_error(png_ptr, "Row has too many bytes to allocate in memory.");
03150 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
03151 png_ptr->rowbytes + 1));
03152
03153 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
03154
03155 png_debug1(3, "width = %lu,\n", png_ptr->width);
03156 png_debug1(3, "height = %lu,\n", png_ptr->height);
03157 png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
03158 png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
03159 png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
03160 png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
03161
03162 png_ptr->flags |= PNG_FLAG_ROW_INIT;
03163 }
03164 #endif