Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
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);
}
return NULL;
}
FIBITMAP * DLL_CALLCONV
FreeImage_AllocateHeaderForBits(BYTE *ext_bits, unsigned ext_pitch, FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
return FreeImage_AllocateBitmap(FALSE, ext_bits, ext_pitch, type, width, height, bpp, red_mask, green_mask, blue_mask);
}
FIBITMAP * DLL_CALLCONV
FreeImage_AllocateHeaderT(BOOL header_only, FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
return FreeImage_AllocateBitmap(header_only, NULL, 0, type, width, height, bpp, red_mask, green_mask, blue_mask);
}
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
}
FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib);
unsigned width = FreeImage_GetWidth(dib);
unsigned height = FreeImage_GetHeight(dib);
unsigned bpp = FreeImage_GetBPP(dib);
const BYTE *ext_bits = ((FREEIMAGEHEADER *)dib->data)->external_bits;
// check for pixel availability ...
BOOL header_only = FreeImage_HasPixels(dib) ? FALSE : TRUE;
// check whether this image has masks defined ...
BOOL need_masks = (bpp == 16 && type == FIT_BITMAP) ? TRUE : FALSE;
// allocate a new dib
FIBITMAP *new_dib = FreeImage_AllocateHeaderT(header_only, type, width, height, bpp,
FreeImage_GetRedMask(dib), FreeImage_GetGreenMask(dib), FreeImage_GetBlueMask(dib));
if (new_dib) {
// save ICC profile links
FIICCPROFILE *src_iccProfile = FreeImage_GetICCProfile(dib);
FIICCPROFILE *dst_iccProfile = FreeImage_GetICCProfile(new_dib);
// save metadata links
METADATAMAP *src_metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
METADATAMAP *dst_metadata = ((FREEIMAGEHEADER *)new_dib->data)->metadata;
// calculate the size of the src 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' calculation
size_t dib_size = FreeImage_GetInternalImageSize(header_only || ext_bits, width, height, bpp, need_masks);
// copy the bitmap + internal pointers (remember to restore new_dib internal pointers later)
memcpy(new_dib->data, dib->data, dib_size);
// reset ICC profile link for new_dib
memset(dst_iccProfile, 0, sizeof(FIICCPROFILE));
// restore metadata link for new_dib
((FREEIMAGEHEADER *)new_dib->data)->metadata = dst_metadata;
// reset thumbnail link for new_dib
((FREEIMAGEHEADER *)new_dib->data)->thumbnail = NULL;
// copy possible ICC profile
FreeImage_CreateICCProfile(new_dib, src_iccProfile->data, src_iccProfile->size);
dst_iccProfile->flags = src_iccProfile->flags;
// copy metadata models
for(METADATAMAP::iterator i = (*src_metadata).begin(); i != (*src_metadata).end(); i++) {
int model = (*i).first;
TAGMAP *src_tagmap = (*i).second;
if(src_tagmap) {
// create a metadata model
TAGMAP *dst_tagmap = new(std::nothrow) TAGMAP();
if(dst_tagmap) {
// fill the model
for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
std::string dst_key = (*j).first;
FITAG *dst_tag = FreeImage_CloneTag( (*j).second );
// assign key and tag value
(*dst_tagmap)[dst_key] = dst_tag;
}
// assign model and tagmap
(*dst_metadata)[model] = dst_tagmap;
}
}
}
// copy the thumbnail
FreeImage_SetThumbnail(new_dib, FreeImage_GetThumbnail(dib));
// copy user provided pixel buffer (if any)
if(ext_bits) {
const unsigned pitch = FreeImage_GetPitch(dib);
const unsigned linesize = FreeImage_GetLine(dib);
for(unsigned y = 0; y < height; y++) {
memcpy(FreeImage_GetScanLine(new_dib, y), ext_bits, linesize);
ext_bits += pitch;
}
}
return new_dib;
}
return NULL;
}
// ----------------------------------------------------------
BYTE * DLL_CALLCONV
FreeImage_GetBits(FIBITMAP *dib) {
if(!FreeImage_HasPixels(dib)) {
return NULL;
}
if(((FREEIMAGEHEADER *)dib->data)->external_bits) {
return ((FREEIMAGEHEADER *)dib->data)->external_bits;
}
// returns the pixels aligned on a FIBITMAP_ALIGNMENT bytes alignment boundary
size_t lp = (size_t)FreeImage_GetInfoHeader(dib);
lp += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * FreeImage_GetColorsUsed(dib);
lp += FreeImage_HasRGBMasks(dib) ? sizeof(DWORD) * 3 : 0;
lp += (lp % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - lp % FIBITMAP_ALIGNMENT : 0);
return (BYTE *)lp;
}
// ----------------------------------------------------------
// DIB information functions
// ----------------------------------------------------------
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
int current_pos = mdh->pos;
int mapsize = (int)tagmap->size();
if(current_pos < mapsize) {
// get the tag element at position pos
int count = 0;
for(TAGMAP::iterator i = tagmap->begin(); i != tagmap->end(); i++) {
if(count == current_pos) {
*tag = (*i).second;
mdh->pos++;
break;
}
count++;
}
return TRUE;
}
return FALSE;
}
void DLL_CALLCONV
FreeImage_FindCloseMetadata(FIMETADATA *mdhandle) {
if (NULL != mdhandle) { // delete the handle
if (NULL != mdhandle->data) {
free(mdhandle->data);
}
free(mdhandle); // ... and the wrapper
}
}
// ----------------------------------------------------------
BOOL DLL_CALLCONV
FreeImage_CloneMetadata(FIBITMAP *dst, FIBITMAP *src) {
if(!src || !dst) {
return FALSE;
}
// get metadata links
METADATAMAP *src_metadata = ((FREEIMAGEHEADER *)src->data)->metadata;
METADATAMAP *dst_metadata = ((FREEIMAGEHEADER *)dst->data)->metadata;
// copy metadata models, *except* the FIMD_ANIMATION model
for(METADATAMAP::iterator i = (*src_metadata).begin(); i != (*src_metadata).end(); i++) {
int model = (*i).first;
if(model == (int)FIMD_ANIMATION) {
continue;
}
TAGMAP *src_tagmap = (*i).second;
if(src_tagmap) {
if( dst_metadata->find(model) != dst_metadata->end() ) {
// destroy dst model
FreeImage_SetMetadata((FREE_IMAGE_MDMODEL)model, dst, NULL, NULL);
}
// create a metadata model
TAGMAP *dst_tagmap = new(std::nothrow) TAGMAP();
if(dst_tagmap) {
// fill the model
for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
std::string dst_key = (*j).first;
FITAG *dst_tag = FreeImage_CloneTag( (*j).second );
// assign key and tag value
(*dst_tagmap)[dst_key] = dst_tag;
}
// assign model and tagmap
(*dst_metadata)[model] = dst_tagmap;
}
}
}
// clone resolution
FreeImage_SetDotsPerMeterX(dst, FreeImage_GetDotsPerMeterX(src));
FreeImage_SetDotsPerMeterY(dst, FreeImage_GetDotsPerMeterY(src));
return TRUE;
}
// ----------------------------------------------------------
BOOL DLL_CALLCONV
FreeImage_SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG *tag) {
if(!dib) {
return FALSE;
}
TAGMAP *tagmap = NULL;
// get the metadata model
METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
METADATAMAP::iterator model_iterator = metadata->find(model);
if (model_iterator != metadata->end()) {
tagmap = model_iterator->second;
}
if(key != NULL) {
if(!tagmap) {
// this model, doesn't exist: create it
tagmap = new(std::nothrow) TAGMAP();
(*metadata)[model] = tagmap;
}
if(tag) {
// first check the tag
if(FreeImage_GetTagKey(tag) == NULL) {
FreeImage_SetTagKey(tag, key);
} else if(strcmp(key, FreeImage_GetTagKey(tag)) != 0) {
// set the tag key
FreeImage_SetTagKey(tag, key);
}
if(FreeImage_GetTagCount(tag) * FreeImage_TagDataWidth(FreeImage_GetTagType(tag)) != FreeImage_GetTagLength(tag)) {
FreeImage_OutputMessageProc(FIF_UNKNOWN, "Invalid data count for tag '%s'", key);
return FALSE;
}
// fill the tag ID if possible and if it's needed
TagLib& tag_lib = TagLib::instance();
switch(model) {
case FIMD_IPTC:
{
int id = tag_lib.getTagID(TagLib::IPTC, key);
/*
if(id == -1) {
FreeImage_OutputMessageProc(FIF_UNKNOWN, "IPTC: Invalid key '%s'", key);
}
*/
FreeImage_SetTagID(tag, (WORD)id);
}
break;
default:
break;
}
// delete existing tag
FITAG *old_tag = (*tagmap)[key];
if(old_tag) {
FreeImage_DeleteTag(old_tag);
}
// create a new tag
(*tagmap)[key] = FreeImage_CloneTag(tag);
}
else {
// delete existing tag
TAGMAP::iterator i = tagmap->find(key);
if(i != tagmap->end()) {
FITAG *old_tag = (*i).second;
FreeImage_DeleteTag(old_tag);
tagmap->erase(key);
}
}
}
else {
// destroy the metadata model
if(tagmap) {
for(TAGMAP::iterator i = tagmap->begin(); i != tagmap->end(); i++) {
FITAG *tag = (*i).second;
FreeImage_DeleteTag(tag);
( run in 1.331 second using v1.01-cache-2.11-cpan-5b529ec07f3 )