Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/PluginPNG.cpp view on Meta::CPAN
png_structp png_ptr;
png_infop info_ptr;
png_colorp palette = NULL;
png_uint_32 width, height;
BOOL has_alpha_channel = FALSE;
RGBQUAD *pal; // pointer to dib palette
int bit_depth, pixel_depth; // pixel_depth = bit_depth * channels
int palette_entries;
int interlace_type;
fi_ioStructure fio;
fio.s_handle = handle;
fio.s_io = io;
if ((dib) && (handle)) {
try {
// create the chunk manage structure
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, error_handler, warning_handler);
if (!png_ptr) {
return FALSE;
}
// allocate/initialize the image information data.
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
return FALSE;
}
// Set error handling. REQUIRED if you aren't supplying your own
// error handling functions in the png_create_write_struct() call.
if (setjmp(png_jmpbuf(png_ptr))) {
// if we get here, we had a problem reading the file
png_destroy_write_struct(&png_ptr, &info_ptr);
return FALSE;
}
// init the IO
png_set_write_fn(png_ptr, &fio, _WriteProc, _FlushProc);
// set physical resolution
png_uint_32 res_x = (png_uint_32)FreeImage_GetDotsPerMeterX(dib);
png_uint_32 res_y = (png_uint_32)FreeImage_GetDotsPerMeterY(dib);
if ((res_x > 0) && (res_y > 0)) {
png_set_pHYs(png_ptr, info_ptr, res_x, res_y, PNG_RESOLUTION_METER);
}
// Set the image information here. Width and height are up to 2^31,
// bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
// the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
// PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
// or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
// PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
// currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
width = FreeImage_GetWidth(dib);
height = FreeImage_GetHeight(dib);
pixel_depth = FreeImage_GetBPP(dib);
BOOL bInterlaced = FALSE;
if( (flags & PNG_INTERLACED) == PNG_INTERLACED) {
interlace_type = PNG_INTERLACE_ADAM7;
bInterlaced = TRUE;
} else {
interlace_type = PNG_INTERLACE_NONE;
}
// set the ZLIB compression level or default to PNG default compression level (ZLIB level = 6)
int zlib_level = flags & 0x0F;
if((zlib_level >= 1) && (zlib_level <= 9)) {
png_set_compression_level(png_ptr, zlib_level);
} else if((flags & PNG_Z_NO_COMPRESSION) == PNG_Z_NO_COMPRESSION) {
png_set_compression_level(png_ptr, Z_NO_COMPRESSION);
}
// filtered strategy works better for high color images
if(pixel_depth >= 16){
png_set_compression_strategy(png_ptr, Z_FILTERED);
png_set_filter(png_ptr, 0, PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_PAETH);
} else {
png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
}
FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
if(image_type == FIT_BITMAP) {
// standard image type
bit_depth = (pixel_depth > 8) ? 8 : pixel_depth;
} else {
// 16-bit greyscale or 16-bit RGB(A)
bit_depth = 16;
}
// check for transparent images
BOOL bIsTransparent =
(image_type == FIT_BITMAP) && FreeImage_IsTransparent(dib) && (FreeImage_GetTransparencyCount(dib) > 0) ? TRUE : FALSE;
switch (FreeImage_GetColorType(dib)) {
case FIC_MINISWHITE:
if(!bIsTransparent) {
// Invert monochrome files to have 0 as black and 1 as white (no break here)
png_set_invert_mono(png_ptr);
}
// (fall through)
case FIC_MINISBLACK:
if(!bIsTransparent) {
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
PNG_COLOR_TYPE_GRAY, interlace_type,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
break;
( run in 1.226 second using v1.01-cache-2.11-cpan-d7f47b0818f )