📄 pngrtran.c
字号:
#if defined(PNG_READ_PACK_SUPPORTED)
if ((png_ptr->transformations & PNG_PACK) && info_ptr->bit_depth < 8)
info_ptr->bit_depth = 8;
#endif
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
!(info_ptr->color_type & PNG_COLOR_MASK_COLOR))
info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
#endif
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
info_ptr->channels = 1;
else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
info_ptr->channels = 3;
else
info_ptr->channels = 1;
if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
info_ptr->channels++;
info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
info_ptr->bit_depth);
info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
}
/* transform the row. The order of transformations is significant,
and is very touchy. If you add a transformation, take care to
decide how it fits in with the other transformations here */
void
png_do_read_transformations(png_structp png_ptr)
{
#if defined(PNG_READ_EXPAND_SUPPORTED)
if ((png_ptr->transformations & PNG_EXPAND) &&
png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
{
png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
}
else if (png_ptr->transformations & PNG_EXPAND)
{
if (png_ptr->num_trans)
png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
&(png_ptr->trans_values));
else
png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
NULL);
}
#endif
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
if (png_ptr->transformations & PNG_BACKGROUND)
png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
&(png_ptr->trans_values), &(png_ptr->background),
&(png_ptr->background_1),
png_ptr->gamma_table, png_ptr->gamma_from_1,
png_ptr->gamma_to_1, png_ptr->gamma_16_table,
png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
png_ptr->gamma_shift);
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED)
if ((png_ptr->transformations & PNG_GAMMA) &&
!(png_ptr->transformations & PNG_BACKGROUND))
png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->gamma_table, png_ptr->gamma_16_table,
png_ptr->gamma_shift);
#endif
#if defined(PNG_READ_16_TO_8_SUPPORTED)
if (png_ptr->transformations & PNG_16_TO_8)
png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_READ_DITHER_SUPPORTED)
if (png_ptr->transformations & PNG_DITHER)
{
png_do_dither((png_row_infop)&(png_ptr->row_info),
png_ptr->row_buf + 1,
png_ptr->palette_lookup,
png_ptr->dither_index);
}
#endif
#if defined(PNG_READ_INVERT_SUPPORTED)
if (png_ptr->transformations & PNG_INVERT_MONO)
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED)
if (png_ptr->transformations & PNG_SHIFT)
png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
&(png_ptr->shift));
#endif
#if defined(PNG_READ_PACK_SUPPORTED)
if (png_ptr->transformations & PNG_PACK)
png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_READ_BGR_SUPPORTED)
if (png_ptr->transformations & PNG_BGR)
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
if (png_ptr->transformations & PNG_GRAY_TO_RGB)
png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_READ_SWAP_SUPPORTED)
if (png_ptr->transformations & PNG_SWAP_BYTES)
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_READ_FILLER_SUPPORTED)
if (png_ptr->transformations & PNG_FILLER)
png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->filler, png_ptr->flags);
#endif
}
#if defined(PNG_READ_PACK_SUPPORTED)
/* unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
without changing the actual values. Thus, if you had a row with
a bit depth of 1, you would end up with bytes that only contained
the numbers 0 or 1. If you would rather they contain 0 and 255, use
png_do_shift() after this. */
void
png_do_unpack(png_row_infop row_info, png_bytep row)
{
int shift;
png_bytep sp, dp;
png_uint_32 i;
if (row && row_info && row_info->bit_depth < 8)
{
switch (row_info->bit_depth)
{
case 1:
{
sp = row + (png_size_t)((row_info->width - 1) >> 3);
dp = row + (png_size_t)row_info->width - 1;
shift = 7 - (int)((row_info->width + 7) & 7);
for (i = 0; i < row_info->width; i++)
{
*dp = (png_byte)((*sp >> shift) & 0x1);
if (shift == 7)
{
shift = 0;
sp--;
}
else
shift++;
dp--;
}
break;
}
case 2:
{
sp = row + (png_size_t)((row_info->width - 1) >> 2);
dp = row + (png_size_t)row_info->width - 1;
shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
for (i = 0; i < row_info->width; i++)
{
*dp = (png_byte)((*sp >> shift) & 0x3);
if (shift == 6)
{
shift = 0;
sp--;
}
else
shift += 2;
dp--;
}
break;
}
case 4:
{
sp = row + (png_size_t)((row_info->width - 1) >> 1);
dp = row + (png_size_t)row_info->width - 1;
shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
for (i = 0; i < row_info->width; i++)
{
*dp = (png_byte)((*sp >> shift) & 0xf);
if (shift == 4)
{
shift = 0;
sp--;
}
else
shift = 4;
dp--;
}
break;
}
}
row_info->bit_depth = 8;
row_info->pixel_depth = (png_byte)(8 * row_info->channels);
row_info->rowbytes = row_info->width * row_info->channels;
}
}
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED)
/* reverse the effects of png_do_shift. This routine merely shifts the
pixels back to their significant bits values. Thus, if you have
a row of bit depth 8, but only 5 are significant, this will shift
the values back to 0 through 31 */
void
png_do_unshift(png_row_infop row_info, png_bytep row,
png_color_8p sig_bits)
{
png_bytep bp;
png_uint_16 value;
png_uint_32 i;
if (row && row_info && sig_bits &&
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{
int shift[4];
int channels;
channels = 0;
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
{
shift[channels++] = row_info->bit_depth - sig_bits->red;
shift[channels++] = row_info->bit_depth - sig_bits->green;
shift[channels++] = row_info->bit_depth - sig_bits->blue;
}
else
{
shift[channels++] = row_info->bit_depth - sig_bits->gray;
}
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
{
shift[channels++] = row_info->bit_depth - sig_bits->alpha;
}
value = 0;
for (i = 0; i < channels; i++)
{
if (shift[(png_size_t)i] <= 0)
shift[(png_size_t)i] = 0;
else
value = 1;
}
if (!value)
return;
switch (row_info->bit_depth)
{
case 2:
{
for (bp = row, i = 0;
i < row_info->rowbytes;
i++, bp++)
{
*bp >>= 1;
*bp &= 0x55;
}
break;
}
case 4:
{
png_byte mask;
mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
(png_byte)((int)0xf >> shift[0]);
for (bp = row, i = 0;
i < row_info->rowbytes;
i++, bp++)
{
*bp >>= shift[0];
*bp &= mask;
}
break;
}
case 8:
{
for (bp = row, i = 0;
i < row_info->width; i++)
{
int c;
for (c = 0; c < row_info->channels; c++, bp++)
{
*bp >>= shift[c];
}
}
break;
}
case 16:
{
for (bp = row, i = 0;
i < row_info->width; i++)
{
int c;
for (c = 0; c < row_info->channels; c++, bp += 2)
{
value = (png_uint_16)((*bp << 8) + *(bp + 1));
value >>= shift[c];
*bp = (png_byte)(value >> 8);
*(bp + 1) = (png_byte)(value & 0xff);
}
}
break;
}
}
}
}
#endif
#if defined(PNG_READ_16_TO_8_SUPPORTED)
/* chop rows of bit depth 16 down to 8 */
void
png_do_chop(png_row_infop row_info, png_bytep row)
{
png_bytep sp, dp;
png_uint_32 i;
if (row && row_info && row_info->bit_depth == 16)
{
sp = row;
dp = row;
for (i = 0; i < row_info->width * row_info->channels; i++)
{
*dp = *sp;
/* not yet, as I'm afraid of overflow here
*dp = ((((((png_uint_16)(*sp) << 8)) |
(png_uint_16)((*(sp + 1) - *sp) & 0xff) +
0x7f) >> 8) & 0xff);
*/
sp += 2;
dp++;
}
row_info->bit_depth = 8;
row_info->pixel_depth = (png_byte)(8 * row_info->channels);
row_info->rowbytes = row_info->width * row_info->channels;
}
}
#endif
#if defined(PNG_READ_FILLER_SUPPORTED)
/* add filler byte */
void
png_do_read_filler(png_row_infop row_info, png_bytep row,
png_byte filler, png_byte flags)
{
png_bytep sp, dp;
png_uint_32 i;
if (row && row_info && row_info->color_type == 2 &&
row_info->bit_depth == 8)
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
for (i = 1, sp = row + (png_size_t)row_info->width * 3,
dp = row + (png_size_t)row_info->width * 4;
i < row_info->width;
i++)
{
*(--dp) = filler;
*(--dp) = *(--sp);
*(--dp) = *(--sp);
*(--dp) = *(--sp);
}
*(--dp) = filler;
row_info->channels = 4;
row_info->pixel_depth = 32;
row_info->rowbytes = row_info->width * 4;
}
else
{
for (i = 0, sp = row + (png_size_t)row_info->width * 3,
dp = row + (png_size_t)row_info->width * 4;
i < row_info->width;
i++)
{
*(--dp) = *(--sp);
*(--dp) = *(--sp);
*(--dp) = *(--sp);
*(--dp) = filler;
}
row_info->channels = 4;
row_info->pixel_depth = 32;
row_info->rowbytes = row_info->width * 4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -