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