view release on metacpan or search on metacpan
src/Source/FreeImage.h view on Meta::CPAN
#define FI_COLOR_IS_RGB_COLOR 0x00 //! RGBQUAD color is a RGB color (contains no valid alpha channel)
#define FI_COLOR_IS_RGBA_COLOR 0x01 //! RGBQUAD color is a RGBA color (contains a valid alpha channel)
#define FI_COLOR_FIND_EQUAL_COLOR 0x02 //! For palettized images: lookup equal RGB color from palette
#define FI_COLOR_ALPHA_IS_INDEX 0x04 //! The color's rgbReserved member (alpha) contains the palette index to be used
#define FI_COLOR_PALETTE_SEARCH_MASK (FI_COLOR_FIND_EQUAL_COLOR | FI_COLOR_ALPHA_IS_INDEX) // No color lookup is performed
// RescaleEx options ---------------------------------------------------------
// Constants used in FreeImage_RescaleEx
#define FI_RESCALE_DEFAULT 0x00 //! default options; none of the following other options apply
#define FI_RESCALE_TRUE_COLOR 0x01 //! for non-transparent greyscale images, convert to 24-bit if src bitdepth <= 8 (default is a 8-bit greyscale image).
#define FI_RESCALE_OMIT_METADATA 0x02 //! do not copy metadata to the rescaled image
#ifdef __cplusplus
extern "C" {
#endif
// Init / Error routines ----------------------------------------------------
DLL_API void DLL_CALLCONV FreeImage_Initialise(BOOL load_local_plugins_only FI_DEFAULT(FALSE));
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
RGBQUAD bkgnd_color;
/**@name transparency management */
//@{
/**
why another table ? for easy transparency table retrieval !
transparency could be stored in the palette, which is better
overall, but it requires quite some changes and it will render
FreeImage_GetTransparencyTable obsolete in its current form;
*/
BYTE transparent_table[256];
/** number of transparent colors */
int transparency_count;
/** TRUE if the image is transparent */
BOOL transparent;
//@}
/** space to hold ICC profile */
FIICCPROFILE iccProfile;
/** contains a list of metadata models attached to the bitmap */
METADATAMAP *metadata;
/** FALSE if the FIBITMAP only contains the header and no pixel data */
BOOL has_pixels;
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
memset(bitmap->data, 0, dib_size);
// write out the FREEIMAGEHEADER
FREEIMAGEHEADER *fih = (FREEIMAGEHEADER *)bitmap->data;
fih->type = type;
memset(&fih->bkgnd_color, 0, sizeof(RGBQUAD));
fih->transparent = FALSE;
fih->transparency_count = 0;
memset(fih->transparent_table, 0xff, 256);
fih->has_pixels = header_only ? FALSE : TRUE;
// initialize FIICCPROFILE link
FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(bitmap);
iccProfile->size = 0;
iccProfile->data = 0;
iccProfile->flags = 0;
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
FreeImage_IsTransparent(FIBITMAP *dib) {
if(dib) {
FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
switch(image_type) {
case FIT_BITMAP:
if(FreeImage_GetBPP(dib) == 32) {
if(FreeImage_GetColorType(dib) == FIC_RGBALPHA) {
return TRUE;
}
} else {
return ((FREEIMAGEHEADER *)dib->data)->transparent ? TRUE : FALSE;
}
break;
case FIT_RGBA16:
case FIT_RGBAF:
return TRUE;
default:
break;
}
}
return FALSE;
}
BYTE * DLL_CALLCONV
FreeImage_GetTransparencyTable(FIBITMAP *dib) {
return dib ? ((FREEIMAGEHEADER *)dib->data)->transparent_table : NULL;
}
void DLL_CALLCONV
FreeImage_SetTransparent(FIBITMAP *dib, BOOL enabled) {
if (dib) {
if ((FreeImage_GetBPP(dib) <= 8) || (FreeImage_GetBPP(dib) == 32)) {
((FREEIMAGEHEADER *)dib->data)->transparent = enabled;
} else {
((FREEIMAGEHEADER *)dib->data)->transparent = FALSE;
}
}
}
unsigned DLL_CALLCONV
FreeImage_GetTransparencyCount(FIBITMAP *dib) {
return dib ? ((FREEIMAGEHEADER *)dib->data)->transparency_count : 0;
}
void DLL_CALLCONV
FreeImage_SetTransparencyTable(FIBITMAP *dib, BYTE *table, int count) {
if (dib) {
count = MAX(0, MIN(count, 256));
if (FreeImage_GetBPP(dib) <= 8) {
((FREEIMAGEHEADER *)dib->data)->transparent = (count > 0) ? TRUE : FALSE;
((FREEIMAGEHEADER *)dib->data)->transparency_count = count;
if (table) {
memcpy(((FREEIMAGEHEADER *)dib->data)->transparent_table, table, count);
} else {
memset(((FREEIMAGEHEADER *)dib->data)->transparent_table, 0xff, count);
}
}
}
}
/** @brief Sets the index of the palette entry to be used as transparent color
for the image specified. Does nothing on high color images.
This method sets the index of the palette entry to be used as single transparent
color for the image specified. This works on palletised images only and does
nothing for high color images.
Although it is possible for palletised images to have more than one transparent
color, this method sets the palette entry specified as the single transparent
color for the image. All other colors will be set to be non-transparent by this
method.
As with FreeImage_SetTransparencyTable(), this method also sets the image's
transparency property to TRUE (as it is set and obtained by
FreeImage_SetTransparent() and FreeImage_IsTransparent() respectively) for
palletised images.
@param dib Input image, whose transparent color is to be set.
@param index The index of the palette entry to be set as transparent color.
*/
void DLL_CALLCONV
FreeImage_SetTransparentIndex(FIBITMAP *dib, int index) {
if (dib) {
int count = FreeImage_GetColorsUsed(dib);
if (count) {
BYTE *new_tt = (BYTE *)malloc(count * sizeof(BYTE));
memset(new_tt, 0xFF, count);
if ((index >= 0) && (index < count)) {
new_tt[index] = 0x00;
}
FreeImage_SetTransparencyTable(dib, new_tt, count);
free(new_tt);
}
}
}
/** @brief Returns the palette entry used as transparent color for the image
specified. Works for palletised images only and returns -1 for high color
images or if the image has no color set to be transparent.
Although it is possible for palletised images to have more than one transparent
color, this function always returns the index of the first palette entry, set
to be transparent.
@param dib Input image, whose transparent color is to be returned.
@return Returns the index of the palette entry used as transparent color for
the image specified or -1 if there is no transparent color found (e.g. the image
is a high color image).
*/
int DLL_CALLCONV
FreeImage_GetTransparentIndex(FIBITMAP *dib) {
int count = FreeImage_GetTransparencyCount(dib);
BYTE *tt = FreeImage_GetTransparencyTable(dib);
for (int i = 0; i < count; i++) {
if (tt[i] == 0) {
return i;
}
src/Source/FreeImage/Conversion32.cpp view on Meta::CPAN
target[FI_RGBA_BLUE] = source[FI_RGBA_BLUE];
target[FI_RGBA_ALPHA] = 0xFF;
target += 4;
source += 3;
}
}
// ----------------------------------------------------------
inline void
FreeImage_ConvertLine1To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
for (int cols = 0; cols < width_in_pixels; cols++) {
int index = (source[cols>>3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
target[FI_RGBA_BLUE] = palette[index].rgbBlue;
target[FI_RGBA_GREEN] = palette[index].rgbGreen;
target[FI_RGBA_RED] = palette[index].rgbRed;
target[FI_RGBA_ALPHA] = (index < transparent_pixels) ? table[index] : 255;
target += 4;
}
}
inline void
FreeImage_ConvertLine4To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
BOOL low_nibble = FALSE;
int x = 0;
for (int cols = 0 ; cols < width_in_pixels ; ++cols) {
if (low_nibble) {
target[FI_RGBA_BLUE] = palette[LOWNIBBLE(source[x])].rgbBlue;
target[FI_RGBA_GREEN] = palette[LOWNIBBLE(source[x])].rgbGreen;
target[FI_RGBA_RED] = palette[LOWNIBBLE(source[x])].rgbRed;
target[FI_RGBA_ALPHA] = (LOWNIBBLE(source[x]) < transparent_pixels) ? table[LOWNIBBLE(source[x])] : 255;
x++;
} else {
target[FI_RGBA_BLUE] = palette[HINIBBLE(source[x]) >> 4].rgbBlue;
target[FI_RGBA_GREEN] = palette[HINIBBLE(source[x]) >> 4].rgbGreen;
target[FI_RGBA_RED] = palette[HINIBBLE(source[x]) >> 4].rgbRed;
target[FI_RGBA_ALPHA] = (HINIBBLE(source[x] >> 4) < transparent_pixels) ? table[HINIBBLE(source[x]) >> 4] : 255;
}
low_nibble = !low_nibble;
target += 4;
}
}
inline void
FreeImage_ConvertLine8To32MapTransparency(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette, BYTE *table, int transparent_pixels) {
for (int cols = 0; cols < width_in_pixels; cols++) {
target[FI_RGBA_BLUE] = palette[source[cols]].rgbBlue;
target[FI_RGBA_GREEN] = palette[source[cols]].rgbGreen;
target[FI_RGBA_RED] = palette[source[cols]].rgbRed;
target[FI_RGBA_ALPHA] = (source[cols] < transparent_pixels) ? table[source[cols]] : 255;
target += 4;
}
}
// ----------------------------------------------------------
FIBITMAP * DLL_CALLCONV
FreeImage_ConvertTo32Bits(FIBITMAP *dib) {
if(!FreeImage_HasPixels(dib)) return NULL;
src/Source/FreeImage/MNGHelper.cpp view on Meta::CPAN
} // switch( GetChunckType )
} // while(!mEnd)
FreeImage_CloseMemory(hJpegMemory);
FreeImage_CloseMemory(hPngMemory);
FreeImage_CloseMemory(hIDATMemory);
free(mChunk);
free(PLTE_file_chunk);
// convert to 32-bit if a transparent layer is available
if(!header_only && dib_alpha) {
FIBITMAP *dst = FreeImage_ConvertTo32Bits(dib);
if((FreeImage_GetBPP(dib_alpha) == 8) && (FreeImage_GetImageType(dib_alpha) == FIT_BITMAP)) {
FreeImage_SetChannel(dst, dib_alpha, FICC_ALPHA);
} else {
FIBITMAP *dst_alpha = FreeImage_ConvertTo8Bits(dib_alpha);
FreeImage_SetChannel(dst, dst_alpha, FICC_ALPHA);
FreeImage_Unload(dst_alpha);
}
FreeImage_Unload(dib);
src/Source/FreeImage/PSDParser.cpp view on Meta::CPAN
// (Photoshop 6.0) Indexed Color Table Count
// 2 bytes for the number of colors in table that are actually defined
case 1046:
n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
nBytes += n * sizeof(ShortValue);
_ColourCount = (short)psdGetValue(ShortValue, sizeof(ShortValue) );
break;
// (Photoshop 6.0) Transparency Index.
// 2 bytes for the index of transparent color, if any.
case 1047:
n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
nBytes += n * sizeof(ShortValue);
_TransparentIndex = (short)psdGetValue(ShortValue, sizeof(ShortValue) );
break;
default:
{
// skip resource
unsigned skip_length = MIN(oResource._Size, nTotalBytes - nBytes);
src/Source/FreeImage/PluginDDS.cpp view on Meta::CPAN
if (wCol[0] > wCol[1] || !isDXT1) {
// 4 color block
for (i = 0; i < 2; i++) {
colors[i + 2].a = 0xff;
colors[i + 2].r = (BYTE)((WORD (colors[0].r) * (2 - i) + WORD (colors[1].r) * (1 + i)) / 3);
colors[i + 2].g = (BYTE)((WORD (colors[0].g) * (2 - i) + WORD (colors[1].g) * (1 + i)) / 3);
colors[i + 2].b = (BYTE)((WORD (colors[0].b) * (2 - i) + WORD (colors[1].b) * (1 + i)) / 3);
}
}
else {
// 3 color block, number 4 is transparent
colors[2].a = 0xff;
colors[2].r = (BYTE)((WORD (colors[0].r) + WORD (colors[1].r)) / 2);
colors[2].g = (BYTE)((WORD (colors[0].g) + WORD (colors[1].g)) / 2);
colors[2].b = (BYTE)((WORD (colors[0].b) + WORD (colors[1].b)) / 2);
colors[3].a = 0x00;
colors[3].g = 0x00;
colors[3].b = 0x00;
colors[3].r = 0x00;
}
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
if( page == -1 ) {
page = 0;
}
if( page < 0 || page >= (int)info->image_descriptor_offsets.size() ) {
return NULL;
}
FIBITMAP *dib = NULL;
try {
bool have_transparent = false, no_local_palette = false, interlaced = false;
int disposal_method = GIF_DISPOSAL_LEAVE, delay_time = 0, transparent_color = 0;
WORD left, top, width, height;
BYTE packed, b;
WORD w;
//playback pages to generate what the user would see for this frame
if( (flags & GIF_PLAYBACK) == GIF_PLAYBACK ) {
//Logical Screen Descriptor
io->seek_proc(handle, 6, SEEK_SET);
WORD logicalwidth, logicalheight;
io->read_proc(&logicalwidth, 2, 1, handle);
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
}
}
//cache some info about each of the pages so we can avoid decoding as many of them as possible
std::vector<PageInfo> pageinfo;
int start = page, end = page;
while( start >= 0 ) {
//Graphic Control Extension
io->seek_proc(handle, (long)(info->graphic_control_extension_offsets[start] + 1), SEEK_SET);
io->read_proc(&packed, 1, 1, handle);
have_transparent = (packed & GIF_PACKED_GCE_HAVETRANS) ? true : false;
disposal_method = (packed & GIF_PACKED_GCE_DISPOSAL) >> 2;
//Image Descriptor
io->seek_proc(handle, (long)(info->image_descriptor_offsets[start]), SEEK_SET);
io->read_proc(&left, 2, 1, handle);
io->read_proc(&top, 2, 1, handle);
io->read_proc(&width, 2, 1, handle);
io->read_proc(&height, 2, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
SwapShort(&left);
SwapShort(&top);
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
pageinfo.push_back(PageInfo(disposal_method, left, top, width, height));
if( start != end ) {
if( left == 0 && top == 0 && width == logicalwidth && height == logicalheight ) {
if( disposal_method == GIF_DISPOSAL_BACKGROUND ) {
pageinfo.pop_back();
start++;
break;
} else if( disposal_method != GIF_DISPOSAL_PREVIOUS ) {
if( !have_transparent ) {
break;
}
}
}
}
start--;
}
if( start < 0 ) {
start = 0;
}
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
}
}
continue;
}
}
//decode page
FIBITMAP *pagedib = Load(io, handle, page, GIF_LOAD256, data);
if( pagedib != NULL ) {
RGBQUAD *pal = FreeImage_GetPalette(pagedib);
have_transparent = false;
if( FreeImage_IsTransparent(pagedib) ) {
int count = FreeImage_GetTransparencyCount(pagedib);
BYTE *table = FreeImage_GetTransparencyTable(pagedib);
for( int i = 0; i < count; i++ ) {
if( table[i] == 0 ) {
have_transparent = true;
transparent_color = i;
break;
}
}
}
//copy page data into logical buffer, with full alpha opaqueness
for( y = 0; y < info.height; y++ ) {
const int scanidx = logicalheight - (y + info.top) - 1;
if ( scanidx < 0 ) {
break; // If data is corrupt, don't calculate in invalid scanline
}
scanline = (RGBQUAD *)FreeImage_GetScanLine(dib, scanidx) + info.left;
BYTE *pageline = FreeImage_GetScanLine(pagedib, info.height - y - 1);
for( x = 0; x < info.width; x++ ) {
if( !have_transparent || *pageline != transparent_color ) {
*scanline = pal[*pageline];
scanline->rgbReserved = 255;
}
scanline++;
pageline++;
}
}
//copy frame time
if( page == end ) {
FITAG *tag;
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
//Graphic Control Extension
if( info->graphic_control_extension_offsets[page] != 0 ) {
io->seek_proc(handle, (long)(info->graphic_control_extension_offsets[page] + 1), SEEK_SET);
io->read_proc(&packed, 1, 1, handle);
io->read_proc(&w, 2, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
SwapShort(&w);
#endif
io->read_proc(&b, 1, 1, handle);
have_transparent = (packed & GIF_PACKED_GCE_HAVETRANS) ? true : false;
disposal_method = (packed & GIF_PACKED_GCE_DISPOSAL) >> 2;
delay_time = w * 10; //convert cs to ms
transparent_color = b;
if( have_transparent ) {
int size = 1 << bpp;
if( transparent_color <= size ) {
BYTE table[256];
memset(table, 0xFF, size);
table[transparent_color] = 0;
FreeImage_SetTransparencyTable(dib, table, size);
}
}
}
FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "FrameTime", ANIMTAG_FRAMETIME, FIDT_LONG, 1, 4, &delay_time);
b = (BYTE)disposal_method;
FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "DisposalMethod", ANIMTAG_DISPOSALMETHOD, FIDT_BYTE, 1, 1, &b);
delete stringtable;
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
try {
BYTE packed, b;
WORD w;
FITAG *tag;
int bpp = FreeImage_GetBPP(dib);
if( bpp != 1 && bpp != 4 && bpp != 8 ) {
throw "Only 1, 4, or 8 bpp images supported";
}
bool have_transparent = false, no_local_palette = false, interlaced = false;
int disposal_method = GIF_DISPOSAL_BACKGROUND, delay_time = 100, transparent_color = 0;
WORD left = 0, top = 0, width = (WORD)FreeImage_GetWidth(dib), height = (WORD)FreeImage_GetHeight(dib);
WORD output_height = height;
if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "FrameLeft", FIDT_SHORT, &tag) ) {
left = *(WORD *)FreeImage_GetTagValue(tag);
}
if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "FrameTop", FIDT_SHORT, &tag) ) {
top = *(WORD *)FreeImage_GetTagValue(tag);
}
if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "NoLocalPalette", FIDT_BYTE, &tag) ) {
no_local_palette = *(BYTE *)FreeImage_GetTagValue(tag) ? true : false;
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
FreeImage_FindCloseMetadata(mdhandle);
}
}
//Graphic Control Extension
if( FreeImage_IsTransparent(dib) ) {
int count = FreeImage_GetTransparencyCount(dib);
BYTE *table = FreeImage_GetTransparencyTable(dib);
for( int i = 0; i < count; i++ ) {
if( table[i] == 0 ) {
have_transparent = true;
transparent_color = i;
break;
}
}
}
io->write_proc((void *)"\x21\xF9\x04", 3, 1, handle);
b = (BYTE)((disposal_method << 2) & GIF_PACKED_GCE_DISPOSAL);
if( have_transparent ) b |= GIF_PACKED_GCE_HAVETRANS;
io->write_proc(&b, 1, 1, handle);
//Notes about delay time for GIFs:
//IE5/IE6 have a minimum and default of 100ms
//Mozilla/Firefox/Netscape 6+/Opera have a minimum of 20ms and a default of 100ms if <20ms is specified or the GCE is absent
//Netscape 4 has a minimum of 10ms if 0ms is specified, but will use 0ms if the GCE is absent
w = (WORD)(delay_time / 10); //convert ms to cs
#ifdef FREEIMAGE_BIGENDIAN
SwapShort(&w);
#endif
io->write_proc(&w, 2, 1, handle);
b = (BYTE)transparent_color;
io->write_proc(&b, 1, 1, handle);
b = 0;
io->write_proc(&b, 1, 1, handle);
//Image Descriptor
b = GIF_BLOCK_IMAGE_DESCRIPTOR;
io->write_proc(&b, 1, 1, handle);
io->write_proc(&left, 2, 1, handle);
io->write_proc(&top, 2, 1, handle);
io->write_proc(&width, 2, 1, handle);
src/Source/FreeImage/PluginICO.cpp view on Meta::CPAN
BYTE *and_bits = and_mask;
// clear the mask
memset(and_mask, 0, size_and);
for(int y = 0; y < height; y++) {
RGBQUAD *bits = (RGBQUAD*)FreeImage_GetScanLine(dib, y);
for(int x = 0; x < width; x++) {
if(bits[x].rgbReserved != 0xFF) {
// set any transparent color to full transparency
and_bits[x >> 3] |= (0x80 >> (x & 0x7));
}
}
and_bits += width_and;
}
}
else if(bit_count <= 8) {
// create the AND mask from the transparency table
src/Source/FreeImage/PluginICO.cpp view on Meta::CPAN
switch(FreeImage_GetBPP(dib)) {
case 1:
{
for(int y = 0; y < height; y++) {
BYTE *bits = (BYTE*)FreeImage_GetScanLine(dib, y);
for(int x = 0; x < width; x++) {
// get pixel at (x, y)
BYTE index = (bits[x >> 3] & (0x80 >> (x & 0x07))) != 0;
if(trns[index] != 0xFF) {
// set any transparent color to full transparency
and_bits[x >> 3] |= (0x80 >> (x & 0x7));
}
}
and_bits += width_and;
}
}
break;
case 4:
{
for(int y = 0; y < height; y++) {
BYTE *bits = (BYTE*)FreeImage_GetScanLine(dib, y);
for(int x = 0; x < width; x++) {
// get pixel at (x, y)
BYTE shift = (BYTE)((1 - x % 2) << 2);
BYTE index = (bits[x >> 1] & (0x0F << shift)) >> shift;
if(trns[index] != 0xFF) {
// set any transparent color to full transparency
and_bits[x >> 3] |= (0x80 >> (x & 0x7));
}
}
and_bits += width_and;
}
}
break;
case 8:
{
for(int y = 0; y < height; y++) {
BYTE *bits = (BYTE*)FreeImage_GetScanLine(dib, y);
for(int x = 0; x < width; x++) {
// get pixel at (x, y)
BYTE index = bits[x];
if(trns[index] != 0xFF) {
// set any transparent color to full transparency
and_bits[x >> 3] |= (0x80 >> (x & 0x7));
}
}
and_bits += width_and;
}
}
break;
}
}
src/Source/FreeImage/PluginIFF.cpp view on Meta::CPAN
#pragma pack(1)
#endif
typedef struct {
WORD w, h; /* raster width & height in pixels */
WORD x, y; /* position for this image */
BYTE nPlanes; /* # source bitplanes */
BYTE masking; /* masking technique */
BYTE compression; /* compression algorithm */
BYTE pad1; /* UNUSED. For consistency, put 0 here.*/
WORD transparentColor; /* transparent "color number" */
BYTE xAspect, yAspect; /* aspect ratio, a rational number x/y */
WORD pageWidth, pageHeight; /* source "page" size in pixels */
} BMHD;
#ifdef _WIN32
#pragma pack(pop)
#else
#pragma pack()
#endif
#ifndef FREEIMAGE_BIGENDIAN
static void
SwapHeader(BMHD *header) {
SwapShort(&header->w);
SwapShort(&header->h);
SwapShort(&header->x);
SwapShort(&header->y);
SwapShort(&header->transparentColor);
SwapShort(&header->pageWidth);
SwapShort(&header->pageHeight);
}
#endif
// ----------------------------------------------------------
/* IFF chunk IDs */
typedef DWORD IFF_ID;
src/Source/FreeImage/PluginPNG.cpp view on Meta::CPAN
*/
static BOOL
ConfigureDecoder(png_structp png_ptr, png_infop info_ptr, int flags, FREE_IMAGE_TYPE *output_image_type) {
// get original image info
const int color_type = png_get_color_type(png_ptr, info_ptr);
const int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
const int pixel_depth = bit_depth * png_get_channels(png_ptr, info_ptr);
FREE_IMAGE_TYPE image_type = FIT_BITMAP; // assume standard image type
// check for transparency table or single transparent color
BOOL bIsTransparent = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) == PNG_INFO_tRNS ? TRUE : FALSE;
// check allowed combinations of colour type and bit depth
// then get converted FreeImage type
switch(color_type) {
case PNG_COLOR_TYPE_GRAY: // color type '0', bitdepth = 1, 2, 4, 8, 16
switch(bit_depth) {
case 1:
case 2:
src/Source/FreeImage/PluginPNG.cpp view on Meta::CPAN
// if a tRNS chunk is provided, we must also expand the grayscale data to 8-bits,
// this allows us to make use of the transparency table with existing FreeImage methods
if (bIsTransparent && (pixel_depth < 8)) {
png_set_expand_gray_1_2_4_to_8(png_ptr);
}
break;
case 16:
image_type = (pixel_depth == 16) ? FIT_UINT16 : FIT_UNKNOWN;
// 16-bit grayscale images can contain a transparent value (shade)
// if found, expand the transparent value to a full alpha channel
if (bIsTransparent && (image_type != FIT_UNKNOWN)) {
// expand tRNS to a full alpha channel
png_set_tRNS_to_alpha(png_ptr);
// expand new 16-bit gray + 16-bit alpha to full 64-bit RGBA
png_set_gray_to_rgb(png_ptr);
image_type = FIT_RGBA16;
}
break;
src/Source/FreeImage/PluginPNG.cpp view on Meta::CPAN
if(!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// store the transparency table
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
// array of alpha (transparency) entries for palette
png_bytep trans_alpha = NULL;
// number of transparent entries
int num_trans = 0;
// graylevel or color sample values of the single transparent color for non-paletted images
png_color_16p trans_color = NULL;
png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color);
if((color_type == PNG_COLOR_TYPE_GRAY) && trans_color) {
// single transparent color
if (trans_color->gray < 256) {
BYTE table[256];
memset(table, 0xFF, 256);
table[trans_color->gray] = 0;
FreeImage_SetTransparencyTable(dib, table, 256);
}
// check for a full transparency table, too
else if ((trans_alpha) && (pixel_depth <= 8)) {
FreeImage_SetTransparencyTable(dib, (BYTE *)trans_alpha, num_trans);
}
} else if((color_type == PNG_COLOR_TYPE_PALETTE) && trans_alpha) {
// transparency table
FreeImage_SetTransparencyTable(dib, (BYTE *)trans_alpha, num_trans);
}
}
// store the background color (only supported for FIT_BITMAP types)
if ((image_type == FIT_BITMAP) && png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) {
// Get the background color to draw transparent and alpha images over.
// Note that even if the PNG file supplies a background, you are not required to
// use it - you should use the (solid) application background if it has one.
png_color_16p image_background = NULL;
RGBQUAD rgbBkColor;
if (png_get_bKGD(png_ptr, info_ptr, &image_background)) {
rgbBkColor.rgbRed = (BYTE)image_background->red;
rgbBkColor.rgbGreen = (BYTE)image_background->green;
rgbBkColor.rgbBlue = (BYTE)image_background->blue;
src/Source/FreeImage/PluginPNG.cpp view on Meta::CPAN
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;
}
// If a monochrome image is transparent, save it with a palette
// (fall through)
case FIC_PALETTE:
{
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
PNG_COLOR_TYPE_PALETTE, interlace_type,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
// set the palette
src/Source/FreeImage/PluginPNG.cpp view on Meta::CPAN
#endif
int number_passes = 1;
if (bInterlaced) {
number_passes = png_set_interlace_handling(png_ptr);
}
if ((pixel_depth == 32) && (!has_alpha_channel)) {
BYTE *buffer = (BYTE *)malloc(width * 3);
// transparent conversion to 24-bit
// the number of passes is either 1 for non-interlaced images, or 7 for interlaced images
for (int pass = 0; pass < number_passes; pass++) {
for (png_uint_32 k = 0; k < height; k++) {
FreeImage_ConvertLine32To24(buffer, FreeImage_GetScanLine(dib, height - k - 1), width);
png_write_row(png_ptr, buffer);
}
}
free(buffer);
} else {
// the number of passes is either 1 for non-interlaced images, or 7 for interlaced images
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
}
int bpp = bitspersample * samplesperpixel;
if(fit == FIT_BITMAP) {
// standard bitmap type
if(bpp == 16) {
if((samplesperpixel == 2) && (bitspersample == 8)) {
// 8-bit indexed + 8-bit alpha channel -> convert to 8-bit transparent
dib = FreeImage_AllocateHeader(header_only, width, height, 8);
} else {
// 16-bit RGB -> expect it to be 565
dib = FreeImage_AllocateHeader(header_only, width, height, bpp, FI16_565_RED_MASK, FI16_565_GREEN_MASK, FI16_565_BLUE_MASK);
}
}
else {
dib = FreeImage_AllocateHeader(header_only, width, height, MIN(bpp, 32), FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
uint16 photometric;
if(image_type == FIT_BITMAP) {
// standard image: 1-, 4-, 8-, 16-, 24-, 32-bit
samplesperpixel = ((bitsperpixel == 24) ? 3 : ((bitsperpixel == 32) ? 4 : 1));
bitspersample = bitsperpixel / samplesperpixel;
photometric = GetPhotometric(dib);
if((bitsperpixel == 8) && FreeImage_IsTransparent(dib)) {
// 8-bit transparent picture : convert later to 8-bit + 8-bit alpha
samplesperpixel = 2;
bitspersample = 8;
}
else if(bitsperpixel == 32) {
// 32-bit images : check for CMYK or alpha transparency
if((((iccProfile->flags & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) || ((flags & TIFF_CMYK) == TIFF_CMYK))) {
// CMYK support
photometric = PHOTOMETRIC_SEPARATED;
TIFFSetField(out, TIFFTAG_INKSET, INKSET_CMYK);
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
if(image_type == FIT_BITMAP) {
// standard bitmap type
switch(bitsperpixel) {
case 1 :
case 4 :
case 8 :
{
if((bitsperpixel == 8) && FreeImage_IsTransparent(dib)) {
// 8-bit transparent picture : convert to 8-bit + 8-bit alpha
// get the transparency table
BYTE *trns = FreeImage_GetTransparencyTable(dib);
BYTE *buffer = (BYTE *)malloc(2 * width * sizeof(BYTE));
if(buffer == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
for (int y = height - 1; y >= 0; y--) {
src/Source/FreeImageToolkit/Background.cpp view on Meta::CPAN
if (m == 0) {
break;
}
}
palette += sizeof(RGBQUAD);
}
}
return result;
}
/** @brief Blends an alpha-transparent foreground color over an opaque background
color.
This function blends the alpha-transparent foreground color fgcolor over the
background color bgcolor. The background color is considered fully opaque,
whatever it's alpha value contains, whereas the foreground color is considered
to be a real RGBA color with an alpha value, which is used for the blend
operation. The resulting color is returned through the blended parameter.
@param bgcolor The background color for the blend operation.
@param fgcolor The foreground color for the blend operation. This color's alpha
value, stored in the rgbReserved member, is the alpha value used for the blend
operation.
@param blended This out parameter takes the blended color and so, returns it to
the caller. This color's alpha value will be 0xFF (255) so, the blended color
src/Source/FreeImageToolkit/Background.cpp view on Meta::CPAN
BYTE *src_bits = FreeImage_GetScanLine(dib, 0);
BYTE *dst_bits = src_bits;
BOOL supports_alpha = ((bpp >= 24) || ((bpp == 8) && (color_type != FIC_PALETTE)));
// Check for RGBA case if bitmap supports alpha
// blending (8-bit greyscale, 24- or 32-bit images)
if (supports_alpha && (options & FI_COLOR_IS_RGBA_COLOR)) {
if (color->rgbReserved == 0) {
// the fill color is fully transparent; we are done
return TRUE;
}
// Only if the fill color is NOT fully opaque, draw it with
// the (much) slower FreeImage_DrawLine function and return.
// Since we do not have the FreeImage_DrawLine function in this
// release, just assume to have an unicolor background and fill
// all with an 'alpha-blended' color.
if (color->rgbReserved < 255) {
src/Source/FreeImageToolkit/Background.cpp view on Meta::CPAN
by an RGBQUAD structure for all images of type FIT_BITMAP (including all palletized
images), the smallest possible size of this memory is the size of the RGBQUAD structure,
which uses 4 bytes.
So, color must point to a double, if the image to be filled is of type FIT_DOUBLE and
point to a RGBF structure if the image is of type FIT_RGBF and so on.
However, the fill color is always specified through a RGBQUAD structure for all images
of type FIT_BITMAP. So, for 32- and 24-bit images, the red, green and blue members of
the RGBQUAD structure are directly used for the image's red, green and blue channel
respectively. Although alpha transparent RGBQUAD colors are supported, the alpha channel
of a 32-bit image never gets modified by this function. A fill color with an alpha value
smaller than 255 gets blended with the image's actual background color, which is determined
from the image's bottom-left pixel. So, currently using alpha enabled colors, assumes the
image to be unicolor before the fill operation. However, the RGBQUAD's rgbReserved member is
only taken into account, if option FI_COLOR_IS_RGBA_COLOR has been specified.
For 16-bit images, the red-, green- and blue components of the specified color are
transparently translated into either the 16-bit 555 or 565 representation. This depends
on the image's actual red- green- and blue masks.
Special attention must be payed for palletized images. Generally, the RGB color specified
is looked up in the image's palette. The found palette index is then used to fill the image.
There are some option flags, that affect this lookup process:
no option specified (0x00) Uses the color, that is nearest to the specified color.
This is the default behavior and should always find a
color in the palette. However, the visual result may
far from what was expected and mainly depends on the
src/Source/FreeImageToolkit/Background.cpp view on Meta::CPAN
So, calling this function with all parameters left, top, right and bottom set to zero, is
effectively the same as calling function FreeImage_Clone; setting all parameters left, top,
right and bottom to value equal to or smaller than zero, my easily be substituted by a call
to function FreeImage_Copy. Both these cases produce a new image, which is guaranteed not to
be larger than the input image. Thus, since the specified color is not needed in these cases,
the pointer color may be NULL.
Both parameters color and options work according to function FreeImage_FillBackground. So,
please refer to the documentation of FreeImage_FillBackground to learn more about parameters
color and options. For palletized images, the palette of the input image src is
transparently copied to the newly created enlarged or shrunken image, so any color
look-ups are performed on this palette.
Here are some examples, that illustrate, how to use the parameters left, top, right and
bottom:
// create a white color
RGBQUAD c;
c.rgbRed = 0xFF;
c.rgbGreen = 0xFF;
c.rgbBlue = 0xFF;
src/Source/FreeImageToolkit/Colors.cpp view on Meta::CPAN
<i>dstcolors</i> are also mapped to these specified in <i>srccolors</i>. For
high color images, the actual image data will be modified whereas, for
palletized images only the palette will be changed.<br>
The function returns the number of pixels changed or zero, if no pixels were
changed.
Both arrays <i>srccolors</i> and <i>dstcolors</i> are assumed not to hold less
than <i>count</i> colors.<br>
For 16-bit images, all colors specified are transparently converted to their
proper 16-bit representation (either in RGB555 or RGB565 format, which is
determined by the image's red- green- and blue-mask).<br>
<b>Note, that this behaviour is different from what FreeImage_ApplyPaletteIndexMapping()
does, which modifies the actual image data on palletized images.</b>
@param dib Input/output image to be processed.
@param srccolors Array of colors to be used as the mapping source.
@param dstcolors Array of colors to be used as the mapping destination.
@param count The number of colors to be mapped. This is the size of both
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
color_type = GetExtendedColorType(src, &bIsGreyscale);
} else {
color_type = FIC_RGB;
}
// determine the required bit depth of the destination image
unsigned dst_bpp;
unsigned dst_bpp_s1 = 0;
if (color_type == FIC_PALETTE && !bIsGreyscale) {
// non greyscale FIC_PALETTE images require a high-color destination
// image (24- or 32-bits depending on the image's transparent state)
dst_bpp = FreeImage_IsTransparent(src) ? 32 : 24;
} else if (src_bpp <= 8) {
// greyscale images require an 8-bit destination image
// (or a 32-bit image if the image is transparent);
// however, if flag FI_RESCALE_TRUE_COLOR is set, we will return
// a true color (24 bpp) image
if (FreeImage_IsTransparent(src)) {
dst_bpp = 32;
// additionally, for transparent images we always need a
// palette including transparency information (an RGBA palette)
// so, set color_type accordingly
color_type = FIC_PALETTE;
} else {
dst_bpp = ((flags & FI_RESCALE_TRUE_COLOR) == FI_RESCALE_TRUE_COLOR) ? 24 : 8;
// in any case, we use a fast 8-bit temporary image for the
// first filter operation (stage 1, either horizontal or
// vertical) and implicitly convert to 24 bpp (if requested
// by flag FI_RESCALE_TRUE_COLOR) during the second filter
// operation
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
}
return (out != src) ? out : FreeImage_Clone(src);
}
RGBQUAD pal_buffer[256];
RGBQUAD *src_pal = NULL;
// provide the source image's palette to the rescaler for
// FIC_PALETTE type images (this includes palletized greyscale
// images with an unordered palette as well as transparent images)
if (color_type == FIC_PALETTE) {
if (dst_bpp == 32) {
// a 32-bit destination image signals transparency, so
// create an RGBA palette from the source palette
src_pal = GetRGBAPalette(src, pal_buffer);
} else {
src_pal = FreeImage_GetPalette(src);
}
}
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
// step through rows
switch(FreeImage_GetImageType(src)) {
case FIT_BITMAP:
{
switch(FreeImage_GetBPP(src)) {
case 1:
{
switch(FreeImage_GetBPP(dst)) {
case 8:
{
// transparently convert the 1-bit non-transparent greyscale image to 8 bpp
src_offset_x >>= 3;
if (src_pal) {
// we have got a palette
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
// clamp and place result in destination pixel
dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
}
}
}
}
break;
case 24:
{
// transparently convert the non-transparent 1-bit image to 24 bpp
src_offset_x >>= 3;
if (src_pal) {
// we have got a palette
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
dst_bits[FI_RGBA_BLUE] = bval;
dst_bits += 3;
}
}
}
}
break;
case 32:
{
// transparently convert the transparent 1-bit image to 32 bpp;
// we always have got a palette here
src_offset_x >>= 3;
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
break;
}
}
break;
case 4:
{
switch(FreeImage_GetBPP(dst)) {
case 8:
{
// transparently convert the non-transparent 4-bit greyscale image to 8 bpp;
// we always have got a palette for 4-bit images
src_offset_x >>= 1;
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
// clamp and place result in destination pixel
dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
}
}
}
break;
case 24:
{
// transparently convert the non-transparent 4-bit image to 24 bpp;
// we always have got a palette for 4-bit images
src_offset_x >>= 1;
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
dst_bits[FI_RGBA_GREEN] = (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
dst_bits[FI_RGBA_BLUE] = (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
dst_bits += 3;
}
}
}
break;
case 32:
{
// transparently convert the transparent 4-bit image to 32 bpp;
// we always have got a palette for 4-bit images
src_offset_x >>= 1;
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
break;
}
}
break;
case 8:
{
switch(FreeImage_GetBPP(dst)) {
case 8:
{
// scale the 8-bit non-transparent greyscale image
// into an 8 bpp destination image
if (src_pal) {
// we have got a palette
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
BYTE * const dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
// clamp and place result in destination pixel
dst_bits[x] = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
}
}
}
}
break;
case 24:
{
// transparently convert the non-transparent 8-bit image to 24 bpp
if (src_pal) {
// we have got a palette
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
const unsigned iLeft = weightsTable.getLeftBoundary(x); // retrieve left boundary
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
dst_bits[FI_RGBA_BLUE] = bval;
dst_bits += 3;
}
}
}
}
break;
case 32:
{
// transparently convert the transparent 8-bit image to 32 bpp;
// we always have got a palette here
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x;
BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
const unsigned iLeft = weightsTable.getLeftBoundary(x); // retrieve left boundary
const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft; // retrieve right boundary
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
}
}
}
break;
}
}
break;
case 16:
{
// transparently convert the 16-bit non-transparent image to 24 bpp
if (IS_FORMAT_RGB565(src)) {
// image has 565 format
for (unsigned y = 0; y < height; y++) {
// scale each row
const WORD * const src_bits = (WORD *)FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x / sizeof(WORD);
BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
const unsigned iLeft = weightsTable.getLeftBoundary(x); // retrieve left boundary
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
dst_bits[FI_RGBA_BLUE] = (BYTE)CLAMP<int>((int)(((b * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
dst_bits += 3;
}
}
}
}
break;
case 24:
{
// scale the 24-bit non-transparent image into a 24 bpp destination image
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x * 3;
BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
const unsigned iLeft = weightsTable.getLeftBoundary(x); // retrieve left boundary
const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft; // retrieve right boundary
const BYTE * pixel = src_bits + iLeft * 3;
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
dst_bits[FI_RGBA_GREEN] = (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
dst_bits[FI_RGBA_BLUE] = (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
dst_bits += 3;
}
}
}
break;
case 32:
{
// scale the 32-bit transparent image into a 32 bpp destination image
for (unsigned y = 0; y < height; y++) {
// scale each row
const BYTE * const src_bits = FreeImage_GetScanLine(src, y + src_offset_y) + src_offset_x * 4;
BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
for (unsigned x = 0; x < dst_width; x++) {
// loop through row
const unsigned iLeft = weightsTable.getLeftBoundary(x); // retrieve left boundary
const unsigned iLimit = weightsTable.getRightBoundary(x) - iLeft; // retrieve right boundary
const BYTE *pixel = src_bits + iLeft * 4;
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
switch(FreeImage_GetBPP(src)) {
case 1:
{
const unsigned src_pitch = FreeImage_GetPitch(src);
const BYTE * const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + (src_offset_x >> 3);
switch(FreeImage_GetBPP(dst)) {
case 8:
{
// transparently convert the 1-bit non-transparent greyscale image to 8 bpp
if (src_pal) {
// we have got a palette
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
BYTE *dst_bits = dst_base + x;
const unsigned index = x >> 3;
const unsigned mask = 0x80 >> (x & 0x07);
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
dst_bits += dst_pitch;
}
}
}
}
break;
case 24:
{
// transparently convert the non-transparent 1-bit image to 24 bpp
if (src_pal) {
// we have got a palette
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
BYTE *dst_bits = dst_base + x * 3;
const unsigned index = x >> 3;
const unsigned mask = 0x80 >> (x & 0x07);
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
dst_bits[FI_RGBA_BLUE] = bval;
dst_bits += dst_pitch;
}
}
}
}
break;
case 32:
{
// transparently convert the transparent 1-bit image to 32 bpp;
// we always have got a palette here
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
BYTE *dst_bits = dst_base + x * 4;
const unsigned index = x >> 3;
const unsigned mask = 0x80 >> (x & 0x07);
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
// loop through column
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
break;
case 4:
{
const unsigned src_pitch = FreeImage_GetPitch(src);
const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + (src_offset_x >> 1);
switch(FreeImage_GetBPP(dst)) {
case 8:
{
// transparently convert the non-transparent 4-bit greyscale image to 8 bpp;
// we always have got a palette for 4-bit images
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
BYTE *dst_bits = dst_base + x;
const unsigned index = x >> 1;
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
// loop through column
const unsigned iLeft = weightsTable.getLeftBoundary(y); // retrieve left boundary
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
// clamp and place result in destination pixel
*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
dst_bits += dst_pitch;
}
}
}
break;
case 24:
{
// transparently convert the non-transparent 4-bit image to 24 bpp;
// we always have got a palette for 4-bit images
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
BYTE *dst_bits = dst_base + x * 3;
const unsigned index = x >> 1;
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
// loop through column
const unsigned iLeft = weightsTable.getLeftBoundary(y); // retrieve left boundary
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
dst_bits[FI_RGBA_GREEN] = (BYTE)CLAMP<int>((int)(g + 0.5), 0, 0xFF);
dst_bits[FI_RGBA_BLUE] = (BYTE)CLAMP<int>((int)(b + 0.5), 0, 0xFF);
dst_bits += dst_pitch;
}
}
}
break;
case 32:
{
// transparently convert the transparent 4-bit image to 32 bpp;
// we always have got a palette for 4-bit images
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
BYTE *dst_bits = dst_base + x * 4;
const unsigned index = x >> 1;
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
// loop through column
const unsigned iLeft = weightsTable.getLeftBoundary(y); // retrieve left boundary
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
break;
case 8:
{
const unsigned src_pitch = FreeImage_GetPitch(src);
const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x;
switch(FreeImage_GetBPP(dst)) {
case 8:
{
// scale the 8-bit non-transparent greyscale image into an 8 bpp destination image
if (src_pal) {
// we have got a palette
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
BYTE *dst_bits = dst_base + x;
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
// loop through column
const unsigned iLeft = weightsTable.getLeftBoundary(y); // retrieve left boundary
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
*dst_bits = (BYTE)CLAMP<int>((int)(value + 0.5), 0, 0xFF);
dst_bits += dst_pitch;
}
}
}
}
break;
case 24:
{
// transparently convert the non-transparent 8-bit image to 24 bpp
if (src_pal) {
// we have got a palette
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
BYTE *dst_bits = dst_base + x * 3;
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
// loop through column
const unsigned iLeft = weightsTable.getLeftBoundary(y); // retrieve left boundary
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
dst_bits[FI_RGBA_BLUE] = bval;
dst_bits += dst_pitch;
}
}
}
}
break;
case 32:
{
// transparently convert the transparent 8-bit image to 32 bpp;
// we always have got a palette here
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
BYTE *dst_bits = dst_base + x * 4;
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
// loop through column
const unsigned iLeft = weightsTable.getLeftBoundary(y); // retrieve left boundary
const unsigned iLimit = weightsTable.getRightBoundary(y) - iLeft; // retrieve right boundary
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
}
}
}
break;
}
}
break;
case 16:
{
// transparently convert the 16-bit non-transparent image to 24 bpp
const unsigned src_pitch = FreeImage_GetPitch(src) / sizeof(WORD);
const WORD *const src_base = (WORD *)FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x;
if (IS_FORMAT_RGB565(src)) {
// image has 565 format
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
BYTE *dst_bits = dst_base + x * 3;
// scale each column
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
dst_bits[FI_RGBA_BLUE] = (BYTE)CLAMP<int>((int)(((b * 0xFF) / 0x1F) + 0.5), 0, 0xFF);
dst_bits += dst_pitch;
}
}
}
}
break;
case 24:
{
// scale the 24-bit transparent image into a 24 bpp destination image
const unsigned src_pitch = FreeImage_GetPitch(src);
const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * 3;
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
const unsigned index = x * 3;
BYTE *dst_bits = dst_base + index;
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
src/Source/FreeImageToolkit/Resize.cpp view on Meta::CPAN
dst_bits[FI_RGBA_GREEN] = (BYTE)CLAMP<int>((int) (g + 0.5), 0, 0xFF);
dst_bits[FI_RGBA_BLUE] = (BYTE)CLAMP<int>((int) (b + 0.5), 0, 0xFF);
dst_bits += dst_pitch;
}
}
}
break;
case 32:
{
// scale the 32-bit transparent image into a 32 bpp destination image
const unsigned src_pitch = FreeImage_GetPitch(src);
const BYTE *const src_base = FreeImage_GetBits(src) + src_offset_y * src_pitch + src_offset_x * 4;
for (unsigned x = 0; x < width; x++) {
// work on column x in dst
const unsigned index = x * 4;
BYTE *dst_bits = dst_base + index;
// scale each column
for (unsigned y = 0; y < dst_height; y++) {
src/Source/LibJPEG/README view on Meta::CPAN
the assets of these former principals, agents, and beneficiaries of the
foreclosed institutions and corporations.
IJG asserts what is: that each man, woman, and child has unalienable value
and rights granted and deposited in them by the Creator and not any one of
the people is subordinate to any artificial principality, corporate fiction
or the special interest of another without their appropriate knowing,
willing and intentional consent made by contract or accommodation agreement.
IJG expresses that which already was.
The people have already determined and demanded that public administration
entities, national governments, and their supporting judicial systems must
be fully transparent, accountable, and liable.
IJG has secured the value for all concerned free people of the planet.
A partial list of foreclosed institutions and corporations ("Hall of Shame")
is currently prepared and will be published later.
TO DO
=====
Version 9 is the second release of a new generation JPEG standard
src/Source/LibJPEG/libjpeg.txt view on Meta::CPAN
slow communications link, a decoder can generate a low-quality image very
quickly from the first scan, then gradually improve the displayed quality as
more scans are received. The final image after all scans are complete is
identical to that of a regular (sequential) JPEG file of the same quality
setting. Progressive JPEG files are often slightly smaller than equivalent
sequential JPEG files, but the possibility of incremental display is the main
reason for using progressive JPEG.
The IJG encoder library generates progressive JPEG files when given a
suitable "scan script" defining how to divide the data into scans.
Creation of progressive JPEG files is otherwise transparent to the encoder.
Progressive JPEG files can also be read transparently by the decoder library.
If the decoding application simply uses the library as defined above, it
will receive a final decoded image without any indication that the file was
progressive. Of course, this approach does not allow incremental display.
To perform incremental display, an application needs to use the decoder
library's "buffered-image" mode, in which it receives a decoded image
multiple times.
Each displayed scan requires about as much work to decode as a full JPEG
image of the same size, so the decoder must be fairly fast in relation to the
data transmission rate in order to make incremental display useful. However,
src/Source/LibJPEG/libjpeg.txt view on Meta::CPAN
manager, since jpeg_finish_compress() does not support suspension. We
should also note that the compressor currently forces Huffman optimization
mode when creating a progressive JPEG file, because the default Huffman
tables are unsuitable for progressive files.
Progressive decompression:
When buffered-image mode is not used, the decoder library will read all of
a multi-scan file during jpeg_start_decompress(), so that it can provide a
final decoded image. (Here "multi-scan" means either progressive or
multi-scan sequential.) This makes multi-scan files transparent to the
decoding application. However, existing applications that used suspending
input with version 5 of the IJG library will need to be modified to check
for a suspension return from jpeg_start_decompress().
To perform incremental display, an application must use the library's
buffered-image mode. This is described in the next section.
Buffered-image mode
-------------------
src/Source/LibPNG/CHANGES view on Meta::CPAN
Added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P)
Minor corrections in libpng.txt
Added simple sRGB support (Glenn R-P)
Easier conditional compiling, e.g.,
define PNG_READ/WRITE_NOT_FULLY_SUPPORTED;
all configurable options can be selected from command-line instead
of having to edit pngconf.h (Glenn R-P)
Fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P)
Added more conditions for png_do_background, to avoid changing
black pixels to background when a background is supplied and
no pixels are transparent
Repaired PNG_NO_STDIO behavior
Tested NODIV support and made it default behavior (Greg Roelofs)
Added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler)
Regularized version numbering scheme and bumped shared-library major
version number to 2 to avoid problems with libpng 0.89 apps
(Greg Roelofs)
Version 0.98 [January, 1998]
Cleaned up some typos in libpng.txt and in code documentation
Fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler)
src/Source/LibPNG/CHANGES view on Meta::CPAN
the limit for PNG unsigned 32-bit integers when encoded.
Revised calls to png_create_read_struct() and png_create_write_struct()
for simpler debugging.
Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK)
Version 1.2.2beta2 [February 23, 2002]
Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths.
Check for invalid image dimensions in png_get_IHDR.
Added missing "fi;" in the install target of the SGI makefiles.
Added install-static to all makefiles that make shared libraries.
Always do gamma compensation when image is partially transparent.
Version 1.2.2beta3 [March 7, 2002]
Compute background.gray and background_1.gray even when color_type is RGB
in case image gets reduced to gray later.
Modified shared-library makefiles to install pkgconfig/libpngNN.pc.
Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown
Removed unused png_write_destroy_info prototype from png.h
Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case
Added install-shared target to all makefiles that make shared libraries.
Stopped a double free of palette, hist, and trans when not using free_me.
src/Source/LibPNG/CHANGES view on Meta::CPAN
the option the tests written in configure itself fail compilation because
they cause compiler warnings.
Rewrote autogen.sh to run autoreconf instead of running tools one-by-one.
Conditionalize the install rules for MINGW and CYGWIN in CMakeLists.txt and
set CMAKE_LIBRARY_OUTPUT_DIRECTORY to "lib" on all platforms (C. Yapp).
Freeze libtool files in the 'scripts' directory. This version of autogen.sh
attempts to dissuade people from running it when it is not, or should not,
be necessary. In fact, autogen.sh does not work when run in a libpng
directory extracted from a tar distribution anymore. You must run it in
a GIT clone instead.
Added two images to contrib/pngsuite (1-bit and 2-bit transparent grayscale),
and renamed three whose names were inconsistent with those in
pngsuite/README.txt.
Version 1.6.0beta08 [February 1, 2012]
Fixed Image::colormap misalignment in pngstest.c
Check libtool/libtoolize version number (2.4.2) in configure.ac
Divide test-pngstest.sh into separate pngstest runs for basic and
transparent images.
Moved automake options to AM_INIT_AUTOMAKE in configure.ac
Added color-tests, silent-rules (Not yet implemented in Makefile.am) and
version checking to configure.ac
Improved pngstest speed by not doing redundant tests and add const to
the background parameter of png_image_finish_read. The --background
option is now done automagically only when required, so that commandline
option no longer exists.
Cleaned up pngpriv.h to consistently declare all functions and data.
Also eliminated PNG_CONST_DATA, which is apparently not needed but we
can't be sure until it is gone.
src/Source/LibPNG/CHANGES view on Meta::CPAN
pnglibconf.h.prebuilt and pnglibconf.h.
Version 1.6.0beta14 [February 27, 2012]
Added information about the new limits in the manual.
Updated Makefile.in
Version 1.6.0beta15 [March 2, 2012]
Removed unused "current_text" members of png_struct and the png_free()
of png_ptr->current_text from pngread.c
Rewrote pngstest.c for substantial speed improvement.
Fixed transparent pixel and 16-bit rgb tests in pngstest and removed a
spurious check in pngwrite.c
Added PNG_IMAGE_FLAG_FAST for the benefit of applications that store
intermediate files, or intermediate in-memory data, while processing
image data with the simplified API. The option makes the files larger
but faster to write and read. pngstest now uses this by default; this
can be disabled with the --slow option.
Improved pngstest fine tuning of error numbers, new test file generator.
The generator generates images that test the full range of sample values,
allow the error numbers in pngstest to be tuned and checked. makepng
also allows generation of images with extra chunks, although this is
src/Source/LibPNG/INSTALL view on Meta::CPAN
an "unsigned char far * far *".
XI. Prepending a prefix to exported symbols
Starting with libpng-1.6.0, you can configure libpng (when using the
"configure" script) to prefix all exported symbols by means of the
configuration option "--with-libpng-prefix=FOO_", where FOO_ can be any
string beginning with a letter and containing only uppercase
and lowercase letters, digits, and the underscore (i.e., a C language
identifier). This creates a set of macros in pnglibconf.h, so this is
transparent to applications; their function calls get transformed by
the macros to use the modified names.
XII. Configuring for compiler xxx:
All includes for libpng are in pngconf.h. If you need to add, change
or delete an include, this is the place to do it.
The includes that are not needed outside libpng are placed in pngpriv.h,
which is only used by the routines inside libpng itself.
The files in libpng proper only include pngpriv.h and png.h, which
in turn includes pngconf.h and, as of libpng-1.5.0, pnglibconf.h.
src/Source/LibPNG/example.c view on Meta::CPAN
/* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png_ptr);
/* Expand paletted or RGB images with transparency to full alpha channels
* so the data will be available as RGBA quartets.
*/
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) != 0)
png_set_tRNS_to_alpha(png_ptr);
/* Set the background color to draw transparent and alpha images over.
* It is possible to set the red, green, and blue components directly
* for paletted images instead of supplying a palette index. Note that
* even if the PNG file supplies a background, you are not required to
* use it - you should use the (solid) application background if it has one.
*/
png_color_16 my_background, *image_background;
if (png_get_bKGD(png_ptr, info_ptr, &image_background) != 0)
png_set_background(png_ptr, image_background,
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
be used!
The remaining modes assume you don't need to do any further color correction or
that if you do, your color correction software knows all about alpha (it
probably doesn't!). They 'associate' the alpha with the color information by
storing color channel values that have been scaled by the alpha. The
advantage is that the color channels can be resampled (the image can be
scaled) in this form. The disadvantage is that normal practice is to store
linear, not (gamma) encoded, values and this requires 16-bit channels for
still images rather than the 8-bit channels that are just about sufficient if
gamma encoding is used. In addition all non-transparent pixel values,
including completely opaque ones, must be gamma encoded to produce the final
image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
described below (the latter being the two common names for associated alpha
color channels). Note that PNG files always contain non-associated color
channels; png_set_alpha_mode() with one of the modes causes the decoder to
convert the pixels to an associated form before returning them to your
application.
Since it is not necessary to perform arithmetic on opaque color values so
long as they are not to be resampled and are in the final color space it is
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
the output is always 16 bits per component. This permits accurate scaling
and processing of the data. If you know that your input PNG files were
generated locally you might need to replace PNG_DEFAULT_sRGB with the
correct value for your system.
png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
If you just need to composite the PNG image onto an existing background
and if you control the code that does this you can use the optimization
setting. In this case you just copy completely opaque pixels to the
output. For pixels that are not completely transparent (you just skip
those) you do the composition math using png_composite or png_composite_16
below then encode the resultant 8-bit or 16-bit values to match the output
encoding.
Other cases
If neither the PNG nor the standard linear encoding work for you because
of the software or hardware you use then you have a big problem. The PNG
case will probably result in halos around the image. The linear encoding
will probably result in a washed out, too bright, image (it's actually too
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
second call overrides the output gamma without changing the default. This
is easier than achieving the same effect with png_set_gamma. You must use
PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
fire if more than one call to png_set_alpha_mode and png_set_background is
made in the same read operation, however multiple calls with PNG_ALPHA_PNG
are ignored.
If you don't need, or can't handle, the alpha channel you can call
png_set_background() to remove it by compositing against a fixed color. Don't
call png_set_strip_alpha() to do this - it will leave spurious pixel values in
transparent parts of this image.
png_set_background(png_ptr, &background_color,
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1);
The background_color is an RGB or grayscale value according to the data format
libpng will produce for you. Because you don't yet know the format of the PNG
file, if you call png_set_background at this point you must arrange for the
format produced by libpng to always have 8-bit or 16-bit components and then
store the color as an 8-bit or 16-bit color as appropriate. The color contains
separate gray and RGB component values, so you can let libpng produce gray or
RGB output according to the input format, but low bit depth grayscale images
must always be converted to at least 8-bit format. (Even though low bit depth
grayscale images can't have an alpha channel they can have a transparent
color!)
You set the transforms you need later, either as flags to the high level
interface or libpng API calls for the low level interface. For reference the
settings and API calls required are:
8-bit values:
PNG_TRANSFORM_SCALE_16 | PNG_EXPAND
png_set_expand(png_ptr); png_set_scale_16(png_ptr);
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
1) The PNG file gamma from the gAMA chunk. This overwrites the default value
provided by an earlier call to png_set_gamma or png_set_alpha_mode.
2) Prior to libpng-1.5.4 the background color from a bKGd chunk. This
damages the information provided by an earlier call to png_set_background
resulting in unexpected behavior. Libpng-1.5.4 no longer does this.
3) The number of significant bits in each component value. Libpng uses this to
optimize gamma handling by reducing the internal lookup table sizes.
4) The transparent color information from a tRNS chunk. This can be modified by
a later call to png_set_tRNS.
Querying the info structure
Functions are used to get the information from the info_ptr once it
has been read. Note that these fields may not be completely filled
in until png_read_end() has read the chunk data following the image.
png_get_IHDR(png_ptr, info_ptr, &width, &height,
&bit_depth, &color_type, &interlace_type,
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
These are also important, but their validity depends on whether the chunk
has been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
data has been read, or zero if it is missing. The parameters to the
png_get_<chunk> are set directly if they are simple data types, or a
pointer into the info_ptr is returned for any complex types.
The colorspace data from gAMA, cHRM, sRGB, iCCP, and sBIT chunks
is simply returned to give the application information about how the
image was encoded. Libpng itself only does transformations using the file
gamma when combining semitransparent pixels with the background color, and,
since libpng-1.6.0, when converting between 8-bit sRGB and 16-bit linear pixels
within the simplified API. Libpng also uses the file gamma when converting
RGB to gray, beginning with libpng-1.0.5, if the application calls
png_set_rgb_to_gray()).
png_get_PLTE(png_ptr, info_ptr, &palette,
&num_palette);
palette - the palette for the file
(array of png_color)
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
red, green, and blue channels,
whichever are appropriate for the
given color type (png_color_16)
png_get_tRNS(png_ptr, info_ptr, &trans_alpha,
&num_trans, &trans_color);
trans_alpha - array of alpha (transparency)
entries for palette (PNG_INFO_tRNS)
num_trans - number of transparent entries
(PNG_INFO_tRNS)
trans_color - graylevel or color sample values of
the single transparent color for
non-paletted images (PNG_INFO_tRNS)
png_get_hIST(png_ptr, info_ptr, &hist);
(PNG_INFO_hIST)
hist - histogram of palette (array of
png_uint_16)
png_get_tIME(png_ptr, info_ptr, &mod_time);
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
right overall transformation. When two transforms are separated by a comma
either will do the job. When transforms are enclosed in [] the transform should
do the job but this is currently unimplemented - a different format will result
if the suggested transformations are used.
In PNG files, the alpha channel in an image
is the level of opacity. If you need the alpha channel in an image to
be the level of transparency instead of opacity, you can invert the
alpha channel (or the tRNS chunk data) after it's read, so that 0 is
fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
images) is fully transparent, with
png_set_invert_alpha(png_ptr);
PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
they can, resulting in, for example, 8 pixels per byte for 1 bit
files. This code expands to 1 pixel per byte without changing the
values of the pixels:
if (bit_depth < 8)
png_set_packing(png_ptr);
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
green, and blue channels, whichever are
appropriate for the given color type
(png_color_16)
png_set_tRNS(png_ptr, info_ptr, trans_alpha,
num_trans, trans_color);
trans_alpha - array of alpha (transparency)
entries for palette (PNG_INFO_tRNS)
num_trans - number of transparent entries
(PNG_INFO_tRNS)
trans_color - graylevel or color sample values
(in order red, green, blue) of the
single transparent color for
non-paletted images (PNG_INFO_tRNS)
png_set_hIST(png_ptr, info_ptr, hist);
hist - histogram of palette (array of
png_uint_16) (PNG_INFO_hIST)
png_set_tIME(png_ptr, info_ptr, mod_time);
mod_time - time image was last modified
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
If you are going the low-level route instead, you are now ready to
write all the file information up to the actual image data. You do
this with a call to png_write_info().
png_write_info(png_ptr, info_ptr);
Note that there is one transformation you may need to do before
png_write_info(). In PNG files, the alpha channel in an image is the
level of opacity. If your data is supplied as a level of transparency,
you can invert the alpha channel before you write it, so that 0 is
fully transparent and 255 (in 8-bit or paletted images) or 65535
(in 16-bit images) is fully opaque, with
png_set_invert_alpha(png_ptr);
This must appear before png_write_info() instead of later with the
other transformations because in the case of paletted images the tRNS
chunk data has to be inverted before the tRNS chunk is written. If
your image is not a paletted image, the tRNS data (which in such cases
represents a single color to be rendered as transparent) won't need to
be changed, and you can safely do this transformation after your
png_write_info() call.
If you need to write a private chunk that you want to appear before
the PLTE chunk when PLTE is present, you can write the PNG info in
two steps, and insert code to write your own chunk between them:
png_write_info_before_PLTE(png_ptr, info_ptr);
png_set_unknown_chunks(png_ptr, info_ptr, ...);
png_write_info(png_ptr, info_ptr);
src/Source/LibPNG/libpng.3 view on Meta::CPAN
be used!
The remaining modes assume you don't need to do any further color correction or
that if you do, your color correction software knows all about alpha (it
probably doesn't!). They 'associate' the alpha with the color information by
storing color channel values that have been scaled by the alpha. The
advantage is that the color channels can be resampled (the image can be
scaled) in this form. The disadvantage is that normal practice is to store
linear, not (gamma) encoded, values and this requires 16-bit channels for
still images rather than the 8-bit channels that are just about sufficient if
gamma encoding is used. In addition all non-transparent pixel values,
including completely opaque ones, must be gamma encoded to produce the final
image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
described below (the latter being the two common names for associated alpha
color channels). Note that PNG files always contain non-associated color
channels; png_set_alpha_mode() with one of the modes causes the decoder to
convert the pixels to an associated form before returning them to your
application.
Since it is not necessary to perform arithmetic on opaque color values so
long as they are not to be resampled and are in the final color space it is
src/Source/LibPNG/libpng.3 view on Meta::CPAN
the output is always 16 bits per component. This permits accurate scaling
and processing of the data. If you know that your input PNG files were
generated locally you might need to replace PNG_DEFAULT_sRGB with the
correct value for your system.
png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
If you just need to composite the PNG image onto an existing background
and if you control the code that does this you can use the optimization
setting. In this case you just copy completely opaque pixels to the
output. For pixels that are not completely transparent (you just skip
those) you do the composition math using png_composite or png_composite_16
below then encode the resultant 8-bit or 16-bit values to match the output
encoding.
Other cases
If neither the PNG nor the standard linear encoding work for you because
of the software or hardware you use then you have a big problem. The PNG
case will probably result in halos around the image. The linear encoding
will probably result in a washed out, too bright, image (it's actually too
src/Source/LibPNG/libpng.3 view on Meta::CPAN
second call overrides the output gamma without changing the default. This
is easier than achieving the same effect with png_set_gamma. You must use
PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
fire if more than one call to png_set_alpha_mode and png_set_background is
made in the same read operation, however multiple calls with PNG_ALPHA_PNG
are ignored.
If you don't need, or can't handle, the alpha channel you can call
png_set_background() to remove it by compositing against a fixed color. Don't
call png_set_strip_alpha() to do this - it will leave spurious pixel values in
transparent parts of this image.
png_set_background(png_ptr, &background_color,
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1);
The background_color is an RGB or grayscale value according to the data format
libpng will produce for you. Because you don't yet know the format of the PNG
file, if you call png_set_background at this point you must arrange for the
format produced by libpng to always have 8-bit or 16-bit components and then
store the color as an 8-bit or 16-bit color as appropriate. The color contains
separate gray and RGB component values, so you can let libpng produce gray or
RGB output according to the input format, but low bit depth grayscale images
must always be converted to at least 8-bit format. (Even though low bit depth
grayscale images can't have an alpha channel they can have a transparent
color!)
You set the transforms you need later, either as flags to the high level
interface or libpng API calls for the low level interface. For reference the
settings and API calls required are:
8-bit values:
PNG_TRANSFORM_SCALE_16 | PNG_EXPAND
png_set_expand(png_ptr); png_set_scale_16(png_ptr);
src/Source/LibPNG/libpng.3 view on Meta::CPAN
1) The PNG file gamma from the gAMA chunk. This overwrites the default value
provided by an earlier call to png_set_gamma or png_set_alpha_mode.
2) Prior to libpng-1.5.4 the background color from a bKGd chunk. This
damages the information provided by an earlier call to png_set_background
resulting in unexpected behavior. Libpng-1.5.4 no longer does this.
3) The number of significant bits in each component value. Libpng uses this to
optimize gamma handling by reducing the internal lookup table sizes.
4) The transparent color information from a tRNS chunk. This can be modified by
a later call to png_set_tRNS.
.SS Querying the info structure
Functions are used to get the information from the info_ptr once it
has been read. Note that these fields may not be completely filled
in until png_read_end() has read the chunk data following the image.
png_get_IHDR(png_ptr, info_ptr, &width, &height,
&bit_depth, &color_type, &interlace_type,
src/Source/LibPNG/libpng.3 view on Meta::CPAN
These are also important, but their validity depends on whether the chunk
has been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
data has been read, or zero if it is missing. The parameters to the
png_get_<chunk> are set directly if they are simple data types, or a
pointer into the info_ptr is returned for any complex types.
The colorspace data from gAMA, cHRM, sRGB, iCCP, and sBIT chunks
is simply returned to give the application information about how the
image was encoded. Libpng itself only does transformations using the file
gamma when combining semitransparent pixels with the background color, and,
since libpng-1.6.0, when converting between 8-bit sRGB and 16-bit linear pixels
within the simplified API. Libpng also uses the file gamma when converting
RGB to gray, beginning with libpng-1.0.5, if the application calls
png_set_rgb_to_gray()).
png_get_PLTE(png_ptr, info_ptr, &palette,
&num_palette);
palette - the palette for the file
(array of png_color)
src/Source/LibPNG/libpng.3 view on Meta::CPAN
red, green, and blue channels,
whichever are appropriate for the
given color type (png_color_16)
png_get_tRNS(png_ptr, info_ptr, &trans_alpha,
&num_trans, &trans_color);
trans_alpha - array of alpha (transparency)
entries for palette (PNG_INFO_tRNS)
num_trans - number of transparent entries
(PNG_INFO_tRNS)
trans_color - graylevel or color sample values of
the single transparent color for
non-paletted images (PNG_INFO_tRNS)
png_get_hIST(png_ptr, info_ptr, &hist);
(PNG_INFO_hIST)
hist - histogram of palette (array of
png_uint_16)
png_get_tIME(png_ptr, info_ptr, &mod_time);
src/Source/LibPNG/libpng.3 view on Meta::CPAN
right overall transformation. When two transforms are separated by a comma
either will do the job. When transforms are enclosed in [] the transform should
do the job but this is currently unimplemented - a different format will result
if the suggested transformations are used.
In PNG files, the alpha channel in an image
is the level of opacity. If you need the alpha channel in an image to
be the level of transparency instead of opacity, you can invert the
alpha channel (or the tRNS chunk data) after it's read, so that 0 is
fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
images) is fully transparent, with
png_set_invert_alpha(png_ptr);
PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
they can, resulting in, for example, 8 pixels per byte for 1 bit
files. This code expands to 1 pixel per byte without changing the
values of the pixels:
if (bit_depth < 8)
png_set_packing(png_ptr);
src/Source/LibPNG/libpng.3 view on Meta::CPAN
green, and blue channels, whichever are
appropriate for the given color type
(png_color_16)
png_set_tRNS(png_ptr, info_ptr, trans_alpha,
num_trans, trans_color);
trans_alpha - array of alpha (transparency)
entries for palette (PNG_INFO_tRNS)
num_trans - number of transparent entries
(PNG_INFO_tRNS)
trans_color - graylevel or color sample values
(in order red, green, blue) of the
single transparent color for
non-paletted images (PNG_INFO_tRNS)
png_set_hIST(png_ptr, info_ptr, hist);
hist - histogram of palette (array of
png_uint_16) (PNG_INFO_hIST)
png_set_tIME(png_ptr, info_ptr, mod_time);
mod_time - time image was last modified
src/Source/LibPNG/libpng.3 view on Meta::CPAN
If you are going the low-level route instead, you are now ready to
write all the file information up to the actual image data. You do
this with a call to png_write_info().
png_write_info(png_ptr, info_ptr);
Note that there is one transformation you may need to do before
png_write_info(). In PNG files, the alpha channel in an image is the
level of opacity. If your data is supplied as a level of transparency,
you can invert the alpha channel before you write it, so that 0 is
fully transparent and 255 (in 8-bit or paletted images) or 65535
(in 16-bit images) is fully opaque, with
png_set_invert_alpha(png_ptr);
This must appear before png_write_info() instead of later with the
other transformations because in the case of paletted images the tRNS
chunk data has to be inverted before the tRNS chunk is written. If
your image is not a paletted image, the tRNS data (which in such cases
represents a single color to be rendered as transparent) won't need to
be changed, and you can safely do this transformation after your
png_write_info() call.
If you need to write a private chunk that you want to appear before
the PLTE chunk when PLTE is present, you can write the PNG info in
two steps, and insert code to write your own chunk between them:
png_write_info_before_PLTE(png_ptr, info_ptr);
png_set_unknown_chunks(png_ptr, info_ptr, ...);
png_write_info(png_ptr, info_ptr);
src/Source/LibPNG/png.h view on Meta::CPAN
* are assumed to have the sRGB encoding if not marked with a gamma value and
* the output is always 16 bits per component. This permits accurate scaling
* and processing of the data. If you know that your input PNG files were
* generated locally you might need to replace PNG_DEFAULT_sRGB with the
* correct value for your system.
*
* png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
* If you just need to composite the PNG image onto an existing background
* and if you control the code that does this you can use the optimization
* setting. In this case you just copy completely opaque pixels to the
* output. For pixels that are not completely transparent (you just skip
* those) you do the composition math using png_composite or png_composite_16
* below then encode the resultant 8-bit or 16-bit values to match the output
* encoding.
*
* Other cases
* If neither the PNG nor the standard linear encoding work for you because
* of the software or hardware you use then you have a big problem. The PNG
* case will probably result in halos around the image. The linear encoding
* will probably result in a washed out, too bright, image (it's actually too
* contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably
src/Source/LibPNG/pnginfo.h view on Meta::CPAN
struct png_info_def
{
/* The following are necessary for every PNG file */
png_uint_32 width; /* width of image in pixels (from IHDR) */
png_uint_32 height; /* height of image in pixels (from IHDR) */
png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
png_size_t rowbytes; /* bytes needed to hold an untransformed row */
png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
/* The following three should have been named *_method not *_type */
png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
/* The following are set by png_set_IHDR, called from the application on
* write, but the are never actually used by the write code.
*/
src/Source/LibPNG/pnginfo.h view on Meta::CPAN
*/
png_color_8 sig_bit; /* significant bits in color channels */
#endif
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
defined(PNG_READ_BACKGROUND_SUPPORTED)
/* The tRNS chunk supplies transparency data for paletted images and
* other image types that don't need a full alpha channel. There are
* "num_trans" transparency values for a paletted image, stored in the
* same order as the palette colors, starting from index 0. Values
* for the data are in the range [0, 255], ranging from fully transparent
* to fully opaque, respectively. For non-paletted images, there is a
* single color specified that should be treated as fully transparent.
* Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
*/
png_bytep trans_alpha; /* alpha values for paletted image */
png_color_16 trans_color; /* transparent color for non-palette image */
#endif
#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
/* The bKGD chunk gives the suggested image background color if the
* display program does not have its own background color and the image
* is needs to composited onto a background before display. The colors
* in "background" are normally in the same color space/depth as the
* pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
*/
png_color_16 background;
src/Source/LibPNG/pngread.c view on Meta::CPAN
return i;
}
#define PNG_GRAY_COLORMAP_ENTRIES 256
static int
make_ga_colormap(png_image_read_control *display)
{
unsigned int i, a;
/* Alpha is retained, the output will be a color-map with entries
* selected by six levels of alpha. One transparent entry, 6 gray
* levels for all the intermediate alpha values, leaving 230 entries
* for the opaque grays. The color-map entries are the six values
* [0..5]*51, the GA processing uses PNG_DIV51(value) to find the
* relevant entry.
*
* if (alpha > 229) // opaque
* {
* // The 231 entries are selected to make the math below work:
* base = 0;
* entry = (231 * gray + 128) >> 8;
* }
* else if (alpha < 26) // transparent
* {
* base = 231;
* entry = 0;
* }
* else // partially opaque
* {
* base = 226 + 6 * PNG_DIV51(alpha);
* entry = PNG_DIV51(gray);
* }
*/
src/Source/LibPNG/pngread.c view on Meta::CPAN
*/
unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0;
cmap_entries = 1U << png_ptr->bit_depth;
if (cmap_entries > image->colormap_entries)
png_error(png_ptr, "gray[8] color-map: too few entries");
step = 255 / (cmap_entries - 1);
output_processing = PNG_CMAP_NONE;
/* If there is a tRNS chunk then this either selects a transparent
* value or, if the output has no alpha, the background color.
*/
if (png_ptr->num_trans > 0)
{
trans = png_ptr->trans_color.gray;
if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)
back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
}
src/Source/LibPNG/pngread.c view on Meta::CPAN
for (i=val=0; i<cmap_entries; ++i, val += step)
{
/* 'i' is a file value. While this will result in duplicated
* entries for 8-bit non-sRGB encoded files it is necessary to
* have non-gamma corrected values to do tRNS handling.
*/
if (i != trans)
png_create_colormap_entry(display, i, val, val, val, 255,
P_FILE/*8-bit with file gamma*/);
/* Else this entry is transparent. The colors don't matter if
* there is an alpha channel (back_alpha == 0), but it does no
* harm to pass them in; the values are not set above so this
* passes in white.
*
* NOTE: this preserves the full precision of the application
* supplied background color when it is used.
*/
else
png_create_colormap_entry(display, i, back_r, back_g, back_b,
back_alpha, output_encoding);
src/Source/LibPNG/pngread.c view on Meta::CPAN
if (png_ptr->bit_depth < 8)
png_set_packing(png_ptr);
}
else /* bit depth is 16 */
{
/* The 16-bit input values can be converted directly to 8-bit gamma
* encoded values; however, if a tRNS chunk is present 257 color-map
* entries are required. This means that the extra entry requires
* special processing; add an alpha channel, sacrifice gray level
* 254 and convert transparent (alpha==0) entries to that.
*
* Use libpng to chop the data to 8 bits. Convert it to sRGB at the
* same time to minimize quality loss. If a tRNS chunk is present
* this means libpng must handle it too; otherwise it is impossible
* to do the exact match on the 16-bit value.
*
* If the output has no alpha channel *and* the background color is
* gray then it is possible to let libpng handle the substitution by
* ensuring that the corresponding gray level matches the background
* color exactly.
src/Source/LibPNG/pngread.c view on Meta::CPAN
output_processing = PNG_CMAP_NONE;
break;
}
back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
}
/* output_processing means that the libpng-processed row will be
* 8-bit GA and it has to be processing to single byte color-map
* values. Entry 254 is replaced by either a completely
* transparent entry or by the background color at full
* precision (and the background color is not a simple gray
* level in this case.)
*/
expand_tRNS = 1;
output_processing = PNG_CMAP_TRANS;
background_index = 254;
/* And set (overwrite) color-map entry 254 to the actual
* background color at full precision.
*/
src/Source/LibPNG/pngread.c view on Meta::CPAN
else /* alpha is removed */
{
/* Alpha must be removed as the PNG data is processed when the
* background is a color because the G and A channels are
* independent and the vector addition (non-parallel vectors) is a
* 2-D problem.
*
* This can be reduced to the same algorithm as above by making a
* colormap containing gray levels (for the opaque grays), a
* background entry (for a transparent pixel) and a set of four six
* level color values, one set for each intermediate alpha value.
* See the comments in make_ga_colormap for how this works in the
* per-pixel processing.
*
* If the background is gray, however, we only need a 256 entry gray
* level color map. It is sufficient to make the entry generated
* for the background color be exactly the color specified.
*/
if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 ||
(back_r == back_g && back_g == back_b))
src/Source/LibPNG/pngread.c view on Meta::CPAN
/* Exclude the case where the output is gray; we can always handle this
* with the cases above.
*/
if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0)
{
/* The color-map will be grayscale, so we may as well convert the
* input RGB values to a simple grayscale and use the grayscale
* code above.
*
* NOTE: calling this apparently damages the recognition of the
* transparent color in background color handling; call
* png_set_tRNS_to_alpha before png_set_background_fixed.
*/
png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
-1);
data_encoding = P_sRGB;
/* The output will now be one or two 8-bit gray or gray+alpha
* channels. The more complex case arises when the input has alpha.
*/
if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
src/Source/LibPNG/pngread.c view on Meta::CPAN
/* But if the input has alpha or transparency it must be removed
*/
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
png_ptr->num_trans > 0)
{
png_color_16 c;
png_uint_32 gray = back_g;
/* We need to ensure that the application background exists in
* the colormap and that completely transparent pixels map to
* it. Achieve this simply by ensuring that the entry
* selected for the background really is the background color.
*/
if (data_encoding == P_FILE) /* from the fixup above */
{
/* The app supplied a gray which is in output_encoding, we
* need to convert it to a value of the input (P_FILE)
* encoding then set this palette entry to the required
* output encoding.
*/
src/Source/LibPNG/pngread.c view on Meta::CPAN
back_g, 0/*unused*/, P_LINEAR);
}
/* The background passed to libpng, however, must be the
* output (normally sRGB) value.
*/
c.index = 0; /*unused*/
c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
/* NOTE: the following is apparently a bug in libpng. Without
* it the transparent color recognition in
* png_set_background_fixed seems to go wrong.
*/
expand_tRNS = 1;
png_set_background_fixed(png_ptr, &c,
PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
0/*gamma: not used*/);
}
output_processing = PNG_CMAP_NONE;
}
}
else /* output is color */
{
/* We could use png_quantize here so long as there is no transparent
* color or alpha; png_quantize ignores alpha. Easier overall just
* to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.
* Consequently we always want libpng to produce sRGB data.
*/
data_encoding = P_sRGB;
/* Is there any transparency or alpha? */
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
png_ptr->num_trans > 0)
{
src/Source/LibPNG/pngread.c view on Meta::CPAN
*/
if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
{
png_uint_32 r;
if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
png_error(png_ptr, "rgb+alpha color-map: too few entries");
cmap_entries = make_rgb_colormap(display);
/* Add a transparent entry. */
png_create_colormap_entry(display, cmap_entries, 255, 255,
255, 0, P_sRGB);
/* This is stored as the background index for the processing
* algorithm.
*/
background_index = cmap_entries++;
/* Add 27 r,g,b entries each with alpha 0.5. */
for (r=0; r<256; r = (r << 1) | 0x7f)
src/Source/LibPNG/pngread.c view on Meta::CPAN
unsigned int entry;
/* NOTE: this code is copied as a comment in
* make_ga_colormap above. Please update the
* comment if you change this code!
*/
if (alpha > 229) /* opaque */
{
entry = (231 * gray + 128) >> 8;
}
else if (alpha < 26) /* transparent */
{
entry = 231;
}
else /* partially opaque */
{
entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray);
}
*outrow = (png_byte)entry;
}
src/Source/LibPNG/pngread.c view on Meta::CPAN
c.index = 0; /*unused*/
c.red = display->background->red;
c.green = display->background->green;
c.blue = display->background->blue;
c.gray = display->background->green;
/* This is always an 8-bit sRGB value, using the 'green' channel
* for gray is much better than calculating the luminance here;
* we can get off-by-one errors in that calculation relative to
* the app expectations and that will show up in transparent
* pixels.
*/
png_set_background_fixed(png_ptr, &c,
PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
0/*gamma: not used*/);
}
else /* compose on row: implemented below. */
{
do_local_compose = 1;
src/Source/LibPNG/pngrtran.c view on Meta::CPAN
if (png_rtran_ok(png_ptr, 0) == 0)
return;
png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
}
/* GRR 19990627: the following three functions currently are identical
* to png_set_expand(). However, it is entirely reasonable that someone
* might wish to expand an indexed image to RGB but *not* expand a single,
* fully transparent palette entry to a full alpha channel--perhaps instead
* convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
* the transparent color with a particular RGB value, or drop tRNS entirely.
* IOW, a future version of the library may make the transformations flag
* a bit more fine-grained, with separate bits for each of these three
* functions.
*
* More to the point, these functions make it obvious what libpng will be
* doing, whereas "expand" can (and does) mean any number of things.
*
* GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
* to expand only the sample depth but not to expand the tRNS to alpha
* and its name was changed to png_set_expand_gray_1_2_4_to_8().
src/Source/LibPNG/pngrtran.c view on Meta::CPAN
PNG_RGB_TO_GRAY_ERR)
png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
}
}
#endif
/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
*
* In most cases, the "simple transparency" should be done prior to doing
* gray-to-RGB, or you will have to test 3x as many bytes to check if a
* pixel is transparent. You would also need to make sure that the
* transparency information is upgraded to RGB.
*
* To summarize, the current flow is:
* - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
* with background "in place" if transparent,
* convert to RGB if necessary
* - Gray + alpha -> composite with gray background and remove alpha bytes,
* convert to RGB if necessary
*
* To support RGB backgrounds for gray images we need:
* - Gray + simple transparency -> convert to RGB + simple transparency,
* compare 3 or 6 bytes and composite with
* background "in place" if transparent
* (3x compare/pixel compared to doing
* composite with gray bkgrnd)
* - Gray + alpha -> convert to RGB + alpha, composite with background and
* remove alpha bytes (3x float
* operations/pixel compared with composite
* on gray background)
*
* Greg's change will do this. The reason it wasn't done before is for
* performance, as this increases the per-pixel operations. If we would check
* in advance if the background was gray or RGB, and position the gray-to-RGB
src/Source/LibPNG/pngstruct.h view on Meta::CPAN
png_color_8 sig_bit; /* significant bits in each available channel */
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
png_color_8 shift; /* shift for significant bit tranformation */
#endif
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
|| defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
png_bytep trans_alpha; /* alpha values for paletted files */
png_color_16 trans_color; /* transparent color for non-paletted files */
#endif
png_read_status_ptr read_row_fn; /* called after each row is decoded */
png_write_status_ptr write_row_fn; /* called after each row is encoded */
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
png_progressive_info_ptr info_fn; /* called after header data fully read */
png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */
png_progressive_end_ptr end_fn; /* called after image is complete */
png_bytep save_buffer_ptr; /* current location in save_buffer */
png_bytep save_buffer; /* buffer for previously read data */
src/Source/LibPNG/pngwrite.c view on Meta::CPAN
reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
c = channels;
do /* always at least one channel */
{
png_uint_16 component = *in_ptr++;
/* The following gives 65535 for an alpha of 0, which is fine,
* otherwise if 0/0 is represented as some other value there is more
* likely to be a discontinuity which will probably damage
* compression when moving from a fully transparent area to a
* nearly transparent one. (The assumption here is that opaque
* areas tend not to be 0 intensity.)
*/
if (component >= alpha)
component = 65535;
/* component<alpha, so component/alpha is less than one and
* component*reciprocal is less than 2^31.
*/
else if (component > 0 && alpha < 65535)
{
src/Source/LibPNG/pngwrite.c view on Meta::CPAN
*/
#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
static png_byte
png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
png_uint_32 reciprocal/*from the above macro*/)
{
/* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
* is represented as some other value there is more likely to be a
* discontinuity which will probably damage compression when moving from a
* fully transparent area to a nearly transparent one. (The assumption here
* is that opaque areas tend not to be 0 intensity.)
*
* There is a rounding problem here; if alpha is less than 128 it will end up
* as 0 when scaled to 8 bits. To avoid introducing spurious colors into the
* output change for this too.
*/
if (component >= alpha || alpha < 128)
return 255;
/* component<alpha, so component/alpha is less than one and
src/Source/LibPNG/pngwutil.c view on Meta::CPAN
{
png_byte buf[6];
png_debug(1, "in png_write_tRNS");
if (color_type == PNG_COLOR_TYPE_PALETTE)
{
if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
{
png_app_warning(png_ptr,
"Invalid number of transparent colors specified");
return;
}
/* Write the chunk out as it is */
png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
(png_size_t)num_trans);
}
else if (color_type == PNG_COLOR_TYPE_GRAY)
{
src/Source/LibTIFF4/tif_open.c view on Meta::CPAN
* the value of the FillOrder tag; something they probably do
* not do right now.
*
* The 'M' and 'm' flags are provided because some virtual memory
* systems exhibit poor behaviour when large images are mapped.
* These options permit clients to control the use of memory-mapped
* files on a per-file basis.
*
* The 'C' and 'c' flags are provided because the library support
* for chopping up large strips into multiple smaller strips is not
* application-transparent and as such can cause problems. The 'c'
* option permits applications that only want to look at the tags,
* for example, to get the unadulterated TIFF tag information.
*/
for (cp = mode; *cp; cp++)
switch (*cp) {
case 'b':
#ifndef WORDS_BIGENDIAN
if (m&O_CREAT)
tif->tif_flags |= TIFF_SWAB;
#endif
src/Source/LibWebP/ChangeLog view on Meta::CPAN
c606182 webp-container-spec: Tighten language added by last
a34a502 pngdec: output error messages from libpng
e84c625 Merge "Detect canvas and image size mismatch in decoder."
f626fe2 Detect canvas and image size mismatch in decoder.
f5fbdee demux: stricter image bounds check
30c8158 add extra assert in Huffman decode code
8967b9f SSE2 for lossless decoding (critical) functions.
699d80e Jump-lookup for Huffman coding
c34307a fix some VS9 warnings about type conversion
eeada35 pngdec: add missing include
54b6510 gif2webp: If aligning to even offsets, extra pixels should be transparent
0bcf5ce Merge "remove a malloc() in case we're using only FILTER_NONE for alpha"
2c07143 remove a malloc() in case we're using only FILTER_NONE for alpha
a4d5f59 Faster lossless decoding
fd53bb7 Merge "alternate LUT-base reverse-bits code"
d1c166e Merge "Container spec: a clarification on background color."
fdb9177 Rename a method
5e96753 Container spec: a clarification on background color.
30e77d0 Merge branch '0.3.0'
1b631e2 alternate LUT-base reverse-bits code
24cc307 ~20% faster lossless decoding