📄 pngrutil.c
字号:
png_bytep sp, dp;
int sshift, dshift;
png_byte v;
png_uint_32 i;
int j;
sp = row + (png_size_t)((row_info->width - 1) >> 3);
sshift = 7 - (int)((row_info->width + 7) & 7);
dp = row + (png_size_t)((final_width - 1) >> 3);
dshift = 7 - (int)((final_width + 7) & 7);
for (i = row_info->width; i; i--)
{
v = (png_byte)((*sp >> sshift) & 0x1);
for (j = 0; j < png_pass_inc[pass]; j++)
{
*dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
*dp |= (png_byte)(v << dshift);
if (dshift == 7)
{
dshift = 0;
dp--;
}
else
dshift++;
}
if (sshift == 7)
{
sshift = 0;
sp--;
}
else
sshift++;
}
break;
}
case 2:
{
png_bytep sp, dp;
int sshift, dshift;
png_byte v;
png_uint_32 i, j;
sp = row + (png_size_t)((row_info->width - 1) >> 2);
sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
dp = row + (png_size_t)((final_width - 1) >> 2);
dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
for (i = row_info->width; i; i--)
{
v = (png_byte)((*sp >> sshift) & 0x3);
for (j = 0; j < png_pass_inc[pass]; j++)
{
*dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
*dp |= (png_byte)(v << dshift);
if (dshift == 6)
{
dshift = 0;
dp--;
}
else
dshift += 2;
}
if (sshift == 6)
{
sshift = 0;
sp--;
}
else
sshift += 2;
}
break;
}
case 4:
{
png_bytep sp, dp;
int sshift, dshift;
png_byte v;
png_uint_32 i;
int j;
sp = row + (png_size_t)((row_info->width - 1) >> 1);
sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
dp = row + (png_size_t)((final_width - 1) >> 1);
dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
for (i = row_info->width; i; i--)
{
v = (png_byte)((*sp >> sshift) & 0xf);
for (j = 0; j < png_pass_inc[pass]; j++)
{
*dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
*dp |= (png_byte)(v << dshift);
if (dshift == 4)
{
dshift = 0;
dp--;
}
else
dshift = 4;
}
if (sshift == 4)
{
sshift = 0;
sp--;
}
else
sshift = 4;
}
break;
}
default:
{
png_bytep sp, dp;
png_byte v[8];
png_uint_32 i;
int j;
int pixel_bytes;
pixel_bytes = (row_info->pixel_depth >> 3);
sp = row + (png_size_t)((row_info->width - 1) * pixel_bytes);
dp = row + (png_size_t)((final_width - 1) * pixel_bytes);
for (i = row_info->width; i; i--)
{
png_memcpy(v, sp, pixel_bytes);
for (j = 0; j < png_pass_inc[pass]; j++)
{
png_memcpy(dp, v, pixel_bytes);
dp -= pixel_bytes;
}
sp -= pixel_bytes;
}
break;
}
}
row_info->width = final_width;
row_info->rowbytes = ((final_width *
(png_uint_32)row_info->pixel_depth + 7) >> 3);
}
}
#endif
void
png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
png_bytep prev_row, int filter)
{
switch (filter)
{
case 0:
break;
case 1:
{
png_uint_32 i;
int bpp;
png_bytep rp;
png_bytep lp;
bpp = (row_info->pixel_depth + 7) / 8;
for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
i < row_info->rowbytes; i++, rp++, lp++)
{
*rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
}
break;
}
case 2:
{
png_uint_32 i;
png_bytep rp;
png_bytep pp;
for (i = 0, rp = row, pp = prev_row;
i < row_info->rowbytes; i++, rp++, pp++)
{
*rp = (png_byte)(((int)(*rp) + (int)(*pp)) & 0xff);
}
break;
}
case 3:
{
png_uint_32 i;
int bpp;
png_bytep rp;
png_bytep pp;
png_bytep lp;
bpp = (row_info->pixel_depth + 7) / 8;
for (i = 0, rp = row, pp = prev_row;
i < (png_uint_32)bpp; i++, rp++, pp++)
{
*rp = (png_byte)(((int)(*rp) +
((int)(*pp) / 2)) & 0xff);
}
for (lp = row; i < row_info->rowbytes; i++, rp++, lp++, pp++)
{
*rp = (png_byte)(((int)(*rp) +
(int)(*pp + *lp) / 2) & 0xff);
}
break;
}
case 4:
{
int bpp;
png_uint_32 i;
png_bytep rp;
png_bytep pp;
png_bytep lp;
png_bytep cp;
bpp = (row_info->pixel_depth + 7) / 8;
for (i = 0, rp = row, pp = prev_row,
lp = row - bpp, cp = prev_row - bpp;
i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++)
{
int a, b, c, pa, pb, pc, p;
b = *pp;
if (i >= (png_uint_32)bpp)
{
c = *cp;
a = *lp;
}
else
{
a = c = 0;
}
p = a + b - c;
pa = abs(p - a);
pb = abs(p - b);
pc = abs(p - c);
if (pa <= pb && pa <= pc)
p = a;
else if (pb <= pc)
p = b;
else
p = c;
*rp = (png_byte)(((int)(*rp) + p) & 0xff);
}
break;
}
default:
png_error(png_ptr, "Bad adaptive filter type");
break;
}
}
void
png_read_finish_row(png_structp png_ptr)
{
png_ptr->row_number++;
if (png_ptr->row_number < png_ptr->num_rows)
return;
if (png_ptr->interlaced)
{
png_ptr->row_number = 0;
png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
do
{
png_ptr->pass++;
if (png_ptr->pass >= 7)
break;
png_ptr->iwidth = (png_ptr->width +
png_pass_inc[png_ptr->pass] - 1 -
png_pass_start[png_ptr->pass]) /
png_pass_inc[png_ptr->pass];
png_ptr->irowbytes = ((png_ptr->iwidth *
png_ptr->pixel_depth + 7) >> 3) + 1;
if (!(png_ptr->transformations & PNG_INTERLACE))
{
png_ptr->num_rows = (png_ptr->height +
png_pass_yinc[png_ptr->pass] - 1 -
png_pass_ystart[png_ptr->pass]) /
png_pass_yinc[png_ptr->pass];
if (!(png_ptr->num_rows))
continue;
}
if (png_ptr->transformations & PNG_INTERLACE)
break;
} while (png_ptr->iwidth == 0);
if (png_ptr->pass < 7)
return;
}
if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
{
char extra;
int ret;
png_ptr->zstream->next_out = (Byte *)&extra;
png_ptr->zstream->avail_out = (uInt)1;
do
{
if (!(png_ptr->zstream->avail_in))
{
while (!png_ptr->idat_size)
{
png_byte buf[4];
png_uint_32 crc;
png_read_data(png_ptr, buf, 4);
crc = png_get_uint_32(buf);
if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
(png_ptr->crc & 0xffffffffL))
png_warning(png_ptr, "Bad CRC value");
png_read_data(png_ptr, buf, 4);
png_ptr->idat_size = png_get_uint_32(buf);
png_reset_crc(png_ptr);
png_crc_read(png_ptr, buf, 4);
if (png_memcmp(buf, png_IDAT, 4))
png_error(png_ptr, "Not enough image data");
}
png_ptr->zstream->avail_in = (uInt)png_ptr->zbuf_size;
png_ptr->zstream->next_in = png_ptr->zbuf;
if (png_ptr->zbuf_size > png_ptr->idat_size)
png_ptr->zstream->avail_in = (uInt)png_ptr->idat_size;
png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream->avail_in);
png_ptr->idat_size -= png_ptr->zstream->avail_in;
}
ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
if (ret == Z_STREAM_END)
{
if (!(png_ptr->zstream->avail_out) || png_ptr->zstream->avail_in ||
png_ptr->idat_size)
png_error(png_ptr, "Extra compressed data");
png_ptr->mode |= PNG_AT_LAST_IDAT;
break;
}
if (ret != Z_OK)
png_error(png_ptr, png_ptr->zstream->msg ? png_ptr->zstream->msg :
"Decompression Error");
if (!(png_ptr->zstream->avail_out))
png_error(png_ptr, "Extra compressed data");
} while (1);
png_ptr->zstream->avail_out = 0;
}
if (png_ptr->idat_size || png_ptr->zstream->avail_in)
png_error(png_ptr, "Extra compression data");
inflateReset(png_ptr->zstream);
png_ptr->mode |= PNG_AT_LAST_IDAT;
}
void
png_read_start_row(png_structp png_ptr)
{
int max_pixel_depth;
png_uint_32 rowbytes;
png_ptr->zstream->avail_in = 0;
png_init_read_transformations(png_ptr);
if (png_ptr->interlaced)
{
if (!(png_ptr->transformations & PNG_INTERLACE))
png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
png_pass_ystart[0]) / png_pass_yinc[0];
else
png_ptr->num_rows = png_ptr->height;
png_ptr->iwidth = (png_ptr->width +
png_pass_inc[png_ptr->pass] - 1 -
png_pass_start[png_ptr->pass]) /
png_pass_inc[png_ptr->pass];
png_ptr->irowbytes = ((png_ptr->iwidth *
png_ptr->pixel_depth + 7) >> 3) + 1;
}
else
{
png_ptr->num_rows = png_ptr->height;
png_ptr->iwidth = png_ptr->width;
png_ptr->irowbytes = png_ptr->rowbytes + 1;
}
max_pixel_depth = png_ptr->pixel_depth;
#if defined(PNG_READ_PACK_SUPPORTED)
if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
max_pixel_depth = 8;
#endif
#if defined(PNG_READ_EXPAND_SUPPORTED)
if (png_ptr->transformations & PNG_EXPAND)
{
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
if (png_ptr->num_trans)
max_pixel_depth = 32;
else
max_pixel_depth = 24;
}
else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
{
if (max_pixel_depth < 8)
max_pixel_depth = 8;
if (png_ptr->num_trans)
max_pixel_depth *= 2;
}
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
{
if (png_ptr->num_trans)
{
max_pixel_depth *= 4;
max_pixel_depth /= 3;
}
}
}
#endif
#if defined(PNG_READ_FILLER_SUPPORTED)
if (png_ptr->transformations & (PNG_FILLER))
{
if (max_pixel_depth < 32)
max_pixel_depth = 32;
}
#endif
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
if (png_ptr->transformations & PNG_GRAY_TO_RGB)
{
if ((png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
if (max_pixel_depth <= 16)
max_pixel_depth = 32;
else if (max_pixel_depth <= 32)
max_pixel_depth = 64;
}
else
{
if (max_pixel_depth <= 8)
max_pixel_depth = 24;
else if (max_pixel_depth <= 16)
max_pixel_depth = 48;
}
}
#endif
/* align the width on the next larger 8 pixels. Mainly used
for interlacing */
rowbytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
/* calculate the maximum bytes needed, adding a byte and a pixel
for safety sake */
rowbytes = ((rowbytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
1 + ((max_pixel_depth + 7) >> 3);
#ifdef PNG_MAX_MALLOC_64K
if (rowbytes > 65536L)
png_error(png_ptr, "This image requires a row greater than 64KB");
#endif
png_ptr->row_buf = (png_bytep )png_large_malloc(png_ptr, rowbytes);
#ifdef PNG_MAX_MALLOC_64K
if (png_ptr->rowbytes + 1 > 65536L)
png_error(png_ptr, "This image requires a row greater than 64KB");
#endif
png_ptr->prev_row = png_large_malloc(png_ptr, png_ptr->rowbytes + 1);
png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
png_ptr->flags |= PNG_FLAG_ROW_INIT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -