summaryrefslogtreecommitdiff
path: root/plugins/AdvaImg/src/FreeImage/BitmapAccess.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/AdvaImg/src/FreeImage/BitmapAccess.cpp')
-rw-r--r--plugins/AdvaImg/src/FreeImage/BitmapAccess.cpp1573
1 files changed, 0 insertions, 1573 deletions
diff --git a/plugins/AdvaImg/src/FreeImage/BitmapAccess.cpp b/plugins/AdvaImg/src/FreeImage/BitmapAccess.cpp
deleted file mode 100644
index 2fbec7ab24..0000000000
--- a/plugins/AdvaImg/src/FreeImage/BitmapAccess.cpp
+++ /dev/null
@@ -1,1573 +0,0 @@
-// ==========================================================
-// FreeImage implementation
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Detlev Vendt (detlev.vendt@brillit.de)
-// - Petr Supina (psup@centrum.cz)
-// - Carsten Klein (c.klein@datagis.com)
-// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
-//
-// This file is part of FreeImage 3
-//
-// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
-// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
-// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
-// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
-// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
-// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
-// THIS DISCLAIMER.
-//
-// Use at your own risk!
-// ==========================================================
-
-#ifdef _MSC_VER
-#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
-#endif
-
-#include <stdlib.h>
-#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__)
-#include <malloc.h>
-#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);
-}
-
-void FreeImage_Aligned_Free(void* mem) {
- __mingw_aligned_free (mem);
-}
-
-#else
-
-void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment) {
- assert(alignment == FIBITMAP_ALIGNMENT);
- /*
- In some rare situations, the malloc routines can return misaligned memory.
- The routine FreeImage_Aligned_Malloc allocates a bit more memory to do
- aligned writes. Normally, it *should* allocate "alignment" extra memory and then writes
- one dword back the true pointer. But if the memory manager returns a
- misaligned block that is less than a dword from the next alignment,
- then the writing back one dword will corrupt memory.
-
- For example, suppose that alignment is 16 and malloc returns the address 0xFFFF.
-
- 16 - 0xFFFF % 16 + 0xFFFF = 16 - 15 + 0xFFFF = 0x10000.
-
- Now, you subtract one dword from that and write and that will corrupt memory.
-
- That's why the code below allocates *two* alignments instead of one.
- */
- void* mem_real = malloc(amount + 2 * alignment);
- if(!mem_real) return NULL;
- char* mem_align = (char*)((unsigned long)(2 * alignment - (unsigned long)mem_real % (unsigned long)alignment) + (unsigned long)mem_real);
- *((long*)mem_align - 1) = (long)mem_real;
- return mem_align;
-}
-
-void FreeImage_Aligned_Free(void* mem) {
- free((void*)*((long*)mem - 1));
-}
-
-#endif // _WIN32 || _WIN64
-
-// ----------------------------------------------------------
-// FIBITMAP memory management
-// ----------------------------------------------------------
-
-/**
-Calculate the size of a FreeImage image.
-Align the palette and the pixels on a FIBITMAP_ALIGNMENT bytes alignment boundary.
-This function includes a protection against malicious images, based on a KISS integer overflow detection mechanism.
-
-@param header_only If TRUE, calculate a 'header only' FIBITMAP size, otherwise calculate a full FIBITMAP size
-@param width Image width
-@param height Image height
-@param bpp Number of bits-per-pixel
-@param need_masks We only store the masks (and allocate memory for them) for 16-bit images of type FIT_BITMAP
-@return Returns a size in BYTE units
-@see FreeImage_AllocateBitmap
-*/
-static size_t
-FreeImage_GetInternalImageSize(BOOL header_only, unsigned width, unsigned height, unsigned bpp, BOOL need_masks) {
- size_t dib_size = sizeof(FREEIMAGEHEADER);
- dib_size += (dib_size % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - dib_size % FIBITMAP_ALIGNMENT : 0);
- dib_size += FIBITMAP_ALIGNMENT - sizeof(BITMAPINFOHEADER) % FIBITMAP_ALIGNMENT;
- dib_size += sizeof(BITMAPINFOHEADER);
- // palette is aligned on a 16 bytes boundary
- dib_size += sizeof(RGBQUAD) * CalculateUsedPaletteEntries(bpp);
- // we both add palette size and masks size if need_masks is true, since CalculateUsedPaletteEntries
- // always returns 0 if need_masks is true (which is only true for 16 bit images).
- dib_size += need_masks ? sizeof(DWORD) * 3 : 0;
- dib_size += (dib_size % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - dib_size % FIBITMAP_ALIGNMENT : 0);
-
- if(!header_only) {
- const size_t header_size = dib_size;
-
- // pixels are aligned on a 16 bytes boundary
- dib_size += (size_t)CalculatePitch(CalculateLine(width, bpp)) * (size_t)height;
-
- // check for possible malloc overflow using a KISS integer overflow detection mechanism
- {
- const double dPitch = floor( ((double)bpp * width + 31.0) / 32.0 ) * 4.0;
- const double dImageSize = (double)header_size + dPitch * height;
- if(dImageSize != (double)dib_size) {
- // here, we are sure to encounter a malloc overflow: try to avoid it ...
- return 0;
- }
-
- /*
- The following constant take into account the additionnal memory used by
- aligned malloc functions as well as debug malloc functions.
- It is supposed here that using a (8 * FIBITMAP_ALIGNMENT) risk margin will be enough
- for the target compiler.
- */
- const double FIBITMAP_MAX_MEMORY = (double)((size_t)-1) - 8 * FIBITMAP_ALIGNMENT;
-
- if(dImageSize > FIBITMAP_MAX_MEMORY) {
- // avoid possible overflow inside C allocation functions
- return 0;
- }
- }
- }
-
- return dib_size;
-}
-
-/**
-Helper for 16-bit FIT_BITMAP
-Returns a pointer to the bitmap's red-, green- and blue masks.
-@param dib The bitmap to obtain masks from.
-@return Returns a pointer to the bitmap's red-, green- and blue masks
-or NULL, if no masks are present (e.g. for 24 bit images).
-*/
-static FREEIMAGERGBMASKS *
-FreeImage_GetRGBMasks(FIBITMAP *dib) {
- return FreeImage_HasRGBMasks(dib) ? (FREEIMAGERGBMASKS *)(((BYTE *)FreeImage_GetInfoHeader(dib)) + sizeof(BITMAPINFOHEADER)) : NULL;
-}
-
-/**
-Internal FIBITMAP allocation.
-
-This function accepts (ext_bits, ext_pitch) arguments. If these are provided the FIBITMAP
-will be allocated as "header only", but bits and pitch will be stored within the FREEIMAGEHEADER
-and the resulting FIBITMAP will have pixels, i.e. HasPixels() will return TRUE.
-- GetBits() and GetPitch return the correct values - either offsets or the stored values (user-provided bits and pitch).
-- Clone() creates a new FIBITMAP with copy of the user pixel data.
-- Unload's implementation does not need to change - it just release a "header only" dib.
-Note that when using external data, the data does not need to have the same alignment as the default 4-byte alignment.
-This enables the possibility to access buffers with, for instance, stricter alignment,
-like the ones used in low-level APIs like OpenCL or intrinsics.
-
-@param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
-@param ext_bits Pointer to external user's pixel buffer if using wrapped buffer, NULL otherwise
-@param ext_pitch Pointer to external user's pixel buffer pitch if using wrapped buffer, 0 otherwise
-@param type Image type
-@param width Image width
-@param height Image height
-@param bpp Number of bits per pixel
-@param red_mask Image red mask
-@param green_mask Image green mask
-@param blue_mask Image blue mask
-@return Returns the allocated FIBITMAP if successful, returns NULL otherwise
-*/
-static FIBITMAP *
-FreeImage_AllocateBitmap(BOOL header_only, 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) {
-
- // check input variables
- width = abs(width);
- height = abs(height);
- if(!((width > 0) && (height > 0))) {
- return NULL;
- }
- if(ext_bits) {
- if(ext_pitch == 0) {
- return NULL;
- }
- assert(header_only == FALSE);
- }
-
- // we only store the masks (and allocate memory for them) for 16-bit images of type FIT_BITMAP
- BOOL need_masks = FALSE;
-
- // check pixel bit depth
- switch(type) {
- case FIT_BITMAP:
- switch(bpp) {
- case 1:
- case 4:
- case 8:
- break;
- case 16:
- need_masks = TRUE;
- break;
- case 24:
- case 32:
- break;
- default:
- bpp = 8;
- break;
- }
- break;
- case FIT_UINT16:
- bpp = 8 * sizeof(unsigned short);
- break;
- case FIT_INT16:
- bpp = 8 * sizeof(short);
- break;
- case FIT_UINT32:
- bpp = 8 * sizeof(DWORD);
- break;
- 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);
- }
-
- 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);
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_AllocateHeader(BOOL header_only, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
- return FreeImage_AllocateBitmap(header_only, NULL, 0, FIT_BITMAP, width, height, bpp, red_mask, green_mask, blue_mask);
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_Allocate(int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
- return FreeImage_AllocateBitmap(FALSE, NULL, 0, FIT_BITMAP, width, height, bpp, red_mask, green_mask, blue_mask);
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_AllocateT(FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
- return FreeImage_AllocateBitmap(FALSE, NULL, 0, type, width, height, bpp, red_mask, green_mask, blue_mask);
-}
-
-void DLL_CALLCONV
-FreeImage_Unload(FIBITMAP *dib) {
- if (NULL != dib) {
- if (NULL != dib->data) {
- // delete possible icc profile ...
- if (FreeImage_GetICCProfile(dib)->data) {
- free(FreeImage_GetICCProfile(dib)->data);
- }
-
- // delete metadata models
- METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
-
- for(METADATAMAP::iterator i = (*metadata).begin(); i != (*metadata).end(); i++) {
- TAGMAP *tagmap = (*i).second;
-
- if(tagmap) {
- for(TAGMAP::iterator j = tagmap->begin(); j != tagmap->end(); j++) {
- FITAG *tag = (*j).second;
- FreeImage_DeleteTag(tag);
- }
-
- delete tagmap;
- }
- }
-
- delete metadata;
-
- // delete embedded thumbnail
- FreeImage_Unload(FreeImage_GetThumbnail(dib));
-
- // delete bitmap ...
- FreeImage_Aligned_Free(dib->data);
- }
-
- free(dib); // ... and the wrapper
- }
-}
-
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_Clone(FIBITMAP *dib) {
- if(!dib) {
- return NULL;
- }
-
- 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
-// ----------------------------------------------------------
-
-FIBITMAP* DLL_CALLCONV
-FreeImage_GetThumbnail(FIBITMAP *dib) {
- return (dib != NULL) ? ((FREEIMAGEHEADER *)dib->data)->thumbnail : NULL;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SetThumbnail(FIBITMAP *dib, FIBITMAP *thumbnail) {
- if(dib == NULL) {
- return FALSE;
- }
- FIBITMAP *currentThumbnail = ((FREEIMAGEHEADER *)dib->data)->thumbnail;
- if(currentThumbnail == thumbnail) {
- return TRUE;
- }
- FreeImage_Unload(currentThumbnail);
-
- ((FREEIMAGEHEADER *)dib->data)->thumbnail = FreeImage_HasPixels(thumbnail) ? FreeImage_Clone(thumbnail) : NULL;
-
- return TRUE;
-}
-
-// ----------------------------------------------------------
-
-FREE_IMAGE_COLOR_TYPE DLL_CALLCONV
-FreeImage_GetColorType(FIBITMAP *dib) {
- RGBQUAD *rgb;
-
- const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-
- // special bitmap type
- if(image_type != FIT_BITMAP) {
- switch(image_type) {
- case FIT_UINT16:
- {
- // 16-bit greyscale TIF can be either FIC_MINISBLACK (the most common case) or FIC_MINISWHITE
- // you can check this using EXIF_MAIN metadata
- FITAG *photometricTag = NULL;
- if(FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, "PhotometricInterpretation", &photometricTag)) {
- const short *value = (short*)FreeImage_GetTagValue(photometricTag);
- // PHOTOMETRIC_MINISWHITE = 0 => min value is white
- // PHOTOMETRIC_MINISBLACK = 1 => min value is black
- return (*value == 0) ? FIC_MINISWHITE : FIC_MINISBLACK;
- }
- return FIC_MINISBLACK;
- }
- break;
- case FIT_RGB16:
- case FIT_RGBF:
- return FIC_RGB;
- case FIT_RGBA16:
- case FIT_RGBAF:
- return FIC_RGBALPHA;
- }
-
- return FIC_MINISBLACK;
- }
-
- // standard image type
- switch (FreeImage_GetBPP(dib)) {
- case 1:
- {
- rgb = FreeImage_GetPalette(dib);
-
- if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) && (rgb->rgbBlue == 0)) {
- rgb++;
-
- if ((rgb->rgbRed == 255) && (rgb->rgbGreen == 255) && (rgb->rgbBlue == 255)) {
- return FIC_MINISBLACK;
- }
- }
-
- if ((rgb->rgbRed == 255) && (rgb->rgbGreen == 255) && (rgb->rgbBlue == 255)) {
- rgb++;
-
- if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) && (rgb->rgbBlue == 0)) {
- return FIC_MINISWHITE;
- }
- }
-
- return FIC_PALETTE;
- }
-
- case 4:
- case 8: // Check if the DIB has a color or a greyscale palette
- {
- int ncolors = FreeImage_GetColorsUsed(dib);
- int minisblack = 1;
- rgb = FreeImage_GetPalette(dib);
-
- for (int i = 0; i < ncolors; i++) {
- if ((rgb->rgbRed != rgb->rgbGreen) || (rgb->rgbRed != rgb->rgbBlue)) {
- return FIC_PALETTE;
- }
-
- // The DIB has a color palette if the greyscale isn't a linear ramp
- // Take care of reversed grey images
- if (rgb->rgbRed != i) {
- if ((ncolors-i-1) != rgb->rgbRed) {
- return FIC_PALETTE;
- } else {
- minisblack = 0;
- }
- }
-
- rgb++;
- }
-
- return minisblack ? FIC_MINISBLACK : FIC_MINISWHITE;
- }
-
- case 16:
- case 24:
- return FIC_RGB;
-
- case 32:
- {
- if (FreeImage_GetICCProfile(dib)->flags & FIICC_COLOR_IS_CMYK) {
- return FIC_CMYK;
- }
-
- if( FreeImage_HasPixels(dib) ) {
- // check for fully opaque alpha layer
- for (unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
- rgb = (RGBQUAD *)FreeImage_GetScanLine(dib, y);
-
- for (unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
- if (rgb[x].rgbReserved != 0xFF) {
- return FIC_RGBALPHA;
- }
- }
- }
- return FIC_RGB;
- }
-
- return FIC_RGBALPHA;
- }
-
- default :
- return FIC_MINISBLACK;
- }
-}
-
-// ----------------------------------------------------------
-
-FREE_IMAGE_TYPE DLL_CALLCONV
-FreeImage_GetImageType(FIBITMAP *dib) {
- return (dib != NULL) ? ((FREEIMAGEHEADER *)dib->data)->type : FIT_UNKNOWN;
-}
-
-// ----------------------------------------------------------
-
-BOOL DLL_CALLCONV
-FreeImage_HasPixels(FIBITMAP *dib) {
- return (dib != NULL) ? ((FREEIMAGEHEADER *)dib->data)->has_pixels : FALSE;
-}
-
-// ----------------------------------------------------------
-
-BOOL DLL_CALLCONV
-FreeImage_HasRGBMasks(FIBITMAP *dib) {
- return dib && FreeImage_GetInfoHeader(dib)->biCompression == BI_BITFIELDS;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetRedMask(FIBITMAP *dib) {
- FREEIMAGERGBMASKS *masks = NULL;
- FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
- switch(image_type) {
- case FIT_BITMAP:
- // check for 16-bit RGB (565 or 555)
- masks = FreeImage_GetRGBMasks(dib);
- if (masks) {
- return masks->red_mask;
- }
- return FreeImage_GetBPP(dib) >= 24 ? FI_RGBA_RED_MASK : 0;
- default:
- return 0;
- }
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetGreenMask(FIBITMAP *dib) {
- FREEIMAGERGBMASKS *masks = NULL;
- FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
- switch(image_type) {
- case FIT_BITMAP:
- // check for 16-bit RGB (565 or 555)
- masks = FreeImage_GetRGBMasks(dib);
- if (masks) {
- return masks->green_mask;
- }
- return FreeImage_GetBPP(dib) >= 24 ? FI_RGBA_GREEN_MASK : 0;
- default:
- return 0;
- }
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetBlueMask(FIBITMAP *dib) {
- FREEIMAGERGBMASKS *masks = NULL;
- FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
- switch(image_type) {
- case FIT_BITMAP:
- // check for 16-bit RGB (565 or 555)
- masks = FreeImage_GetRGBMasks(dib);
- if (masks) {
- return masks->blue_mask;
- }
- return FreeImage_GetBPP(dib) >= 24 ? FI_RGBA_BLUE_MASK : 0;
- default:
- return 0;
- }
-}
-
-// ----------------------------------------------------------
-
-BOOL DLL_CALLCONV
-FreeImage_HasBackgroundColor(FIBITMAP *dib) {
- 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) {
- return dib ? FreeImage_GetInfoHeader(dib)->biBitCount : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetLine(FIBITMAP *dib) {
- return dib ? ((FreeImage_GetWidth(dib) * FreeImage_GetBPP(dib)) + 7) / 8 : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetPitch(FIBITMAP *dib) {
- if(dib) {
- FREEIMAGEHEADER *fih = (FREEIMAGEHEADER *)dib->data;
- return fih->external_bits ? fih->external_pitch : (FreeImage_GetLine(dib) + 3 & ~3);
- }
- return 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetColorsUsed(FIBITMAP *dib) {
- return dib ? FreeImage_GetInfoHeader(dib)->biClrUsed : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetDIBSize(FIBITMAP *dib) {
- return (dib) ? sizeof(BITMAPINFOHEADER) + (FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD)) + (FreeImage_GetPitch(dib) * FreeImage_GetHeight(dib)) : 0;
-}
-
-RGBQUAD * DLL_CALLCONV
-FreeImage_GetPalette(FIBITMAP *dib) {
- return (dib && FreeImage_GetBPP(dib) < 16) ? (RGBQUAD *)(((BYTE *)FreeImage_GetInfoHeader(dib)) + sizeof(BITMAPINFOHEADER)) : NULL;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetDotsPerMeterX(FIBITMAP *dib) {
- return (dib) ? FreeImage_GetInfoHeader(dib)->biXPelsPerMeter : 0;
-}
-
-unsigned DLL_CALLCONV
-FreeImage_GetDotsPerMeterY(FIBITMAP *dib) {
- return (dib) ? FreeImage_GetInfoHeader(dib)->biYPelsPerMeter : 0;
-}
-
-void DLL_CALLCONV
-FreeImage_SetDotsPerMeterX(FIBITMAP *dib, unsigned res) {
- if(dib) {
- FreeImage_GetInfoHeader(dib)->biXPelsPerMeter = res;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_SetDotsPerMeterY(FIBITMAP *dib, unsigned res) {
- if(dib) {
- FreeImage_GetInfoHeader(dib)->biYPelsPerMeter = res;
- }
-}
-
-BITMAPINFOHEADER * DLL_CALLCONV
-FreeImage_GetInfoHeader(FIBITMAP *dib) {
- if(!dib) {
- return NULL;
- }
- size_t lp = (size_t)dib->data + sizeof(FREEIMAGEHEADER);
- lp += (lp % FIBITMAP_ALIGNMENT ? FIBITMAP_ALIGNMENT - lp % FIBITMAP_ALIGNMENT : 0);
- lp += FIBITMAP_ALIGNMENT - sizeof(BITMAPINFOHEADER) % FIBITMAP_ALIGNMENT;
- return (BITMAPINFOHEADER *)lp;
-}
-
-BITMAPINFO * DLL_CALLCONV
-FreeImage_GetInfo(FIBITMAP *dib) {
- return (BITMAPINFO *)FreeImage_GetInfoHeader(dib);
-}
-
-// ----------------------------------------------------------
-// Metadata routines
-// ----------------------------------------------------------
-
-FIMETADATA * DLL_CALLCONV
-FreeImage_FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, FITAG **tag) {
- if(!dib) {
- return NULL;
- }
-
- // get the metadata model
- METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
- TAGMAP *tagmap = NULL;
- if( (*metadata).find(model) != (*metadata).end() ) {
- tagmap = (*metadata)[model];
- }
- if(tagmap) {
- // allocate a handle
- FIMETADATA *handle = (FIMETADATA *)malloc(sizeof(FIMETADATA));
- if(handle) {
- // calculate the size of a METADATAHEADER
- int header_size = sizeof(METADATAHEADER);
-
- handle->data = (BYTE *)malloc(header_size * sizeof(BYTE));
-
- if(handle->data) {
- memset(handle->data, 0, header_size * sizeof(BYTE));
-
- // write out the METADATAHEADER
- METADATAHEADER *mdh = (METADATAHEADER *)handle->data;
-
- mdh->pos = 1;
- mdh->tagmap = tagmap;
-
- // get the first element
- TAGMAP::iterator i = tagmap->begin();
- *tag = (*i).second;
-
- return handle;
- }
-
- free(handle);
- }
- }
-
- return NULL;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_FindNextMetadata(FIMETADATA *mdhandle, FITAG **tag) {
- if(!mdhandle) {
- return FALSE;
- }
-
- METADATAHEADER *mdh = (METADATAHEADER *)mdhandle->data;
- TAGMAP *tagmap = mdh->tagmap;
-
- 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);
- }
-
- delete tagmap;
- metadata->erase(model_iterator);
- }
- }
-
- return TRUE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_GetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG **tag) {
- if(!dib || !key || !tag) {
- return FALSE;
- }
-
- TAGMAP *tagmap = NULL;
- *tag = NULL;
-
- // get the metadata model
- METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
- if(!(*metadata).empty()) {
- METADATAMAP::iterator model_iterator = metadata->find(model);
- if (model_iterator != metadata->end() ) {
- // this model exists : try to get the requested tag
- tagmap = model_iterator->second;
- TAGMAP::iterator tag_iterator = tagmap->find(key);
- if (tag_iterator != tagmap->end() ) {
- // get the requested tag
- *tag = tag_iterator->second;
- }
- }
- }
-
- return (*tag != NULL) ? TRUE : FALSE;
-}
-
-/**
-Build and set a FITAG whose type is FIDT_ASCII.
-@param model Metadata model to be filled
-@param dib Image to be filled
-@param key Tag key
-@param value Tag value as a ASCII string
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-BOOL DLL_CALLCONV
-FreeImage_SetMetadataKeyValue(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, const char *value) {
- if(!dib || !key || !value) {
- return FALSE;
- }
- // create a tag
- FITAG *tag = FreeImage_CreateTag();
- if(tag) {
- BOOL bSuccess = TRUE;
- // fill the tag
- DWORD tag_length = (DWORD)(strlen(value) + 1);
- bSuccess &= FreeImage_SetTagKey(tag, key);
- bSuccess &= FreeImage_SetTagLength(tag, tag_length);
- bSuccess &= FreeImage_SetTagCount(tag, tag_length);
- bSuccess &= FreeImage_SetTagType(tag, FIDT_ASCII);
- bSuccess &= FreeImage_SetTagValue(tag, value);
- if(bSuccess) {
- // set the tag
- bSuccess &= FreeImage_SetMetadata(model, dib, FreeImage_GetTagKey(tag), tag);
- }
- // delete the tag
- FreeImage_DeleteTag(tag);
-
- return bSuccess;
- }
-
- return FALSE;
-}
-
-// ----------------------------------------------------------
-
-unsigned DLL_CALLCONV
-FreeImage_GetMetadataCount(FREE_IMAGE_MDMODEL model, FIBITMAP *dib) {
- if(!dib) {
- return FALSE;
- }
-
- TAGMAP *tagmap = NULL;
-
- // get the metadata model
- METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
- if( (*metadata).find(model) != (*metadata).end() ) {
- tagmap = (*metadata)[model];
- }
- if(!tagmap) {
- // this model, doesn't exist: return
- return 0;
- }
-
- // get the tag count
- return (unsigned)tagmap->size();
-}
-
-// ----------------------------------------------------------
-
-unsigned DLL_CALLCONV
-FreeImage_GetMemorySize(FIBITMAP *dib) {
- if (!dib) {
- return 0;
- }
- FREEIMAGEHEADER *header = (FREEIMAGEHEADER *)dib->data;
- BITMAPINFOHEADER *bih = FreeImage_GetInfoHeader(dib);
-
- BOOL header_only = !header->has_pixels || header->external_bits != NULL;
- BOOL need_masks = bih->biCompression == BI_BITFIELDS;
- unsigned width = bih->biWidth;
- unsigned height = bih->biHeight;
- unsigned bpp = bih->biBitCount;
-
- // start off with the size of the FIBITMAP structure
- size_t size = sizeof(FIBITMAP);
-
- // add sizes of FREEIMAGEHEADER, BITMAPINFOHEADER, palette and DIB data
- size += FreeImage_GetInternalImageSize(header_only, width, height, bpp, need_masks);
-
- // add ICC profile size
- size += header->iccProfile.size;
-
- // add thumbnail image size
- if (header->thumbnail) {
- // we assume a thumbnail not having a thumbnail as well,
- // so this recursive call should not create an infinite loop
- size += FreeImage_GetMemorySize(header->thumbnail);
- }
-
- // add metadata size
- METADATAMAP *md = header->metadata;
- if (!md) {
- return (unsigned)size;
- }
-
- // add size of METADATAMAP
- size += sizeof(METADATAMAP);
-
- const size_t models = md->size();
- if (models == 0) {
- return (unsigned)size;
- }
-
- unsigned tags = 0;
-
- for (METADATAMAP::iterator i = md->begin(); i != md->end(); i++) {
- TAGMAP *tm = i->second;
- if (tm) {
- for (TAGMAP::iterator j = tm->begin(); j != tm->end(); j++) {
- ++tags;
- const std::string & key = j->first;
- size += key.capacity();
- size += FreeImage_GetTagMemorySize(j->second);
- }
- }
- }
-
- // add size of all TAGMAP instances
- size += models * sizeof(TAGMAP);
- // add size of tree nodes in METADATAMAP
- size += MapIntrospector<METADATAMAP>::GetNodesMemorySize(models);
- // add size of tree nodes in TAGMAP
- size += MapIntrospector<TAGMAP>::GetNodesMemorySize(tags);
-
- return (unsigned)size;
-}
-