Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
#endif // _WIN32 || _WIN64 || __MINGW32__
#include "FreeImage.h"
#include "FreeImageIO.h"
#include "Utilities.h"
#include "MapIntrospector.h"
#include "../Metadata/FreeImageTag.h"
/**
Constants for the BITMAPINFOHEADER::biCompression field
BI_RGB:
The bitmap is in uncompressed red green blue (RGB) format that is not compressed and does not use color masks.
BI_BITFIELDS:
The bitmap is not compressed and the color table consists of three DWORD color masks that specify the red, green, and blue components,
respectively, of each pixel. This is valid when used with 16 and 32-bits per pixel bitmaps.
*/
#ifndef _WINGDI_
#define BI_RGB 0L
#define BI_BITFIELDS 3L
#endif // _WINGDI_
// ----------------------------------------------------------
// Metadata definitions
// ----------------------------------------------------------
/** helper for map<key, value> where value is a pointer to a FreeImage tag */
typedef std::map<std::string, FITAG*> TAGMAP;
/** helper for map<FREE_IMAGE_MDMODEL, TAGMAP*> */
typedef std::map<int, TAGMAP*> METADATAMAP;
/** helper for metadata iterator */
FI_STRUCT (METADATAHEADER) {
long pos; //! current position when iterating the map
TAGMAP *tagmap; //! pointer to the tag map
};
// ----------------------------------------------------------
// FIBITMAP definition
// ----------------------------------------------------------
/**
FreeImage header structure
*/
FI_STRUCT (FREEIMAGEHEADER) {
/** data type - bitmap, array of long, double, complex, etc */
FREE_IMAGE_TYPE type;
/** background color used for RGB transparency */
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;
/** optionally contains a thumbnail attached to the bitmap */
FIBITMAP *thumbnail;
/**@name external pixel buffer management */
//@{
/** pointer to user provided pixels, NULL otherwise */
BYTE *external_bits;
/** user provided pitch, 0 otherwise */
unsigned external_pitch;
//@}
//BYTE filler[1]; // fill to 32-bit alignment
};
// ----------------------------------------------------------
// FREEIMAGERGBMASKS definition
// ----------------------------------------------------------
/**
RGB mask structure - mainly used for 16-bit RGB555 / RGB 565 FIBITMAP
*/
FI_STRUCT (FREEIMAGERGBMASKS) {
unsigned red_mask; //! bit layout of the red components
unsigned green_mask; //! bit layout of the green components
unsigned blue_mask; //! bit layout of the blue components
};
// ----------------------------------------------------------
// Memory allocation on a specified alignment boundary
// ----------------------------------------------------------
#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment) {
assert(alignment == FIBITMAP_ALIGNMENT);
return _aligned_malloc(amount, alignment);
}
void FreeImage_Aligned_Free(void* mem) {
_aligned_free(mem);
}
#elif defined (__MINGW32__)
void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment) {
assert(alignment == FIBITMAP_ALIGNMENT);
return __mingw_aligned_malloc (amount, alignment);
}
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
case FIT_INT32:
bpp = 8 * sizeof(LONG);
break;
case FIT_FLOAT:
bpp = 8 * sizeof(float);
break;
case FIT_DOUBLE:
bpp = 8 * sizeof(double);
break;
case FIT_COMPLEX:
bpp = 8 * sizeof(FICOMPLEX);
break;
case FIT_RGB16:
bpp = 8 * sizeof(FIRGB16);
break;
case FIT_RGBA16:
bpp = 8 * sizeof(FIRGBA16);
break;
case FIT_RGBF:
bpp = 8 * sizeof(FIRGBF);
break;
case FIT_RGBAF:
bpp = 8 * sizeof(FIRGBAF);
break;
default:
return NULL;
}
FIBITMAP *bitmap = (FIBITMAP *)malloc(sizeof(FIBITMAP));
if (bitmap != NULL) {
// calculate the size of a FreeImage image
// align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary
// palette is aligned on a 16 bytes boundary
// pixels are aligned on a 16 bytes boundary
// when using a user provided pixel buffer, force a 'header only' allocation
size_t dib_size = FreeImage_GetInternalImageSize(header_only || ext_bits, width, height, bpp, need_masks);
if(dib_size == 0) {
// memory allocation will fail (probably a malloc overflow)
free(bitmap);
return NULL;
}
bitmap->data = (BYTE *)FreeImage_Aligned_Malloc(dib_size * sizeof(BYTE), FIBITMAP_ALIGNMENT);
if (bitmap->data != NULL) {
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;
// initialize metadata models list
fih->metadata = new(std::nothrow) METADATAMAP;
// initialize attached thumbnail
fih->thumbnail = NULL;
// store a pointer to user provided pixel buffer (if any)
fih->external_bits = ext_bits;
fih->external_pitch = ext_pitch;
// write out the BITMAPINFOHEADER
BITMAPINFOHEADER *bih = FreeImage_GetInfoHeader(bitmap);
bih->biSize = sizeof(BITMAPINFOHEADER);
bih->biWidth = width;
bih->biHeight = height;
bih->biPlanes = 1;
bih->biCompression = need_masks ? BI_BITFIELDS : BI_RGB;
bih->biBitCount = (WORD)bpp;
bih->biClrUsed = CalculateUsedPaletteEntries(bpp);
bih->biClrImportant = bih->biClrUsed;
bih->biXPelsPerMeter = 2835; // 72 dpi
bih->biYPelsPerMeter = 2835; // 72 dpi
if(bpp == 8) {
// build a default greyscale palette (very useful for image processing)
RGBQUAD *pal = FreeImage_GetPalette(bitmap);
for(int i = 0; i < 256; i++) {
pal[i].rgbRed = (BYTE)i;
pal[i].rgbGreen = (BYTE)i;
pal[i].rgbBlue = (BYTE)i;
}
}
// just setting the masks (only if needed) just like the palette.
if (need_masks) {
FREEIMAGERGBMASKS *masks = FreeImage_GetRGBMasks(bitmap);
masks->red_mask = red_mask;
masks->green_mask = green_mask;
masks->blue_mask = blue_mask;
}
return bitmap;
}
free(bitmap);
}
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
if(dib) {
RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
return (bkgnd_color->rgbReserved != 0) ? TRUE : FALSE;
}
return FALSE;
}
BOOL DLL_CALLCONV
FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor) {
if(dib && bkcolor) {
if(FreeImage_HasBackgroundColor(dib)) {
// get the background color
RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
memcpy(bkcolor, bkgnd_color, sizeof(RGBQUAD));
// get the background index
if(FreeImage_GetBPP(dib) == 8) {
RGBQUAD *pal = FreeImage_GetPalette(dib);
for(unsigned i = 0; i < FreeImage_GetColorsUsed(dib); i++) {
if(bkgnd_color->rgbRed == pal[i].rgbRed) {
if(bkgnd_color->rgbGreen == pal[i].rgbGreen) {
if(bkgnd_color->rgbBlue == pal[i].rgbBlue) {
bkcolor->rgbReserved = (BYTE)i;
return TRUE;
}
}
}
}
}
bkcolor->rgbReserved = 0;
return TRUE;
}
}
return FALSE;
}
BOOL DLL_CALLCONV
FreeImage_SetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor) {
if(dib) {
RGBQUAD *bkgnd_color = &((FREEIMAGEHEADER *)dib->data)->bkgnd_color;
if(bkcolor) {
// set the background color
memcpy(bkgnd_color, bkcolor, sizeof(RGBQUAD));
// enable the file background color
bkgnd_color->rgbReserved = 1;
} else {
// clear and disable the file background color
memset(bkgnd_color, 0, sizeof(RGBQUAD));
}
return TRUE;
}
return FALSE;
}
// ----------------------------------------------------------
BOOL DLL_CALLCONV
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;
}
}
return -1;
}
// ----------------------------------------------------------
FIICCPROFILE * DLL_CALLCONV
FreeImage_GetICCProfile(FIBITMAP *dib) {
FIICCPROFILE *profile = (dib) ? (FIICCPROFILE *)&((FREEIMAGEHEADER *)dib->data)->iccProfile : NULL;
return profile;
}
FIICCPROFILE * DLL_CALLCONV
FreeImage_CreateICCProfile(FIBITMAP *dib, void *data, long size) {
// clear the profile but preserve profile->flags
FreeImage_DestroyICCProfile(dib);
// create the new profile
FIICCPROFILE *profile = FreeImage_GetICCProfile(dib);
if(size && profile) {
profile->data = malloc(size);
if(profile->data) {
memcpy(profile->data, data, profile->size = size);
}
}
return profile;
}
void DLL_CALLCONV
FreeImage_DestroyICCProfile(FIBITMAP *dib) {
FIICCPROFILE *profile = FreeImage_GetICCProfile(dib);
if(profile) {
if (profile->data) {
free (profile->data);
}
// clear the profile but preserve profile->flags
profile->data = NULL;
profile->size = 0;
}
}
// ----------------------------------------------------------
unsigned DLL_CALLCONV
FreeImage_GetWidth(FIBITMAP *dib) {
return dib ? FreeImage_GetInfoHeader(dib)->biWidth : 0;
}
unsigned DLL_CALLCONV
FreeImage_GetHeight(FIBITMAP *dib) {
return (dib) ? FreeImage_GetInfoHeader(dib)->biHeight : 0;
}
unsigned DLL_CALLCONV
FreeImage_GetBPP(FIBITMAP *dib) {
( run in 0.498 second using v1.01-cache-2.11-cpan-fa01517f264 )