📄 pngrutil.c
字号:
}
png_crc_read(png_ptr, buf, 1);
if (png_crc_finish(png_ptr, 0))
return;
intent = buf[0];
/* check for bad intent */
if (intent >= PNG_sRGB_INTENT_LAST)
{
png_warning(png_ptr, "Unknown sRGB intent");
return;
}
#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
if ((info_ptr->valid & PNG_INFO_gAMA))
{
int igamma;
#ifdef PNG_FIXED_POINT_SUPPORTED
igamma=(int)info_ptr->int_gamma;
#else
# ifdef PNG_FLOATING_POINT_SUPPORTED
igamma=(int)(info_ptr->gamma * 100000.);
# endif
#endif
#if 0 && defined(PNG_cHRM_SUPPORTED) && !defined(PNG_FIXED_POINT_SUPPORTED)
/* We need to define these here because they aren't in png.h */
png_fixed_point int_x_white;
png_fixed_point int_y_white;
png_fixed_point int_x_red;
png_fixed_point int_y_red;
png_fixed_point int_x_green;
png_fixed_point int_y_green;
png_fixed_point int_x_blue;
png_fixed_point int_y_blue;
#endif
if(igamma < 45000L || igamma > 46000L)
{
png_warning(png_ptr,
"Ignoring incorrect gAMA value when sRGB is also present");
#ifndef PNG_NO_CONSOLE_IO
# ifdef PNG_FIXED_POINT_SUPPORTED
fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
# else
# ifdef PNG_FLOATING_POINT_SUPPORTED
fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
# endif
# endif
#endif
}
}
#endif /* PNG_READ_gAMA_SUPPORTED */
#ifdef PNG_READ_cHRM_SUPPORTED
#ifdef PNG_FIXED_POINT_SUPPORTED
if (info_ptr->valid & PNG_INFO_cHRM)
if (abs(info_ptr->int_x_white - 31270L) > 1000 ||
abs(info_ptr->int_y_white - 32900L) > 1000 ||
abs(info_ptr->int_x_red - 64000L) > 1000 ||
abs(info_ptr->int_y_red - 33000L) > 1000 ||
abs(info_ptr->int_x_green - 30000L) > 1000 ||
abs(info_ptr->int_y_green - 60000L) > 1000 ||
abs(info_ptr->int_x_blue - 15000L) > 1000 ||
abs(info_ptr->int_y_blue - 6000L) > 1000)
{
png_warning(png_ptr,
"Ignoring incorrect cHRM value when sRGB is also present");
}
#endif /* PNG_FIXED_POINT_SUPPORTED */
#endif /* PNG_READ_cHRM_SUPPORTED */
png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
}
#endif /* PNG_READ_sRGB_SUPPORTED */
#if defined(PNG_READ_iCCP_SUPPORTED)
void /* PRIVATE */
png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Note: this does not properly handle chunks that are > 64K under DOS */
{
png_charp chunkdata;
png_byte compression_type;
png_charp profile;
png_uint_32 skip = 0;
png_uint_32 profile_size = 0;
png_uint_32 profile_length = 0;
png_size_t slength, prefix_length, data_length;
png_debug(1, "in png_handle_iCCP\n");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before iCCP");
else if (png_ptr->mode & PNG_HAVE_IDAT)
{
png_warning(png_ptr, "Invalid iCCP after IDAT");
png_crc_finish(png_ptr, length);
return;
}
else if (png_ptr->mode & PNG_HAVE_PLTE)
/* Should be an error, but we can cope with it */
png_warning(png_ptr, "Out of place iCCP chunk");
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
{
png_warning(png_ptr, "Duplicate iCCP chunk");
png_crc_finish(png_ptr, length);
return;
}
#ifdef PNG_MAX_MALLOC_64K
if (length > (png_uint_32)65535L)
{
png_warning(png_ptr, "iCCP chunk too large to fit in memory");
skip = length - (png_uint_32)65535L;
length = (png_uint_32)65535L;
}
#endif
chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
slength = (png_size_t)length;
png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
if (png_crc_finish(png_ptr, skip))
{
png_free(png_ptr, chunkdata);
return;
}
chunkdata[slength] = 0x00;
for (profile = chunkdata; *profile; profile++)
/* empty loop to find end of name */ ;
++profile;
/* there should be at least one zero (the compression type byte)
following the separator, and we should be on it */
if ( profile >= chunkdata + slength)
{
png_free(png_ptr, chunkdata);
png_warning(png_ptr, "Malformed iCCP chunk");
return;
}
/* compression_type should always be zero */
compression_type = *profile++;
if (compression_type)
{
png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
wrote nonzero) */
}
prefix_length = profile - chunkdata;
chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
slength, prefix_length, &data_length);
profile_length = data_length - prefix_length;
if ( prefix_length > data_length || profile_length < 4)
{
png_free(png_ptr, chunkdata);
png_warning(png_ptr, "Profile size field missing from iCCP chunk");
return;
}
/* Check the profile_size recorded in the first 32 bits of the ICC profile */
profile_size = ((*(chunkdata+prefix_length))<<24) |
((*(chunkdata+prefix_length+1))<<16) |
((*(chunkdata+prefix_length+2))<< 8) |
((*(chunkdata+prefix_length+3)) );
if(profile_size < profile_length)
profile_length = profile_size;
if(profile_size > profile_length)
{
png_free(png_ptr, chunkdata);
png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
return;
}
png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
chunkdata + prefix_length, profile_length);
png_free(png_ptr, chunkdata);
}
#endif /* PNG_READ_iCCP_SUPPORTED */
#if defined(PNG_READ_sPLT_SUPPORTED)
void /* PRIVATE */
png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Note: this does not properly handle chunks that are > 64K under DOS */
{
png_bytep chunkdata;
png_bytep entry_start;
png_sPLT_t new_palette;
#ifdef PNG_NO_POINTER_INDEXING
png_sPLT_entryp pp;
#endif
int data_length, entry_size, i;
png_uint_32 skip = 0;
png_size_t slength;
png_debug(1, "in png_handle_sPLT\n");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before sPLT");
else if (png_ptr->mode & PNG_HAVE_IDAT)
{
png_warning(png_ptr, "Invalid sPLT after IDAT");
png_crc_finish(png_ptr, length);
return;
}
#ifdef PNG_MAX_MALLOC_64K
if (length > (png_uint_32)65535L)
{
png_warning(png_ptr, "sPLT chunk too large to fit in memory");
skip = length - (png_uint_32)65535L;
length = (png_uint_32)65535L;
}
#endif
chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
slength = (png_size_t)length;
png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
if (png_crc_finish(png_ptr, skip))
{
png_free(png_ptr, chunkdata);
return;
}
chunkdata[slength] = 0x00;
for (entry_start = chunkdata; *entry_start; entry_start++)
/* empty loop to find end of name */ ;
++entry_start;
/* a sample depth should follow the separator, and we should be on it */
if (entry_start > chunkdata + slength)
{
png_free(png_ptr, chunkdata);
png_warning(png_ptr, "malformed sPLT chunk");
return;
}
new_palette.depth = *entry_start++;
entry_size = (new_palette.depth == 8 ? 6 : 10);
data_length = (slength - (entry_start - chunkdata));
/* integrity-check the data length */
if (data_length % entry_size)
{
png_free(png_ptr, chunkdata);
png_warning(png_ptr, "sPLT chunk has bad length");
return;
}
new_palette.nentries = data_length / entry_size;
new_palette.entries = (png_sPLT_entryp)png_malloc(
png_ptr, new_palette.nentries * sizeof(png_sPLT_entry));
#ifndef PNG_NO_POINTER_INDEXING
for (i = 0; i < new_palette.nentries; i++)
{
png_sPLT_entryp pp = new_palette.entries + i;
if (new_palette.depth == 8)
{
pp->red = *entry_start++;
pp->green = *entry_start++;
pp->blue = *entry_start++;
pp->alpha = *entry_start++;
}
else
{
pp->red = png_get_uint_16(entry_start); entry_start += 2;
pp->green = png_get_uint_16(entry_start); entry_start += 2;
pp->blue = png_get_uint_16(entry_start); entry_start += 2;
pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
}
pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
}
#else
pp = new_palette.entries;
for (i = 0; i < new_palette.nentries; i++)
{
if (new_palette.depth == 8)
{
pp[i].red = *entry_start++;
pp[i].green = *entry_start++;
pp[i].blue = *entry_start++;
pp[i].alpha = *entry_start++;
}
else
{
pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
}
pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
}
#endif
/* discard all chunk data except the name and stash that */
new_palette.name = (png_charp)chunkdata;
png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
png_free(png_ptr, chunkdata);
png_free(png_ptr, new_palette.entries);
}
#endif /* PNG_READ_sPLT_SUPPORTED */
#if defined(PNG_READ_tRNS_SUPPORTED)
void /* PRIVATE */
png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
png_debug(1, "in png_handle_tRNS\n");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before tRNS");
else if (png_ptr->mode & PNG_HAVE_IDAT)
{
png_warning(png_ptr, "Invalid tRNS after IDAT");
png_crc_finish(png_ptr, length);
return;
}
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
{
png_warning(png_ptr, "Duplicate tRNS chunk");
png_crc_finish(png_ptr, length);
return;
}
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
if (!(png_ptr->mode & PNG_HAVE_PLTE))
{
/* Should be an error, but we can cope with it */
png_warning(png_ptr, "Missing PLTE before tRNS");
}
else if (length > (png_uint_32)png_ptr->num_palette)
{
png_warning(png_ptr, "Incorrect tRNS chunk length");
png_crc_finish(png_ptr, length);
return;
}
if (length == 0)
{
png_warning(png_ptr, "Zero length tRNS chunk");
png_crc_finish(png_ptr, length);
return;
}
png_crc_read(png_ptr, readbuf, (png_size_t)length);
png_ptr->num_trans = (png_uint_16)length;
}
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
{
png_byte buf[6];
if (length != 6)
{
png_warning(png_ptr, "Incorrect tRNS chunk length");
png_crc_finish(png_ptr, length);
return;
}
png_crc_read(png_ptr, buf, (png_size_t)length);
png_ptr->num_trans = 1;
png_ptr->trans_values.red = png_get_uint_16(buf);
png_ptr->trans_values.green = png_get_uint_16(buf + 2);
png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
}
else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
{
png_byte buf[6];
if (length != 2)
{
png_warning(png_ptr, "Incorrect tRNS chunk length");
png_crc_finish(png_ptr, length);
return;
}
png_crc_read(png_ptr, buf, 2);
png_ptr->num_trans = 1;
png_ptr->trans_values.gray = png_get_uint_16(buf);
}
else
{
png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
png_crc_finish(png_ptr, length);
return;
}
if (png_crc_finish(png_ptr, 0))
return;
png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
&(png_ptr->trans_values));
}
#endif
#if defined(PNG_READ_bKGD_SUPPORTED)
void /* PRIVATE */
png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
png_size_t truelen;
png_byte buf[6];
png_debug(1, "in png_handle_bKGD\n");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before bKGD");
else if (png_ptr->mode & PNG_HAVE_IDAT)
{
png_warning(png_ptr, "Invalid bKGD after IDAT");
png_crc_finish(png_ptr, length);
return;
}
else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
!(png_ptr->mode & PNG_HAVE_PLTE))
{
png_warning(png_ptr, "Missing PLTE before bKGD");
png_crc_finish(png_ptr, length);
return;
}
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -