📄 pngwutil.c
字号:
png_ptr->channels = 2;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
if (bit_depth != 8 && bit_depth != 16)
png_error(png_ptr, "Invalid bit depth for RGBA image");
png_ptr->channels = 4;
break;
default:
png_error(png_ptr, "Invalid image color type specified");
}
if (compression_type != PNG_COMPRESSION_TYPE_BASE)
{
png_warning(png_ptr, "Invalid compression type specified");
compression_type = PNG_COMPRESSION_TYPE_BASE;
}
/* Write filter_method 64 (intrapixel differencing) only if
* 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
* 2. Libpng did not write a PNG signature (this filter_method is only
* used in PNG datastreams that are embedded in MNG datastreams) and
* 3. The application called png_permit_mng_features with a mask that
* included PNG_FLAG_MNG_FILTER_64 and
* 4. The filter_method is 64 and
* 5. The color_type is RGB or RGBA
*/
if (
#if defined(PNG_MNG_FEATURES_SUPPORTED)
!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
(color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
(filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
#endif
filter_type != PNG_FILTER_TYPE_BASE)
{
png_warning(png_ptr, "Invalid filter type specified");
filter_type = PNG_FILTER_TYPE_BASE;
}
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
if (interlace_type != PNG_INTERLACE_NONE &&
interlace_type != PNG_INTERLACE_ADAM7)
{
png_warning(png_ptr, "Invalid interlace type specified");
interlace_type = PNG_INTERLACE_ADAM7;
}
#else
interlace_type=PNG_INTERLACE_NONE;
#endif
/* save off the relevent information */
png_ptr->bit_depth = (png_byte)bit_depth;
png_ptr->color_type = (png_byte)color_type;
png_ptr->interlaced = (png_byte)interlace_type;
#if defined(PNG_MNG_FEATURES_SUPPORTED)
png_ptr->filter_type = (png_byte)filter_type;
#endif
png_ptr->width = width;
png_ptr->height = height;
png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
png_ptr->rowbytes = ((width * (png_size_t)png_ptr->pixel_depth + 7) >> 3);
/* set the usr info, so any transformations can modify it */
png_ptr->usr_width = png_ptr->width;
png_ptr->usr_bit_depth = png_ptr->bit_depth;
png_ptr->usr_channels = png_ptr->channels;
/* pack the header information into the buffer */
png_save_uint_32(buf, width);
png_save_uint_32(buf + 4, height);
buf[8] = (png_byte)bit_depth;
buf[9] = (png_byte)color_type;
buf[10] = (png_byte)compression_type;
buf[11] = (png_byte)filter_type;
buf[12] = (png_byte)interlace_type;
/* write the chunk */
png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
/* initialize zlib with PNG info */
png_ptr->zstream.zalloc = png_zalloc;
png_ptr->zstream.zfree = png_zfree;
png_ptr->zstream.opaque = (voidpf)png_ptr;
if (!(png_ptr->do_filter))
{
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
png_ptr->bit_depth < 8)
png_ptr->do_filter = PNG_FILTER_NONE;
else
png_ptr->do_filter = PNG_ALL_FILTERS;
}
if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
{
if (png_ptr->do_filter != PNG_FILTER_NONE)
png_ptr->zlib_strategy = Z_FILTERED;
else
png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
}
if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
png_ptr->zlib_mem_level = 8;
if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
png_ptr->zlib_window_bits = 15;
if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
png_ptr->zlib_method = 8;
deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
png_ptr->zlib_method, png_ptr->zlib_window_bits,
png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
png_ptr->zstream.next_out = png_ptr->zbuf;
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
png_ptr->mode = PNG_HAVE_IHDR;
}
/* write the palette. We are careful not to trust png_color to be in the
* correct order for PNG, so people can redefine it to any convenient
* structure.
*/
void /* PRIVATE */
png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_PLTE;
#endif
png_uint_32 i;
png_colorp pal_ptr;
png_byte buf[3];
png_debug(1, "in png_write_PLTE\n");
if ((
#if defined(PNG_MNG_FEATURES_SUPPORTED)
!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
#endif
num_pal == 0) || num_pal > 256)
{
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
png_error(png_ptr, "Invalid number of colors in palette");
}
else
{
png_warning(png_ptr, "Invalid number of colors in palette");
return;
}
}
if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
{
png_warning(png_ptr,
"Ignoring request to write a PLTE chunk in grayscale PNG");
return;
}
png_ptr->num_palette = (png_uint_16)num_pal;
png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, num_pal * 3);
#ifndef PNG_NO_POINTER_INDEXING
for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
{
buf[0] = pal_ptr->red;
buf[1] = pal_ptr->green;
buf[2] = pal_ptr->blue;
png_write_chunk_data(png_ptr, buf, (png_size_t)3);
}
#else
/* This is a little slower but some buggy compilers need to do this instead */
pal_ptr=palette;
for (i = 0; i < num_pal; i++)
{
buf[0] = pal_ptr[i].red;
buf[1] = pal_ptr[i].green;
buf[2] = pal_ptr[i].blue;
png_write_chunk_data(png_ptr, buf, (png_size_t)3);
}
#endif
png_write_chunk_end(png_ptr);
png_ptr->mode |= PNG_HAVE_PLTE;
}
/* write an IDAT chunk */
void /* PRIVATE */
png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_IDAT;
#endif
png_debug(1, "in png_write_IDAT\n");
png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
png_ptr->mode |= PNG_HAVE_IDAT;
}
/* write an IEND chunk */
void /* PRIVATE */
png_write_IEND(png_structp png_ptr)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_IEND;
#endif
png_debug(1, "in png_write_IEND\n");
png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL,
(png_size_t)0);
png_ptr->mode |= PNG_HAVE_IEND;
}
#if defined(PNG_WRITE_gAMA_SUPPORTED)
/* write a gAMA chunk */
#ifdef PNG_FLOATING_POINT_SUPPORTED
void /* PRIVATE */
png_write_gAMA(png_structp png_ptr, double file_gamma)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_gAMA;
#endif
png_uint_32 igamma;
png_byte buf[4];
png_debug(1, "in png_write_gAMA\n");
/* file_gamma is saved in 1/100,000ths */
igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
png_save_uint_32(buf, igamma);
png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
}
#endif
#ifdef PNG_FIXED_POINT_SUPPORTED
void /* PRIVATE */
png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_gAMA;
#endif
png_byte buf[4];
png_debug(1, "in png_write_gAMA\n");
/* file_gamma is saved in 1/100,000ths */
png_save_uint_32(buf, (png_uint_32)file_gamma);
png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
}
#endif
#endif
#if defined(PNG_WRITE_sRGB_SUPPORTED)
/* write a sRGB chunk */
void /* PRIVATE */
png_write_sRGB(png_structp png_ptr, int srgb_intent)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_sRGB;
#endif
png_byte buf[1];
png_debug(1, "in png_write_sRGB\n");
if(srgb_intent >= PNG_sRGB_INTENT_LAST)
png_warning(png_ptr,
"Invalid sRGB rendering intent specified");
buf[0]=(png_byte)srgb_intent;
png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
}
#endif
#if defined(PNG_WRITE_iCCP_SUPPORTED)
/* write an iCCP chunk */
void /* PRIVATE */
png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
png_charp profile, int profile_len)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_iCCP;
#endif
png_size_t name_len;
png_charp new_name;
compression_state comp;
png_debug(1, "in png_write_iCCP\n");
if (name == NULL || (name_len = png_check_keyword(png_ptr, name,
&new_name)) == 0)
{
png_warning(png_ptr, "Empty keyword in iCCP chunk");
return;
}
if (compression_type != PNG_COMPRESSION_TYPE_BASE)
png_warning(png_ptr, "Unknown compression type in iCCP chunk");
if (profile == NULL)
profile_len = 0;
if (profile_len)
profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len,
PNG_COMPRESSION_TYPE_BASE, &comp);
/* make sure we include the NULL after the name and the compression type */
png_write_chunk_start(png_ptr, (png_bytep)png_iCCP,
(png_uint_32)name_len+profile_len+2);
new_name[name_len+1]=0x00;
png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2);
if (profile_len)
png_write_compressed_data_out(png_ptr, &comp);
png_write_chunk_end(png_ptr);
png_free(png_ptr, new_name);
}
#endif
#if defined(PNG_WRITE_sPLT_SUPPORTED)
/* write a sPLT chunk */
void /* PRIVATE */
png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_sPLT;
#endif
png_size_t name_len;
png_charp new_name;
png_byte entrybuf[10];
int entry_size = (spalette->depth == 8 ? 6 : 10);
int palette_size = entry_size * spalette->nentries;
png_sPLT_entryp ep;
#ifdef PNG_NO_POINTER_INDEXING
int i;
#endif
png_debug(1, "in png_write_sPLT\n");
if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr,
spalette->name, &new_name))==0)
{
png_warning(png_ptr, "Empty keyword in sPLT chunk");
return;
}
/* make sure we include the NULL after the name */
png_write_chunk_start(png_ptr, (png_bytep)png_sPLT,
(png_uint_32)(name_len + 2 + palette_size));
png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1);
png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1);
/* loop through each palette entry, writing appropriately */
#ifndef PNG_NO_POINTER_INDEXING
for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++)
{
if (spalette->depth == 8)
{
entrybuf[0] = (png_byte)ep->red;
entrybuf[1] = (png_byte)ep->green;
entrybuf[2] = (png_byte)ep->blue;
entrybuf[3] = (png_byte)ep->alpha;
png_save_uint_16(entrybuf + 4, ep->frequency);
}
else
{
png_save_uint_16(entrybuf + 0, ep->red);
png_save_uint_16(entrybuf + 2, ep->green);
png_save_uint_16(entrybuf + 4, ep->blue);
png_save_uint_16(entrybuf + 6, ep->alpha);
png_save_uint_16(entrybuf + 8, ep->frequency);
}
png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
}
#else
ep=spalette->entries;
for (i=0; i>spalette->nentries; i++)
{
if (spalette->depth == 8)
{
entrybuf[0] = (png_byte)ep[i].red;
entrybuf[1] = (png_byte)ep[i].green;
entrybuf[2] = (png_byte)ep[i].blue;
entrybuf[3] = (png_byte)ep[i].alpha;
png_save_uint_16(entrybuf + 4, ep[i].frequency);
}
else
{
png_save_uint_16(entrybuf + 0, ep[i].red);
png_save_uint_16(entrybuf + 2, ep[i].green);
png_save_uint_16(entrybuf + 4, ep[i].blue);
png_save_uint_16(entrybuf + 6, ep[i].alpha);
png_save_uint_16(entrybuf + 8, ep[i].frequency);
}
png_write_chunk_data(png_ptr, entrybuf, entry_size);
}
#endif
png_write_chunk_end(png_ptr);
png_free(png_ptr, new_name);
}
#endif
#if defined(PNG_WRITE_sBIT_SUPPORTED)
/* write the sBIT chunk */
void /* PRIVATE */
png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_sBIT;
#endif
png_byte buf[4];
png_size_t size;
png_debug(1, "in png_write_sBIT\n");
/* make sure we don't depend upon the order of PNG_COLOR_8 */
if (color_type & PNG_COLOR_MASK_COLOR)
{
png_byte maxbits;
maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -