📄 pngrutil.c
字号:
png_ptr->background.red = png_get_uint_16(buf);
png_ptr->background.green = png_get_uint_16(buf + 2);
png_ptr->background.blue = png_get_uint_16(buf + 4);
}
png_read_bKGD(png_ptr, info, &(png_ptr->background));
}
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
void
png_handle_hIST(png_structp png_ptr, png_infop info, png_uint_32 length)
{
int num, i;
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before hIST");
else if (!(png_ptr->mode & PNG_HAVE_PLTE))
{
png_warning(png_ptr, "Missing PLTE before hIST");
png_crc_skip(png_ptr, length);
return;
}
if (length != 2 * png_ptr->num_palette)
{
png_warning(png_ptr, "Incorrect hIST chunk length");
png_crc_skip(png_ptr, length);
return;
}
num = (int)length / 2;
png_ptr->hist = (png_uint_16p)png_large_malloc(png_ptr,
num * sizeof (png_uint_16));
png_ptr->do_free |= PNG_FREE_HIST;
for (i = 0; i < num; i++)
{
png_byte buf[2];
png_crc_read(png_ptr, buf, 2);
png_ptr->hist[i] = png_get_uint_16(buf);
}
png_read_hIST(png_ptr, info, png_ptr->hist);
}
#endif
#if defined(PNG_READ_pHYs_SUPPORTED)
void
png_handle_pHYs(png_structp png_ptr, png_infop info, png_uint_32 length)
{
png_byte buf[9];
png_uint_32 res_x, res_y;
int unit_type;
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before pHYS");
if (length != 9)
{
png_warning(png_ptr, "Incorrect pHYs chunk length");
png_crc_skip(png_ptr, length);
return;
}
png_crc_read(png_ptr, buf, 9);
res_x = png_get_uint_32(buf);
res_y = png_get_uint_32(buf + 4);
unit_type = buf[8];
png_read_pHYs(png_ptr, info, res_x, res_y, unit_type);
}
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
void
png_handle_oFFs(png_structp png_ptr, png_infop info, png_uint_32 length)
{
png_byte buf[9];
png_uint_32 offset_x, offset_y;
int unit_type;
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before oFFs");
if (length != 9)
{
png_warning(png_ptr, "Incorrect oFFs chunk length");
png_crc_skip(png_ptr, length);
return;
}
png_crc_read(png_ptr, buf, 9);
offset_x = png_get_uint_32(buf);
offset_y = png_get_uint_32(buf + 4);
unit_type = buf[8];
png_read_oFFs(png_ptr, info, offset_x, offset_y, unit_type);
}
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
void
png_handle_tIME(png_structp png_ptr, png_infop info, png_uint_32 length)
{
png_byte buf[7];
png_time mod_time;
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before tIME");
if (length != 7)
{
png_warning(png_ptr, "Incorrect tIME chunk length");
png_crc_skip(png_ptr, length);
return;
}
png_crc_read(png_ptr, buf, 7);
mod_time.second = buf[6];
mod_time.minute = buf[5];
mod_time.hour = buf[4];
mod_time.day = buf[3];
mod_time.month = buf[2];
mod_time.year = png_get_uint_16(buf);
png_read_tIME(png_ptr, info, &mod_time);
}
#endif
#if defined(PNG_READ_tEXt_SUPPORTED)
/* note: this does not correctly handle chunks that are > 64K */
void
png_handle_tEXt(png_structp png_ptr, png_infop info, png_uint_32 length)
{
png_charp key;
png_charp text;
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before tEXt");
key = (png_charp )png_large_malloc(png_ptr, length + 1);
png_crc_read(png_ptr, (png_bytep )key, length);
key[(png_size_t)length] = '\0';
for (text = key; *text; text++)
/* empty loop to check key length */ ;
if (text != key + (png_size_t)length)
text++;
png_read_tEXt(png_ptr, info, key, text, length - (text - key));
}
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
/* note: this does not correctly handle chunks that are > 64K compressed
on those systems that can't malloc more than 64KB at a time. */
void
png_handle_zTXt(png_structp png_ptr, png_infop info, png_uint_32 length)
{
static char msg[] = "Error decoding zTXt chunk";
png_charp key;
png_charp text;
png_uint_32 text_size, key_size;
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before zTXt");
key = png_large_malloc(png_ptr, length + 1);
png_crc_read(png_ptr, (png_bytep )key, length);
key[(png_size_t)length] = '\0';
for (text = key; *text; text++)
/* empty loop */ ;
/* zTXt can't have zero text */
if (text == key + (png_size_t)length)
{
png_warning(png_ptr, "Zero length zTXt chunk");
text_size = 0;
}
else if (*(++text)) /* check compression type byte */
{
png_warning(png_ptr, "Unknown zTXt compression type");
/* Copy what we can of the error message into the text chunk */
text_size = length - (text - key) - 1;
text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
png_memcpy(text, msg, (png_size_t)(text_size + 1));
}
else
{
text++;
png_ptr->zstream->next_in = (png_bytep )text;
png_ptr->zstream->avail_in = (uInt)(length - (text - key));
png_ptr->zstream->next_out = png_ptr->zbuf;
png_ptr->zstream->avail_out = (png_size_t)png_ptr->zbuf_size;
key_size = text - key;
text_size = 0;
text = NULL;
while (png_ptr->zstream->avail_in)
{
int ret;
ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END)
{
if (png_ptr->zstream->msg)
png_warning(png_ptr, png_ptr->zstream->msg);
else
png_warning(png_ptr, "zTXt decompression error");
inflateReset(png_ptr->zstream);
png_ptr->zstream->avail_in = 0;
if (!text)
{
text_size = key_size + sizeof(msg) + 1;
text = (png_charp)png_large_malloc(png_ptr, text_size);
png_memcpy(text, key, (png_size_t)key_size);
}
text[text_size - 1] = '\0';
/* Copy what we can of the error message into the text chunk */
text_size = length - (text - key) - 1;
text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
png_memcpy(text + key_size, msg, (png_size_t)(text_size + 1));
break;
}
if (!png_ptr->zstream->avail_out || ret == Z_STREAM_END)
{
if (!text)
{
text = (png_charp)png_large_malloc(png_ptr,
png_ptr->zbuf_size - png_ptr->zstream->avail_out +
key_size + 1);
png_memcpy(text + (png_size_t)key_size, png_ptr->zbuf,
(png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out));
png_memcpy(text, key, (png_size_t)key_size);
text_size = key_size + (png_size_t)png_ptr->zbuf_size -
png_ptr->zstream->avail_out;
*(text + (png_size_t)text_size) = '\0';
}
else
{
png_charp tmp;
tmp = text;
text = png_large_malloc(png_ptr, text_size +
png_ptr->zbuf_size - png_ptr->zstream->avail_out + 1);
png_memcpy(text, tmp, (png_size_t)text_size);
png_large_free(png_ptr, tmp);
png_memcpy(text + (png_size_t)text_size, png_ptr->zbuf,
(png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out));
text_size += png_ptr->zbuf_size - png_ptr->zstream->avail_out;
*(text + (png_size_t)text_size) = '\0';
}
if (ret != Z_STREAM_END)
{
png_ptr->zstream->next_out = png_ptr->zbuf;
png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
}
else
{
break;
}
}
}
inflateReset(png_ptr->zstream);
png_ptr->zstream->avail_in = 0;
png_large_free(png_ptr, key);
key = text;
text += (png_size_t)key_size;
text_size -= key_size;
}
png_read_zTXt(png_ptr, info, key, text, text_size, 0);
}
#endif
/* Combines the row recently read in with the previous row.
This routine takes care of alpha and transparency if requested.
This routine also handles the two methods of progressive display
of interlaced images, depending on the mask value.
The mask value describes which pixels are to be combined with
the row. The pattern always repeats every 8 pixels, so just 8
bits are needed. A one indicates the pixels is to be combined,
a zero indicates the pixel is to be skipped. This is in addition
to any alpha or transparency value associated with the pixel. If
you want all pixels to be combined, pass 0xff (255) in mask.
*/
void
png_combine_row(png_structp png_ptr, png_bytep row,
int mask)
{
if (mask == 0xff)
{
png_memcpy(row, png_ptr->row_buf + 1,
(png_size_t)((png_ptr->width *
png_ptr->row_info.pixel_depth + 7) >> 3));
}
else
{
switch (png_ptr->row_info.pixel_depth)
{
case 1:
{
png_bytep sp;
png_bytep dp;
int m;
int shift;
png_uint_32 i;
int value;
sp = png_ptr->row_buf + 1;
dp = row;
shift = 7;
m = 0x80;
for (i = 0; i < png_ptr->width; i++)
{
if (m & mask)
{
value = (*sp >> shift) & 0x1;
*dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
*dp |= (png_byte)(value << shift);
}
if (shift == 0)
{
shift = 7;
sp++;
dp++;
}
else
shift--;
if (m == 1)
m = 0x80;
else
m >>= 1;
}
break;
}
case 2:
{
png_bytep sp;
png_bytep dp;
int m;
int shift;
png_uint_32 i;
int value;
sp = png_ptr->row_buf + 1;
dp = row;
shift = 6;
m = 0x80;
for (i = 0; i < png_ptr->width; i++)
{
if (m & mask)
{
value = (*sp >> shift) & 0x3;
*dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
*dp |= (png_byte)(value << shift);
}
if (shift == 0)
{
shift = 6;
sp++;
dp++;
}
else
shift -= 2;
if (m == 1)
m = 0x80;
else
m >>= 1;
}
break;
}
case 4:
{
png_bytep sp;
png_bytep dp;
int m;
int shift;
png_uint_32 i;
int value;
sp = png_ptr->row_buf + 1;
dp = row;
shift = 4;
m = 0x80;
for (i = 0; i < png_ptr->width; i++)
{
if (m & mask)
{
value = (*sp >> shift) & 0xf;
*dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
*dp |= (png_byte)(value << shift);
}
if (shift == 0)
{
shift = 4;
sp++;
dp++;
}
else
shift -= 4;
if (m == 1)
m = 0x80;
else
m >>= 1;
}
break;
}
default:
{
png_bytep sp;
png_bytep dp;
png_uint_32 i;
int pixel_bytes, m;
pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
sp = png_ptr->row_buf + 1;
dp = row;
m = 0x80;
for (i = 0; i < png_ptr->width; i++)
{
if (m & mask)
{
png_memcpy(dp, sp, pixel_bytes);
}
sp += pixel_bytes;
dp += pixel_bytes;
if (m == 1)
m = 0x80;
else
m >>= 1;
}
break;
}
}
}
}
#if defined(PNG_READ_INTERLACING_SUPPORTED)
void
png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass)
{
if (row && row_info)
{
png_uint_32 final_width;
final_width = row_info->width * png_pass_inc[pass];
switch (row_info->pixel_depth)
{
case 1:
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -