summaryrefslogtreecommitdiff
path: root/plugins/AdvaImg/src/FreeImage
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/AdvaImg/src/FreeImage')
-rw-r--r--plugins/AdvaImg/src/FreeImage/BitmapAccess.cpp1573
-rw-r--r--plugins/AdvaImg/src/FreeImage/CacheFile.cpp271
-rw-r--r--plugins/AdvaImg/src/FreeImage/ColorLookup.cpp785
-rw-r--r--plugins/AdvaImg/src/FreeImage/Conversion.cpp551
-rw-r--r--plugins/AdvaImg/src/FreeImage/Conversion16_555.cpp209
-rw-r--r--plugins/AdvaImg/src/FreeImage/Conversion16_565.cpp204
-rw-r--r--plugins/AdvaImg/src/FreeImage/Conversion24.cpp252
-rw-r--r--plugins/AdvaImg/src/FreeImage/Conversion32.cpp345
-rw-r--r--plugins/AdvaImg/src/FreeImage/Conversion4.cpp246
-rw-r--r--plugins/AdvaImg/src/FreeImage/Conversion8.cpp305
-rw-r--r--plugins/AdvaImg/src/FreeImage/ConversionFloat.cpp194
-rw-r--r--plugins/AdvaImg/src/FreeImage/ConversionRGB16.cpp144
-rw-r--r--plugins/AdvaImg/src/FreeImage/ConversionRGBA16.cpp147
-rw-r--r--plugins/AdvaImg/src/FreeImage/ConversionRGBAF.cpp250
-rw-r--r--plugins/AdvaImg/src/FreeImage/ConversionRGBF.cpp243
-rw-r--r--plugins/AdvaImg/src/FreeImage/ConversionType.cpp699
-rw-r--r--plugins/AdvaImg/src/FreeImage/ConversionUINT16.cpp134
-rw-r--r--plugins/AdvaImg/src/FreeImage/FreeImage.cpp226
-rw-r--r--plugins/AdvaImg/src/FreeImage/FreeImageIO.cpp175
-rw-r--r--plugins/AdvaImg/src/FreeImage/GetType.cpp91
-rw-r--r--plugins/AdvaImg/src/FreeImage/Halftoning.cpp474
-rw-r--r--plugins/AdvaImg/src/FreeImage/J2KHelper.cpp591
-rw-r--r--plugins/AdvaImg/src/FreeImage/J2KHelper.h36
-rw-r--r--plugins/AdvaImg/src/FreeImage/LFPQuantizer.cpp208
-rw-r--r--plugins/AdvaImg/src/FreeImage/MNGHelper.cpp1320
-rw-r--r--plugins/AdvaImg/src/FreeImage/MemoryIO.cpp237
-rw-r--r--plugins/AdvaImg/src/FreeImage/MultiPage.cpp990
-rw-r--r--plugins/AdvaImg/src/FreeImage/NNQuantizer.cpp507
-rw-r--r--plugins/AdvaImg/src/FreeImage/PSDParser.cpp1057
-rw-r--r--plugins/AdvaImg/src/FreeImage/PSDParser.h271
-rw-r--r--plugins/AdvaImg/src/FreeImage/PixelAccess.cpp197
-rw-r--r--plugins/AdvaImg/src/FreeImage/Plugin.cpp822
-rw-r--r--plugins/AdvaImg/src/FreeImage/PluginBMP.cpp1494
-rw-r--r--plugins/AdvaImg/src/FreeImage/PluginGIF.cpp1406
-rw-r--r--plugins/AdvaImg/src/FreeImage/PluginICO.cpp824
-rw-r--r--plugins/AdvaImg/src/FreeImage/PluginJPEG.cpp1706
-rw-r--r--plugins/AdvaImg/src/FreeImage/PluginPNG.cpp1115
-rw-r--r--plugins/AdvaImg/src/FreeImage/TIFFLogLuv.cpp65
-rw-r--r--plugins/AdvaImg/src/FreeImage/ToneMapping.cpp75
-rw-r--r--plugins/AdvaImg/src/FreeImage/WuQuantizer.cpp559
-rw-r--r--plugins/AdvaImg/src/FreeImage/ZLibInterface.cpp223
-rw-r--r--plugins/AdvaImg/src/FreeImage/tmoColorConvert.cpp479
-rw-r--r--plugins/AdvaImg/src/FreeImage/tmoDrago03.cpp295
-rw-r--r--plugins/AdvaImg/src/FreeImage/tmoFattal02.cpp689
-rw-r--r--plugins/AdvaImg/src/FreeImage/tmoReinhard05.cpp260
45 files changed, 0 insertions, 22944 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;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/CacheFile.cpp b/plugins/AdvaImg/src/FreeImage/CacheFile.cpp
deleted file mode 100644
index 309faf8faf..0000000000
--- a/plugins/AdvaImg/src/FreeImage/CacheFile.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-// ==========================================================
-// Multi-Page functions
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - checkered (checkered@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 "CacheFile.h"
-
-// ----------------------------------------------------------
-
-CacheFile::CacheFile(const std::string filename, BOOL keep_in_memory) :
-m_file(NULL),
-m_filename(filename),
-m_free_pages(),
-m_page_cache_mem(),
-m_page_cache_disk(),
-m_page_map(),
-m_page_count(0),
-m_current_block(NULL),
-m_keep_in_memory(keep_in_memory) {
-}
-
-CacheFile::~CacheFile() {
-}
-
-BOOL
-CacheFile::open() {
- if ((!m_filename.empty()) && (!m_keep_in_memory)) {
- m_file = fopen(m_filename.c_str(), "w+b");
- return (m_file != NULL);
- }
-
- return (m_keep_in_memory == TRUE);
-}
-
-void
-CacheFile::close() {
- // dispose the cache entries
-
- while (!m_page_cache_disk.empty()) {
- Block *block = *m_page_cache_disk.begin();
- m_page_cache_disk.pop_front();
- delete [] block->data;
- delete block;
- }
- while (!m_page_cache_mem.empty()) {
- Block *block = *m_page_cache_mem.begin();
- m_page_cache_mem.pop_front();
- delete [] block->data;
- delete block;
- }
-
- if (m_file) {
- // close the file
-
- fclose(m_file);
-
- // delete the file
-
- remove(m_filename.c_str());
- }
-}
-
-void
-CacheFile::cleanupMemCache() {
- if (!m_keep_in_memory) {
- if (m_page_cache_mem.size() > CACHE_SIZE) {
- // flush the least used block to file
-
- Block *old_block = m_page_cache_mem.back();
- fseek(m_file, old_block->nr * BLOCK_SIZE, SEEK_SET);
- fwrite(old_block->data, BLOCK_SIZE, 1, m_file);
-
- // remove the data
-
- delete [] old_block->data;
- old_block->data = NULL;
-
- // move the block to another list
-
- m_page_cache_disk.splice(m_page_cache_disk.begin(), m_page_cache_mem, --m_page_cache_mem.end());
- m_page_map[old_block->nr] = m_page_cache_disk.begin();
- }
- }
-}
-
-int
-CacheFile::allocateBlock() {
- Block *block = new Block;
- block->data = new BYTE[BLOCK_SIZE];
- block->next = 0;
-
- if (!m_free_pages.empty()) {
- block->nr = *m_free_pages.begin();
- m_free_pages.pop_front();
- } else {
- block->nr = m_page_count++;
- }
-
- m_page_cache_mem.push_front(block);
- m_page_map[block->nr] = m_page_cache_mem.begin();
-
- cleanupMemCache();
-
- return block->nr;
-}
-
-Block *
-CacheFile::lockBlock(int nr) {
- if (m_current_block == NULL) {
- PageMapIt it = m_page_map.find(nr);
-
- if (it != m_page_map.end()) {
- m_current_block = *(it->second);
-
- // the block is swapped out to disc. load it back
- // and remove the block from the cache. it might get cached
- // again as soon as the memory buffer fills up
-
- if (m_current_block->data == NULL) {
- m_current_block->data = new BYTE[BLOCK_SIZE];
-
- fseek(m_file, m_current_block->nr * BLOCK_SIZE, SEEK_SET);
- fread(m_current_block->data, BLOCK_SIZE, 1, m_file);
-
- m_page_cache_mem.splice(m_page_cache_mem.begin(), m_page_cache_disk, it->second);
- m_page_map[nr] = m_page_cache_mem.begin();
- }
-
- // if the memory cache size is too large, swap an item to disc
-
- cleanupMemCache();
-
- // return the current block
-
- return m_current_block;
- }
- }
-
- return NULL;
-}
-
-BOOL
-CacheFile::unlockBlock(int nr) {
- if (m_current_block) {
- m_current_block = NULL;
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL
-CacheFile::deleteBlock(int nr) {
- if (!m_current_block) {
- PageMapIt it = m_page_map.find(nr);
-
- // remove block from cache
-
- if (it != m_page_map.end())
- m_page_map.erase(nr);
-
- // add block to free page list
-
- m_free_pages.push_back(nr);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL
-CacheFile::readFile(BYTE *data, int nr, int size) {
- if ((data) && (size > 0)) {
- int s = 0;
- int block_nr = nr;
-
- do {
- int copy_nr = block_nr;
-
- Block *block = lockBlock(copy_nr);
-
- block_nr = block->next;
-
- memcpy(data + s, block->data, (s + BLOCK_SIZE > size) ? size - s : BLOCK_SIZE);
-
- unlockBlock(copy_nr);
-
- s += BLOCK_SIZE;
- } while (block_nr != 0);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-int
-CacheFile::writeFile(BYTE *data, int size) {
- if ((data) && (size > 0)) {
- int nr_blocks_required = 1 + (size / BLOCK_SIZE);
- int count = 0;
- int s = 0;
- int stored_alloc;
- int alloc;
-
- stored_alloc = alloc = allocateBlock();
-
- do {
- int copy_alloc = alloc;
-
- Block *block = lockBlock(copy_alloc);
-
- block->next = 0;
-
- memcpy(block->data, data + s, (s + BLOCK_SIZE > size) ? size - s : BLOCK_SIZE);
-
- if (count + 1 < nr_blocks_required)
- alloc = block->next = allocateBlock();
-
- unlockBlock(copy_alloc);
-
- s += BLOCK_SIZE;
- } while (++count < nr_blocks_required);
-
- return stored_alloc;
- }
-
- return 0;
-}
-
-void
-CacheFile::deleteFile(int nr) {
- do {
- Block *block = lockBlock(nr);
-
- if (block == NULL)
- break;
-
- int next = block->next;
-
- unlockBlock(nr);
-
- deleteBlock(nr);
-
- nr = next;
- } while (nr != 0);
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/ColorLookup.cpp b/plugins/AdvaImg/src/FreeImage/ColorLookup.cpp
deleted file mode 100644
index 0f4435a725..0000000000
--- a/plugins/AdvaImg/src/FreeImage/ColorLookup.cpp
+++ /dev/null
@@ -1,785 +0,0 @@
-// ==========================================================
-// X11 and SVG Color name lookup
-//
-// Design and implementation by
-// - Karl-Heinz Bussian (khbussian@moss.de)
-//
-// 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!
-//
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// RGB color names ---------------------------------------------------------
-
-typedef struct tagNamedColor {
- const char *name; //! color name
- BYTE r; //! red value
- BYTE g; //! green value
- BYTE b; //! blue value
-} NamedColor;
-
-// --------------------------------------------------------------------------
-
-/**
-Helper function : perform a binary search on a color array
-@param name Color name
-@param color_array Color array
-@param n Length of the color array
-@return Returns the color index in the array if successful, returns -1 otherwise
-*/
-static int
-binsearch(const char *name, const NamedColor *color_array, int n) {
- int cond, low, mid, high;
-
- low = 0;
- high = n - 1;
- while (low <= high) {
- mid = (low + high) / 2;
- if ((cond = strcmp(name, color_array[mid].name)) < 0) {
- high = mid - 1;
- } else if (cond > 0) {
- low = mid + 1;
- } else {
- return mid;
- }
- }
- return -1;
-}
-
-/**
-Perform a binary search on a color array
-@param szColor Color name
-@param color_array Color array
-@param ncolors Length of the color array
-@return Returns the color index in the array if successful, returns -1 otherwise
-*/
-static int
-FreeImage_LookupNamedColor(const char *szColor, const NamedColor *color_array, int ncolors) {
- int i;
- char color[64];
-
- // make lower case name, squezze white space
-
- for (i = 0; szColor[i] && i < sizeof(color) - 1; i++) {
- if (isspace(szColor[i])) {
- continue;
- }
- if (isupper(szColor[i])) {
- color[i] = (char)tolower(szColor[i]);
- } else {
- color[i] = szColor[i];
- }
- }
- color[i] = 0;
-
- return binsearch(color, color_array, ncolors);
-}
-
-// ==========================================================
-// X11 Color name lookup
-
-/**
- This big list of color names was formed from the file: /usr/X11R6/lib/X11/rgb.txt
- found on a standard Linux installation.
-*/
-
-static NamedColor X11ColorMap[] = {
- { "aliceblue", 240, 248, 255 },
- { "antiquewhite", 250, 235, 215 },
- { "antiquewhite1", 255, 239, 219 },
- { "antiquewhite2", 238, 223, 204 },
- { "antiquewhite3", 205, 192, 176 },
- { "antiquewhite4", 139, 131, 120 },
- { "aquamarine", 127, 255, 212 },
- { "aquamarine1", 127, 255, 212 },
- { "aquamarine2", 118, 238, 198 },
- { "aquamarine3", 102, 205, 170 },
- { "aquamarine4", 69, 139, 116 },
- { "azure", 240, 255, 255 },
- { "azure1", 240, 255, 255 },
- { "azure2", 224, 238, 238 },
- { "azure3", 193, 205, 205 },
- { "azure4", 131, 139, 139 },
- { "beige", 245, 245, 220 },
- { "bisque", 255, 228, 196 },
- { "bisque1", 255, 228, 196 },
- { "bisque2", 238, 213, 183 },
- { "bisque3", 205, 183, 158 },
- { "bisque4", 139, 125, 107 },
- { "black", 0, 0, 0 },
- { "blanchedalmond", 255, 235, 205 },
- { "blue", 0, 0, 255 },
- { "blue1", 0, 0, 255 },
- { "blue2", 0, 0, 238 },
- { "blue3", 0, 0, 205 },
- { "blue4", 0, 0, 139 },
- { "blueviolet", 138, 43, 226 },
- { "brown", 165, 42, 42 },
- { "brown1", 255, 64, 64 },
- { "brown2", 238, 59, 59 },
- { "brown3", 205, 51, 51 },
- { "brown4", 139, 35, 35 },
- { "burlywood", 222, 184, 135 },
- { "burlywood1", 255, 211, 155 },
- { "burlywood2", 238, 197, 145 },
- { "burlywood3", 205, 170, 125 },
- { "burlywood4", 139, 115, 85 },
- { "cadetblue", 95, 158, 160 },
- { "cadetblue1", 152, 245, 255 },
- { "cadetblue2", 142, 229, 238 },
- { "cadetblue3", 122, 197, 205 },
- { "cadetblue4", 83, 134, 139 },
- { "chartreuse", 127, 255, 0 },
- { "chartreuse1", 127, 255, 0 },
- { "chartreuse2", 118, 238, 0 },
- { "chartreuse3", 102, 205, 0 },
- { "chartreuse4", 69, 139, 0 },
- { "chocolate", 210, 105, 30 },
- { "chocolate1", 255, 127, 36 },
- { "chocolate2", 238, 118, 33 },
- { "chocolate3", 205, 102, 29 },
- { "chocolate4", 139, 69, 19 },
- { "coral", 255, 127, 80 },
- { "coral1", 255, 114, 86 },
- { "coral2", 238, 106, 80 },
- { "coral3", 205, 91, 69 },
- { "coral4", 139, 62, 47 },
- { "cornflowerblue", 100, 149, 237 },
- { "cornsilk", 255, 248, 220 },
- { "cornsilk1", 255, 248, 220 },
- { "cornsilk2", 238, 232, 205 },
- { "cornsilk3", 205, 200, 177 },
- { "cornsilk4", 139, 136, 120 },
- { "cyan", 0, 255, 255 },
- { "cyan1", 0, 255, 255 },
- { "cyan2", 0, 238, 238 },
- { "cyan3", 0, 205, 205 },
- { "cyan4", 0, 139, 139 },
- { "darkblue", 0, 0, 139 },
- { "darkcyan", 0, 139, 139 },
- { "darkgoldenrod", 184, 134, 11 },
- { "darkgoldenrod1", 255, 185, 15 },
- { "darkgoldenrod2", 238, 173, 14 },
- { "darkgoldenrod3", 205, 149, 12 },
- { "darkgoldenrod4", 139, 101, 8 },
- { "darkgreen", 0, 100, 0 },
- { "darkkhaki", 189, 183, 107 },
- { "darkmagenta", 139, 0, 139 },
- { "darkolivegreen", 85, 107, 47 },
- { "darkolivegreen1", 202, 255, 112 },
- { "darkolivegreen2", 188, 238, 104 },
- { "darkolivegreen3", 162, 205, 90 },
- { "darkolivegreen4", 110, 139, 61 },
- { "darkorange", 255, 140, 0 },
- { "darkorange1", 255, 127, 0 },
- { "darkorange2", 238, 118, 0 },
- { "darkorange3", 205, 102, 0 },
- { "darkorange4", 139, 69, 0 },
- { "darkorchid", 153, 50, 204 },
- { "darkorchid1", 191, 62, 255 },
- { "darkorchid2", 178, 58, 238 },
- { "darkorchid3", 154, 50, 205 },
- { "darkorchid4", 104, 34, 139 },
- { "darkred", 139, 0, 0 },
- { "darksalmon", 233, 150, 122 },
- { "darkseagreen", 143, 188, 143 },
- { "darkseagreen1", 193, 255, 193 },
- { "darkseagreen2", 180, 238, 180 },
- { "darkseagreen3", 155, 205, 155 },
- { "darkseagreen4", 105, 139, 105 },
- { "darkslateblue", 72, 61, 139 },
- { "darkslategray", 47, 79, 79 },
- { "darkslategray1", 151, 255, 255 },
- { "darkslategray2", 141, 238, 238 },
- { "darkslategray3", 121, 205, 205 },
- { "darkslategray4", 82, 139, 139 },
- { "darkslategrey", 47, 79, 79 },
- { "darkturquoise", 0, 206, 209 },
- { "darkviolet", 148, 0, 211 },
- { "deeppink", 255, 20, 147 },
- { "deeppink1", 255, 20, 147 },
- { "deeppink2", 238, 18, 137 },
- { "deeppink3", 205, 16, 118 },
- { "deeppink4", 139, 10, 80 },
- { "deepskyblue", 0, 191, 255 },
- { "deepskyblue1", 0, 191, 255 },
- { "deepskyblue2", 0, 178, 238 },
- { "deepskyblue3", 0, 154, 205 },
- { "deepskyblue4", 0, 104, 139 },
- { "dimgray", 105, 105, 105 },
- { "dimgrey", 105, 105, 105 },
- { "dodgerblue", 30, 144, 255 },
- { "dodgerblue1", 30, 144, 255 },
- { "dodgerblue2", 28, 134, 238 },
- { "dodgerblue3", 24, 116, 205 },
- { "dodgerblue4", 16, 78, 139 },
- { "firebrick", 178, 34, 34 },
- { "firebrick1", 255, 48, 48 },
- { "firebrick2", 238, 44, 44 },
- { "firebrick3", 205, 38, 38 },
- { "firebrick4", 139, 26, 26 },
- { "floralwhite", 255, 250, 240 },
- { "forestgreen", 176, 48, 96 },
- { "gainsboro", 220, 220, 220 },
- { "ghostwhite", 248, 248, 255 },
- { "gold", 255, 215, 0 },
- { "gold1", 255, 215, 0 },
- { "gold2", 238, 201, 0 },
- { "gold3", 205, 173, 0 },
- { "gold4", 139, 117, 0 },
- { "goldenrod", 218, 165, 32 },
- { "goldenrod1", 255, 193, 37 },
- { "goldenrod2", 238, 180, 34 },
- { "goldenrod3", 205, 155, 29 },
- { "goldenrod4", 139, 105, 20 },
- { "gray", 190, 190, 190 },
- { "green", 0, 255, 0 },
- { "green1", 0, 255, 0 },
- { "green2", 0, 238, 0 },
- { "green3", 0, 205, 0 },
- { "green4", 0, 139, 0 },
- { "greenyellow", 173, 255, 47 },
- { "grey", 190, 190, 190 },
- { "honeydew", 240, 255, 240 },
- { "honeydew1", 240, 255, 240 },
- { "honeydew2", 224, 238, 224 },
- { "honeydew3", 193, 205, 193 },
- { "honeydew4", 131, 139, 131 },
- { "hotpink", 255, 105, 180 },
- { "hotpink1", 255, 110, 180 },
- { "hotpink2", 238, 106, 167 },
- { "hotpink3", 205, 96, 144 },
- { "hotpink4", 139, 58, 98 },
- { "indianred", 205, 92, 92 },
- { "indianred1", 255, 106, 106 },
- { "indianred2", 238, 99, 99 },
- { "indianred3", 205, 85, 85 },
- { "indianred4", 139, 58, 58 },
- { "ivory", 255, 255, 240 },
- { "ivory1", 255, 255, 240 },
- { "ivory2", 238, 238, 224 },
- { "ivory3", 205, 205, 193 },
- { "ivory4", 139, 139, 131 },
- { "khaki", 240, 230, 140 },
- { "khaki1", 255, 246, 143 },
- { "khaki2", 238, 230, 133 },
- { "khaki3", 205, 198, 115 },
- { "khaki4", 139, 134, 78 },
- { "lavender", 230, 230, 250 },
- { "lavenderblush", 255, 240, 245 },
- { "lavenderblush1", 255, 240, 245 },
- { "lavenderblush2", 238, 224, 229 },
- { "lavenderblush3", 205, 193, 197 },
- { "lavenderblush4", 139, 131, 134 },
- { "lawngreen", 124, 252, 0 },
- { "lemonchiffon", 255, 250, 205 },
- { "lemonchiffon1", 255, 250, 205 },
- { "lemonchiffon2", 238, 233, 191 },
- { "lemonchiffon3", 205, 201, 165 },
- { "lemonchiffon4", 139, 137, 112 },
- { "lightblue", 173, 216, 230 },
- { "lightblue1", 191, 239, 255 },
- { "lightblue2", 178, 223, 238 },
- { "lightblue3", 154, 192, 205 },
- { "lightblue4", 104, 131, 139 },
- { "lightcoral", 240, 128, 128 },
- { "lightcyan", 224, 255, 255 },
- { "lightcyan1", 224, 255, 255 },
- { "lightcyan2", 209, 238, 238 },
- { "lightcyan3", 180, 205, 205 },
- { "lightcyan4", 122, 139, 139 },
- { "lightgoldenrod", 238, 221, 130 },
- { "lightgoldenrod1", 255, 236, 139 },
- { "lightgoldenrod2", 238, 220, 130 },
- { "lightgoldenrod3", 205, 190, 112 },
- { "lightgoldenrod4", 139, 129, 76 },
- { "lightgoldenrodyellow", 250, 250, 210 },
- { "lightgray", 211, 211, 211 },
- { "lightgreen", 144, 238, 144 },
- { "lightgrey", 211, 211, 211 },
- { "lightpink", 255, 182, 193 },
- { "lightpink1", 255, 174, 185 },
- { "lightpink2", 238, 162, 173 },
- { "lightpink3", 205, 140, 149 },
- { "lightpink4", 139, 95, 101 },
- { "lightsalmon", 255, 160, 122 },
- { "lightsalmon1", 255, 160, 122 },
- { "lightsalmon2", 238, 149, 114 },
- { "lightsalmon3", 205, 129, 98 },
- { "lightsalmon4", 139, 87, 66 },
- { "lightseagreen", 32, 178, 170 },
- { "lightskyblue", 135, 206, 250 },
- { "lightskyblue1", 176, 226, 255 },
- { "lightskyblue2", 164, 211, 238 },
- { "lightskyblue3", 141, 182, 205 },
- { "lightskyblue4", 96, 123, 139 },
- { "lightslateblue", 132, 112, 255 },
- { "lightslategray", 119, 136, 153 },
- { "lightslategrey", 119, 136, 153 },
- { "lightsteelblue", 176, 196, 222 },
- { "lightsteelblue1", 202, 225, 255 },
- { "lightsteelblue2", 188, 210, 238 },
- { "lightsteelblue3", 162, 181, 205 },
- { "lightsteelblue4", 110, 123, 139 },
- { "lightyellow", 255, 255, 224 },
- { "lightyellow1", 255, 255, 224 },
- { "lightyellow2", 238, 238, 209 },
- { "lightyellow3", 205, 205, 180 },
- { "lightyellow4", 139, 139, 122 },
- { "limegreen", 50, 205, 50 },
- { "linen", 250, 240, 230 },
- { "magenta", 255, 0, 255 },
- { "magenta1", 255, 0, 255 },
- { "magenta2", 238, 0, 238 },
- { "magenta3", 205, 0, 205 },
- { "magenta4", 139, 0, 139 },
- { "maroon", 0, 255, 255 },
- { "maroon1", 255, 52, 179 },
- { "maroon2", 238, 48, 167 },
- { "maroon3", 205, 41, 144 },
- { "maroon4", 139, 28, 98 },
- { "mediumaquamarine", 102, 205, 170 },
- { "mediumblue", 0, 0, 205 },
- { "mediumorchid", 186, 85, 211 },
- { "mediumorchid1", 224, 102, 255 },
- { "mediumorchid2", 209, 95, 238 },
- { "mediumorchid3", 180, 82, 205 },
- { "mediumorchid4", 122, 55, 139 },
- { "mediumpurple", 147, 112, 219 },
- { "mediumpurple1", 171, 130, 255 },
- { "mediumpurple2", 159, 121, 238 },
- { "mediumpurple3", 137, 104, 205 },
- { "mediumpurple4", 93, 71, 139 },
- { "mediumseagreen", 60, 179, 113 },
- { "mediumslateblue", 123, 104, 238 },
- { "mediumspringgreen", 0, 250, 154 },
- { "mediumturquoise", 72, 209, 204 },
- { "mediumvioletred", 199, 21, 133 },
- { "midnightblue", 25, 25, 112 },
- { "mintcream", 245, 255, 250 },
- { "mistyrose", 255, 228, 225 },
- { "mistyrose1", 255, 228, 225 },
- { "mistyrose2", 238, 213, 210 },
- { "mistyrose3", 205, 183, 181 },
- { "mistyrose4", 139, 125, 123 },
- { "moccasin", 255, 228, 181 },
- { "navajowhite", 255, 222, 173 },
- { "navajowhite1", 255, 222, 173 },
- { "navajowhite2", 238, 207, 161 },
- { "navajowhite3", 205, 179, 139 },
- { "navajowhite4", 139, 121, 94 },
- { "navy", 0, 0, 128 },
- { "navyblue", 0, 0, 128 },
- { "oldlace", 253, 245, 230 },
- { "olivedrab", 107, 142, 35 },
- { "olivedrab1", 192, 255, 62 },
- { "olivedrab2", 179, 238, 58 },
- { "olivedrab3", 154, 205, 50 },
- { "olivedrab4", 105, 139, 34 },
- { "orange", 255, 165, 0 },
- { "orange1", 255, 165, 0 },
- { "orange2", 238, 154, 0 },
- { "orange3", 205, 133, 0 },
- { "orange4", 139, 90, 0 },
- { "orangered", 255, 69, 0 },
- { "orangered1", 255, 69, 0 },
- { "orangered2", 238, 64, 0 },
- { "orangered3", 205, 55, 0 },
- { "orangered4", 139, 37, 0 },
- { "orchid", 218, 112, 214 },
- { "orchid1", 255, 131, 250 },
- { "orchid2", 238, 122, 233 },
- { "orchid3", 205, 105, 201 },
- { "orchid4", 139, 71, 137 },
- { "palegoldenrod", 238, 232, 170 },
- { "palegreen", 152, 251, 152 },
- { "palegreen1", 154, 255, 154 },
- { "palegreen2", 144, 238, 144 },
- { "palegreen3", 124, 205, 124 },
- { "palegreen4", 84, 139, 84 },
- { "paleturquoise", 175, 238, 238 },
- { "paleturquoise1", 187, 255, 255 },
- { "paleturquoise2", 174, 238, 238 },
- { "paleturquoise3", 150, 205, 205 },
- { "paleturquoise4", 102, 139, 139 },
- { "palevioletred", 219, 112, 147 },
- { "palevioletred1", 255, 130, 171 },
- { "palevioletred2", 238, 121, 159 },
- { "palevioletred3", 205, 104, 137 },
- { "palevioletred4", 139, 71, 93 },
- { "papayawhip", 255, 239, 213 },
- { "peachpuff", 255, 218, 185 },
- { "peachpuff1", 255, 218, 185 },
- { "peachpuff2", 238, 203, 173 },
- { "peachpuff3", 205, 175, 149 },
- { "peachpuff4", 139, 119, 101 },
- { "peru", 205, 133, 63 },
- { "pink", 255, 192, 203 },
- { "pink1", 255, 181, 197 },
- { "pink2", 238, 169, 184 },
- { "pink3", 205, 145, 158 },
- { "pink4", 139, 99, 108 },
- { "plum", 221, 160, 221 },
- { "plum1", 255, 187, 255 },
- { "plum2", 238, 174, 238 },
- { "plum3", 205, 150, 205 },
- { "plum4", 139, 102, 139 },
- { "powderblue", 176, 224, 230 },
- { "purple", 160, 32, 240 },
- { "purple1", 155, 48, 255 },
- { "purple2", 145, 44, 238 },
- { "purple3", 125, 38, 205 },
- { "purple4", 85, 26, 139 },
- { "red", 255, 0, 0 },
- { "red1", 255, 0, 0 },
- { "red2", 238, 0, 0 },
- { "red3", 205, 0, 0 },
- { "red4", 139, 0, 0 },
- { "rosybrown", 188, 143, 143 },
- { "rosybrown1", 255, 193, 193 },
- { "rosybrown2", 238, 180, 180 },
- { "rosybrown3", 205, 155, 155 },
- { "rosybrown4", 139, 105, 105 },
- { "royalblue", 65, 105, 225 },
- { "royalblue1", 72, 118, 255 },
- { "royalblue2", 67, 110, 238 },
- { "royalblue3", 58, 95, 205 },
- { "royalblue4", 39, 64, 139 },
- { "saddlebrown", 139, 69, 19 },
- { "salmon", 250, 128, 114 },
- { "salmon1", 255, 140, 105 },
- { "salmon2", 238, 130, 98 },
- { "salmon3", 205, 112, 84 },
- { "salmon4", 139, 76, 57 },
- { "sandybrown", 244, 164, 96 },
- { "seagreen", 46, 139, 87 },
- { "seagreen1", 84, 255, 159 },
- { "seagreen2", 78, 238, 148 },
- { "seagreen3", 67, 205, 128 },
- { "seagreen4", 46, 139, 87 },
- { "seashell", 255, 245, 238 },
- { "seashell1", 255, 245, 238 },
- { "seashell2", 238, 229, 222 },
- { "seashell3", 205, 197, 191 },
- { "seashell4", 139, 134, 130 },
- { "sienna", 160, 82, 45 },
- { "sienna1", 255, 130, 71 },
- { "sienna2", 238, 121, 66 },
- { "sienna3", 205, 104, 57 },
- { "sienna4", 139, 71, 38 },
- { "skyblue", 135, 206, 235 },
- { "skyblue1", 135, 206, 255 },
- { "skyblue2", 126, 192, 238 },
- { "skyblue3", 108, 166, 205 },
- { "skyblue4", 74, 112, 139 },
- { "slateblue", 106, 90, 205 },
- { "slateblue1", 131, 111, 255 },
- { "slateblue2", 122, 103, 238 },
- { "slateblue3", 105, 89, 205 },
- { "slateblue4", 71, 60, 139 },
- { "slategray", 112, 128, 144 },
- { "slategray1", 198, 226, 255 },
- { "slategray2", 185, 211, 238 },
- { "slategray3", 159, 182, 205 },
- { "slategray4", 108, 123, 139 },
- { "slategrey", 112, 128, 144 },
- { "snow", 255, 250, 250 },
- { "snow1", 255, 250, 250 },
- { "snow2", 238, 233, 233 },
- { "snow3", 205, 201, 201 },
- { "snow4", 139, 137, 137 },
- { "springgreen", 0, 255, 127 },
- { "springgreen1", 0, 255, 127 },
- { "springgreen2", 0, 238, 118 },
- { "springgreen3", 0, 205, 102 },
- { "springgreen4", 0, 139, 69 },
- { "steelblue", 70, 130, 180 },
- { "steelblue1", 99, 184, 255 },
- { "steelblue2", 92, 172, 238 },
- { "steelblue3", 79, 148, 205 },
- { "steelblue4", 54, 100, 139 },
- { "tan", 210, 180, 140 },
- { "tan1", 255, 165, 79 },
- { "tan2", 238, 154, 73 },
- { "tan3", 205, 133, 63 },
- { "tan4", 139, 90, 43 },
- { "thistle", 216, 191, 216 },
- { "thistle1", 255, 225, 255 },
- { "thistle2", 238, 210, 238 },
- { "thistle3", 205, 181, 205 },
- { "thistle4", 139, 123, 139 },
- { "tomato", 255, 99, 71 },
- { "tomato1", 255, 99, 71 },
- { "tomato2", 238, 92, 66 },
- { "tomato3", 205, 79, 57 },
- { "tomato4", 139, 54, 38 },
- { "turquoise", 64, 224, 208 },
- { "turquoise1", 0, 245, 255 },
- { "turquoise2", 0, 229, 238 },
- { "turquoise3", 0, 197, 205 },
- { "turquoise4", 0, 134, 139 },
- { "violet", 238, 130, 238 },
- { "violetred", 208, 32, 144 },
- { "violetred1", 255, 62, 150 },
- { "violetred2", 238, 58, 140 },
- { "violetred3", 205, 50, 120 },
- { "violetred4", 139, 34, 82 },
- { "wheat", 245, 222, 179 },
- { "wheat1", 255, 231, 186 },
- { "wheat2", 238, 216, 174 },
- { "wheat3", 205, 186, 150 },
- { "wheat4", 139, 126, 102 },
- { "white", 255, 255, 255 },
- { "whitesmoke", 245, 245, 245 },
- { "yellow", 255, 255, 0 },
- { "yellow1", 255, 255, 0 },
- { "yellow2", 238, 238, 0 },
- { "yellow3", 205, 205, 0 },
- { "yellow4", 139, 139, 0 },
- { "yellowgreen", 154, 205, 50 }
-};
-
-
-BOOL DLL_CALLCONV
-FreeImage_LookupX11Color(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue) {
- int i;
-
- // lookup color
- i = FreeImage_LookupNamedColor(szColor, X11ColorMap, sizeof(X11ColorMap)/sizeof(X11ColorMap[0]));
- if (i >= 0) {
- *nRed = X11ColorMap[i].r;
- *nGreen = X11ColorMap[i].g;
- *nBlue = X11ColorMap[i].b;
- return TRUE;
- }
-
- // not found, try for grey color with attached percent value
- if ( (szColor[0] == 'g' || szColor[0] == 'G') &&
- (szColor[1] == 'r' || szColor[1] == 'R') &&
- (szColor[2] == 'e' || szColor[2] == 'E' || szColor[2] == 'a' || szColor[2] == 'A' ) &&
- (szColor[3] == 'y' || szColor[3] == 'Y' ) ) {
-
- // grey<num>, or gray<num>, num 1...100
- i = strtol(szColor+4, NULL, 10);
- *nRed = (BYTE)(255.0/100.0 * i);
- *nGreen = *nRed;
- *nBlue = *nRed;
-
- return TRUE;
- }
-
- // not found at all
- *nRed = 0;
- *nGreen = 0;
- *nBlue = 0;
-
- return FALSE;
-}
-
-// ==========================================================
-// SVG Color name lookup
-
-/**
- These are the colors defined in the SVG standard (I haven't checked
- the final recommendation for changes)
-*/
-static NamedColor SVGColorMap[] = {
- { "aliceblue", 240, 248, 255 },
- { "antiquewhite", 250, 235, 215 },
- { "aqua", 0, 255, 255 },
- { "aquamarine", 127, 255, 212 },
- { "azure", 240, 255, 255 },
- { "beige", 245, 245, 220 },
- { "bisque", 255, 228, 196 },
- { "black", 0, 0, 0 },
- { "blanchedalmond", 255, 235, 205 },
- { "blue", 0, 0, 255 },
- { "blueviolet", 138, 43, 226 },
- { "brown", 165, 42, 42 },
- { "burlywood", 222, 184, 135 },
- { "cadetblue", 95, 158, 160 },
- { "chartreuse", 127, 255, 0 },
- { "chocolate", 210, 105, 30 },
- { "coral", 255, 127, 80 },
- { "cornflowerblue", 100, 149, 237 },
- { "cornsilk", 255, 248, 220 },
- { "crimson", 220, 20, 60 },
- { "cyan", 0, 255, 255 },
- { "darkblue", 0, 0, 139 },
- { "darkcyan", 0, 139, 139 },
- { "darkgoldenrod", 184, 134, 11 },
- { "darkgray", 169, 169, 169 },
- { "darkgreen", 0, 100, 0 },
- { "darkgrey", 169, 169, 169 },
- { "darkkhaki", 189, 183, 107 },
- { "darkmagenta", 139, 0, 139 },
- { "darkolivegreen", 85, 107, 47 },
- { "darkorange", 255, 140, 0 },
- { "darkorchid", 153, 50, 204 },
- { "darkred", 139, 0, 0 },
- { "darksalmon", 233, 150, 122 },
- { "darkseagreen", 143, 188, 143 },
- { "darkslateblue", 72, 61, 139 },
- { "darkslategray", 47, 79, 79 },
- { "darkslategrey", 47, 79, 79 },
- { "darkturquoise", 0, 206, 209 },
- { "darkviolet", 148, 0, 211 },
- { "deeppink", 255, 20, 147 },
- { "deepskyblue", 0, 191, 255 },
- { "dimgray", 105, 105, 105 },
- { "dimgrey", 105, 105, 105 },
- { "dodgerblue", 30, 144, 255 },
- { "firebrick", 178, 34, 34 },
- { "floralwhite", 255, 250, 240 },
- { "forestgreen", 34, 139, 34 },
- { "fuchsia", 255, 0, 255 },
- { "gainsboro", 220, 220, 220 },
- { "ghostwhite", 248, 248, 255 },
- { "gold", 255, 215, 0 },
- { "goldenrod", 218, 165, 32 },
- { "gray", 128, 128, 128 },
- { "green", 0, 128, 0 },
- { "greenyellow", 173, 255, 47 },
- { "grey", 128, 128, 128 },
- { "honeydew", 240, 255, 240 },
- { "hotpink", 255, 105, 180 },
- { "indianred", 205, 92, 92 },
- { "indigo", 75, 0, 130 },
- { "ivory", 255, 255, 240 },
- { "khaki", 240, 230, 140 },
- { "lavender", 230, 230, 250 },
- { "lavenderblush", 255, 240, 245 },
- { "lawngreen", 124, 252, 0 },
- { "lemonchiffon", 255, 250, 205 },
- { "lightblue", 173, 216, 230 },
- { "lightcoral", 240, 128, 128 },
- { "lightcyan", 224, 255, 255 },
- { "lightgoldenrodyellow", 250, 250, 210 },
- { "lightgray", 211, 211, 211 },
- { "lightgreen", 144, 238, 144 },
- { "lightgrey", 211, 211, 211 },
- { "lightpink", 255, 182, 193 },
- { "lightsalmon", 255, 160, 122 },
- { "lightseagreen", 32, 178, 170 },
- { "lightskyblue", 135, 206, 250 },
- { "lightslategray", 119, 136, 153 },
- { "lightslategrey", 119, 136, 153 },
- { "lightsteelblue", 176, 196, 222 },
- { "lightyellow", 255, 255, 224 },
- { "lime", 0, 255, 0 },
- { "limegreen", 50, 205, 50 },
- { "linen", 250, 240, 230 },
- { "magenta", 255, 0, 255 },
- { "maroon", 128, 0, 0 },
- { "mediumaquamarine", 102, 205, 170 },
- { "mediumblue", 0, 0, 205 },
- { "mediumorchid", 186, 85, 211 },
- { "mediumpurple", 147, 112, 219 },
- { "mediumseagreen", 60, 179, 113 },
- { "mediumslateblue", 123, 104, 238 },
- { "mediumspringgreen", 0, 250, 154 },
- { "mediumturquoise", 72, 209, 204 },
- { "mediumvioletred", 199, 21, 133 },
- { "midnightblue", 25, 25, 112 },
- { "mintcream", 245, 255, 250 },
- { "mistyrose", 255, 228, 225 },
- { "moccasin", 255, 228, 181 },
- { "navajowhite", 255, 222, 173 },
- { "navy", 0, 0, 128 },
- { "oldlace", 253, 245, 230 },
- { "olive", 128, 128, 0 },
- { "olivedrab", 107, 142, 35 },
- { "orange", 255, 165, 0 },
- { "orangered", 255, 69, 0 },
- { "orchid", 218, 112, 214 },
- { "palegoldenrod", 238, 232, 170 },
- { "palegreen", 152, 251, 152 },
- { "paleturquoise", 175, 238, 238 },
- { "palevioletred", 219, 112, 147 },
- { "papayawhip", 255, 239, 213 },
- { "peachpuff", 255, 218, 185 },
- { "peru", 205, 133, 63 },
- { "pink", 255, 192, 203 },
- { "plum", 221, 160, 221 },
- { "powderblue", 176, 224, 230 },
- { "purple", 128, 0, 128 },
- { "red", 255, 0, 0 },
- { "rosybrown", 188, 143, 143 },
- { "royalblue", 65, 105, 225 },
- { "saddlebrown", 139, 69, 19 },
- { "salmon", 250, 128, 114 },
- { "sandybrown", 244, 164, 96 },
- { "seagreen", 46, 139, 87 },
- { "seashell", 255, 245, 238 },
- { "sienna", 160, 82, 45 },
- { "silver", 192, 192, 192 },
- { "skyblue", 135, 206, 235 },
- { "slateblue", 106, 90, 205 },
- { "slategray", 112, 128, 144 },
- { "slategrey", 112, 128, 144 },
- { "snow", 255, 250, 250 },
- { "springgreen", 0, 255, 127 },
- { "steelblue", 70, 130, 180 },
- { "tan", 210, 180, 140 },
- { "teal", 0, 128, 128 },
- { "thistle", 216, 191, 216 },
- { "tomato", 255, 99, 71 },
- { "turquoise", 64, 224, 208 },
- { "violet", 238, 130, 238 },
- { "wheat", 245, 222, 179 },
- { "white", 255, 255, 255 },
- { "whitesmoke", 245, 245, 245 },
- { "yellow", 255, 255, 0 },
- { "yellowgreen", 154, 205, 50 }
-};
-
-
-BOOL DLL_CALLCONV
-FreeImage_LookupSVGColor(const char *szColor, BYTE *nRed, BYTE *nGreen, BYTE *nBlue) {
- int i;
-
- // lookup color
- i = FreeImage_LookupNamedColor(szColor, SVGColorMap, sizeof(SVGColorMap)/sizeof(SVGColorMap[0]));
- if (i >= 0) {
- *nRed = SVGColorMap[i].r;
- *nGreen = SVGColorMap[i].g;
- *nBlue = SVGColorMap[i].b;
- return TRUE;
- }
-
- // not found, try for grey color with attached percent value
- if ( (szColor[0] == 'g' || szColor[0] == 'G') &&
- (szColor[1] == 'r' || szColor[1] == 'R') &&
- (szColor[2] == 'e' || szColor[2] == 'E' || szColor[2] == 'a' || szColor[2] == 'A' ) &&
- (szColor[3] == 'y' || szColor[3] == 'Y' ) ) {
-
- // grey<num>, or gray<num>, num 1...100
- i = strtol(szColor+4, NULL, 10);
- *nRed = (BYTE)(255.0/100.0 * i);
- *nGreen = *nRed;
- *nBlue = *nRed;
- return TRUE;
- }
-
- // not found at all
- *nRed = 0;
- *nGreen = 0;
- *nBlue = 0;
-
- return FALSE;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/Conversion.cpp b/plugins/AdvaImg/src/FreeImage/Conversion.cpp
deleted file mode 100644
index 815057ad08..0000000000
--- a/plugins/AdvaImg/src/FreeImage/Conversion.cpp
+++ /dev/null
@@ -1,551 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Jani Kajala (janik@remedy.fi)
-// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
-// - Carsten Klein (cklein05@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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "Quantizers.h"
-
-// ----------------------------------------------------------
-
-#define CONVERT(from, to) case to : FreeImage_ConvertLine##from##To##to(bits, scanline, FreeImage_GetWidth(dib)); break;
-#define CONVERTWITHPALETTE(from, to) case to : FreeImage_ConvertLine##from##To##to(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib)); break;
-
-#define CONVERTTO16(from) \
- case 16 : \
- if ((red_mask == FI16_555_RED_MASK) && (green_mask == FI16_555_GREEN_MASK) && (blue_mask == FI16_555_BLUE_MASK)) { \
- FreeImage_ConvertLine##from##To16_555(bits, scanline, FreeImage_GetWidth(dib)); \
- } else { \
- FreeImage_ConvertLine##from##To16_565(bits, scanline, FreeImage_GetWidth(dib)); \
- } \
- break;
-
-#define CONVERTTO16WITHPALETTE(from) \
- case 16 : \
- if ((red_mask == FI16_555_RED_MASK) && (green_mask == FI16_555_GREEN_MASK) && (blue_mask == FI16_555_BLUE_MASK)) { \
- FreeImage_ConvertLine##from##To16_555(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib)); \
- } else { \
- FreeImage_ConvertLine##from##To16_565(bits, scanline, FreeImage_GetWidth(dib), FreeImage_GetPalette(dib)); \
- } \
- break;
-
-// ==========================================================
-// Utility functions declared in Utilities.h
-
-BOOL SwapRedBlue32(FIBITMAP* dib) {
- if(FreeImage_GetImageType(dib) != FIT_BITMAP) {
- return FALSE;
- }
-
- const unsigned bytesperpixel = FreeImage_GetBPP(dib) / 8;
- if(bytesperpixel > 4 || bytesperpixel < 3) {
- return FALSE;
- }
-
- const unsigned height = FreeImage_GetHeight(dib);
- const unsigned pitch = FreeImage_GetPitch(dib);
- const unsigned lineSize = FreeImage_GetLine(dib);
-
- BYTE* line = FreeImage_GetBits(dib);
- for(unsigned y = 0; y < height; ++y, line += pitch) {
- for(BYTE* pixel = line; pixel < line + lineSize ; pixel += bytesperpixel) {
- INPLACESWAP(pixel[0], pixel[2]);
- }
- }
-
- return TRUE;
-}
-
-// ----------------------------------------------------------
-
-static inline void
-assignRGB(WORD r, WORD g, WORD b, WORD* out) {
- out[0] = r;
- out[1] = g;
- out[2] = b;
-}
-
-static inline void
-assignRGB(BYTE r, BYTE g, BYTE b, BYTE* out) {
- out[FI_RGBA_RED] = r;
- out[FI_RGBA_GREEN] = g;
- out[FI_RGBA_BLUE] = b;
-}
-
-/**
-CMYK -> CMY -> RGB conversion from http://www.easyrgb.com/
-
-CMYK to CMY [0-1]: C,M,Y * (1 - K) + K
-CMY to RGB [0-1]: (1 - C,M,Y)
-
-=> R,G,B = (1 - C,M,Y) * (1 - K)
-mapped to [0-MAX_VAL]:
-(MAX_VAL - C,M,Y) * (MAX_VAL - K) / MAX_VAL
-*/
-template <class T>
-static inline void
-CMYKToRGB(T C, T M, T Y, T K, T* out) {
- unsigned max_val = std::numeric_limits<T>::max();
-
- unsigned r = (max_val - C) * (max_val - K) / max_val;
- unsigned g = (max_val - M) * (max_val - K) / max_val;
- unsigned b = (max_val - Y) * (max_val - K) / max_val;
-
- // clamp values to [0..max_val]
- T red = (T)CLAMP(r, (unsigned)0, max_val);
- T green = (T)CLAMP(g, (unsigned)0, max_val);
- T blue = (T)CLAMP(b, (unsigned)0, max_val);
-
- assignRGB(red, green, blue, out);
-}
-
-template <class T>
-static void
-_convertCMYKtoRGBA(unsigned width, unsigned height, BYTE* line_start, unsigned pitch, unsigned samplesperpixel) {
- const BOOL hasBlack = (samplesperpixel > 3) ? TRUE : FALSE;
- const T MAX_VAL = std::numeric_limits<T>::max();
-
- T K = 0;
- for(unsigned y = 0; y < height; y++) {
- T *line = (T*)line_start;
-
- for(unsigned x = 0; x < width; x++) {
- if(hasBlack) {
- K = line[FI_RGBA_ALPHA];
- line[FI_RGBA_ALPHA] = MAX_VAL; // TODO write the first extra channel as alpha!
- }
-
- CMYKToRGB<T>(line[0], line[1], line[2], K, line);
-
- line += samplesperpixel;
- }
- line_start += pitch;
- }
-}
-
-BOOL
-ConvertCMYKtoRGBA(FIBITMAP* dib) {
- if(!FreeImage_HasPixels(dib)) {
- return FALSE;
- }
-
- const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
- const unsigned bytesperpixel = FreeImage_GetBPP(dib)/8;
-
- unsigned channelSize = 1;
- if (image_type == FIT_RGBA16 || image_type == FIT_RGB16) {
- channelSize = sizeof(WORD);
- } else if (!(image_type == FIT_BITMAP && (bytesperpixel > 2))) {
- return FALSE;
- }
-
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
- BYTE *line_start = FreeImage_GetScanLine(dib, 0);
- const unsigned pitch = FreeImage_GetPitch(dib);
-
- unsigned samplesperpixel = FreeImage_GetLine(dib) / width / channelSize;
-
- if(channelSize == sizeof(WORD)) {
- _convertCMYKtoRGBA<WORD>(width, height, line_start, pitch, samplesperpixel);
- } else {
- _convertCMYKtoRGBA<BYTE>(width, height, line_start, pitch, samplesperpixel);
- }
-
- return TRUE;
-}
-
-// ----------------------------------------------------------
-
-/**
-CIELab -> XYZ conversion from http://www.easyrgb.com/
-*/
-static void
-CIELabToXYZ(float L, float a, float b, float *X, float *Y, float *Z) {
- float pow_3;
-
- // CIELab -> XYZ conversion
- // ------------------------
- float var_Y = (L + 16.F ) / 116.F;
- float var_X = a / 500.F + var_Y;
- float var_Z = var_Y - b / 200.F;
-
- pow_3 = powf(var_Y, 3);
- if(pow_3 > 0.008856F) {
- var_Y = pow_3;
- } else {
- var_Y = ( var_Y - 16.F / 116.F ) / 7.787F;
- }
- pow_3 = powf(var_X, 3);
- if(pow_3 > 0.008856F) {
- var_X = pow_3;
- } else {
- var_X = ( var_X - 16.F / 116.F ) / 7.787F;
- }
- pow_3 = powf(var_Z, 3);
- if(pow_3 > 0.008856F) {
- var_Z = pow_3;
- } else {
- var_Z = ( var_Z - 16.F / 116.F ) / 7.787F;
- }
-
- static const float ref_X = 95.047F;
- static const float ref_Y = 100.000F;
- static const float ref_Z = 108.883F;
-
- *X = ref_X * var_X; // ref_X = 95.047 (Observer= 2°, Illuminant= D65)
- *Y = ref_Y * var_Y; // ref_Y = 100.000
- *Z = ref_Z * var_Z; // ref_Z = 108.883
-}
-
-/**
-XYZ -> RGB conversion from http://www.easyrgb.com/
-*/
-static void
-XYZToRGB(float X, float Y, float Z, float *R, float *G, float *B) {
- float var_X = X / 100; // X from 0 to 95.047 (Observer = 2°, Illuminant = D65)
- float var_Y = Y / 100; // Y from 0 to 100.000
- float var_Z = Z / 100; // Z from 0 to 108.883
-
- float var_R = var_X * 3.2406F + var_Y * -1.5372F + var_Z * -0.4986F;
- float var_G = var_X * -0.9689F + var_Y * 1.8758F + var_Z * 0.0415F;
- float var_B = var_X * 0.0557F + var_Y * -0.2040F + var_Z * 1.0570F;
-
- float exponent = 1.F / 2.4F;
-
- if(var_R > 0.0031308F) {
- var_R = 1.055F * powf(var_R, exponent) - 0.055F;
- } else {
- var_R = 12.92F * var_R;
- }
- if(var_G > 0.0031308F) {
- var_G = 1.055F * powf(var_G, exponent) - 0.055F;
- } else {
- var_G = 12.92F * var_G;
- }
- if(var_B > 0.0031308F) {
- var_B = 1.055F * powf(var_B, exponent) - 0.055F;
- } else {
- var_B = 12.92F * var_B;
- }
-
- *R = var_R;
- *G = var_G;
- *B = var_B;
-}
-
-template<class T>
-static void
-CIELabToRGB(float L, float a, float b, T *rgb) {
- float X, Y, Z;
- float R, G, B;
- const float max_val = std::numeric_limits<T>::max();
-
- CIELabToXYZ(L, a, b, &X, &Y, &Z);
- XYZToRGB(X, Y, Z, &R, &G, &B);
-
- // clamp values to [0..max_val]
- T red = (T)CLAMP(R * max_val, 0.0F, max_val);
- T green = (T)CLAMP(G * max_val, 0.0F, max_val);
- T blue = (T)CLAMP(B * max_val, 0.0F, max_val);
-
- assignRGB(red, green, blue, rgb);
-}
-
-template<class T>
-static void
-_convertLABtoRGB(unsigned width, unsigned height, BYTE* line_start, unsigned pitch, unsigned samplesperpixel) {
- const unsigned max_val = std::numeric_limits<T>::max();
- const float sL = 100.F / max_val;
- const float sa = 256.F / max_val;
- const float sb = 256.F / max_val;
-
- for(unsigned y = 0; y < height; y++) {
- T *line = (T*)line_start;
-
- for(unsigned x = 0; x < width; x++) {
- CIELabToRGB(line[0]* sL, line[1]* sa - 128.F, line[2]* sb - 128.F, line);
-
- line += samplesperpixel;
- }
- line_start += pitch;
- }
-}
-
-BOOL
-ConvertLABtoRGB(FIBITMAP* dib) {
- if(!FreeImage_HasPixels(dib)) {
- return FALSE;
- }
-
- const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
- const unsigned bytesperpixel = FreeImage_GetBPP(dib) / 8;
-
- unsigned channelSize = 1;
- if (image_type == FIT_RGBA16 || image_type == FIT_RGB16) {
- channelSize = sizeof(WORD);
- } else if (!(image_type == FIT_BITMAP && (bytesperpixel > 2))) {
- return FALSE;
- }
-
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
- BYTE *line_start = FreeImage_GetScanLine(dib, 0);
- const unsigned pitch = FreeImage_GetPitch(dib);
-
- unsigned samplesperpixel = FreeImage_GetLine(dib) / width / channelSize;
-
- if(channelSize == 1) {
- _convertLABtoRGB<BYTE>(width, height, line_start, pitch, samplesperpixel);
- }
- else {
- _convertLABtoRGB<WORD>(width, height, line_start, pitch, samplesperpixel);
- }
-
- return TRUE;
-}
-
-// ----------------------------------------------------------
-
-FIBITMAP*
-RemoveAlphaChannel(FIBITMAP* src) {
-
- if(!FreeImage_HasPixels(src)) {
- return NULL;
- }
-
- const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(src);
-
- switch(image_type) {
- case FIT_BITMAP:
- if(FreeImage_GetBPP(src) == 32) {
- // convert to 24-bit
- return FreeImage_ConvertTo24Bits(src);
- }
- break;
- case FIT_RGBA16:
- // convert to RGB16
- return FreeImage_ConvertToRGB16(src);
- case FIT_RGBAF:
- // convert to RGBF
- return FreeImage_ConvertToRGBF(src);
- default:
- // unsupported image type
- return NULL;
- }
-
- return NULL;
-}
-
-
-// ==========================================================
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ColorQuantize(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize) {
- return FreeImage_ColorQuantizeEx(dib, quantize);
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ColorQuantizeEx(FIBITMAP *dib, FREE_IMAGE_QUANTIZE quantize, int PaletteSize, int ReserveSize, RGBQUAD *ReservePalette) {
- if( PaletteSize < 2 ) PaletteSize = 2;
- if( PaletteSize > 256 ) PaletteSize = 256;
- if( ReserveSize < 0 ) ReserveSize = 0;
- if( ReserveSize > PaletteSize ) ReserveSize = PaletteSize;
- if (FreeImage_HasPixels(dib)) {
- const unsigned bpp = FreeImage_GetBPP(dib);
- if((FreeImage_GetImageType(dib) == FIT_BITMAP) && (bpp == 24 || bpp == 32)) {
- switch(quantize) {
- case FIQ_WUQUANT :
- {
- try {
- WuQuantizer Q (dib);
- FIBITMAP *dst = Q.Quantize(PaletteSize, ReserveSize, ReservePalette);
- if(dst) {
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, dib);
- }
- return dst;
- } catch (const char *) {
- return NULL;
- }
- break;
- }
- case FIQ_NNQUANT :
- {
- if (bpp == 32) {
- // 32-bit images not supported by NNQUANT
- return NULL;
- }
- // sampling factor in range 1..30.
- // 1 => slower (but better), 30 => faster. Default value is 1
- const int sampling = 1;
-
- NNQuantizer Q(PaletteSize);
- FIBITMAP *dst = Q.Quantize(dib, ReserveSize, ReservePalette, sampling);
- if(dst) {
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, dib);
- }
- return dst;
- }
- case FIQ_LFPQUANT :
- {
- LFPQuantizer Q(PaletteSize);
- FIBITMAP *dst = Q.Quantize(dib, ReserveSize, ReservePalette);
- if(dst) {
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, dib);
- }
- return dst;
- }
- }
- }
- }
-
- return NULL;
-}
-
-// ==========================================================
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertFromRawBitsEx(BOOL copySource, BYTE *bits, FREE_IMAGE_TYPE type, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown) {
- FIBITMAP *dib = NULL;
-
- if(copySource) {
- // allocate a FIBITMAP with internally managed pixel buffer
- dib = FreeImage_AllocateT(type, width, height, bpp, red_mask, green_mask, blue_mask);
- if(!dib) {
- return NULL;
- }
- // copy user provided pixel buffer into the dib
- const unsigned linesize = FreeImage_GetLine(dib);
- for(int y = 0; y < height; y++) {
- memcpy(FreeImage_GetScanLine(dib, y), bits, linesize);
- // next line in user's buffer
- bits += pitch;
- }
- // flip pixels vertically if needed
- if(topdown) {
- FreeImage_FlipVertical(dib);
- }
- }
- else {
- // allocate a FIBITMAP using a wrapper to user provided pixel buffer
- dib = FreeImage_AllocateHeaderForBits(bits, pitch, type, width, height, bpp, red_mask, green_mask, blue_mask);
- if(!dib) {
- return NULL;
- }
- // flip pixels vertically if needed
- if(topdown) {
- FreeImage_FlipVertical(dib);
- }
- }
-
- return dib;
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertFromRawBits(BYTE *bits, int width, int height, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown) {
- return FreeImage_ConvertFromRawBitsEx(TRUE /* copySource */, bits, FIT_BITMAP, width, height, pitch, bpp, red_mask, green_mask, blue_mask, topdown);
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertToRawBits(BYTE *bits, FIBITMAP *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown) {
- if (FreeImage_HasPixels(dib) && (bits != NULL)) {
- for (unsigned i = 0; i < FreeImage_GetHeight(dib); ++i) {
- BYTE *scanline = FreeImage_GetScanLine(dib, topdown ? (FreeImage_GetHeight(dib) - i - 1) : i);
-
- if ((bpp == 16) && (FreeImage_GetBPP(dib) == 16)) {
- // convert 555 to 565 or vice versa
-
- if ((red_mask == FI16_555_RED_MASK) && (green_mask == FI16_555_GREEN_MASK) && (blue_mask == FI16_555_BLUE_MASK)) {
- if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
- FreeImage_ConvertLine16_565_To16_555(bits, scanline, FreeImage_GetWidth(dib));
- } else {
- memcpy(bits, scanline, FreeImage_GetLine(dib));
- }
- } else {
- if ((FreeImage_GetRedMask(dib) == FI16_555_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_555_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_555_BLUE_MASK)) {
- FreeImage_ConvertLine16_555_To16_565(bits, scanline, FreeImage_GetWidth(dib));
- } else {
- memcpy(bits, scanline, FreeImage_GetLine(dib));
- }
- }
- } else if (FreeImage_GetBPP(dib) != bpp) {
- switch(FreeImage_GetBPP(dib)) {
- case 1 :
- switch(bpp) {
- CONVERT(1, 8)
- CONVERTTO16WITHPALETTE(1)
- CONVERTWITHPALETTE(1, 24)
- CONVERTWITHPALETTE(1, 32)
- }
-
- break;
-
- case 4 :
- switch(bpp) {
- CONVERT(4, 8)
- CONVERTTO16WITHPALETTE(4)
- CONVERTWITHPALETTE(4, 24)
- CONVERTWITHPALETTE(4, 32)
- }
-
- break;
-
- case 8 :
- switch(bpp) {
- CONVERTTO16WITHPALETTE(8)
- CONVERTWITHPALETTE(8, 24)
- CONVERTWITHPALETTE(8, 32)
- }
-
- break;
-
- case 24 :
- switch(bpp) {
- CONVERT(24, 8)
- CONVERTTO16(24)
- CONVERT(24, 32)
- }
-
- break;
-
- case 32 :
- switch(bpp) {
- CONVERT(32, 8)
- CONVERTTO16(32)
- CONVERT(32, 24)
- }
-
- break;
- }
- } else {
- memcpy(bits, scanline, FreeImage_GetLine(dib));
- }
-
- bits += pitch;
- }
- }
-}
diff --git a/plugins/AdvaImg/src/FreeImage/Conversion16_555.cpp b/plugins/AdvaImg/src/FreeImage/Conversion16_555.cpp
deleted file mode 100644
index 3eb4c330a5..0000000000
--- a/plugins/AdvaImg/src/FreeImage/Conversion16_555.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Jani Kajala (janik@remedy.fi)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-
-#define RGB555(b, g, r) ((((b) >> 3) << FI16_555_BLUE_SHIFT) | (((g) >> 3) << FI16_555_GREEN_SHIFT) | (((r) >> 3) << FI16_555_RED_SHIFT))
-
-// ----------------------------------------------------------
-// internal conversions X to 16 bits (555)
-// ----------------------------------------------------------
-
-void DLL_CALLCONV
-FreeImage_ConvertLine1To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- WORD *new_bits = (WORD *)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- int index = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
-
- new_bits[cols] = RGB555(palette[index].rgbBlue, palette[index].rgbGreen, palette[index].rgbRed);
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine4To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- WORD *new_bits = (WORD *)target;
- BOOL lonibble = FALSE;
- int x = 0;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- RGBQUAD *grab_palette;
-
- if (lonibble) {
- grab_palette = palette + LOWNIBBLE(source[x++]);
- } else {
- grab_palette = palette + (HINIBBLE(source[x]) >> 4);
- }
-
- new_bits[cols] = RGB555(grab_palette->rgbBlue, grab_palette->rgbGreen, grab_palette->rgbRed);
-
- lonibble = !lonibble;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine8To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- WORD *new_bits = (WORD *)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- RGBQUAD *grab_palette = palette + source[cols];
-
- new_bits[cols] = RGB555(grab_palette->rgbBlue, grab_palette->rgbGreen, grab_palette->rgbRed);
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16_565_To16_555(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *src_bits = (WORD *)source;
- WORD *new_bits = (WORD *)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- new_bits[cols] = RGB555((((src_bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F,
- (((src_bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F,
- (((src_bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine24To16_555(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *new_bits = (WORD *)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- new_bits[cols] = RGB555(source[FI_RGBA_BLUE], source[FI_RGBA_GREEN], source[FI_RGBA_RED]);
-
- source += 3;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine32To16_555(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *new_bits = (WORD *)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- new_bits[cols] = RGB555(source[FI_RGBA_BLUE], source[FI_RGBA_GREEN], source[FI_RGBA_RED]);
-
- source += 4;
- }
-}
-
-// ----------------------------------------------------------
-// smart convert X to 16 bits
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertTo16Bits555(FIBITMAP *dib) {
- if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) return NULL;
-
- const int width = FreeImage_GetWidth(dib);
- const int height = FreeImage_GetHeight(dib);
- const int bpp = FreeImage_GetBPP(dib);
-
- if(bpp == 16) {
- if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
- // RGB 565
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 16, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
- if(new_dib == NULL) {
- return NULL;
- }
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine16_565_To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- return new_dib;
- } else {
- // RGB 555
- return FreeImage_Clone(dib);
- }
- }
- else {
- // other bpp cases => convert to RGB 555
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 16, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
- if(new_dib == NULL) {
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- switch (bpp) {
- case 1 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine1To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
-
- return new_dib;
- }
-
- case 4 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine4To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
-
- return new_dib;
- }
-
- case 8 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine8To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
-
- return new_dib;
- }
-
- case 24 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine24To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
-
- return new_dib;
- }
-
- case 32 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine32To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
-
- return new_dib;
- }
-
- default :
- // unreachable code ...
- FreeImage_Unload(new_dib);
- break;
-
- }
- }
-
- return NULL;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/Conversion16_565.cpp b/plugins/AdvaImg/src/FreeImage/Conversion16_565.cpp
deleted file mode 100644
index fd790b92f4..0000000000
--- a/plugins/AdvaImg/src/FreeImage/Conversion16_565.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Jani Kajala (janik@remedy.fi)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// internal conversions X to 16 bits (565)
-// ----------------------------------------------------------
-
-void DLL_CALLCONV
-FreeImage_ConvertLine1To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- WORD *new_bits = (WORD *)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- int index = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0;
-
- new_bits[cols] = RGB565(palette[index].rgbBlue, palette[index].rgbGreen, palette[index].rgbRed);
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine4To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- WORD *new_bits = (WORD *)target;
- BOOL lonibble = FALSE;
- int x = 0;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- RGBQUAD *grab_palette;
-
- if (lonibble) {
- grab_palette = palette + LOWNIBBLE(source[x++]);
- } else {
- grab_palette = palette + (HINIBBLE(source[x]) >> 4);
- }
-
- new_bits[cols] = RGB565(grab_palette->rgbBlue, grab_palette->rgbGreen, grab_palette->rgbRed);
-
- lonibble = !lonibble;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine8To16_565(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- WORD *new_bits = (WORD *)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- RGBQUAD *grab_palette = palette + source[cols];
-
- new_bits[cols] = RGB565(grab_palette->rgbBlue, grab_palette->rgbGreen, grab_palette->rgbRed);
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16_555_To16_565(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *src_bits = (WORD *)source;
- WORD *new_bits = (WORD *)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- new_bits[cols] = RGB565((((src_bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F,
- (((src_bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F,
- (((src_bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine24To16_565(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *new_bits = (WORD *)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- new_bits[cols] = RGB565(source[FI_RGBA_BLUE], source[FI_RGBA_GREEN], source[FI_RGBA_RED]);
-
- source += 3;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine32To16_565(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *new_bits = (WORD *)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- new_bits[cols] = RGB565(source[FI_RGBA_BLUE], source[FI_RGBA_GREEN], source[FI_RGBA_RED]);
-
- source += 4;
- }
-}
-
-// ----------------------------------------------------------
-// smart convert X to 16 bits (565)
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertTo16Bits565(FIBITMAP *dib) {
- if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) return NULL;
-
- const int width = FreeImage_GetWidth(dib);
- const int height = FreeImage_GetHeight(dib);
- const int bpp = FreeImage_GetBPP(dib);
-
- if(bpp == 16) {
- if ((FreeImage_GetRedMask(dib) == FI16_555_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_555_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_555_BLUE_MASK)) {
- // RGB 555
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 16, FI16_565_RED_MASK, FI16_565_GREEN_MASK, FI16_565_BLUE_MASK);
- if(new_dib == NULL) {
- return NULL;
- }
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine16_555_To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- return new_dib;
- } else {
- // RGB 565
- return FreeImage_Clone(dib);
- }
- }
- else {
- // other bpp cases => convert to RGB 565
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 16, FI16_565_RED_MASK, FI16_565_GREEN_MASK, FI16_565_BLUE_MASK);
- if(new_dib == NULL) {
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- switch (bpp) {
- case 1 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine1To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
-
- return new_dib;
- }
-
- case 4 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine4To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
-
- return new_dib;
- }
-
- case 8 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine8To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
-
- return new_dib;
- }
-
- case 24 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine24To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
-
- return new_dib;
- }
-
- case 32 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine32To16_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
-
- return new_dib;
- }
-
- default :
- // unreachable code ...
- FreeImage_Unload(new_dib);
- break;
- }
- }
-
- return NULL;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/Conversion24.cpp b/plugins/AdvaImg/src/FreeImage/Conversion24.cpp
deleted file mode 100644
index 85ce90417b..0000000000
--- a/plugins/AdvaImg/src/FreeImage/Conversion24.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Dale Larson (dlarson@norsesoft.com)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Jani Kajala (janik@remedy.fi)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// internal conversions X to 24 bits
-// ----------------------------------------------------------
-
-void DLL_CALLCONV
-FreeImage_ConvertLine1To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- for (int cols = 0; cols < width_in_pixels; cols++) {
- BYTE 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 += 3;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine4To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- 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;
-
- 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;
- }
-
- low_nibble = !low_nibble;
-
- target += 3;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine8To24(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- 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 += 3;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To24_555(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *bits = (WORD *)source;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- target[FI_RGBA_RED] = (BYTE)((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
- target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
- target[FI_RGBA_BLUE] = (BYTE)((((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
-
- target += 3;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To24_565(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *bits = (WORD *)source;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- target[FI_RGBA_RED] = (BYTE)((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
- target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
- target[FI_RGBA_BLUE] = (BYTE)((((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
-
- target += 3;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine32To24(BYTE *target, BYTE *source, int width_in_pixels) {
- for (int cols = 0; cols < width_in_pixels; cols++) {
- target[FI_RGBA_BLUE] = source[FI_RGBA_BLUE];
- target[FI_RGBA_GREEN] = source[FI_RGBA_GREEN];
- target[FI_RGBA_RED] = source[FI_RGBA_RED];
-
- target += 3;
- source += 4;
- }
-}
-
-// ----------------------------------------------------------
-// smart convert X to 24 bits
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertTo24Bits(FIBITMAP *dib) {
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- const unsigned bpp = FreeImage_GetBPP(dib);
- const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-
- if((image_type != FIT_BITMAP) && (image_type != FIT_RGB16) && (image_type != FIT_RGBA16)) {
- return NULL;
- }
-
- const int width = FreeImage_GetWidth(dib);
- const int height = FreeImage_GetHeight(dib);
-
- if(image_type == FIT_BITMAP) {
- if(bpp == 24) {
- return FreeImage_Clone(dib);
- }
-
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(new_dib == NULL) {
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- switch(bpp) {
- case 1 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine1To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
- return new_dib;
- }
-
- case 4 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine4To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
- return new_dib;
- }
-
- case 8 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine8To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
- return new_dib;
- }
-
- case 16 :
- {
- for (int rows = 0; rows < height; rows++) {
- if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
- FreeImage_ConvertLine16To24_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- } else {
- // includes case where all the masks are 0
- FreeImage_ConvertLine16To24_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- }
- return new_dib;
- }
-
- case 32 :
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine32To24(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- return new_dib;
- }
- }
-
- } else if(image_type == FIT_RGB16) {
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(new_dib == NULL) {
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- const unsigned src_pitch = FreeImage_GetPitch(dib);
- const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
- const BYTE *src_bits = FreeImage_GetBits(dib);
- BYTE *dst_bits = FreeImage_GetBits(new_dib);
- for (int rows = 0; rows < height; rows++) {
- const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
- RGBTRIPLE *dst_pixel = (RGBTRIPLE*)dst_bits;
- for(int cols = 0; cols < width; cols++) {
- dst_pixel[cols].rgbtRed = (BYTE)(src_pixel[cols].red >> 8);
- dst_pixel[cols].rgbtGreen = (BYTE)(src_pixel[cols].green >> 8);
- dst_pixel[cols].rgbtBlue = (BYTE)(src_pixel[cols].blue >> 8);
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
-
- return new_dib;
-
- } else if(image_type == FIT_RGBA16) {
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(new_dib == NULL) {
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- const unsigned src_pitch = FreeImage_GetPitch(dib);
- const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
- const BYTE *src_bits = FreeImage_GetBits(dib);
- BYTE *dst_bits = FreeImage_GetBits(new_dib);
- for (int rows = 0; rows < height; rows++) {
- const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
- RGBTRIPLE *dst_pixel = (RGBTRIPLE*)dst_bits;
- for(int cols = 0; cols < width; cols++) {
- dst_pixel[cols].rgbtRed = (BYTE)(src_pixel[cols].red >> 8);
- dst_pixel[cols].rgbtGreen = (BYTE)(src_pixel[cols].green >> 8);
- dst_pixel[cols].rgbtBlue = (BYTE)(src_pixel[cols].blue >> 8);
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
-
- return new_dib;
- }
-
- return NULL;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/Conversion32.cpp b/plugins/AdvaImg/src/FreeImage/Conversion32.cpp
deleted file mode 100644
index 0dc31287e6..0000000000
--- a/plugins/AdvaImg/src/FreeImage/Conversion32.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Jani Kajala (janik@remedy.fi)
-// - Detlev Vendt (detlev.vendt@brillit.de)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// internal conversions X to 32 bits
-// ----------------------------------------------------------
-
-void DLL_CALLCONV
-FreeImage_ConvertLine1To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- 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] = 0xFF;
- target += 4;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine4To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- 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;
-
- 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;
- }
-
- low_nibble = !low_nibble;
-
- target[FI_RGBA_ALPHA] = 0xFF;
- target += 4;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine8To32(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- 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] = 0xFF;
- target += 4;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To32_555(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *bits = (WORD *)source;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- target[FI_RGBA_RED] = (BYTE)((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
- target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
- target[FI_RGBA_BLUE] = (BYTE)((((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
- target[FI_RGBA_ALPHA] = 0xFF;
- target += 4;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To32_565(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *bits = (WORD *)source;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- target[FI_RGBA_RED] = (BYTE)((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
- target[FI_RGBA_GREEN] = (BYTE)((((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
- target[FI_RGBA_BLUE] = (BYTE)((((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
- target[FI_RGBA_ALPHA] = 0xFF;
- target += 4;
- }
-}
-/*
-void DLL_CALLCONV
-FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels) {
- for (int cols = 0; cols < width_in_pixels; cols++) {
- *(DWORD *)target = (*(DWORD *) source & FI_RGBA_RGB_MASK) | FI_RGBA_ALPHA_MASK;
- target += 4;
- source += 3;
- }
-}
-*/
-/**
-This unoptimized version of the conversion function avoid an undetermined bug with VC++ SP6.
-The bug occurs in release mode only, when the image height is equal to 537
-(try e.g. a size of 432x537 to reproduce the bug with the optimized function).
-*/
-void DLL_CALLCONV
-FreeImage_ConvertLine24To32(BYTE *target, BYTE *source, int width_in_pixels) {
- for (int cols = 0; cols < width_in_pixels; cols++) {
- target[FI_RGBA_RED] = source[FI_RGBA_RED];
- target[FI_RGBA_GREEN] = source[FI_RGBA_GREEN];
- 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;
-
- const int bpp = FreeImage_GetBPP(dib);
- const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-
- if((image_type != FIT_BITMAP) && (image_type != FIT_RGB16) && (image_type != FIT_RGBA16)) {
- return NULL;
- }
-
- const int width = FreeImage_GetWidth(dib);
- const int height = FreeImage_GetHeight(dib);
-
- if(image_type == FIT_BITMAP) {
-
- if(bpp == 32) {
- return FreeImage_Clone(dib);
- }
-
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(new_dib == NULL) {
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- BOOL bIsTransparent = FreeImage_IsTransparent(dib);
-
- switch(bpp) {
- case 1:
- {
- if(bIsTransparent) {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine1To32MapTransparency(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
- }
- } else {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine1To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
- }
-
- return new_dib;
- }
-
- case 4:
- {
- if(bIsTransparent) {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine4To32MapTransparency(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
- }
- } else {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine4To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
- }
-
- return new_dib;
- }
-
- case 8:
- {
- if(bIsTransparent) {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine8To32MapTransparency(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib), FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib));
- }
- } else {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine8To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
- }
-
- return new_dib;
- }
-
- case 16:
- {
- for (int rows = 0; rows < height; rows++) {
- if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
- FreeImage_ConvertLine16To32_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- } else {
- // includes case where all the masks are 0
- FreeImage_ConvertLine16To32_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- }
-
- return new_dib;
- }
-
- case 24:
- {
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine24To32(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
-
- return new_dib;
- }
- }
-
- } else if(image_type == FIT_RGB16) {
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(new_dib == NULL) {
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- const unsigned src_pitch = FreeImage_GetPitch(dib);
- const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
- const BYTE *src_bits = FreeImage_GetBits(dib);
- BYTE *dst_bits = FreeImage_GetBits(new_dib);
- for (int rows = 0; rows < height; rows++) {
- const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
- RGBQUAD *dst_pixel = (RGBQUAD*)dst_bits;
- for(int cols = 0; cols < width; cols++) {
- dst_pixel[cols].rgbRed = (BYTE)(src_pixel[cols].red >> 8);
- dst_pixel[cols].rgbGreen = (BYTE)(src_pixel[cols].green >> 8);
- dst_pixel[cols].rgbBlue = (BYTE)(src_pixel[cols].blue >> 8);
- dst_pixel[cols].rgbReserved = (BYTE)0xFF;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
-
- return new_dib;
-
- } else if(image_type == FIT_RGBA16) {
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(new_dib == NULL) {
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- const unsigned src_pitch = FreeImage_GetPitch(dib);
- const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
- const BYTE *src_bits = FreeImage_GetBits(dib);
- BYTE *dst_bits = FreeImage_GetBits(new_dib);
- for (int rows = 0; rows < height; rows++) {
- const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
- RGBQUAD *dst_pixel = (RGBQUAD*)dst_bits;
- for(int cols = 0; cols < width; cols++) {
- dst_pixel[cols].rgbRed = (BYTE)(src_pixel[cols].red >> 8);
- dst_pixel[cols].rgbGreen = (BYTE)(src_pixel[cols].green >> 8);
- dst_pixel[cols].rgbBlue = (BYTE)(src_pixel[cols].blue >> 8);
- dst_pixel[cols].rgbReserved = (BYTE)(src_pixel[cols].alpha >> 8);
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
-
- return new_dib;
- }
-
- return NULL;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/Conversion4.cpp b/plugins/AdvaImg/src/FreeImage/Conversion4.cpp
deleted file mode 100644
index 13048b6d3f..0000000000
--- a/plugins/AdvaImg/src/FreeImage/Conversion4.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Riley McNiff (rmcniff@marexgroup.com)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// internal conversions X to 4 bits
-// ----------------------------------------------------------
-
-void DLL_CALLCONV
-FreeImage_ConvertLine1To4(BYTE *target, BYTE *source, int width_in_pixels) {
- BOOL hinibble = TRUE;
- for (int cols = 0; cols < width_in_pixels; cols++){
- if (hinibble == TRUE){
- target[cols >> 1] = ((source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 15 : 0) << 4;
- }
- else {
- target[cols >> 1] |= ((source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 15 : 0);
- }
-
- hinibble = !hinibble;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine8To4(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) {
- BOOL hinibble = TRUE;
- BYTE index;
-
- for (int cols = 0; cols < width_in_pixels; cols++){
- index = GREY(palette[source[cols]].rgbRed, palette[source[cols]].rgbGreen, palette[source[cols]].rgbBlue);
- if (hinibble) {
- target[cols >> 1] = (index & 0xF0);
- } else {
- target[cols >> 1] |= (index >> 4);
- }
-
- hinibble = !hinibble;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To4_555(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *bits = (WORD *)source;
- BOOL hinibble = TRUE;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- if (hinibble) {
- target[cols >> 1] = GREY((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F,
- (((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F,
- (((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F)
- & 0xF0;
- } else {
- target[cols >> 1] |= GREY((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F,
- (((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F,
- (((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F)
- >> 4;
- }
-
- hinibble = !hinibble;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To4_565(BYTE *target, BYTE *source, int width_in_pixels) {
- WORD *bits = (WORD *)source;
- BOOL hinibble = TRUE;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- if (hinibble) {
- target[cols >> 1] = GREY((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F,
- (((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F,
- (((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F)
- & 0xF0;
- } else {
- target[cols >> 1] |= GREY((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F,
- (((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F,
- (((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F)
- >> 4;
- }
-
- hinibble = !hinibble;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine24To4(BYTE *target, BYTE *source, int width_in_pixels) {
- BOOL hinibble = TRUE;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- if (hinibble) {
- target[cols >> 1] = GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]) & 0xF0;
- } else {
- target[cols >> 1] |= GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]) >> 4;
- }
-
- source += 3;
- hinibble = !hinibble;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine32To4(BYTE *target, BYTE *source, int width_in_pixels) {
- BOOL hinibble = TRUE;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- if (hinibble) {
- target[cols >> 1] = GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]) & 0xF0;
- } else {
- target[cols >> 1] |= GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]) >> 4;
- }
-
- source += 4;
- hinibble = !hinibble;
- }
-}
-
-// ----------------------------------------------------------
-// smart convert X to 4 bits
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertTo4Bits(FIBITMAP *dib) {
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- const int bpp = FreeImage_GetBPP(dib);
-
- if(bpp != 4) {
- const int width = FreeImage_GetWidth(dib);
- const int height = FreeImage_GetHeight(dib);
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 4);
-
- if(new_dib == NULL) {
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- // Build a greyscale palette (*always* needed for image processing)
-
- RGBQUAD *new_pal = FreeImage_GetPalette(new_dib);
-
- for(int i = 0; i < 16; i++) {
- new_pal[i].rgbRed = (BYTE)((i << 4) + i);
- new_pal[i].rgbGreen = (BYTE)((i << 4) + i);
- new_pal[i].rgbBlue = (BYTE)((i << 4) + i);
- }
-
- switch(bpp) {
- case 1:
- {
- if(FreeImage_GetColorType(dib) == FIC_PALETTE) {
-
- // Copy the palette
-
- RGBQUAD *old_pal = FreeImage_GetPalette(dib);
- memcpy(&new_pal[0], &old_pal[0], sizeof(RGBQUAD));
- memcpy(&new_pal[15], &old_pal[1], sizeof(RGBQUAD));
-
- }
- else if(FreeImage_GetColorType(dib) == FIC_MINISWHITE) {
-
- // Reverse the grayscale palette
-
- for(int i = 0; i < 16; i++) {
- new_pal[i].rgbRed = new_pal[i].rgbGreen = new_pal[i].rgbBlue = (BYTE)(255 - ((i << 4) + i));
- }
- }
-
- // Expand and copy the bitmap data
-
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine1To4(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- return new_dib;
- }
-
- case 8 :
- {
- // Expand and copy the bitmap data
-
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine8To4(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib));
- }
- return new_dib;
- }
-
- case 16 :
- {
- // Expand and copy the bitmap data
-
- for (int rows = 0; rows < height; rows++) {
- if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
- FreeImage_ConvertLine16To4_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- } else {
- FreeImage_ConvertLine16To4_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- }
-
- return new_dib;
- }
-
- case 24 :
- {
- // Expand and copy the bitmap data
-
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine24To4(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- return new_dib;
- }
-
- case 32 :
- {
- // Expand and copy the bitmap data
-
- for (int rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine32To4(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- return new_dib;
- }
- }
- }
-
- return FreeImage_Clone(dib);
-}
diff --git a/plugins/AdvaImg/src/FreeImage/Conversion8.cpp b/plugins/AdvaImg/src/FreeImage/Conversion8.cpp
deleted file mode 100644
index 861e8169ce..0000000000
--- a/plugins/AdvaImg/src/FreeImage/Conversion8.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Jani Kajala (janik@remedy.fi)
-// - Karl-Heinz Bussian (khbussian@moss.de)
-// - Carsten Klein (cklein05@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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// internal conversions X to 8 bits
-// ----------------------------------------------------------
-
-void DLL_CALLCONV
-FreeImage_ConvertLine1To8(BYTE *target, BYTE *source, int width_in_pixels) {
- for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++)
- target[cols] = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 255 : 0;
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine4To8(BYTE *target, BYTE *source, int width_in_pixels) {
- unsigned count_new = 0;
- unsigned count_org = 0;
- BOOL hinibble = TRUE;
-
- while (count_new < (unsigned)width_in_pixels) {
- if (hinibble) {
- target[count_new] = (source[count_org] >> 4);
- } else {
- target[count_new] = (source[count_org] & 0x0F);
- count_org++;
- }
- hinibble = !hinibble;
- count_new++;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To8_555(BYTE *target, BYTE *source, int width_in_pixels) {
- const WORD *const bits = (WORD *)source;
- for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
- target[cols] = GREY((((bits[cols] & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F,
- (((bits[cols] & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F,
- (((bits[cols] & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine16To8_565(BYTE *target, BYTE *source, int width_in_pixels) {
- const WORD *const bits = (WORD *)source;
- for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
- target[cols] = GREY((((bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F,
- (((bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F,
- (((bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine24To8(BYTE *target, BYTE *source, int width_in_pixels) {
- for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
- target[cols] = GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]);
- source += 3;
- }
-}
-
-void DLL_CALLCONV
-FreeImage_ConvertLine32To8(BYTE *target, BYTE *source, int width_in_pixels) {
- for (unsigned cols = 0; cols < (unsigned)width_in_pixels; cols++) {
- target[cols] = GREY(source[FI_RGBA_RED], source[FI_RGBA_GREEN], source[FI_RGBA_BLUE]);
- source += 4;
- }
-}
-
-// ----------------------------------------------------------
-// smart convert X to 8 bits
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertTo8Bits(FIBITMAP *dib) {
- if (!FreeImage_HasPixels(dib)) {
- return NULL;
- }
-
- const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
- if (image_type != FIT_BITMAP && image_type != FIT_UINT16) {
- return NULL;
- }
-
- const unsigned bpp = FreeImage_GetBPP(dib);
-
- if (bpp != 8) {
-
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
-
- // Allocate a destination image
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 8);
- if (new_dib == NULL) {
- return NULL;
- }
-
- // Copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- // Palette of destination image has already been initialized
- RGBQUAD *new_pal = FreeImage_GetPalette(new_dib);
-
- const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
-
- if (image_type == FIT_BITMAP) {
-
- switch(bpp) {
- case 1:
- {
- if (color_type == FIC_PALETTE) {
- // Copy the palette
- RGBQUAD *old_pal = FreeImage_GetPalette(dib);
- new_pal[0] = old_pal[0];
- new_pal[255] = old_pal[1];
-
- } else if (color_type == FIC_MINISWHITE) {
- // Create a reverse grayscale palette
- CREATE_GREYSCALE_PALETTE_REVERSE(new_pal, 256);
- }
-
- // Expand and copy the bitmap data
- for (unsigned rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine1To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- return new_dib;
- }
-
- case 4 :
- {
- if (color_type == FIC_PALETTE) {
- // Copy the palette
- memcpy(new_pal, FreeImage_GetPalette(dib), 16 * sizeof(RGBQUAD));
- }
-
- // Expand and copy the bitmap data
- for (unsigned rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine4To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- return new_dib;
- }
-
- case 16 :
- {
- // Expand and copy the bitmap data
- if (IS_FORMAT_RGB565(dib)) {
- for (unsigned rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine16To8_565(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- } else {
- for (unsigned rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine16To8_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- }
- return new_dib;
- }
-
- case 24 :
- {
- // Expand and copy the bitmap data
- for (unsigned rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine24To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- return new_dib;
- }
-
- case 32 :
- {
- // Expand and copy the bitmap data
- for (unsigned rows = 0; rows < height; rows++) {
- FreeImage_ConvertLine32To8(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width);
- }
- return new_dib;
- }
- }
-
- } else if (image_type == FIT_UINT16) {
-
- const unsigned src_pitch = FreeImage_GetPitch(dib);
- const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
- const BYTE *src_bits = FreeImage_GetBits(dib);
- BYTE *dst_bits = FreeImage_GetBits(new_dib);
-
- for (unsigned rows = 0; rows < height; rows++) {
- const WORD *const src_pixel = (WORD*)src_bits;
- BYTE *dst_pixel = (BYTE*)dst_bits;
- for(unsigned cols = 0; cols < width; cols++) {
- dst_pixel[cols] = (BYTE)(src_pixel[cols] >> 8);
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- return new_dib;
- }
-
- } // bpp != 8
-
- return FreeImage_Clone(dib);
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToGreyscale(FIBITMAP *dib) {
- if (!FreeImage_HasPixels(dib)) {
- return NULL;
- }
-
- const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
-
- if (color_type == FIC_PALETTE || color_type == FIC_MINISWHITE) {
-
- const unsigned bpp = FreeImage_GetBPP(dib);
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
-
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 8);
- if (new_dib == NULL) {
- return NULL;
- }
-
- // Copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- // Create a greyscale palette
- BYTE grey_pal[256];
- const RGBQUAD *pal = FreeImage_GetPalette(dib);
- const unsigned size = CalculateUsedPaletteEntries(bpp);
- for (unsigned i = 0; i < size; i++) {
- grey_pal[i] = GREY(pal->rgbRed, pal->rgbGreen, pal->rgbBlue);
- pal++;
- }
-
- const BYTE *src_bits = FreeImage_GetBits(dib);
- BYTE *dst_bits = FreeImage_GetBits(new_dib);
-
- const unsigned src_pitch = FreeImage_GetPitch(dib);
- const unsigned dst_pitch = FreeImage_GetPitch(new_dib);
-
- switch(bpp) {
- case 1:
- {
- for (unsigned y = 0; y < height; y++) {
- for (unsigned x = 0; x < width; x++) {
- const unsigned pixel = (src_bits[x >> 3] & (0x80 >> (x & 0x07))) != 0;
- dst_bits[x] = grey_pal[pixel];
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case 4:
- {
- for (unsigned y = 0; y < height; y++) {
- for (unsigned x = 0; x < width; x++) {
- const unsigned pixel = x & 0x01 ? src_bits[x >> 1] & 0x0F : src_bits[x >> 1] >> 4;
- dst_bits[x] = grey_pal[pixel];
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case 8:
- {
- for (unsigned y = 0; y < height; y++) {
- for (unsigned x = 0; x < width; x++) {
- dst_bits[x] = grey_pal[src_bits[x]];
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
- }
- return new_dib;
- }
-
- // Convert the bitmap to 8-bit greyscale
- return FreeImage_ConvertTo8Bits(dib);
-}
diff --git a/plugins/AdvaImg/src/FreeImage/ConversionFloat.cpp b/plugins/AdvaImg/src/FreeImage/ConversionFloat.cpp
deleted file mode 100644
index 6a01d7f0af..0000000000
--- a/plugins/AdvaImg/src/FreeImage/ConversionFloat.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// smart convert X to Float
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToFloat(FIBITMAP *dib) {
- FIBITMAP *src = NULL;
- FIBITMAP *dst = NULL;
-
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
-
- // check for allowed conversions
- switch(src_type) {
- case FIT_BITMAP:
- {
- // allow conversion from 8-bit
- if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) {
- src = dib;
- } else {
- src = FreeImage_ConvertToGreyscale(dib);
- if(!src) return NULL;
- }
- break;
- }
- case FIT_UINT16:
- case FIT_RGB16:
- case FIT_RGBA16:
- case FIT_RGBF:
- case FIT_RGBAF:
- src = dib;
- break;
- case FIT_FLOAT:
- // float type : clone the src
- return FreeImage_Clone(dib);
- default:
- return NULL;
- }
-
- // allocate dst image
-
- const unsigned width = FreeImage_GetWidth(src);
- const unsigned height = FreeImage_GetHeight(src);
-
- dst = FreeImage_AllocateT(FIT_FLOAT, width, height);
- if(!dst) {
- if(src != dib) {
- FreeImage_Unload(src);
- }
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- // convert from src type to float
-
- const unsigned src_pitch = FreeImage_GetPitch(src);
- const unsigned dst_pitch = FreeImage_GetPitch(dst);
-
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- switch(src_type) {
- case FIT_BITMAP:
- {
- for(unsigned y = 0; y < height; y++) {
- const BYTE *src_pixel = (BYTE*)src_bits;
- float *dst_pixel = (float*)dst_bits;
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- dst_pixel[x] = (float)(src_pixel[x]) / 255;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_UINT16:
- {
- for(unsigned y = 0; y < height; y++) {
- const WORD *src_pixel = (WORD*)src_bits;
- float *dst_pixel = (float*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- dst_pixel[x] = (float)(src_pixel[x]) / 65535;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_RGB16:
- {
- for(unsigned y = 0; y < height; y++) {
- const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
- float *dst_pixel = (float*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_RGBA16:
- {
- for(unsigned y = 0; y < height; y++) {
- const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
- float *dst_pixel = (float*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue) / 65535.0F;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_RGBF:
- {
- for(unsigned y = 0; y < height; y++) {
- const FIRGBF *src_pixel = (FIRGBF*)src_bits;
- float *dst_pixel = (float*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert (assume pixel values are in the range [0..1])
- dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
- dst_pixel[x] = CLAMP(dst_pixel[x], 0.0F, 1.0F);
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_RGBAF:
- {
- for(unsigned y = 0; y < height; y++) {
- const FIRGBAF *src_pixel = (FIRGBAF*)src_bits;
- float *dst_pixel = (float*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert (assume pixel values are in the range [0..1])
- dst_pixel[x] = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
- dst_pixel[x] = CLAMP(dst_pixel[x], 0.0F, 1.0F);
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
- }
-
- if(src != dib) {
- FreeImage_Unload(src);
- }
-
- return dst;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/ConversionRGB16.cpp b/plugins/AdvaImg/src/FreeImage/ConversionRGB16.cpp
deleted file mode 100644
index 156a91b85b..0000000000
--- a/plugins/AdvaImg/src/FreeImage/ConversionRGB16.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// smart convert X to RGB16
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToRGB16(FIBITMAP *dib) {
- FIBITMAP *src = NULL;
- FIBITMAP *dst = NULL;
-
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
-
- // check for allowed conversions
- switch(src_type) {
- case FIT_BITMAP:
- {
- // convert to 24-bit if needed
- if((FreeImage_GetBPP(dib) == 24) || (FreeImage_GetBPP(dib) == 32)) {
- src = dib;
- } else {
- src = FreeImage_ConvertTo24Bits(dib);
- if(!src) return NULL;
- }
- break;
- }
- case FIT_UINT16:
- // allow conversion from unsigned 16-bit
- src = dib;
- break;
- case FIT_RGB16:
- // RGB16 type : clone the src
- return FreeImage_Clone(dib);
- break;
- case FIT_RGBA16:
- // allow conversion from 64-bit RGBA (ignore the alpha channel)
- src = dib;
- break;
- default:
- return NULL;
- }
-
- // allocate dst image
-
- const unsigned width = FreeImage_GetWidth(src);
- const unsigned height = FreeImage_GetHeight(src);
-
- dst = FreeImage_AllocateT(FIT_RGB16, width, height);
- if(!dst) {
- if(src != dib) {
- FreeImage_Unload(src);
- }
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- // convert from src type to RGB16
-
- switch(src_type) {
- case FIT_BITMAP:
- {
- // Calculate the number of bytes per pixel (1 for 8-bit, 3 for 24-bit or 4 for 32-bit)
- const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
-
- for(unsigned y = 0; y < height; y++) {
- const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
- FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- dst_bits[x].red = src_bits[FI_RGBA_RED] << 8;
- dst_bits[x].green = src_bits[FI_RGBA_GREEN] << 8;
- dst_bits[x].blue = src_bits[FI_RGBA_BLUE] << 8;
- src_bits += bytespp;
- }
- }
- }
- break;
-
- case FIT_UINT16:
- {
- for(unsigned y = 0; y < height; y++) {
- const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y);
- FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- // convert by copying greyscale channel to each R, G, B channels
- dst_bits[x].red = src_bits[x];
- dst_bits[x].green = src_bits[x];
- dst_bits[x].blue = src_bits[x];
- }
- }
- }
- break;
-
- case FIT_RGBA16:
- {
- for(unsigned y = 0; y < height; y++) {
- const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y);
- FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- // convert and skip alpha channel
- dst_bits[x].red = src_bits[x].red;
- dst_bits[x].green = src_bits[x].green;
- dst_bits[x].blue = src_bits[x].blue;
- }
- }
- }
- break;
-
- default:
- break;
- }
-
- if(src != dib) {
- FreeImage_Unload(src);
- }
-
- return dst;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/ConversionRGBA16.cpp b/plugins/AdvaImg/src/FreeImage/ConversionRGBA16.cpp
deleted file mode 100644
index 600d8ea1e6..0000000000
--- a/plugins/AdvaImg/src/FreeImage/ConversionRGBA16.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// smart convert X to RGBA16
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToRGBA16(FIBITMAP *dib) {
- FIBITMAP *src = NULL;
- FIBITMAP *dst = NULL;
-
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
-
- // check for allowed conversions
- switch(src_type) {
- case FIT_BITMAP:
- {
- // convert to 32-bit if needed
- if(FreeImage_GetBPP(dib) == 32) {
- src = dib;
- } else {
- src = FreeImage_ConvertTo32Bits(dib);
- if(!src) return NULL;
- }
- break;
- }
- case FIT_UINT16:
- // allow conversion from unsigned 16-bit
- src = dib;
- break;
- case FIT_RGB16:
- // allow conversion from 48-bit RGB
- src = dib;
- break;
- case FIT_RGBA16:
- // RGBA16 type : clone the src
- return FreeImage_Clone(dib);
- break;
- default:
- return NULL;
- }
-
- // allocate dst image
-
- const unsigned width = FreeImage_GetWidth(src);
- const unsigned height = FreeImage_GetHeight(src);
-
- dst = FreeImage_AllocateT(FIT_RGBA16, width, height);
- if(!dst) {
- if(src != dib) {
- FreeImage_Unload(src);
- }
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- // convert from src type to RGBA16
-
- switch(src_type) {
- case FIT_BITMAP:
- {
- // Calculate the number of bytes per pixel (4 for 32-bit)
- const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
-
- for(unsigned y = 0; y < height; y++) {
- const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
- FIRGBA16 *dst_bits = (FIRGBA16*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- dst_bits[x].red = src_bits[FI_RGBA_RED] << 8;
- dst_bits[x].green = src_bits[FI_RGBA_GREEN] << 8;
- dst_bits[x].blue = src_bits[FI_RGBA_BLUE] << 8;
- dst_bits[x].alpha = src_bits[FI_RGBA_ALPHA] << 8;
- src_bits += bytespp;
- }
- }
- }
- break;
-
- case FIT_UINT16:
- {
- for(unsigned y = 0; y < height; y++) {
- const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y);
- FIRGBA16 *dst_bits = (FIRGBA16*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- // convert by copying greyscale channel to each R, G, B channels
- dst_bits[x].red = src_bits[x];
- dst_bits[x].green = src_bits[x];
- dst_bits[x].blue = src_bits[x];
- dst_bits[x].alpha = 0xFFFF;
- }
- }
- }
- break;
-
- case FIT_RGB16:
- {
- for(unsigned y = 0; y < height; y++) {
- const FIRGB16 *src_bits = (FIRGB16*)FreeImage_GetScanLine(src, y);
- FIRGBA16 *dst_bits = (FIRGBA16*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- // convert pixels directly, while adding a "dummy" alpha of 1.0
- dst_bits[x].red = src_bits[x].red;
- dst_bits[x].green = src_bits[x].green;
- dst_bits[x].blue = src_bits[x].blue;
- dst_bits[x].alpha = 0xFFFF;
- }
- }
- }
- break;
-
- default:
- break;
- }
-
- if(src != dib) {
- FreeImage_Unload(src);
- }
-
- return dst;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/ConversionRGBAF.cpp b/plugins/AdvaImg/src/FreeImage/ConversionRGBAF.cpp
deleted file mode 100644
index 2ba2b32b42..0000000000
--- a/plugins/AdvaImg/src/FreeImage/ConversionRGBAF.cpp
+++ /dev/null
@@ -1,250 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Tanner Helland (tannerhelland@users.sf.net)
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// smart convert X to RGBAF
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToRGBAF(FIBITMAP *dib) {
- FIBITMAP *src = NULL;
- FIBITMAP *dst = NULL;
-
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
-
- // check for allowed conversions
- switch(src_type) {
- case FIT_BITMAP:
- {
- // allow conversion from 32-bit
- const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
- if(color_type != FIC_RGBALPHA) {
- src = FreeImage_ConvertTo32Bits(dib);
- if(!src) return NULL;
- } else {
- src = dib;
- }
- break;
- }
- case FIT_UINT16:
- // allow conversion from 16-bit
- src = dib;
- break;
- case FIT_RGB16:
- // allow conversion from 48-bit RGB
- src = dib;
- break;
- case FIT_RGBA16:
- // allow conversion from 64-bit RGBA
- src = dib;
- break;
- case FIT_FLOAT:
- // allow conversion from 32-bit float
- src = dib;
- break;
- case FIT_RGBF:
- // allow conversion from 96-bit RGBF
- src = dib;
- break;
- case FIT_RGBAF:
- // RGBAF type : clone the src
- return FreeImage_Clone(dib);
- break;
- default:
- return NULL;
- }
-
- // allocate dst image
-
- const unsigned width = FreeImage_GetWidth(src);
- const unsigned height = FreeImage_GetHeight(src);
-
- dst = FreeImage_AllocateT(FIT_RGBAF, width, height);
- if(!dst) {
- if(src != dib) {
- FreeImage_Unload(src);
- }
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- // convert from src type to RGBAF
-
- const unsigned src_pitch = FreeImage_GetPitch(src);
- const unsigned dst_pitch = FreeImage_GetPitch(dst);
-
- switch(src_type) {
- case FIT_BITMAP:
- {
- // calculate the number of bytes per pixel (4 for 32-bit)
- const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
-
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const BYTE *src_pixel = (BYTE*)src_bits;
- FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- dst_pixel->red = (float)(src_pixel[FI_RGBA_RED]) / 255.0F;
- dst_pixel->green = (float)(src_pixel[FI_RGBA_GREEN]) / 255.0F;
- dst_pixel->blue = (float)(src_pixel[FI_RGBA_BLUE]) / 255.0F;
- dst_pixel->alpha = (float)(src_pixel[FI_RGBA_ALPHA]) / 255.0F;
-
- src_pixel += bytespp;
- dst_pixel++;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_UINT16:
- {
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const WORD *src_pixel = (WORD*)src_bits;
- FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- const float dst_value = (float)src_pixel[x] / 65535.0F;
- dst_pixel[x].red = dst_value;
- dst_pixel[x].green = dst_value;
- dst_pixel[x].blue = dst_value;
- dst_pixel[x].alpha = 1.0F;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_RGB16:
- {
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const FIRGB16 *src_pixel = (FIRGB16*)src_bits;
- FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- dst_pixel[x].red = (float)(src_pixel[x].red) / 65535.0F;
- dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
- dst_pixel[x].blue = (float)(src_pixel[x].blue) / 65535.0F;
- dst_pixel[x].alpha = 1.0F;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_RGBA16:
- {
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const FIRGBA16 *src_pixel = (FIRGBA16*)src_bits;
- FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- dst_pixel[x].red = (float)(src_pixel[x].red) / 65535.0F;
- dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
- dst_pixel[x].blue = (float)(src_pixel[x].blue) / 65535.0F;
- dst_pixel[x].alpha = (float)(src_pixel[x].alpha) / 65535.0F;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_FLOAT:
- {
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const float *src_pixel = (float*)src_bits;
- FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert by copying greyscale channel to each R, G, B channels
- // assume float values are in [0..1]
- const float value = CLAMP(src_pixel[x], 0.0F, 1.0F);
- dst_pixel[x].red = value;
- dst_pixel[x].green = value;
- dst_pixel[x].blue = value;
- dst_pixel[x].alpha = 1.0F;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_RGBF:
- {
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const FIRGBF *src_pixel = (FIRGBF*)src_bits;
- FIRGBAF *dst_pixel = (FIRGBAF*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert pixels directly, while adding a "dummy" alpha of 1.0
- dst_pixel[x].red = CLAMP(src_pixel[x].red, 0.0F, 1.0F);
- dst_pixel[x].green = CLAMP(src_pixel[x].green, 0.0F, 1.0F);
- dst_pixel[x].blue = CLAMP(src_pixel[x].blue, 0.0F, 1.0F);
- dst_pixel[x].alpha = 1.0F;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
- }
-
- if(src != dib) {
- FreeImage_Unload(src);
- }
-
- return dst;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/ConversionRGBF.cpp b/plugins/AdvaImg/src/FreeImage/ConversionRGBF.cpp
deleted file mode 100644
index a30b36532e..0000000000
--- a/plugins/AdvaImg/src/FreeImage/ConversionRGBF.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// smart convert X to RGBF
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToRGBF(FIBITMAP *dib) {
- FIBITMAP *src = NULL;
- FIBITMAP *dst = NULL;
-
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
-
- // check for allowed conversions
- switch(src_type) {
- case FIT_BITMAP:
- {
- // allow conversion from 24- and 32-bit
- const FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
- if((color_type != FIC_RGB) && (color_type != FIC_RGBALPHA)) {
- src = FreeImage_ConvertTo24Bits(dib);
- if(!src) return NULL;
- } else {
- src = dib;
- }
- break;
- }
- case FIT_UINT16:
- // allow conversion from 16-bit
- src = dib;
- break;
- case FIT_RGB16:
- // allow conversion from 48-bit RGB
- src = dib;
- break;
- case FIT_RGBA16:
- // allow conversion from 64-bit RGBA (ignore the alpha channel)
- src = dib;
- break;
- case FIT_FLOAT:
- // allow conversion from 32-bit float
- src = dib;
- break;
- case FIT_RGBAF:
- // allow conversion from 128-bit RGBAF
- src = dib;
- break;
- case FIT_RGBF:
- // RGBF type : clone the src
- return FreeImage_Clone(dib);
- break;
- default:
- return NULL;
- }
-
- // allocate dst image
-
- const unsigned width = FreeImage_GetWidth(src);
- const unsigned height = FreeImage_GetHeight(src);
-
- dst = FreeImage_AllocateT(FIT_RGBF, width, height);
- if(!dst) {
- if(src != dib) {
- FreeImage_Unload(src);
- }
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- // convert from src type to RGBF
-
- const unsigned src_pitch = FreeImage_GetPitch(src);
- const unsigned dst_pitch = FreeImage_GetPitch(dst);
-
- switch(src_type) {
- case FIT_BITMAP:
- {
- // calculate the number of bytes per pixel (3 for 24-bit or 4 for 32-bit)
- const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src);
-
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const BYTE *src_pixel = (BYTE*)src_bits;
- FIRGBF *dst_pixel = (FIRGBF*)dst_bits;
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- dst_pixel->red = (float)(src_pixel[FI_RGBA_RED]) / 255.0F;
- dst_pixel->green = (float)(src_pixel[FI_RGBA_GREEN]) / 255.0F;
- dst_pixel->blue = (float)(src_pixel[FI_RGBA_BLUE]) / 255.0F;
-
- src_pixel += bytespp;
- dst_pixel ++;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_UINT16:
- {
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const WORD *src_pixel = (WORD*)src_bits;
- FIRGBF *dst_pixel = (FIRGBF*)dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- const float dst_value = (float)src_pixel[x] / 65535.0F;
- dst_pixel[x].red = dst_value;
- dst_pixel[x].green = dst_value;
- dst_pixel[x].blue = dst_value;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_RGB16:
- {
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const FIRGB16 *src_pixel = (FIRGB16*) src_bits;
- FIRGBF *dst_pixel = (FIRGBF*) dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- dst_pixel[x].red = (float)(src_pixel[x].red) / 65535.0F;
- dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
- dst_pixel[x].blue = (float)(src_pixel[x].blue) / 65535.0F;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_RGBA16:
- {
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const FIRGBA16 *src_pixel = (FIRGBA16*) src_bits;
- FIRGBF *dst_pixel = (FIRGBF*) dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert and scale to the range [0..1]
- dst_pixel[x].red = (float)(src_pixel[x].red) / 65535.0F;
- dst_pixel[x].green = (float)(src_pixel[x].green) / 65535.0F;
- dst_pixel[x].blue = (float)(src_pixel[x].blue) / 65535.0F;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_FLOAT:
- {
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const float *src_pixel = (float*) src_bits;
- FIRGBF *dst_pixel = (FIRGBF*) dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert by copying greyscale channel to each R, G, B channels
- // assume float values are in [0..1]
- const float value = CLAMP(src_pixel[x], 0.0F, 1.0F);
- dst_pixel[x].red = value;
- dst_pixel[x].green = value;
- dst_pixel[x].blue = value;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
-
- case FIT_RGBAF:
- {
- const BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const FIRGBAF *src_pixel = (FIRGBAF*) src_bits;
- FIRGBF *dst_pixel = (FIRGBF*) dst_bits;
-
- for(unsigned x = 0; x < width; x++) {
- // convert and skip alpha channel
- dst_pixel[x].red = CLAMP(src_pixel[x].red, 0.0F, 1.0F);
- dst_pixel[x].green = CLAMP(src_pixel[x].green, 0.0F, 1.0F);
- dst_pixel[x].blue = CLAMP(src_pixel[x].blue, 0.0F, 1.0F);
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
- }
- break;
- }
-
- if(src != dib) {
- FreeImage_Unload(src);
- }
-
- return dst;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/ConversionType.cpp b/plugins/AdvaImg/src/FreeImage/ConversionType.cpp
deleted file mode 100644
index 09286e9a99..0000000000
--- a/plugins/AdvaImg/src/FreeImage/ConversionType.cpp
+++ /dev/null
@@ -1,699 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-// - Tanner Helland (tannerhelland@users.sf.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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-
-/** Convert a greyscale image of type Tsrc to type Tdst.
- Conversion is done using standard C language casting convention.
-*/
-template<class Tdst, class Tsrc>
-class CONVERT_TYPE
-{
-public:
- FIBITMAP* convert(FIBITMAP *src, FREE_IMAGE_TYPE dst_type);
-};
-
-template<class Tdst, class Tsrc> FIBITMAP*
-CONVERT_TYPE<Tdst, Tsrc>::convert(FIBITMAP *src, FREE_IMAGE_TYPE dst_type) {
-
- FIBITMAP *dst = NULL;
-
- unsigned width = FreeImage_GetWidth(src);
- unsigned height = FreeImage_GetHeight(src);
- unsigned bpp = FreeImage_GetBPP(src);
-
- // allocate dst image
-
- dst = FreeImage_AllocateT(dst_type, width, height, bpp,
- FreeImage_GetRedMask(src), FreeImage_GetGreenMask(src), FreeImage_GetBlueMask(src));
- if(!dst) return NULL;
-
- // convert from src_type to dst_type
-
- for(unsigned y = 0; y < height; y++) {
- const Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
- Tdst *dst_bits = reinterpret_cast<Tdst*>(FreeImage_GetScanLine(dst, y));
-
- for(unsigned x = 0; x < width; x++) {
- *dst_bits++ = static_cast<Tdst>(*src_bits++);
- }
- }
-
- return dst;
-}
-
-
-/** Convert a greyscale image of type Tsrc to a 8-bit grayscale dib.
- Conversion is done using either a linear scaling from [min, max] to [0, 255]
- or a rounding from src_pixel to (BYTE) MIN(255, MAX(0, q)) where int q = int(src_pixel + 0.5);
-*/
-template<class Tsrc>
-class CONVERT_TO_BYTE
-{
-public:
- FIBITMAP* convert(FIBITMAP *src, BOOL scale_linear);
-};
-
-template<class Tsrc> FIBITMAP*
-CONVERT_TO_BYTE<Tsrc>::convert(FIBITMAP *src, BOOL scale_linear) {
- FIBITMAP *dst = NULL;
- unsigned x, y;
-
- unsigned width = FreeImage_GetWidth(src);
- unsigned height = FreeImage_GetHeight(src);
-
- // allocate a 8-bit dib
-
- dst = FreeImage_AllocateT(FIT_BITMAP, width, height, 8, 0, 0, 0);
- if(!dst) return NULL;
-
- // build a greyscale palette
- RGBQUAD *pal = FreeImage_GetPalette(dst);
- for(int i = 0; i < 256; i++) {
- pal[i].rgbRed = (BYTE)i;
- pal[i].rgbGreen = (BYTE)i;
- pal[i].rgbBlue = (BYTE)i;
- }
-
- // convert the src image to dst
- // (FIBITMAP are stored upside down)
- if(scale_linear) {
- Tsrc max, min;
- double scale;
-
- // find the min and max value of the image
- Tsrc l_min, l_max;
- min = 255, max = 0;
- for(y = 0; y < height; y++) {
- Tsrc *bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
- MAXMIN(bits, width, l_max, l_min);
- if(l_max > max) max = l_max;
- if(l_min < min) min = l_min;
- }
- if(max == min) {
- max = 255; min = 0;
- }
-
- // compute the scaling factor
- scale = 255 / (double)(max - min);
-
- // scale to 8-bit
- for(y = 0; y < height; y++) {
- Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
- BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
- for(x = 0; x < width; x++) {
- dst_bits[x] = (BYTE)( scale * (src_bits[x] - min) + 0.5);
- }
- }
- } else {
- for(y = 0; y < height; y++) {
- Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
- BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
- for(x = 0; x < width; x++) {
- // rounding
- int q = int(src_bits[x] + 0.5);
- dst_bits[x] = (BYTE) MIN(255, MAX(0, q));
- }
- }
- }
-
- return dst;
-}
-
-/** Convert a greyscale image of type Tsrc to a FICOMPLEX dib.
-*/
-template<class Tsrc>
-class CONVERT_TO_COMPLEX
-{
-public:
- FIBITMAP* convert(FIBITMAP *src);
-};
-
-template<class Tsrc> FIBITMAP*
-CONVERT_TO_COMPLEX<Tsrc>::convert(FIBITMAP *src) {
- FIBITMAP *dst = NULL;
-
- unsigned width = FreeImage_GetWidth(src);
- unsigned height = FreeImage_GetHeight(src);
-
- // allocate dst image
-
- dst = FreeImage_AllocateT(FIT_COMPLEX, width, height);
- if(!dst) return NULL;
-
- // convert from src_type to FIT_COMPLEX
-
- for(unsigned y = 0; y < height; y++) {
- const Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y));
- FICOMPLEX *dst_bits = (FICOMPLEX *)FreeImage_GetScanLine(dst, y);
-
- for(unsigned x = 0; x < width; x++) {
- dst_bits[x].r = (double)src_bits[x];
- dst_bits[x].i = 0;
- }
- }
-
- return dst;
-}
-
-// ----------------------------------------------------------
-
-// Convert from type BYTE to type X
-CONVERT_TYPE<unsigned short, BYTE> convertByteToUShort;
-CONVERT_TYPE<short, BYTE> convertByteToShort;
-CONVERT_TYPE<DWORD, BYTE> convertByteToULong;
-CONVERT_TYPE<LONG, BYTE> convertByteToLong;
-CONVERT_TYPE<float, BYTE> convertByteToFloat;
-CONVERT_TYPE<double, BYTE> convertByteToDouble;
-
-// Convert from type X to type BYTE
-CONVERT_TO_BYTE<unsigned short> convertUShortToByte;
-CONVERT_TO_BYTE<short> convertShortToByte;
-CONVERT_TO_BYTE<DWORD> convertULongToByte;
-CONVERT_TO_BYTE<LONG> convertLongToByte;
-CONVERT_TO_BYTE<float> convertFloatToByte;
-CONVERT_TO_BYTE<double> convertDoubleToByte;
-
-// Convert from type X to type float
-CONVERT_TYPE<float, unsigned short> convertUShortToFloat;
-CONVERT_TYPE<float, short> convertShortToFloat;
-CONVERT_TYPE<float, DWORD> convertULongToFloat;
-CONVERT_TYPE<float, LONG> convertLongToFloat;
-
-// Convert from type X to type double
-CONVERT_TYPE<double, unsigned short> convertUShortToDouble;
-CONVERT_TYPE<double, short> convertShortToDouble;
-CONVERT_TYPE<double, DWORD> convertULongToDouble;
-CONVERT_TYPE<double, LONG> convertLongToDouble;
-CONVERT_TYPE<double, float> convertFloatToDouble;
-
-// Convert from type X to type FICOMPLEX
-CONVERT_TO_COMPLEX<BYTE> convertByteToComplex;
-CONVERT_TO_COMPLEX<unsigned short> convertUShortToComplex;
-CONVERT_TO_COMPLEX<short> convertShortToComplex;
-CONVERT_TO_COMPLEX<DWORD> convertULongToComplex;
-CONVERT_TO_COMPLEX<LONG> convertLongToComplex;
-CONVERT_TO_COMPLEX<float> convertFloatToComplex;
-CONVERT_TO_COMPLEX<double> convertDoubleToComplex;
-
-// ----------------------------------------------------------
-
-// ----------------------------------------------------------
-// smart convert X to standard FIBITMAP
-// ----------------------------------------------------------
-
-/** Convert image of any type to a standard 8-bit greyscale image.
-For standard images, a clone of the input image is returned.
-When the scale_linear parameter is TRUE, conversion is done by scaling linearly
-each pixel to an integer value between [0..255]. When it is FALSE, conversion is done
-by rounding each float pixel to an integer between [0..255].
-For complex images, the magnitude is extracted as a double image, then converted according to the scale parameter.
-@param image Image to convert
-@param scale_linear Linear scaling / rounding switch
-*/
-FIBITMAP* DLL_CALLCONV
-FreeImage_ConvertToStandardType(FIBITMAP *src, BOOL scale_linear) {
- FIBITMAP *dst = NULL;
-
- if(!src) return NULL;
-
- // convert from src_type to FIT_BITMAP
-
- const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(src);
-
- switch(src_type) {
- case FIT_BITMAP: // standard image: 1-, 4-, 8-, 16-, 24-, 32-bit
- dst = FreeImage_Clone(src);
- break;
- case FIT_UINT16: // array of unsigned short: unsigned 16-bit
- dst = convertUShortToByte.convert(src, scale_linear);
- break;
- case FIT_INT16: // array of short: signed 16-bit
- dst = convertShortToByte.convert(src, scale_linear);
- break;
- case FIT_UINT32: // array of unsigned long: unsigned 32-bit
- dst = convertULongToByte.convert(src, scale_linear);
- break;
- case FIT_INT32: // array of long: signed 32-bit
- dst = convertLongToByte.convert(src, scale_linear);
- break;
- case FIT_FLOAT: // array of float: 32-bit
- dst = convertFloatToByte.convert(src, scale_linear);
- break;
- case FIT_DOUBLE: // array of double: 64-bit
- dst = convertDoubleToByte.convert(src, scale_linear);
- break;
- case FIT_COMPLEX: // array of FICOMPLEX: 2 x 64-bit
- {
- // Convert to type FIT_DOUBLE
- FIBITMAP *dib_double = FreeImage_GetComplexChannel(src, FICC_MAG);
- if(dib_double) {
- // Convert to a standard bitmap (linear scaling)
- dst = convertDoubleToByte.convert(dib_double, scale_linear);
- // Free image of type FIT_DOUBLE
- FreeImage_Unload(dib_double);
- }
- }
- break;
- case FIT_RGB16: // 48-bit RGB image: 3 x 16-bit
- break;
- case FIT_RGBA16: // 64-bit RGBA image: 4 x 16-bit
- break;
- case FIT_RGBF: // 96-bit RGB float image: 3 x 32-bit IEEE floating point
- break;
- case FIT_RGBAF: // 128-bit RGBA float image: 4 x 32-bit IEEE floating point
- break;
- }
-
- if(NULL == dst) {
- FreeImage_OutputMessageProc(FIF_UNKNOWN, "FREE_IMAGE_TYPE: Unable to convert from type %d to type %d.\n No such conversion exists.", src_type, FIT_BITMAP);
- } else {
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
- }
-
- return dst;
-}
-
-
-
-// ----------------------------------------------------------
-// smart convert X to Y
-// ----------------------------------------------------------
-
-FIBITMAP* DLL_CALLCONV
-FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_linear) {
- FIBITMAP *dst = NULL;
-
- if(!FreeImage_HasPixels(src)) return NULL;
-
- // convert from src_type to dst_type
-
- const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(src);
-
- if(src_type == dst_type) {
- return FreeImage_Clone(src);
- }
-
- const unsigned src_bpp = FreeImage_GetBPP(src);
-
- switch(src_type) {
- case FIT_BITMAP:
- switch(dst_type) {
- case FIT_UINT16:
- dst = FreeImage_ConvertToUINT16(src);
- break;
- case FIT_INT16:
- dst = (src_bpp == 8) ? convertByteToShort.convert(src, dst_type) : NULL;
- break;
- case FIT_UINT32:
- dst = (src_bpp == 8) ? convertByteToULong.convert(src, dst_type) : NULL;
- break;
- case FIT_INT32:
- dst = (src_bpp == 8) ? convertByteToLong.convert(src, dst_type) : NULL;
- break;
- case FIT_FLOAT:
- dst = FreeImage_ConvertToFloat(src);
- break;
- case FIT_DOUBLE:
- dst = (src_bpp == 8) ? convertByteToDouble.convert(src, dst_type) : NULL;
- break;
- case FIT_COMPLEX:
- dst = (src_bpp == 8) ? convertByteToComplex.convert(src) : NULL;
- break;
- case FIT_RGB16:
- dst = FreeImage_ConvertToRGB16(src);
- break;
- case FIT_RGBA16:
- dst = FreeImage_ConvertToRGBA16(src);
- break;
- case FIT_RGBF:
- dst = FreeImage_ConvertToRGBF(src);
- break;
- case FIT_RGBAF:
- dst = FreeImage_ConvertToRGBAF(src);
- break;
- }
- break;
- case FIT_UINT16:
- switch(dst_type) {
- case FIT_BITMAP:
- dst = FreeImage_ConvertToStandardType(src, scale_linear);
- break;
- case FIT_INT16:
- break;
- case FIT_UINT32:
- break;
- case FIT_INT32:
- break;
- case FIT_FLOAT:
- dst = FreeImage_ConvertToFloat(src);
- break;
- case FIT_DOUBLE:
- dst = convertUShortToDouble.convert(src, dst_type);
- break;
- case FIT_COMPLEX:
- dst = convertUShortToComplex.convert(src);
- break;
- case FIT_RGB16:
- dst = FreeImage_ConvertToRGB16(src);
- break;
- case FIT_RGBA16:
- dst = FreeImage_ConvertToRGBA16(src);
- break;
- case FIT_RGBF:
- dst = FreeImage_ConvertToRGBF(src);
- break;
- case FIT_RGBAF:
- dst = FreeImage_ConvertToRGBAF(src);
- break;
- }
- break;
- case FIT_INT16:
- switch(dst_type) {
- case FIT_BITMAP:
- dst = FreeImage_ConvertToStandardType(src, scale_linear);
- break;
- case FIT_UINT16:
- break;
- case FIT_UINT32:
- break;
- case FIT_INT32:
- break;
- case FIT_FLOAT:
- dst = convertShortToFloat.convert(src, dst_type);
- break;
- case FIT_DOUBLE:
- dst = convertShortToDouble.convert(src, dst_type);
- break;
- case FIT_COMPLEX:
- dst = convertShortToComplex.convert(src);
- break;
- case FIT_RGB16:
- break;
- case FIT_RGBA16:
- break;
- case FIT_RGBF:
- break;
- case FIT_RGBAF:
- break;
- }
- break;
- case FIT_UINT32:
- switch(dst_type) {
- case FIT_BITMAP:
- dst = FreeImage_ConvertToStandardType(src, scale_linear);
- break;
- case FIT_UINT16:
- break;
- case FIT_INT16:
- break;
- case FIT_INT32:
- break;
- case FIT_FLOAT:
- dst = convertULongToFloat.convert(src, dst_type);
- break;
- case FIT_DOUBLE:
- dst = convertULongToDouble.convert(src, dst_type);
- break;
- case FIT_COMPLEX:
- dst = convertULongToComplex.convert(src);
- break;
- case FIT_RGB16:
- break;
- case FIT_RGBA16:
- break;
- case FIT_RGBF:
- break;
- case FIT_RGBAF:
- break;
- }
- break;
- case FIT_INT32:
- switch(dst_type) {
- case FIT_BITMAP:
- dst = FreeImage_ConvertToStandardType(src, scale_linear);
- break;
- case FIT_UINT16:
- break;
- case FIT_INT16:
- break;
- case FIT_UINT32:
- break;
- case FIT_FLOAT:
- dst = convertLongToFloat.convert(src, dst_type);
- break;
- case FIT_DOUBLE:
- dst = convertLongToDouble.convert(src, dst_type);
- break;
- case FIT_COMPLEX:
- dst = convertLongToComplex.convert(src);
- break;
- case FIT_RGB16:
- break;
- case FIT_RGBA16:
- break;
- case FIT_RGBF:
- break;
- case FIT_RGBAF:
- break;
- }
- break;
- case FIT_FLOAT:
- switch(dst_type) {
- case FIT_BITMAP:
- dst = FreeImage_ConvertToStandardType(src, scale_linear);
- break;
- case FIT_UINT16:
- break;
- case FIT_INT16:
- break;
- case FIT_UINT32:
- break;
- case FIT_INT32:
- break;
- case FIT_DOUBLE:
- dst = convertFloatToDouble.convert(src, dst_type);
- break;
- case FIT_COMPLEX:
- dst = convertFloatToComplex.convert(src);
- break;
- case FIT_RGB16:
- break;
- case FIT_RGBA16:
- break;
- case FIT_RGBF:
- dst = FreeImage_ConvertToRGBF(src);
- break;
- case FIT_RGBAF:
- dst = FreeImage_ConvertToRGBAF(src);
- break;
- }
- break;
- case FIT_DOUBLE:
- switch(dst_type) {
- case FIT_BITMAP:
- dst = FreeImage_ConvertToStandardType(src, scale_linear);
- break;
- case FIT_UINT16:
- break;
- case FIT_INT16:
- break;
- case FIT_UINT32:
- break;
- case FIT_INT32:
- break;
- case FIT_FLOAT:
- break;
- case FIT_COMPLEX:
- dst = convertDoubleToComplex.convert(src);
- break;
- case FIT_RGB16:
- break;
- case FIT_RGBA16:
- break;
- case FIT_RGBF:
- break;
- case FIT_RGBAF:
- break;
- }
- break;
- case FIT_COMPLEX:
- switch(dst_type) {
- case FIT_BITMAP:
- break;
- case FIT_UINT16:
- break;
- case FIT_INT16:
- break;
- case FIT_UINT32:
- break;
- case FIT_INT32:
- break;
- case FIT_FLOAT:
- break;
- case FIT_DOUBLE:
- break;
- case FIT_RGB16:
- break;
- case FIT_RGBA16:
- break;
- case FIT_RGBF:
- break;
- case FIT_RGBAF:
- break;
- }
- break;
- case FIT_RGB16:
- switch(dst_type) {
- case FIT_BITMAP:
- dst = FreeImage_ConvertTo24Bits(src);
- break;
- case FIT_UINT16:
- dst = FreeImage_ConvertToUINT16(src);
- break;
- case FIT_INT16:
- break;
- case FIT_UINT32:
- break;
- case FIT_INT32:
- break;
- case FIT_FLOAT:
- dst = FreeImage_ConvertToFloat(src);
- break;
- case FIT_DOUBLE:
- break;
- case FIT_COMPLEX:
- break;
- case FIT_RGBA16:
- dst = FreeImage_ConvertToRGBA16(src);
- break;
- case FIT_RGBF:
- dst = FreeImage_ConvertToRGBF(src);
- break;
- case FIT_RGBAF:
- dst = FreeImage_ConvertToRGBAF(src);
- break;
- }
- break;
- case FIT_RGBA16:
- switch(dst_type) {
- case FIT_BITMAP:
- dst = FreeImage_ConvertTo32Bits(src);
- break;
- case FIT_UINT16:
- dst = FreeImage_ConvertToUINT16(src);
- break;
- case FIT_INT16:
- break;
- case FIT_UINT32:
- break;
- case FIT_INT32:
- break;
- case FIT_FLOAT:
- dst = FreeImage_ConvertToFloat(src);
- break;
- case FIT_DOUBLE:
- break;
- case FIT_COMPLEX:
- break;
- case FIT_RGB16:
- dst = FreeImage_ConvertToRGB16(src);
- break;
- case FIT_RGBF:
- dst = FreeImage_ConvertToRGBF(src);
- break;
- case FIT_RGBAF:
- dst = FreeImage_ConvertToRGBAF(src);
- break;
- }
- break;
- case FIT_RGBF:
- switch(dst_type) {
- case FIT_BITMAP:
- break;
- case FIT_UINT16:
- break;
- case FIT_INT16:
- break;
- case FIT_UINT32:
- break;
- case FIT_INT32:
- break;
- case FIT_FLOAT:
- dst = FreeImage_ConvertToFloat(src);
- break;
- case FIT_DOUBLE:
- break;
- case FIT_COMPLEX:
- break;
- case FIT_RGB16:
- break;
- case FIT_RGBA16:
- break;
- case FIT_RGBAF:
- dst = FreeImage_ConvertToRGBAF(src);
- break;
- }
- break;
- case FIT_RGBAF:
- switch(dst_type) {
- case FIT_BITMAP:
- break;
- case FIT_UINT16:
- break;
- case FIT_INT16:
- break;
- case FIT_UINT32:
- break;
- case FIT_INT32:
- break;
- case FIT_FLOAT:
- dst = FreeImage_ConvertToFloat(src);
- break;
- case FIT_DOUBLE:
- break;
- case FIT_COMPLEX:
- break;
- case FIT_RGB16:
- break;
- case FIT_RGBA16:
- break;
- case FIT_RGBF:
- dst = FreeImage_ConvertToRGBF(src);
- break;
- }
- break;
- }
-
- if(NULL == dst) {
- FreeImage_OutputMessageProc(FIF_UNKNOWN, "FREE_IMAGE_TYPE: Unable to convert from type %d to type %d.\n No such conversion exists.", src_type, dst_type);
- } else {
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
- }
-
- return dst;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/ConversionUINT16.cpp b/plugins/AdvaImg/src/FreeImage/ConversionUINT16.cpp
deleted file mode 100644
index 2de0f05ccc..0000000000
--- a/plugins/AdvaImg/src/FreeImage/ConversionUINT16.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// smart convert X to UINT16
-// ----------------------------------------------------------
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_ConvertToUINT16(FIBITMAP *dib) {
- FIBITMAP *src = NULL;
- FIBITMAP *dst = NULL;
-
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
-
- // check for allowed conversions
- switch(src_type) {
- case FIT_BITMAP:
- {
- // convert to greyscale if needed
- if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) {
- src = dib;
- } else {
- src = FreeImage_ConvertToGreyscale(dib);
- if(!src) return NULL;
- }
- break;
- }
- case FIT_UINT16:
- // UINT16 type : clone the src
- return FreeImage_Clone(dib);
- break;
- case FIT_RGB16:
- // allow conversion from 48-bit RGB
- src = dib;
- break;
- case FIT_RGBA16:
- // allow conversion from 64-bit RGBA (ignore the alpha channel)
- src = dib;
- break;
- default:
- return NULL;
- }
-
- // allocate dst image
-
- const unsigned width = FreeImage_GetWidth(src);
- const unsigned height = FreeImage_GetHeight(src);
-
- dst = FreeImage_AllocateT(FIT_UINT16, width, height);
- if(!dst) {
- if(src != dib) {
- FreeImage_Unload(src);
- }
- return NULL;
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- // convert from src type to UINT16
-
- switch(src_type) {
- case FIT_BITMAP:
- {
- for(unsigned y = 0; y < height; y++) {
- const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
- WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- dst_bits[x] = src_bits[x] << 8;
- }
- }
- }
- break;
-
- case FIT_RGB16:
- {
- for(unsigned y = 0; y < height; y++) {
- const FIRGB16 *src_bits = (FIRGB16*)FreeImage_GetScanLine(src, y);
- WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- // convert to grey
- dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue);
- }
- }
- }
- break;
-
- case FIT_RGBA16:
- {
- for(unsigned y = 0; y < height; y++) {
- const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y);
- WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- // convert to grey
- dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue);
- }
- }
- }
- break;
-
- default:
- break;
- }
-
- if(src != dib) {
- FreeImage_Unload(src);
- }
-
- return dst;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/FreeImage.cpp b/plugins/AdvaImg/src/FreeImage/FreeImage.cpp
deleted file mode 100644
index ac53449a14..0000000000
--- a/plugins/AdvaImg/src/FreeImage/FreeImage.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-// ==========================================================
-// FreeImage implementation
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Karl-Heinz Bussian (khbussian@moss.de)
-//
-// 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 _WIN32
-#include <windows.h>
-#endif
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-//----------------------------------------------------------------------
-
-static const char *s_copyright = "This program uses FreeImage, a free, open source image library supporting all common bitmap formats. See http://freeimage.sourceforge.net for details";
-
-//----------------------------------------------------------------------
-
-#if defined(_WIN32) && !defined(__MINGW32__)
-#ifndef FREEIMAGE_LIB
-
-BOOL APIENTRY
-DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
- switch (ul_reason_for_call) {
- case DLL_PROCESS_ATTACH :
- FreeImage_Initialise(FALSE);
- break;
-
- case DLL_PROCESS_DETACH :
- FreeImage_DeInitialise();
- break;
-
- case DLL_THREAD_ATTACH :
- case DLL_THREAD_DETACH :
- break;
- }
-
- return TRUE;
-}
-
-#endif // FREEIMAGE_LIB
-
-#else // !_WIN32
-#ifndef FREEIMAGE_LIB
-
-void FreeImage_SO_Initialise() __attribute__((constructor));
-void FreeImage_SO_DeInitialise() __attribute__((destructor));
-
-void FreeImage_SO_Initialise() {
- FreeImage_Initialise(FALSE);
-}
-
-void FreeImage_SO_DeInitialise() {
- FreeImage_DeInitialise();
-}
-#endif // FREEIMAGE_LIB
-
-#endif // _WIN32
-
-//----------------------------------------------------------------------
-
-const char * DLL_CALLCONV
-FreeImage_GetVersion() {
- static char s_version[16];
- sprintf(s_version, "%d.%d.%d", FREEIMAGE_MAJOR_VERSION, FREEIMAGE_MINOR_VERSION, FREEIMAGE_RELEASE_SERIAL);
- return s_version;
-}
-
-const char * DLL_CALLCONV
-FreeImage_GetCopyrightMessage() {
- return s_copyright;
-}
-
-//----------------------------------------------------------------------
-
-BOOL DLL_CALLCONV
-FreeImage_IsLittleEndian() {
- union {
- DWORD i;
- BYTE c[4];
- } u;
- u.i = 1;
- return (u.c[0] != 0);
-}
-
-//----------------------------------------------------------------------
-
-static FreeImage_OutputMessageFunction freeimage_outputmessage_proc = NULL;
-static FreeImage_OutputMessageFunctionStdCall freeimage_outputmessagestdcall_proc = NULL;
-
-void DLL_CALLCONV
-FreeImage_SetOutputMessage(FreeImage_OutputMessageFunction omf) {
- freeimage_outputmessage_proc = omf;
-}
-
-void DLL_CALLCONV
-FreeImage_SetOutputMessageStdCall(FreeImage_OutputMessageFunctionStdCall omf) {
- freeimage_outputmessagestdcall_proc = omf;
-}
-
-void DLL_CALLCONV
-FreeImage_OutputMessageProc(int fif, const char *fmt, ...) {
- const int MSG_SIZE = 512; // 512 bytes should be more than enough for a short message
-
- if ((fmt != NULL) && ((freeimage_outputmessage_proc != NULL) || (freeimage_outputmessagestdcall_proc != NULL))) {
- char message[MSG_SIZE];
- memset(message, 0, MSG_SIZE);
-
- // initialize the optional parameter list
-
- va_list arg;
- va_start(arg, fmt);
-
- // check the length of the format string
-
- int str_length = (int)( (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt) );
-
- // parse the format string and put the result in 'message'
-
- for (int i = 0, j = 0; i < str_length; ++i) {
- if (fmt[i] == '%') {
- if (i + 1 < str_length) {
- switch(tolower(fmt[i + 1])) {
- case '%' :
- message[j++] = '%';
- break;
-
- case 'o' : // octal numbers
- {
- char tmp[16];
-
- _itoa(va_arg(arg, int), tmp, 8);
-
- strcat(message, tmp);
-
- j += (int)strlen(tmp);
-
- ++i;
-
- break;
- }
-
- case 'i' : // decimal numbers
- case 'd' :
- {
- char tmp[16];
-
- _itoa(va_arg(arg, int), tmp, 10);
-
- strcat(message, tmp);
-
- j += (int)strlen(tmp);
-
- ++i;
-
- break;
- }
-
- case 'x' : // hexadecimal numbers
- {
- char tmp[16];
-
- _itoa(va_arg(arg, int), tmp, 16);
-
- strcat(message, tmp);
-
- j += (int)strlen(tmp);
-
- ++i;
-
- break;
- }
-
- case 's' : // strings
- {
- char *tmp = va_arg(arg, char*);
-
- strcat(message, tmp);
-
- j += (int)strlen(tmp);
-
- ++i;
-
- break;
- }
- };
- } else {
- message[j++] = fmt[i];
- }
- } else {
- message[j++] = fmt[i];
- };
- }
-
- // deinitialize the optional parameter list
-
- va_end(arg);
-
- // output the message to the user program
-
- if (freeimage_outputmessage_proc != NULL)
- freeimage_outputmessage_proc((FREE_IMAGE_FORMAT)fif, message);
-
- if (freeimage_outputmessagestdcall_proc != NULL)
- freeimage_outputmessagestdcall_proc((FREE_IMAGE_FORMAT)fif, message);
- }
-}
diff --git a/plugins/AdvaImg/src/FreeImage/FreeImageIO.cpp b/plugins/AdvaImg/src/FreeImage/FreeImageIO.cpp
deleted file mode 100644
index 83394f049c..0000000000
--- a/plugins/AdvaImg/src/FreeImage/FreeImageIO.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-// ==========================================================
-// Input/Output functions
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "FreeImageIO.h"
-
-// =====================================================================
-// File IO functions
-// =====================================================================
-
-unsigned DLL_CALLCONV
-_ReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle) {
- return (unsigned)fread(buffer, size, count, (FILE *)handle);
-}
-
-unsigned DLL_CALLCONV
-_WriteProc(void *buffer, unsigned size, unsigned count, fi_handle handle) {
- return (unsigned)fwrite(buffer, size, count, (FILE *)handle);
-}
-
-int DLL_CALLCONV
-_SeekProc(fi_handle handle, long offset, int origin) {
- return fseek((FILE *)handle, offset, origin);
-}
-
-long DLL_CALLCONV
-_TellProc(fi_handle handle) {
- return ftell((FILE *)handle);
-}
-
-// ----------------------------------------------------------
-
-void
-SetDefaultIO(FreeImageIO *io) {
- io->read_proc = _ReadProc;
- io->seek_proc = _SeekProc;
- io->tell_proc = _TellProc;
- io->write_proc = _WriteProc;
-}
-
-// =====================================================================
-// Memory IO functions
-// =====================================================================
-
-unsigned DLL_CALLCONV
-_MemoryReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle) {
- unsigned x;
-
- FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);
-
- for(x = 0; x < count; x++) {
- long remaining_bytes = mem_header->file_length - mem_header->current_position;
- //if there isn't size bytes left to read, set pos to eof and return a short count
- if( remaining_bytes < (long)size ) {
- if(remaining_bytes > 0) {
- memcpy( buffer, (char *)mem_header->data + mem_header->current_position, remaining_bytes );
- }
- mem_header->current_position = mem_header->file_length;
- break;
- }
- //copy size bytes count times
- memcpy( buffer, (char *)mem_header->data + mem_header->current_position, size );
- mem_header->current_position += size;
- buffer = (char *)buffer + size;
- }
- return x;
-}
-
-unsigned DLL_CALLCONV
-_MemoryWriteProc(void *buffer, unsigned size, unsigned count, fi_handle handle) {
- void *newdata;
- long newdatalen;
-
- FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);
-
- //double the data block size if we need to
- while( (mem_header->current_position + (long)(size * count)) >= mem_header->data_length ) {
- //if we are at or above 1G, we cant double without going negative
- if( mem_header->data_length & 0x40000000 ) {
- //max 2G
- if( mem_header->data_length == 0x7FFFFFFF ) {
- return 0;
- }
- newdatalen = 0x7FFFFFFF;
- } else if( mem_header->data_length == 0 ) {
- //default to 4K if nothing yet
- newdatalen = 4096;
- } else {
- //double size
- newdatalen = mem_header->data_length << 1;
- }
- newdata = realloc( mem_header->data, newdatalen );
- if( !newdata ) {
- return 0;
- }
- mem_header->data = newdata;
- mem_header->data_length = newdatalen;
- }
- memcpy( (char *)mem_header->data + mem_header->current_position, buffer, size * count );
- mem_header->current_position += size * count;
- if( mem_header->current_position > mem_header->file_length ) {
- mem_header->file_length = mem_header->current_position;
- }
- return count;
-}
-
-int DLL_CALLCONV
-_MemorySeekProc(fi_handle handle, long offset, int origin) {
- FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);
-
- // you can use _MemorySeekProc to reposition the pointer anywhere in a file
- // the pointer can also be positioned beyond the end of the file
-
- switch(origin) { //0 to filelen-1 are 'inside' the file
- default:
- case SEEK_SET: //can fseek() to 0-7FFFFFFF always
- if( offset >= 0 ) {
- mem_header->current_position = offset;
- return 0;
- }
- break;
-
- case SEEK_CUR:
- if( mem_header->current_position + offset >= 0 ) {
- mem_header->current_position += offset;
- return 0;
- }
- break;
-
- case SEEK_END:
- if( mem_header->file_length + offset >= 0 ) {
- mem_header->current_position = mem_header->file_length + offset;
- return 0;
- }
- break;
- }
-
- return -1;
-}
-
-long DLL_CALLCONV
-_MemoryTellProc(fi_handle handle) {
- FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);
-
- return mem_header->current_position;
-}
-
-// ----------------------------------------------------------
-
-void
-SetMemoryIO(FreeImageIO *io) {
- io->read_proc = _MemoryReadProc;
- io->seek_proc = _MemorySeekProc;
- io->tell_proc = _MemoryTellProc;
- io->write_proc = _MemoryWriteProc;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/GetType.cpp b/plugins/AdvaImg/src/FreeImage/GetType.cpp
deleted file mode 100644
index 0ac15fc2e6..0000000000
--- a/plugins/AdvaImg/src/FreeImage/GetType.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// ==========================================================
-// GetType
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-//
-// 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 "FreeImage.h"
-#include "Utilities.h"
-#include "FreeImageIO.h"
-#include "Plugin.h"
-
-// ----------------------------------------------------------
-
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_GetFileTypeFromHandle(FreeImageIO *io, fi_handle handle, int size) {
- if (handle != NULL) {
- int fif_count = FreeImage_GetFIFCount();
-
- for (int i = 0; i < fif_count; ++i) {
- FREE_IMAGE_FORMAT fif = (FREE_IMAGE_FORMAT)i;
- if (FreeImage_Validate(fif, io, handle)) {
- if(fif == FIF_TIFF) {
- // many camera raw files use a TIFF signature ...
- // ... try to revalidate against FIF_RAW (even if it breaks the code genericity)
- if (FreeImage_Validate(FIF_RAW, io, handle)) {
- return FIF_RAW;
- }
- }
- return fif;
- }
- }
- }
-
- return FIF_UNKNOWN;
-}
-
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_GetFileType(const char *filename, int size) {
- FreeImageIO io;
- SetDefaultIO(&io);
-
- FILE *handle = fopen(filename, "rb");
-
- if (handle != NULL) {
- FREE_IMAGE_FORMAT format = FreeImage_GetFileTypeFromHandle(&io, (fi_handle)handle, size);
-
- fclose(handle);
-
- return format;
- }
-
- return FIF_UNKNOWN;
-}
-
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_GetFileTypeU(const wchar_t *filename, int size) {
-#ifdef _WIN32
- FreeImageIO io;
- SetDefaultIO(&io);
- FILE *handle = _wfopen(filename, L"rb");
-
- if (handle != NULL) {
- FREE_IMAGE_FORMAT format = FreeImage_GetFileTypeFromHandle(&io, (fi_handle)handle, size);
-
- fclose(handle);
-
- return format;
- }
-#endif
- return FIF_UNKNOWN;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/Halftoning.cpp b/plugins/AdvaImg/src/FreeImage/Halftoning.cpp
deleted file mode 100644
index bc9076c501..0000000000
--- a/plugins/AdvaImg/src/FreeImage/Halftoning.cpp
+++ /dev/null
@@ -1,474 +0,0 @@
-// ==========================================================
-// Bitmap conversion routines
-// Thresholding and halftoning functions
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-// - Dennis Lim (dlkj@users.sourceforge.net)
-// - Thomas Chmielewski (Chmielewski.Thomas@oce.de)
-//
-// Main reference : Ulichney, R., Digital Halftoning, The MIT Press, Cambridge, MA, 1987
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-static const int WHITE = 255;
-static const int BLACK = 0;
-
-// Floyd & Steinberg error diffusion dithering
-// This algorithm use the following filter
-// * 7
-// 3 5 1 (1/16)
-static FIBITMAP* FloydSteinberg(FIBITMAP *dib) {
-
-#define RAND(RN) (((seed = 1103515245 * seed + 12345) >> 12) % (RN))
-#define INITERR(X, Y) (((int) X) - (((int) Y) ? WHITE : BLACK) + ((WHITE/2)-((int)X)) / 2)
-
- int seed = 0;
- int x, y, p, pixel, threshold, error;
- int width, height, pitch;
- BYTE *bits, *new_bits;
- FIBITMAP *new_dib = NULL;
-
- // allocate a 8-bit DIB
- width = FreeImage_GetWidth(dib);
- height = FreeImage_GetHeight(dib);
- pitch = FreeImage_GetPitch(dib);
- new_dib = FreeImage_Allocate(width, height, 8);
- if(NULL == new_dib) return NULL;
-
- // allocate space for error arrays
- int *lerr = (int*)malloc (width * sizeof(int));
- int *cerr = (int*)malloc (width * sizeof(int));
- memset(lerr, 0, width * sizeof(int));
- memset(cerr, 0, width * sizeof(int));
-
- // left border
- error = 0;
- for(y = 0; y < height; y++) {
- bits = FreeImage_GetScanLine(dib, y);
- new_bits = FreeImage_GetScanLine(new_dib, y);
-
- threshold = (WHITE / 2 + RAND(129) - 64);
- pixel = bits[0] + error;
- p = (pixel > threshold) ? WHITE : BLACK;
- error = pixel - p;
- new_bits[0] = (BYTE)p;
- }
- // right border
- error = 0;
- for(y = 0; y < height; y++) {
- bits = FreeImage_GetScanLine(dib, y);
- new_bits = FreeImage_GetScanLine(new_dib, y);
-
- threshold = (WHITE / 2 + RAND(129) - 64);
- pixel = bits[width-1] + error;
- p = (pixel > threshold) ? WHITE : BLACK;
- error = pixel - p;
- new_bits[width-1] = (BYTE)p;
- }
- // top border
- bits = FreeImage_GetBits(dib);
- new_bits = FreeImage_GetBits(new_dib);
- error = 0;
- for(x = 0; x < width; x++) {
- threshold = (WHITE / 2 + RAND(129) - 64);
- pixel = bits[x] + error;
- p = (pixel > threshold) ? WHITE : BLACK;
- error = pixel - p;
- new_bits[x] = (BYTE)p;
- lerr[x] = INITERR(bits[x], p);
- }
-
- // interior bits
- for(y = 1; y < height; y++) {
- // scan left to right
- bits = FreeImage_GetScanLine(dib, y);
- new_bits = FreeImage_GetScanLine(new_dib, y);
-
- cerr[0] = INITERR(bits[0], new_bits[0]);
- for(x = 1; x < width - 1; x++) {
- error = (lerr[x-1] + 5 * lerr[x] + 3 * lerr[x+1] + 7 * cerr[x-1]) / 16;
- pixel = bits[x] + error;
- if(pixel > (WHITE / 2)) {
- new_bits[x] = WHITE;
- cerr[x] = pixel - WHITE;
- } else {
- new_bits[x] = BLACK;
- cerr[x] = pixel - BLACK;
- }
- }
- // set errors for ends of the row
- cerr[0] = INITERR (bits[0], new_bits[0]);
- cerr[width - 1] = INITERR (bits[width - 1], new_bits[width - 1]);
-
- // swap error buffers
- int *terr = lerr; lerr = cerr; cerr = terr;
- }
-
- free(lerr);
- free(cerr);
-
- return new_dib;
-}
-
-// ==========================================================
-// Bayer ordered dispersed dot dithering
-//
-
-// Function taken from "Ordered Dithering, Stephen Hawley, Graphics Gems, Academic Press, 1990"
-// This function is used to generate a Bayer dithering matrice whose dimension are 2^size by 2^size
-//
-static int dithervalue(int x, int y, int size) {
- int d = 0;
- /*
- * calculate the dither value at a particular
- * (x, y) over the size of the matrix.
- */
- while (size-->0) {
- /* Think of d as the density. At every iteration,
- * d is shifted left one and a new bit is put in the
- * low bit based on x and y. If x is odd and y is even,
- * or x is even and y is odd, a bit is put in. This
- * generates the checkerboard seen in dithering.
- * This quantity is shifted left again and the low bit of
- * y is added in.
- * This whole thing interleaves a checkerboard bit pattern
- * and y's bits, which is the value you want.
- */
- d = (d <<1 | (x&1 ^ y&1))<<1 | y&1;
- x >>= 1;
- y >>= 1;
- }
- return d;
-}
-
-// Ordered dithering with a Bayer matrix of size 2^order by 2^order
-//
-static FIBITMAP* OrderedDispersedDot(FIBITMAP *dib, int order) {
- int x, y;
- int width, height;
- BYTE *bits, *new_bits;
- FIBITMAP *new_dib = NULL;
-
- // allocate a 8-bit DIB
- width = FreeImage_GetWidth(dib);
- height = FreeImage_GetHeight(dib);
- new_dib = FreeImage_Allocate(width, height, 8);
- if(NULL == new_dib) return NULL;
-
- // build the dithering matrix
- int l = (1 << order); // square of dither matrix order; the dimensions of the matrix
- BYTE *matrix = (BYTE*)malloc(l*l * sizeof(BYTE));
- for(int i = 0; i < l*l; i++) {
- // according to "Purdue University: Digital Image Processing Laboratory: Image Halftoning, April 30th, 2006
- matrix[i] = (BYTE)( 255 * (((double)dithervalue(i / l, i % l, order) + 0.5) / (l*l)) );
- }
-
- // perform the dithering
- for(y = 0; y < height; y++) {
- // scan left to right
- bits = FreeImage_GetScanLine(dib, y);
- new_bits = FreeImage_GetScanLine(new_dib, y);
- for(x = 0; x < width; x++) {
- if(bits[x] > matrix[(x % l) + l * (y % l)]) {
- new_bits[x] = WHITE;
- } else {
- new_bits[x] = BLACK;
- }
- }
- }
-
- free(matrix);
-
- return new_dib;
-}
-
-// ==========================================================
-// Ordered clustered dot dithering
-//
-
-// NB : The predefined dither matrices are the same as matrices used in
-// the Netpbm package (http://netpbm.sourceforge.net) and are defined in Ulichney's book.
-// See also : The newsprint web site at http://www.cl.cam.ac.uk/~and1000/newsprint/
-// for more technical info on this dithering technique
-//
-static FIBITMAP* OrderedClusteredDot(FIBITMAP *dib, int order) {
- // Order-3 clustered dithering matrix.
- int cluster3[] = {
- 9,11,10, 8, 6, 7,
- 12,17,16, 5, 0, 1,
- 13,14,15, 4, 3, 2,
- 8, 6, 7, 9,11,10,
- 5, 0, 1,12,17,16,
- 4, 3, 2,13,14,15
- };
-
- // Order-4 clustered dithering matrix.
- int cluster4[] = {
- 18,20,19,16,13,11,12,15,
- 27,28,29,22, 4, 3, 2, 9,
- 26,31,30,21, 5, 0, 1,10,
- 23,25,24,17, 8, 6, 7,14,
- 13,11,12,15,18,20,19,16,
- 4, 3, 2, 9,27,28,29,22,
- 5, 0, 1,10,26,31,30,21,
- 8, 6, 7,14,23,25,24,17
- };
-
- // Order-8 clustered dithering matrix.
- int cluster8[] = {
- 64, 69, 77, 87, 86, 76, 68, 67, 63, 58, 50, 40, 41, 51, 59, 60,
- 70, 94,100,109,108, 99, 93, 75, 57, 33, 27, 18, 19, 28, 34, 52,
- 78,101,114,116,115,112, 98, 83, 49, 26, 13, 11, 12, 15, 29, 44,
- 88,110,123,124,125,118,107, 85, 39, 17, 4, 3, 2, 9, 20, 42,
- 89,111,122,127,126,117,106, 84, 38, 16, 5, 0, 1, 10, 21, 43,
- 79,102,119,121,120,113, 97, 82, 48, 25, 8, 6, 7, 14, 30, 45,
- 71, 95,103,104,105, 96, 92, 74, 56, 32, 24, 23, 22, 31, 35, 53,
- 65, 72, 80, 90, 91, 81, 73, 66, 62, 55, 47, 37, 36, 46, 54, 61,
- 63, 58, 50, 40, 41, 51, 59, 60, 64, 69, 77, 87, 86, 76, 68, 67,
- 57, 33, 27, 18, 19, 28, 34, 52, 70, 94,100,109,108, 99, 93, 75,
- 49, 26, 13, 11, 12, 15, 29, 44, 78,101,114,116,115,112, 98, 83,
- 39, 17, 4, 3, 2, 9, 20, 42, 88,110,123,124,125,118,107, 85,
- 38, 16, 5, 0, 1, 10, 21, 43, 89,111,122,127,126,117,106, 84,
- 48, 25, 8, 6, 7, 14, 30, 45, 79,102,119,121,120,113, 97, 82,
- 56, 32, 24, 23, 22, 31, 35, 53, 71, 95,103,104,105, 96, 92, 74,
- 62, 55, 47, 37, 36, 46, 54, 61, 65, 72, 80, 90, 91, 81, 73, 66
- };
-
- int x, y, pixel;
- int width, height;
- BYTE *bits, *new_bits;
- FIBITMAP *new_dib = NULL;
-
- // allocate a 8-bit DIB
- width = FreeImage_GetWidth(dib);
- height = FreeImage_GetHeight(dib);
- new_dib = FreeImage_Allocate(width, height, 8);
- if(NULL == new_dib) return NULL;
-
- // select the dithering matrix
- int *matrix = NULL;
- switch(order) {
- case 3:
- matrix = &cluster3[0];
- break;
- case 4:
- matrix = &cluster4[0];
- break;
- case 8:
- matrix = &cluster8[0];
- break;
- default:
- return NULL;
- }
-
- // scale the dithering matrix
- int l = 2 * order;
- int scale = 256 / (l * order);
- for(y = 0; y < l; y++) {
- for(x = 0; x < l; x++) {
- matrix[y*l + x] *= scale;
- }
- }
-
- // perform the dithering
- for(y = 0; y < height; y++) {
- // scan left to right
- bits = FreeImage_GetScanLine(dib, y);
- new_bits = FreeImage_GetScanLine(new_dib, y);
- for(x = 0; x < width; x++) {
- pixel = bits[x];
- if(pixel >= matrix[(y % l) + l * (x % l)]) {
- new_bits[x] = WHITE;
- } else {
- new_bits[x] = BLACK;
- }
- }
- }
-
- return new_dib;
-}
-
-
-// ==========================================================
-// Halftoning function
-//
-FIBITMAP * DLL_CALLCONV
-FreeImage_Dither(FIBITMAP *dib, FREE_IMAGE_DITHER algorithm) {
- FIBITMAP *input = NULL, *dib8 = NULL;
-
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- const unsigned bpp = FreeImage_GetBPP(dib);
-
- if(bpp == 1) {
- // Just clone the dib and adjust the palette if needed
- FIBITMAP *new_dib = FreeImage_Clone(dib);
- if(NULL == new_dib) return NULL;
- if(FreeImage_GetColorType(new_dib) == FIC_PALETTE) {
- // Build a monochrome palette
- RGBQUAD *pal = FreeImage_GetPalette(new_dib);
- pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
- pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
- }
- return new_dib;
- }
-
- // Convert the input dib to a 8-bit greyscale dib
- //
- switch(bpp) {
- case 8:
- if(FreeImage_GetColorType(dib) == FIC_MINISBLACK) {
- input = dib;
- } else {
- input = FreeImage_ConvertToGreyscale(dib);
- }
- break;
- case 4:
- case 16:
- case 24:
- case 32:
- input = FreeImage_ConvertToGreyscale(dib);
- break;
- }
- if(NULL == input) return NULL;
-
- // Apply the dithering algorithm
- switch(algorithm) {
- case FID_FS:
- dib8 = FloydSteinberg(input);
- break;
- case FID_BAYER4x4:
- dib8 = OrderedDispersedDot(input, 2);
- break;
- case FID_BAYER8x8:
- dib8 = OrderedDispersedDot(input, 3);
- break;
- case FID_BAYER16x16:
- dib8 = OrderedDispersedDot(input, 4);
- break;
- case FID_CLUSTER6x6:
- dib8 = OrderedClusteredDot(input, 3);
- break;
- case FID_CLUSTER8x8:
- dib8 = OrderedClusteredDot(input, 4);
- break;
- case FID_CLUSTER16x16:
- dib8 = OrderedClusteredDot(input, 8);
- break;
- }
- if(input != dib) {
- FreeImage_Unload(input);
- }
-
- // Build a greyscale palette (needed by threshold)
- RGBQUAD *grey_pal = FreeImage_GetPalette(dib8);
- for(int i = 0; i < 256; i++) {
- grey_pal[i].rgbRed = (BYTE)i;
- grey_pal[i].rgbGreen = (BYTE)i;
- grey_pal[i].rgbBlue = (BYTE)i;
- }
-
- // Convert to 1-bit
- FIBITMAP *new_dib = FreeImage_Threshold(dib8, 128);
- FreeImage_Unload(dib8);
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- return new_dib;
-}
-
-// ==========================================================
-// Thresholding function
-//
-FIBITMAP * DLL_CALLCONV
-FreeImage_Threshold(FIBITMAP *dib, BYTE T) {
- FIBITMAP *dib8 = NULL;
-
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- const unsigned bpp = FreeImage_GetBPP(dib);
-
- if(bpp == 1) {
- // Just clone the dib and adjust the palette if needed
- FIBITMAP *new_dib = FreeImage_Clone(dib);
- if(NULL == new_dib) return NULL;
- if(FreeImage_GetColorType(new_dib) == FIC_PALETTE) {
- // Build a monochrome palette
- RGBQUAD *pal = FreeImage_GetPalette(new_dib);
- pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
- pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
- }
- return new_dib;
- }
-
- // Convert the input dib to a 8-bit greyscale dib
- //
- switch(bpp) {
- case 8:
- if(FreeImage_GetColorType(dib) == FIC_MINISBLACK) {
- dib8 = dib;
- } else {
- dib8 = FreeImage_ConvertToGreyscale(dib);
- }
- break;
- case 4:
- case 16:
- case 24:
- case 32:
- dib8 = FreeImage_ConvertToGreyscale(dib);
- break;
- }
- if(NULL == dib8) return NULL;
-
- // Allocate a new 1-bit DIB
- int width = FreeImage_GetWidth(dib);
- int height = FreeImage_GetHeight(dib);
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 1);
- if(NULL == new_dib) return NULL;
- // Build a monochrome palette
- RGBQUAD *pal = FreeImage_GetPalette(new_dib);
- pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
- pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
-
- // Perform the thresholding
- //
- for(int y = 0; y < height; y++) {
- BYTE *bits8 = FreeImage_GetScanLine(dib8, y);
- BYTE *bits1 = FreeImage_GetScanLine(new_dib, y);
- for(int x = 0; x < width; x++) {
- if(bits8[x] < T) {
- // Set bit(x, y) to 0
- bits1[x >> 3] &= (0xFF7F >> (x & 0x7));
- } else {
- // Set bit(x, y) to 1
- bits1[x >> 3] |= (0x80 >> (x & 0x7));
- }
- }
- }
- if(dib8 != dib) {
- FreeImage_Unload(dib8);
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(new_dib, dib);
-
- return new_dib;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/J2KHelper.cpp b/plugins/AdvaImg/src/FreeImage/J2KHelper.cpp
deleted file mode 100644
index 49bf9290d4..0000000000
--- a/plugins/AdvaImg/src/FreeImage/J2KHelper.cpp
+++ /dev/null
@@ -1,591 +0,0 @@
-// ==========================================================
-// JPEG2000 helpers
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "../LibOpenJPEG/openjpeg.h"
-#include "J2KHelper.h"
-
-// --------------------------------------------------------------------------
-
-static OPJ_UINT64
-_LengthProc(J2KFIO_t *fio) {
- long start_pos = fio->io->tell_proc(fio->handle);
- fio->io->seek_proc(fio->handle, 0, SEEK_END);
- unsigned file_length = fio->io->tell_proc(fio->handle) - start_pos;
- fio->io->seek_proc(fio->handle, start_pos, SEEK_SET);
- return (OPJ_UINT64)file_length;
-}
-
-static OPJ_SIZE_T
-_ReadProc(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) {
- J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
- OPJ_SIZE_T l_nb_read = fio->io->read_proc(p_buffer, 1, (unsigned)p_nb_bytes, fio->handle);
- return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1;
-}
-
-static OPJ_SIZE_T
-_WriteProc(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) {
- J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
- return fio->io->write_proc(p_buffer, 1, (unsigned)p_nb_bytes, fio->handle);
-}
-
-static OPJ_OFF_T
-_SkipProc(OPJ_OFF_T p_nb_bytes, void *p_user_data) {
- J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
- if( fio->io->seek_proc(fio->handle, (long)p_nb_bytes, SEEK_CUR) ) {
- return -1;
- }
- return p_nb_bytes;
-}
-
-static OPJ_BOOL
-_SeekProc(OPJ_OFF_T p_nb_bytes, FILE * p_user_data) {
- J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
- if( fio->io->seek_proc(fio->handle, (long)p_nb_bytes, SEEK_SET) ) {
- return OPJ_FALSE;
- }
- return OPJ_TRUE;
-}
-
-// --------------------------------------------------------------------------
-
-J2KFIO_t*
-opj_freeimage_stream_create(FreeImageIO *io, fi_handle handle, BOOL bRead) {
- if(!handle) {
- return NULL;
- }
- J2KFIO_t *fio = (J2KFIO_t*)malloc(sizeof(J2KFIO_t));
- if(fio) {
- fio->io = io;
- fio->handle = handle;
-
- opj_stream_t *l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, bRead ? OPJ_TRUE : OPJ_FALSE);
- if (l_stream) {
- opj_stream_set_user_data(l_stream, fio, NULL);
- opj_stream_set_user_data_length(l_stream, _LengthProc(fio));
- opj_stream_set_read_function(l_stream, (opj_stream_read_fn)_ReadProc);
- opj_stream_set_write_function(l_stream, (opj_stream_write_fn)_WriteProc);
- opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn)_SkipProc);
- opj_stream_set_seek_function(l_stream, (opj_stream_seek_fn)_SeekProc);
- fio->stream = l_stream;
- return fio;
- } else {
- free(fio);
- }
- }
-
- return NULL;
-}
-
-void
-opj_freeimage_stream_destroy(J2KFIO_t* fio) {
- if(fio) {
- if(fio->stream) {
- opj_stream_destroy(fio->stream);
- }
- free(fio);
- }
-}
-
-// --------------------------------------------------------------------------
-
-/**
-Divide an integer by a power of 2 and round upwards
-@return Returns a divided by 2^b
-*/
-static int int_ceildivpow2(int a, int b) {
- return (a + (1 << b) - 1) >> b;
-}
-
-/**
-Convert a OpenJPEG image to a FIBITMAP
-@param format_id Plugin ID
-@param image OpenJPEG image
-@param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP
-@return Returns the converted image if successful, returns NULL otherwise
-*/
-FIBITMAP* J2KImageToFIBITMAP(int format_id, const opj_image_t *image, BOOL header_only) {
- FIBITMAP *dib = NULL;
-
- try {
- // compute image width and height
-
- //int w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
- int wr = image->comps[0].w;
- int wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
-
- //int h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
- //int hr = image->comps[0].h;
- int hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
-
- // check the number of components
-
- int numcomps = image->numcomps;
-
- BOOL bIsValid = TRUE;
- for(int c = 0; c < numcomps - 1; c++) {
- if( (image->comps[c].dx == image->comps[c+1].dx) &&
- (image->comps[c].dy == image->comps[c+1].dy) &&
- (image->comps[c].prec == image->comps[c+1].prec) ) {
- continue;
- } else {
- bIsValid = FALSE;
- break;
- }
- }
- bIsValid &= ((numcomps == 1) || (numcomps == 3) || (numcomps == 4));
- if(!bIsValid) {
- if(numcomps) {
- FreeImage_OutputMessageProc(format_id, "Warning: image contains %d greyscale components. Only the first will be loaded.\n", numcomps);
- numcomps = 1;
- } else {
- // unknown type
- throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
- }
- }
-
- // create a new DIB
-
- if(image->comps[0].prec <= 8) {
- switch(numcomps) {
- case 1:
- dib = FreeImage_AllocateHeader(header_only, wrr, hrr, 8);
- break;
- case 3:
- dib = FreeImage_AllocateHeader(header_only, wrr, hrr, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- break;
- case 4:
- dib = FreeImage_AllocateHeader(header_only, wrr, hrr, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- break;
- }
- } else if(image->comps[0].prec <= 16) {
- switch(numcomps) {
- case 1:
- dib = FreeImage_AllocateHeaderT(header_only, FIT_UINT16, wrr, hrr);
- break;
- case 3:
- dib = FreeImage_AllocateHeaderT(header_only, FIT_RGB16, wrr, hrr);
- break;
- case 4:
- dib = FreeImage_AllocateHeaderT(header_only, FIT_RGBA16, wrr, hrr);
- break;
- }
- } else {
- throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
- }
- if(!dib) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // "header only" FIBITMAP ?
- if(header_only) {
- return dib;
- }
-
- if(image->comps[0].prec <= 8) {
- if(numcomps == 1) {
- // 8-bit greyscale
- // ----------------------------------------------------------
-
- // build a greyscale palette
-
- RGBQUAD *pal = FreeImage_GetPalette(dib);
- for (int i = 0; i < 256; i++) {
- pal[i].rgbRed = (BYTE)i;
- pal[i].rgbGreen = (BYTE)i;
- pal[i].rgbBlue = (BYTE)i;
- }
-
- // load pixel data
-
- unsigned pixel_count = 0;
-
- for(int y = 0; y < hrr; y++) {
- BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
-
- for(int x = 0; x < wrr; x++) {
- const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
- int index = image->comps[0].data[pixel_pos];
- index += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-
- bits[x] = (BYTE)index;
-
- pixel_count++;
- }
- }
- }
- else if(numcomps == 3) {
-
- // 24-bit RGB
- // ----------------------------------------------------------
-
- // load pixel data
-
- unsigned pixel_count = 0;
-
- for(int y = 0; y < hrr; y++) {
- BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
-
- for(int x = 0; x < wrr; x++) {
- const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
- int r = image->comps[0].data[pixel_pos];
- r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-
- int g = image->comps[1].data[pixel_pos];
- g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
-
- int b = image->comps[2].data[pixel_pos];
- b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
-
- bits[FI_RGBA_RED] = (BYTE)r;
- bits[FI_RGBA_GREEN] = (BYTE)g;
- bits[FI_RGBA_BLUE] = (BYTE)b;
- bits += 3;
-
- pixel_count++;
- }
- }
- }
- else if(numcomps == 4) {
-
- // 32-bit RGBA
- // ----------------------------------------------------------
-
- // load pixel data
-
- unsigned pixel_count = 0;
-
- for(int y = 0; y < hrr; y++) {
- BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
-
- for(int x = 0; x < wrr; x++) {
- const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
- int r = image->comps[0].data[pixel_pos];
- r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-
- int g = image->comps[1].data[pixel_pos];
- g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
-
- int b = image->comps[2].data[pixel_pos];
- b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
-
- int a = image->comps[3].data[pixel_pos];
- a += (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
-
- bits[FI_RGBA_RED] = (BYTE)r;
- bits[FI_RGBA_GREEN] = (BYTE)g;
- bits[FI_RGBA_BLUE] = (BYTE)b;
- bits[FI_RGBA_ALPHA] = (BYTE)a;
- bits += 4;
-
- pixel_count++;
- }
- }
- }
- }
- else if(image->comps[0].prec <= 16) {
- if(numcomps == 1) {
- // 16-bit greyscale
- // ----------------------------------------------------------
-
- // load pixel data
-
- unsigned pixel_count = 0;
-
- for(int y = 0; y < hrr; y++) {
- WORD *bits = (WORD*)FreeImage_GetScanLine(dib, hrr - 1 - y);
-
- for(int x = 0; x < wrr; x++) {
- const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
- int index = image->comps[0].data[pixel_pos];
- index += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-
- bits[x] = (WORD)index;
-
- pixel_count++;
- }
- }
- }
- else if(numcomps == 3) {
-
- // 48-bit RGB
- // ----------------------------------------------------------
-
- // load pixel data
-
- unsigned pixel_count = 0;
-
- for(int y = 0; y < hrr; y++) {
- FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, hrr - 1 - y);
-
- for(int x = 0; x < wrr; x++) {
- const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
- int r = image->comps[0].data[pixel_pos];
- r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-
- int g = image->comps[1].data[pixel_pos];
- g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
-
- int b = image->comps[2].data[pixel_pos];
- b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
-
- bits[x].red = (WORD)r;
- bits[x].green = (WORD)g;
- bits[x].blue = (WORD)b;
-
- pixel_count++;
- }
- }
- }
- else if(numcomps == 4) {
-
- // 64-bit RGBA
- // ----------------------------------------------------------
-
- // load pixel data
-
- unsigned pixel_count = 0;
-
- for(int y = 0; y < hrr; y++) {
- FIRGBA16 *bits = (FIRGBA16*)FreeImage_GetScanLine(dib, hrr - 1 - y);
-
- for(int x = 0; x < wrr; x++) {
- const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
-
- int r = image->comps[0].data[pixel_pos];
- r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
-
- int g = image->comps[1].data[pixel_pos];
- g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
-
- int b = image->comps[2].data[pixel_pos];
- b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
-
- int a = image->comps[3].data[pixel_pos];
- a += (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
-
- bits[x].red = (WORD)r;
- bits[x].green = (WORD)g;
- bits[x].blue = (WORD)b;
- bits[x].alpha = (WORD)a;
-
- pixel_count++;
- }
- }
- }
- }
-
- return dib;
-
- } catch(const char *text) {
- if(dib) FreeImage_Unload(dib);
- FreeImage_OutputMessageProc(format_id, text);
- return NULL;
- }
-
-}
-
-/**
-Convert a FIBITMAP to a OpenJPEG image
-@param format_id Plugin ID
-@param dib FreeImage image
-@param parameters Compression parameters
-@return Returns the converted image if successful, returns NULL otherwise
-*/
-opj_image_t* FIBITMAPToJ2KImage(int format_id, FIBITMAP *dib, const opj_cparameters_t *parameters) {
- int prec, numcomps, x, y, index;
- OPJ_COLOR_SPACE color_space;
- opj_image_cmptparm_t cmptparm[4]; // maximum of 4 components
- opj_image_t *image = NULL; // image to encode
-
- try {
- int w = FreeImage_GetWidth(dib);
- int h = FreeImage_GetHeight(dib);
-
- // get image characteristics
- FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
-
- if(image_type == FIT_BITMAP) {
- // standard image ...
- prec = 8;
- switch(FreeImage_GetColorType(dib)) {
- case FIC_MINISBLACK:
- numcomps = 1;
- color_space = OPJ_CLRSPC_GRAY;
- break;
- case FIC_RGB:
- if(FreeImage_GetBPP(dib) == 32) {
- // 32-bit image with a fully opaque layer
- numcomps = 4;
- color_space = OPJ_CLRSPC_SRGB;
- } else {
- // 24-bit image
- numcomps = 3;
- color_space = OPJ_CLRSPC_SRGB;
- }
- break;
- case FIC_RGBALPHA:
- numcomps = 4;
- color_space = OPJ_CLRSPC_SRGB;
- break;
- default:
- return NULL;
- }
- } else {
- // HDR image ...
- prec = 16;
- switch(image_type) {
- case FIT_UINT16:
- numcomps = 1;
- color_space = OPJ_CLRSPC_GRAY;
- break;
- case FIT_RGB16:
- numcomps = 3;
- color_space = OPJ_CLRSPC_SRGB;
- break;
- case FIT_RGBA16:
- numcomps = 4;
- color_space = OPJ_CLRSPC_SRGB;
- break;
- default:
- return NULL;
- }
- }
-
- // initialize image components
- memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
- for(int i = 0; i < numcomps; i++) {
- cmptparm[i].dx = parameters->subsampling_dx;
- cmptparm[i].dy = parameters->subsampling_dy;
- cmptparm[i].w = w;
- cmptparm[i].h = h;
- cmptparm[i].prec = prec;
- cmptparm[i].bpp = prec;
- cmptparm[i].sgnd = 0;
- }
- // create the image
- image = opj_image_create(numcomps, &cmptparm[0], color_space);
- if(!image) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // set image offset and reference grid
- image->x0 = parameters->image_offset_x0;
- image->y0 = parameters->image_offset_y0;
- image->x1 = parameters->image_offset_x0 + (w - 1) * parameters->subsampling_dx + 1;
- image->y1 = parameters->image_offset_y0 + (h - 1) * parameters->subsampling_dy + 1;
-
- // set image data
- if(prec == 8) {
- switch(numcomps) {
- case 1:
- index = 0;
- for(y = 0; y < h; y++) {
- BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
- for(x = 0; x < w; x++) {
- image->comps[0].data[index] = bits[x];
- index++;
- }
- }
- break;
- case 3:
- index = 0;
- for(y = 0; y < h; y++) {
- BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
- for(x = 0; x < w; x++) {
- image->comps[0].data[index] = bits[FI_RGBA_RED];
- image->comps[1].data[index] = bits[FI_RGBA_GREEN];
- image->comps[2].data[index] = bits[FI_RGBA_BLUE];
- bits += 3;
- index++;
- }
- }
- break;
- case 4:
- index = 0;
- for(y = 0; y < h; y++) {
- BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
- for(x = 0; x < w; x++) {
- image->comps[0].data[index] = bits[FI_RGBA_RED];
- image->comps[1].data[index] = bits[FI_RGBA_GREEN];
- image->comps[2].data[index] = bits[FI_RGBA_BLUE];
- image->comps[3].data[index] = bits[FI_RGBA_ALPHA];
- bits += 4;
- index++;
- }
- }
- break;
- }
- }
- else if(prec == 16) {
- switch(numcomps) {
- case 1:
- index = 0;
- for(y = 0; y < h; y++) {
- WORD *bits = (WORD*)FreeImage_GetScanLine(dib, h - 1 - y);
- for(x = 0; x < w; x++) {
- image->comps[0].data[index] = bits[x];
- index++;
- }
- }
- break;
- case 3:
- index = 0;
- for(y = 0; y < h; y++) {
- FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, h - 1 - y);
- for(x = 0; x < w; x++) {
- image->comps[0].data[index] = bits[x].red;
- image->comps[1].data[index] = bits[x].green;
- image->comps[2].data[index] = bits[x].blue;
- index++;
- }
- }
- break;
- case 4:
- index = 0;
- for(y = 0; y < h; y++) {
- FIRGBA16 *bits = (FIRGBA16*)FreeImage_GetScanLine(dib, h - 1 - y);
- for(x = 0; x < w; x++) {
- image->comps[0].data[index] = bits[x].red;
- image->comps[1].data[index] = bits[x].green;
- image->comps[2].data[index] = bits[x].blue;
- image->comps[3].data[index] = bits[x].alpha;
- index++;
- }
- }
- break;
- }
- }
-
- return image;
-
- } catch (const char *text) {
- if(image) opj_image_destroy(image);
- FreeImage_OutputMessageProc(format_id, text);
- return NULL;
- }
-}
diff --git a/plugins/AdvaImg/src/FreeImage/J2KHelper.h b/plugins/AdvaImg/src/FreeImage/J2KHelper.h
deleted file mode 100644
index a8121f164e..0000000000
--- a/plugins/AdvaImg/src/FreeImage/J2KHelper.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef J2K_HELPER_H
-#define J2K_HELPER_H
-
-// ==========================================================
-// Helper functions (see J2KHelper.cpp)
-// ==========================================================
-
-/**
-FreeImageIO wrapper
-*/
-typedef struct tagJ2KFIO_t {
- FreeImageIO *io; //! FreeImage IO
- fi_handle handle; //! FreeImage handle
- opj_stream_t *stream; //! OpenJPEG stream
-} J2KFIO_t;
-
-/**
-Stream constructor
-*/
-J2KFIO_t* opj_freeimage_stream_create(FreeImageIO *io, fi_handle handle, BOOL bRead);
-
-/**
-Stream destructor
-*/
-void opj_freeimage_stream_destroy(J2KFIO_t* fio);
-
-/**
-Conversion opj_image_t => FIBITMAP
-*/
-FIBITMAP* J2KImageToFIBITMAP(int format_id, const opj_image_t *image, BOOL header_only);
-/**
-Conversion FIBITMAP => opj_image_t
-*/
-opj_image_t* FIBITMAPToJ2KImage(int format_id, FIBITMAP *dib, const opj_cparameters_t *parameters);
-
-#endif // J2K_HELPER_H \ No newline at end of file
diff --git a/plugins/AdvaImg/src/FreeImage/LFPQuantizer.cpp b/plugins/AdvaImg/src/FreeImage/LFPQuantizer.cpp
deleted file mode 100644
index 8b592c30f1..0000000000
--- a/plugins/AdvaImg/src/FreeImage/LFPQuantizer.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-// ==========================================================
-// LFPQuantizer class implementation
-//
-// Design and implementation by
-// - Carsten Klein (cklein05@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!
-// ==========================================================
-
-#include "Quantizers.h"
-#include "FreeImage.h"
-#include "Utilities.h"
-
-LFPQuantizer::LFPQuantizer(unsigned PaletteSize) :
- m_size(0), m_limit(PaletteSize), m_index(0) {
- m_map = new MapEntry[MAP_SIZE];
- memset(m_map, 0xFF, MAP_SIZE * sizeof(MapEntry));
-}
-
-LFPQuantizer::~LFPQuantizer() {
- delete[] m_map;
-}
-
-FIBITMAP* LFPQuantizer::Quantize(FIBITMAP *dib, int ReserveSize, RGBQUAD *ReservePalette) {
-
- if (ReserveSize > 0 && ReservePalette != NULL) {
- AddReservePalette(ReservePalette, ReserveSize);
- }
-
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
-
- FIBITMAP *dib8 = FreeImage_Allocate(width, height, 8);
- if (dib8 == NULL) {
- return NULL;
- }
-
- const unsigned src_pitch = FreeImage_GetPitch(dib);
- const unsigned dst_pitch = FreeImage_GetPitch(dib8);
-
- const BYTE * const src_bits = FreeImage_GetBits(dib);
- BYTE * const dst_bits = FreeImage_GetBits(dib8);
-
- unsigned last_color = -1;
- int last_index = 0;
-
- if (FreeImage_GetBPP(dib) == 24) {
-
- // Getting the source pixel as an unsigned int is much faster than
- // working with FI_RGBA_xxx and shifting. However, this may fail
- // for the very last pixel, since its rgbReserved member (alpha)
- // may actually point to an address beyond the bitmap's memory. So,
- // we do not process the last scanline in the first loop.
-
- // Process all but the last scanline.
- for (unsigned y = 0; y < height - 1; ++y) {
- BYTE *dst_line = dst_bits + y * dst_pitch;
- const BYTE *src_line = src_bits + y * src_pitch;
- for (unsigned x = 0; x < width; ++x) {
- const unsigned color = *((unsigned *) src_line) & 0x00FFFFFF;
- if (color != last_color) {
- last_color = color;
- last_index = GetIndexForColor(color);
- if (last_index == -1) {
- FreeImage_Unload(dib8);
- return NULL;
- }
- }
- dst_line[x] = last_index;
- src_line += 3;
- }
- }
-
- // Process all but the last pixel of the last scanline.
- BYTE *dst_line = dst_bits + (height - 1) * dst_pitch;
- const BYTE *src_line = src_bits + (height - 1) * src_pitch;
- for (unsigned x = 0; x < width - 1; ++x) {
- const unsigned color = *((unsigned *) src_line) & 0x00FFFFFF;
- if (color != last_color) {
- last_color = color;
- last_index = GetIndexForColor(color);
- if (last_index == -1) {
- FreeImage_Unload(dib8);
- return NULL;
- }
- }
- dst_line[x] = last_index;
- src_line += 3;
- }
-
- // Process the last pixel (src_line should already point to it).
- const unsigned color = 0 | src_line[FI_RGBA_BLUE] << FI_RGBA_BLUE_SHIFT
- | src_line[FI_RGBA_GREEN] << FI_RGBA_GREEN_SHIFT
- | src_line[FI_RGBA_RED] << FI_RGBA_RED_SHIFT;
- if (color != last_color) {
- last_color = color;
- last_index = GetIndexForColor(color);
- if (last_index == -1) {
- FreeImage_Unload(dib8);
- return NULL;
- }
- }
- dst_line[width - 1] = last_index;
-
- } else {
- for (unsigned y = 0; y < height; ++y) {
- BYTE *dst_line = dst_bits + y * dst_pitch;
- const BYTE *src_line = src_bits + y * src_pitch;
- for (unsigned x = 0; x < width; ++x) {
- const unsigned color = *((unsigned *) src_line) & 0x00FFFFFF;
- if (color != last_color) {
- last_color = color;
- last_index = GetIndexForColor(color);
- if (last_index == -1) {
- FreeImage_Unload(dib8);
- return NULL;
- }
- }
- dst_line[x] = last_index;
- src_line += 4;
- }
- }
- }
-
- WritePalette(FreeImage_GetPalette(dib8));
- return dib8;
-}
-
-/**
- * Returns the palette index of the specified color. Tries to put the
- * color into the map, if it's not already present in the map. In that
- * case, a new index is used for the color. Returns -1, if adding the
- * color would exceed the desired maximum number of colors in the
- * palette.
- * @param color the color to get the index from
- * @return the palette index of the specified color or -1, if there
- * is no space left in the palette
- */
-inline int LFPQuantizer::GetIndexForColor(unsigned color) {
- unsigned bucket = hash(color) & (MAP_SIZE - 1);
- while (m_map[bucket].color != color) {
- if (m_map[bucket].color == EMPTY_BUCKET) {
- if (m_size == m_limit) {
- return -1;
- }
- m_map[bucket].color = color;
- m_map[bucket].index = m_index++;
- ++m_size;
- break;
- }
- bucket = (bucket + 1) % MAP_SIZE;
- }
- return m_map[bucket].index;
-}
-
-/**
- * Adds the specified number of entries of the specified reserve
- * palette to the newly created palette.
- * @param *palette a pointer to the reserve palette to copy from
- * @param size the number of entries to copy
- */
-void LFPQuantizer::AddReservePalette(const void *palette, unsigned size) {
- if (size > MAX_SIZE) {
- size = MAX_SIZE;
- }
- unsigned *ppal = (unsigned *) palette;
- const unsigned offset = m_limit - size;
- for (unsigned i = 0; i < size; ++i) {
- const unsigned color = *ppal++;
- const unsigned index = i + offset;
- unsigned bucket = hash(color) & (MAP_SIZE - 1);
- while((m_map[bucket].color != EMPTY_BUCKET) && (m_map[bucket].color != color)) {
- bucket = (bucket + 1) % MAP_SIZE;
- }
- if(m_map[bucket].color != color) {
- m_map[bucket].color = color;
- m_map[bucket].index = index;
- }
- }
- m_size += size;
-}
-
-/**
- * Copies the newly created palette into the specified destination
- * palette. Although unused palette entries are not overwritten in
- * the destination palette, it is assumed to have space for at
- * least 256 entries.
- * @param palette a pointer to the destination palette
- */
-void LFPQuantizer::WritePalette(void *palette) {
- for (unsigned i = 0; i < MAP_SIZE; ++i) {
- if (m_map[i].color != EMPTY_BUCKET) {
- ((unsigned *) palette)[m_map[i].index] = m_map[i].color;
- }
- }
-}
diff --git a/plugins/AdvaImg/src/FreeImage/MNGHelper.cpp b/plugins/AdvaImg/src/FreeImage/MNGHelper.cpp
deleted file mode 100644
index 2bc3e833a4..0000000000
--- a/plugins/AdvaImg/src/FreeImage/MNGHelper.cpp
+++ /dev/null
@@ -1,1320 +0,0 @@
-// ==========================================================
-// MNG / JNG helpers
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-/**
-References
-http://www.libpng.org/pub/mng/spec/jng.html
-http://www.w3.org/TR/PNG/
-http://libpng.org/pub/mng/spec/
-*/
-
-// --------------------------------------------------------------------------
-
-#define MNG_INCLUDE_JNG
-
-#ifdef MNG_INCLUDE_JNG
-#define MNG_COLORTYPE_JPEGGRAY 8 /* JHDR */
-#define MNG_COLORTYPE_JPEGCOLOR 10
-#define MNG_COLORTYPE_JPEGGRAYA 12
-#define MNG_COLORTYPE_JPEGCOLORA 14
-
-#define MNG_BITDEPTH_JPEG8 8 /* JHDR */
-#define MNG_BITDEPTH_JPEG12 12
-#define MNG_BITDEPTH_JPEG8AND12 20
-
-#define MNG_COMPRESSION_BASELINEJPEG 8 /* JHDR */
-
-#define MNG_INTERLACE_SEQUENTIAL 0 /* JHDR */
-#define MNG_INTERLACE_PROGRESSIVE 8
-#endif /* MNG_INCLUDE_JNG */
-
-// --------------------------------------------------------------------------
-
-#define JNG_SUPPORTED
-
-/** Size of a JDAT chunk on writing */
-const DWORD JPEG_CHUNK_SIZE = 8192;
-
-/** PNG signature */
-static const BYTE g_png_signature[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
-/** JNG signature */
-static const BYTE g_jng_signature[8] = { 139, 74, 78, 71, 13, 10, 26, 10 };
-
-// --------------------------------------------------------------------------
-
-/** Chunk type converted to enum */
-enum eChunckType {
- UNKNOWN_CHUNCK,
- MHDR,
- BACK,
- BASI,
- CLIP,
- CLON,
- DEFI,
- DHDR,
- DISC,
- ENDL,
- FRAM,
- IEND,
- IHDR,
- JHDR,
- LOOP,
- MAGN,
- MEND,
- MOVE,
- PAST,
- PLTE,
- SAVE,
- SEEK,
- SHOW,
- TERM,
- bKGD,
- cHRM,
- gAMA,
- iCCP,
- nEED,
- pHYg,
- vpAg,
- pHYs,
- sBIT,
- sRGB,
- tRNS,
- IDAT,
- JDAT,
- JDAA,
- JdAA,
- JSEP,
- oFFs,
- hIST,
- iTXt,
- sPLT,
- sTER,
- tEXt,
- tIME,
- zTXt
-};
-
-/**
-Helper for map<key, value> where value is a pointer to a string.
-Used to store tEXt metadata.
-*/
-typedef std::map<std::string, std::string> tEXtMAP;
-
-// --------------------------------------------------------------------------
-
-/*
- Constant strings for known chunk types. If you need to add a chunk,
- add a string holding the name here. To make the code more
- portable, we use ASCII numbers like this, not characters.
-*/
-
-static BYTE mng_MHDR[5]={ 77, 72, 68, 82, (BYTE) '\0'};
-static BYTE mng_BACK[5]={ 66, 65, 67, 75, (BYTE) '\0'};
-static BYTE mng_BASI[5]={ 66, 65, 83, 73, (BYTE) '\0'};
-static BYTE mng_CLIP[5]={ 67, 76, 73, 80, (BYTE) '\0'};
-static BYTE mng_CLON[5]={ 67, 76, 79, 78, (BYTE) '\0'};
-static BYTE mng_DEFI[5]={ 68, 69, 70, 73, (BYTE) '\0'};
-static BYTE mng_DHDR[5]={ 68, 72, 68, 82, (BYTE) '\0'};
-static BYTE mng_DISC[5]={ 68, 73, 83, 67, (BYTE) '\0'};
-static BYTE mng_ENDL[5]={ 69, 78, 68, 76, (BYTE) '\0'};
-static BYTE mng_FRAM[5]={ 70, 82, 65, 77, (BYTE) '\0'};
-static BYTE mng_IEND[5]={ 73, 69, 78, 68, (BYTE) '\0'};
-static BYTE mng_IHDR[5]={ 73, 72, 68, 82, (BYTE) '\0'};
-static BYTE mng_JHDR[5]={ 74, 72, 68, 82, (BYTE) '\0'};
-static BYTE mng_LOOP[5]={ 76, 79, 79, 80, (BYTE) '\0'};
-static BYTE mng_MAGN[5]={ 77, 65, 71, 78, (BYTE) '\0'};
-static BYTE mng_MEND[5]={ 77, 69, 78, 68, (BYTE) '\0'};
-static BYTE mng_MOVE[5]={ 77, 79, 86, 69, (BYTE) '\0'};
-static BYTE mng_PAST[5]={ 80, 65, 83, 84, (BYTE) '\0'};
-static BYTE mng_PLTE[5]={ 80, 76, 84, 69, (BYTE) '\0'};
-static BYTE mng_SAVE[5]={ 83, 65, 86, 69, (BYTE) '\0'};
-static BYTE mng_SEEK[5]={ 83, 69, 69, 75, (BYTE) '\0'};
-static BYTE mng_SHOW[5]={ 83, 72, 79, 87, (BYTE) '\0'};
-static BYTE mng_TERM[5]={ 84, 69, 82, 77, (BYTE) '\0'};
-static BYTE mng_bKGD[5]={ 98, 75, 71, 68, (BYTE) '\0'};
-static BYTE mng_cHRM[5]={ 99, 72, 82, 77, (BYTE) '\0'};
-static BYTE mng_gAMA[5]={103, 65, 77, 65, (BYTE) '\0'};
-static BYTE mng_iCCP[5]={105, 67, 67, 80, (BYTE) '\0'};
-static BYTE mng_nEED[5]={110, 69, 69, 68, (BYTE) '\0'};
-static BYTE mng_pHYg[5]={112, 72, 89, 103, (BYTE) '\0'};
-static BYTE mng_vpAg[5]={118, 112, 65, 103, (BYTE) '\0'};
-static BYTE mng_pHYs[5]={112, 72, 89, 115, (BYTE) '\0'};
-static BYTE mng_sBIT[5]={115, 66, 73, 84, (BYTE) '\0'};
-static BYTE mng_sRGB[5]={115, 82, 71, 66, (BYTE) '\0'};
-static BYTE mng_tRNS[5]={116, 82, 78, 83, (BYTE) '\0'};
-
-#if defined(JNG_SUPPORTED)
-static BYTE mng_IDAT[5]={ 73, 68, 65, 84, (BYTE) '\0'};
-static BYTE mng_JDAT[5]={ 74, 68, 65, 84, (BYTE) '\0'};
-static BYTE mng_JDAA[5]={ 74, 68, 65, 65, (BYTE) '\0'};
-static BYTE mng_JdAA[5]={ 74, 100, 65, 65, (BYTE) '\0'};
-static BYTE mng_JSEP[5]={ 74, 83, 69, 80, (BYTE) '\0'};
-static BYTE mng_oFFs[5]={111, 70, 70, 115, (BYTE) '\0'};
-#endif
-
-static BYTE mng_hIST[5]={104, 73, 83, 84, (BYTE) '\0'};
-static BYTE mng_iTXt[5]={105, 84, 88, 116, (BYTE) '\0'};
-static BYTE mng_sPLT[5]={115, 80, 76, 84, (BYTE) '\0'};
-static BYTE mng_sTER[5]={115, 84, 69, 82, (BYTE) '\0'};
-static BYTE mng_tEXt[5]={116, 69, 88, 116, (BYTE) '\0'};
-static BYTE mng_tIME[5]={116, 73, 77, 69, (BYTE) '\0'};
-static BYTE mng_zTXt[5]={122, 84, 88, 116, (BYTE) '\0'};
-
-
-// --------------------------------------------------------------------------
-
-/**
-Convert a chunk name to a unique ID
-*/
-static eChunckType
-mng_GetChunckType(const BYTE *mChunkName) {
- if(memcmp(mChunkName, mng_MHDR, 4) == 0) {
- return MHDR;
- }
- if(memcmp(mChunkName, mng_LOOP, 4) == 0) {
- return LOOP;
- }
- if(memcmp(mChunkName, mng_DEFI, 4) == 0) {
- return DEFI;
- }
- if(memcmp(mChunkName, mng_PLTE, 4) == 0) {
- return PLTE;
- }
- if(memcmp(mChunkName, mng_tRNS, 4) == 0) {
- return tRNS;
- }
- if(memcmp(mChunkName, mng_IHDR, 4) == 0) {
- return IHDR;
- }
- if(memcmp(mChunkName, mng_JHDR, 4) == 0) {
- return JHDR;
- }
- if(memcmp(mChunkName, mng_MEND, 4) == 0) {
- return MEND;
- }
- if(memcmp(mChunkName, mng_IEND, 4) == 0) {
- return IEND;
- }
- if(memcmp(mChunkName, mng_JDAT, 4) == 0) {
- return JDAT;
- }
- if(memcmp(mChunkName, mng_IDAT, 4) == 0) {
- return IDAT;
- }
- if(memcmp(mChunkName, mng_JDAA, 4) == 0) {
- return JDAA;
- }
- if(memcmp(mChunkName, mng_gAMA, 4) == 0) {
- return gAMA;
- }
- if(memcmp(mChunkName, mng_pHYs, 4) == 0) {
- return pHYs;
- }
- if(memcmp(mChunkName, mng_bKGD, 4) == 0) {
- return bKGD;
- }
- if(memcmp(mChunkName, mng_tEXt, 4) == 0) {
- return tEXt;
- }
-
- return UNKNOWN_CHUNCK;
-}
-
-inline void
-mng_SwapShort(WORD *sp) {
-#ifndef FREEIMAGE_BIGENDIAN
- SwapShort(sp);
-#endif
-}
-
-inline void
-mng_SwapLong(DWORD *lp) {
-#ifndef FREEIMAGE_BIGENDIAN
- SwapLong(lp);
-#endif
-}
-
-/**
-Returns the size, in bytes, of a FreeImageIO stream, from the current position.
-*/
-static long
-mng_LOF(FreeImageIO *io, fi_handle handle) {
- long start_pos = io->tell_proc(handle);
- io->seek_proc(handle, 0, SEEK_END);
- long file_length = io->tell_proc(handle);
- io->seek_proc(handle, start_pos, SEEK_SET);
- return file_length;
-}
-
-/**
-Count the number of bytes in a PNG stream, from IHDR to IEND.
-If successful, the stream position, as given by io->tell_proc(handle),
-should be the end of the PNG stream at the return of the function.
-@param io
-@param handle
-@param inPos
-@param m_TotalBytesOfChunks
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-mng_CountPNGChunks(FreeImageIO *io, fi_handle handle, long inPos, unsigned *m_TotalBytesOfChunks) {
- long mLOF;
- long mPos;
- BOOL mEnd = FALSE;
- DWORD mLength = 0;
- BYTE mChunkName[5];
-
- *m_TotalBytesOfChunks = 0;
-
- // get the length of the file
- mLOF = mng_LOF(io, handle);
-
- // go to the start of the file
- io->seek_proc(handle, inPos, SEEK_SET);
-
- try {
- // parse chunks
- while(mEnd == FALSE) {
- // chunk length
- mPos = io->tell_proc(handle);
- if(mPos + 4 > mLOF) {
- throw(1);
- }
- io->read_proc(&mLength, 1, 4, handle);
- mng_SwapLong(&mLength);
- // chunk name
- mPos = io->tell_proc(handle);
- if(mPos + 4 > mLOF) {
- throw(1);
- }
- io->read_proc(&mChunkName[0], 1, 4, handle);
- mChunkName[4] = '\0';
-
- // go to next chunk
- mPos = io->tell_proc(handle);
- // 4 = size of the CRC
- if(mPos + (long)mLength + 4 > mLOF) {
- throw(1);
- }
- io->seek_proc(handle, mLength + 4, SEEK_CUR);
-
- switch( mng_GetChunckType(mChunkName) ) {
- case IHDR:
- if(mLength != 13) {
- throw(1);
- }
- break;
-
- case IEND:
- mEnd = TRUE;
- // the length below includes 4 bytes CRC, but no bytes for Length
- *m_TotalBytesOfChunks = io->tell_proc(handle) - inPos;
- break;
-
- case UNKNOWN_CHUNCK:
- default:
- break;
- }
-
- } // while(!mEnd)
-
- return TRUE;
-
- } catch(int) {
- return FALSE;
- }
-}
-
-/**
-Retrieve the position of a chunk in a PNG stream
-@param hPngMemory PNG stream handle
-@param chunk_name Name of the chunk to be found
-@param offset Start of the search in the stream
-@param start_pos [returned value] Start position of the chunk
-@param next_pos [returned value] Start position of the next chunk
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-mng_FindChunk(FIMEMORY *hPngMemory, BYTE *chunk_name, long offset, DWORD *start_pos, DWORD *next_pos) {
- DWORD mLength = 0;
-
- BYTE *data = NULL;
- DWORD size_in_bytes = 0;
-
- *start_pos = 0;
- *next_pos = 0;
-
- // get a pointer to the stream buffer
- FreeImage_AcquireMemory(hPngMemory, &data, &size_in_bytes);
- if(!(data && size_in_bytes) || (size_in_bytes < 20) || (size_in_bytes - offset < 20)) {
- // not enough space to read a signature(8 bytes) + a chunk(at least 12 bytes)
- return FALSE;
- }
-
- try {
-
- // skip the signature and/or any following chunk(s)
- DWORD chunk_pos = offset;
-
- while(1) {
- // get chunk length
- if(chunk_pos + 4 > size_in_bytes) {
- break;
- }
-
- memcpy(&mLength, &data[chunk_pos], 4);
- mng_SwapLong(&mLength);
- chunk_pos += 4;
-
- const DWORD next_chunk_pos = chunk_pos + 4 + mLength + 4;
- if(next_chunk_pos > size_in_bytes) {
- break;
- }
-
- // get chunk name
- if(memcmp(&data[chunk_pos], chunk_name, 4) == 0) {
- chunk_pos -= 4; // found chunk
- *start_pos = chunk_pos;
- *next_pos = next_chunk_pos;
- return TRUE;
- }
-
- chunk_pos = next_chunk_pos;
- }
-
- return FALSE;
-
- } catch(int) {
- return FALSE;
- }
-}
-
-/**
-Remove a chunk located at (start_pos, next_pos) in the PNG stream
-@param hPngMemory PNG stream handle
-@param start_pos Start position of the chunk
-@param next_pos Start position of the next chunk
-@return Returns TRUE if successfull, returns FALSE otherwise
-*/
-static BOOL
-mng_CopyRemoveChunks(FIMEMORY *hPngMemory, DWORD start_pos, DWORD next_pos) {
- BYTE *data = NULL;
- DWORD size_in_bytes = 0;
-
- // length of the chunk to remove
- DWORD chunk_length = next_pos - start_pos;
- if(chunk_length == 0) {
- return TRUE;
- }
-
- // get a pointer to the stream buffer
- FreeImage_AcquireMemory(hPngMemory, &data, &size_in_bytes);
- if(!(data && size_in_bytes) || (size_in_bytes < 20) || (chunk_length >= size_in_bytes)) {
- // not enough space to read a signature(8 bytes) + a chunk(at least 12 bytes)
- return FALSE;
- }
-
- // new file length
- unsigned buffer_size = size_in_bytes + chunk_length;
-
- BYTE *buffer = (BYTE*)malloc(buffer_size * sizeof(BYTE));
- if(!buffer) {
- return FALSE;
- }
- memcpy(&buffer[0], &data[0], start_pos);
- memcpy(&buffer[start_pos], &data[next_pos], size_in_bytes - next_pos);
-
- // seek to the start of the stream
- FreeImage_SeekMemory(hPngMemory, 0, SEEK_SET);
- // re-write the stream
- FreeImage_WriteMemory(buffer, 1, buffer_size, hPngMemory);
-
- free(buffer);
-
- return TRUE;
-}
-
-/**
-Insert a chunk just before the inNextChunkName chunk
-@param hPngMemory PNG stream handle
-@param start_pos Start position of the inNextChunkName chunk
-@param next_pos Start position of the next chunk
-@return Returns TRUE if successfull, returns FALSE otherwise
-*/
-static BOOL
-mng_CopyInsertChunks(FIMEMORY *hPngMemory, BYTE *inNextChunkName, BYTE *inInsertChunk, DWORD inChunkLength, DWORD start_pos, DWORD next_pos) {
- BYTE *data = NULL;
- DWORD size_in_bytes = 0;
-
- // length of the chunk to check
- DWORD chunk_length = next_pos - start_pos;
- if(chunk_length == 0) {
- return TRUE;
- }
-
- // get a pointer to the stream buffer
- FreeImage_AcquireMemory(hPngMemory, &data, &size_in_bytes);
- if(!(data && size_in_bytes) || (size_in_bytes < 20) || (chunk_length >= size_in_bytes)) {
- // not enough space to read a signature(8 bytes) + a chunk(at least 12 bytes)
- return FALSE;
- }
-
- // new file length
- unsigned buffer_size = inChunkLength + size_in_bytes;
-
- BYTE *buffer = (BYTE*)malloc(buffer_size * sizeof(BYTE));
- if(!buffer) {
- return FALSE;
- }
- unsigned p = 0;
- memcpy(&buffer[p], &data[0], start_pos);
- p += start_pos;
- memcpy(&buffer[p], inInsertChunk, inChunkLength);
- p += inChunkLength;
- memcpy(&buffer[p], &data[start_pos], size_in_bytes - start_pos);
-
- // seek to the start of the stream
- FreeImage_SeekMemory(hPngMemory, 0, SEEK_SET);
- // re-write the stream
- FreeImage_WriteMemory(buffer, 1, buffer_size, hPngMemory);
-
- free(buffer);
-
- return TRUE;
-}
-
-static BOOL
-mng_RemoveChunk(FIMEMORY *hPngMemory, BYTE *chunk_name) {
- BOOL bResult = FALSE;
-
- DWORD start_pos = 0;
- DWORD next_pos = 0;
-
- bResult = mng_FindChunk(hPngMemory, chunk_name, 8, &start_pos, &next_pos);
- if(!bResult) {
- return FALSE;
- }
-
- bResult = mng_CopyRemoveChunks(hPngMemory, start_pos, next_pos);
- if(!bResult) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-static BOOL
-mng_InsertChunk(FIMEMORY *hPngMemory, BYTE *inNextChunkName, BYTE *inInsertChunk, unsigned chunk_length) {
- BOOL bResult = FALSE;
-
- DWORD start_pos = 0;
- DWORD next_pos = 0;
-
- bResult = mng_FindChunk(hPngMemory, inNextChunkName, 8, &start_pos, &next_pos);
- if(!bResult) {
- return FALSE;
- }
-
- bResult = mng_CopyInsertChunks(hPngMemory, inNextChunkName, inInsertChunk, chunk_length, start_pos, next_pos);
- if(!bResult) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-static FIBITMAP*
-mng_LoadFromMemoryHandle(FIMEMORY *hmem, int flags = 0) {
- long offset = 0;
- FIBITMAP *dib = NULL;
-
- if(hmem) {
- // seek to the start of the stream
- FreeImage_SeekMemory(hmem, offset, SEEK_SET);
-
- // check the file signature and deduce its format
- // (the second argument is currently not used by FreeImage)
- FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(hmem, 0);
- if(fif != FIF_UNKNOWN) {
- dib = FreeImage_LoadFromMemory(fif, hmem, flags);
- }
- }
-
- return dib;
-}
-
-/**
-Write a chunk in a PNG stream from the current position.
-@param chunk_name Name of the chunk
-@param chunk_data Chunk array
-@param length Chunk length
-@param hPngMemory PNG stream handle
-*/
-static void
-mng_WriteChunk(BYTE *chunk_name, BYTE *chunk_data, DWORD length, FIMEMORY *hPngMemory) {
- DWORD crc_file = 0;
- // write a PNG chunk ...
- // - length
- mng_SwapLong(&length);
- FreeImage_WriteMemory(&length, 1, 4, hPngMemory);
- mng_SwapLong(&length);
- // - chunk name
- FreeImage_WriteMemory(chunk_name, 1, 4, hPngMemory);
- if(chunk_data && length) {
- // - chunk data
- FreeImage_WriteMemory(chunk_data, 1, length, hPngMemory);
- // - crc
- crc_file = FreeImage_ZLibCRC32(0, chunk_name, 4);
- crc_file = FreeImage_ZLibCRC32(crc_file, chunk_data, length);
- mng_SwapLong(&crc_file);
- FreeImage_WriteMemory(&crc_file, 1, 4, hPngMemory);
- } else {
- // - crc
- crc_file = FreeImage_ZLibCRC32(0, chunk_name, 4);
- mng_SwapLong(&crc_file);
- FreeImage_WriteMemory(&crc_file, 1, 4, hPngMemory);
- }
-
-}
-
-/**
-Wrap a IDAT chunk as a PNG stream.
-The stream has the structure { g_png_signature, IHDR, IDAT, IEND }
-The image is assumed to be a greyscale image.
-
-@param jng_width Image width
-@param jng_height Image height
-@param jng_alpha_sample_depth Bits per pixel
-@param mChunk PNG grayscale IDAT format
-@param mLength IDAT chunk length
-@param hPngMemory Output memory stream
-*/
-static void
-mng_WritePNGStream(DWORD jng_width, DWORD jng_height, BYTE jng_alpha_sample_depth, BYTE *mChunk, DWORD mLength, FIMEMORY *hPngMemory) {
- // PNG grayscale IDAT format
-
- BYTE data[14];
-
- // wrap the IDAT chunk as a PNG stream
-
- // write PNG file signature
- FreeImage_WriteMemory(g_png_signature, 1, 8, hPngMemory);
-
- // write a IHDR chunk ...
- /*
- The IHDR chunk must appear FIRST. It contains:
- Width: 4 bytes
- Height: 4 bytes
- Bit depth: 1 byte
- Color type: 1 byte
- Compression method: 1 byte
- Filter method: 1 byte
- Interlace method: 1 byte
- */
- // - chunk data
- mng_SwapLong(&jng_width);
- mng_SwapLong(&jng_height);
- memcpy(&data[0], &jng_width, 4);
- memcpy(&data[4], &jng_height, 4);
- mng_SwapLong(&jng_width);
- mng_SwapLong(&jng_height);
- data[8] = jng_alpha_sample_depth;
- data[9] = 0; // color_type gray (jng_color_type)
- data[10] = 0; // compression method 0 (jng_alpha_compression_method)
- data[11] = 0; // filter_method 0 (jng_alpha_filter_method)
- data[12] = 0; // interlace_method 0 (jng_alpha_interlace_method)
-
- mng_WriteChunk(mng_IHDR, &data[0], 13, hPngMemory);
-
- // write a IDAT chunk ...
- mng_WriteChunk(mng_IDAT, mChunk, mLength, hPngMemory);
-
- // write a IEND chunk ...
- mng_WriteChunk(mng_IEND, NULL, 0, hPngMemory);
-
-}
-
-// --------------------------------------------------------------------------
-
-/**
-Build and set a FITAG whose type is FIDT_ASCII.
-The tag must be destroyed by the caller using FreeImage_DeleteTag.
-@param model Metadata model to be filled
-@param dib Image to be filled
-@param key Tag key
-@param value Tag value
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-mng_SetKeyValue(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
- FreeImage_SetMetadata(model, dib, FreeImage_GetTagKey(tag), tag);
- }
- FreeImage_DeleteTag(tag);
- return bSuccess;
- }
-
- return FALSE;
-}
-
-/**
-Read a tEXt chunk and extract the key/value pair.
-@param key_value_pair [returned value] Array of key/value pairs
-@param mChunk Chunk data
-@param mLength Chunk length
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-mng_SetMetadata_tEXt(tEXtMAP &key_value_pair, const BYTE *mChunk, DWORD mLength) {
- std::string key;
- std::string value;
- BYTE *buffer = (BYTE*)malloc(mLength * sizeof(BYTE));
- if(!buffer) {
- return FALSE;
- }
- DWORD pos = 0;
-
- memset(buffer, 0, mLength * sizeof(BYTE));
-
- for(DWORD i = 0; i < mLength; i++) {
- buffer[pos++] = mChunk[i];
- if(mChunk[i] == '\0') {
- if(key.size() == 0) {
- key = (char*)buffer;
- pos = 0;
- memset(buffer, 0, mLength * sizeof(BYTE));
- } else {
- break;
- }
- }
- }
- value = (char*)buffer;
- free(buffer);
-
- key_value_pair[key] = value;
-
- return TRUE;
-}
-
-// --------------------------------------------------------------------------
-
-/**
-Load a FIBITMAP from a MNG or a JNG stream
-@param format_id ID of the caller
-@param io Stream i/o functions
-@param handle Stream handle
-@param Offset Start of the first chunk
-@param flags Loading flags
-@return Returns a dib if successful, returns NULL otherwise
-*/
-FIBITMAP*
-mng_ReadChunks(int format_id, FreeImageIO *io, fi_handle handle, long Offset, int flags = 0) {
- DWORD mLength = 0;
- BYTE mChunkName[5];
- BYTE *mChunk = NULL;
- DWORD crc_file;
- long LastOffset;
- long mOrigPos;
- BYTE *PLTE_file_chunk = NULL; // whole PLTE chunk (lentgh, name, array, crc)
- DWORD PLTE_file_size = 0; // size of PLTE chunk
-
- BOOL m_HasGlobalPalette = FALSE; // may turn to TRUE in PLTE chunk
- unsigned m_TotalBytesOfChunks = 0;
- FIBITMAP *dib = NULL;
- FIBITMAP *dib_alpha = NULL;
-
- FIMEMORY *hJpegMemory = NULL;
- FIMEMORY *hPngMemory = NULL;
- FIMEMORY *hIDATMemory = NULL;
-
- // ---
- DWORD jng_width = 0;
- DWORD jng_height = 0;
- BYTE jng_color_type = 0;
- BYTE jng_image_sample_depth = 0;
- BYTE jng_image_compression_method = 0;
-
- BYTE jng_alpha_sample_depth = 0;
- BYTE jng_alpha_compression_method = 0;
- BYTE jng_alpha_filter_method = 0;
- BYTE jng_alpha_interlace_method = 0;
-
- DWORD mng_frame_width = 0;
- DWORD mng_frame_height = 0;
- DWORD mng_ticks_per_second = 0;
- DWORD mng_nominal_layer_count = 0;
- DWORD mng_nominal_frame_count = 0;
- DWORD mng_nominal_play_time = 0;
- DWORD mng_simplicity_profile = 0;
-
-
- DWORD res_x = 2835; // 72 dpi
- DWORD res_y = 2835; // 72 dpi
- RGBQUAD rgbBkColor = {0, 0, 0, 0};
- WORD bk_red, bk_green, bk_blue;
- BOOL hasBkColor = FALSE;
- BOOL mHasIDAT = FALSE;
-
- tEXtMAP key_value_pair;
-
- // ---
-
- BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
-
- // get the file size
- const long mLOF = mng_LOF(io, handle);
- // go to the first chunk
- io->seek_proc(handle, Offset, SEEK_SET);
-
- try {
- BOOL mEnd = FALSE;
-
- while(mEnd == FALSE) {
- // start of the chunk
- LastOffset = io->tell_proc(handle);
- // read length
- mLength = 0;
- io->read_proc(&mLength, 1, sizeof(mLength), handle);
- mng_SwapLong(&mLength);
- // read name
- io->read_proc(&mChunkName[0], 1, 4, handle);
- mChunkName[4] = '\0';
-
- if(mLength > 0) {
- mChunk = (BYTE*)realloc(mChunk, mLength);
- if(!mChunk) {
- FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: out of memory", mChunkName);
- throw (const char*)NULL;
- }
- Offset = io->tell_proc(handle);
- if(Offset + (long)mLength > mLOF) {
- FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: unexpected end of file", mChunkName);
- throw (const char*)NULL;
- }
- // read chunk
- io->read_proc(mChunk, 1, mLength, handle);
- }
- // read crc
- io->read_proc(&crc_file, 1, sizeof(crc_file), handle);
- mng_SwapLong(&crc_file);
- // check crc
- DWORD crc_check = FreeImage_ZLibCRC32(0, &mChunkName[0], 4);
- crc_check = FreeImage_ZLibCRC32(crc_check, mChunk, mLength);
- if(crc_check != crc_file) {
- FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: bad CRC", mChunkName);
- throw (const char*)NULL;
- }
-
- switch( mng_GetChunckType(mChunkName) ) {
- case MHDR:
- // The MHDR chunk is always first in all MNG datastreams except for those
- // that consist of a single PNG or JNG datastream with a PNG or JNG signature.
- if(mLength == 28) {
- memcpy(&mng_frame_width, &mChunk[0], 4);
- memcpy(&mng_frame_height, &mChunk[4], 4);
- memcpy(&mng_ticks_per_second, &mChunk[8], 4);
- memcpy(&mng_nominal_layer_count, &mChunk[12], 4);
- memcpy(&mng_nominal_frame_count, &mChunk[16], 4);
- memcpy(&mng_nominal_play_time, &mChunk[20], 4);
- memcpy(&mng_simplicity_profile, &mChunk[24], 4);
-
- mng_SwapLong(&mng_frame_width);
- mng_SwapLong(&mng_frame_height);
- mng_SwapLong(&mng_ticks_per_second);
- mng_SwapLong(&mng_nominal_layer_count);
- mng_SwapLong(&mng_nominal_frame_count);
- mng_SwapLong(&mng_nominal_play_time);
- mng_SwapLong(&mng_simplicity_profile);
-
- } else {
- FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: size is %d instead of 28", mChunkName, mLength);
- }
- break;
-
- case MEND:
- mEnd = TRUE;
- break;
-
- case LOOP:
- case ENDL:
- break;
- case DEFI:
- break;
- case SAVE:
- case SEEK:
- case TERM:
- break;
- case BACK:
- break;
-
- // Global "PLTE" and "tRNS" (if any). PNG "PLTE" will be of 0 byte, as it uses global data.
- case PLTE: // Global
- m_HasGlobalPalette = TRUE;
- PLTE_file_size = mLength + 12; // (lentgh, name, array, crc) = (4, 4, mLength, 4)
- PLTE_file_chunk = (BYTE*)realloc(PLTE_file_chunk, PLTE_file_size);
- if(!PLTE_file_chunk) {
- FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: out of memory", mChunkName);
- throw (const char*)NULL;
- } else {
- mOrigPos = io->tell_proc(handle);
- // seek to the start of the chunk
- io->seek_proc(handle, LastOffset, SEEK_SET);
- // load the whole chunk
- io->read_proc(PLTE_file_chunk, 1, PLTE_file_size, handle);
- // go to the start of the next chunk
- io->seek_proc(handle, mOrigPos, SEEK_SET);
- }
- break;
-
- case tRNS: // Global
- break;
-
- case IHDR:
- Offset = LastOffset;
- // parse the PNG file and get its file size
- if(mng_CountPNGChunks(io, handle, Offset, &m_TotalBytesOfChunks) == FALSE) {
- // reach an unexpected end of file
- mEnd = TRUE;
- FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: unexpected end of PNG file", mChunkName);
- break;
- }
-
- // wrap the { IHDR, ..., IEND } chunks as a PNG stream
- if(hPngMemory == NULL) {
- hPngMemory = FreeImage_OpenMemory();
- }
-
- mOrigPos = io->tell_proc(handle);
-
- // write PNG file signature
- FreeImage_SeekMemory(hPngMemory, 0, SEEK_SET);
- FreeImage_WriteMemory(g_png_signature, 1, 8, hPngMemory);
-
- mChunk = (BYTE*)realloc(mChunk, m_TotalBytesOfChunks);
- if(!mChunk) {
- FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: out of memory", mChunkName);
- throw (const char*)NULL;
- }
-
- // on calling CountPNGChunks earlier, we were in Offset pos,
- // go back there
- io->seek_proc(handle, Offset, SEEK_SET);
- io->read_proc(mChunk, 1, m_TotalBytesOfChunks, handle);
- // Put back to original pos
- io->seek_proc(handle, mOrigPos, SEEK_SET);
- // write the PNG chunks
- FreeImage_WriteMemory(mChunk, 1, m_TotalBytesOfChunks, hPngMemory);
-
- // plug in global PLTE if local PLTE exists
- if(m_HasGlobalPalette) {
- // ensure we remove some local chunks, so that global
- // "PLTE" can be inserted right before "IDAT".
- mng_RemoveChunk(hPngMemory, mng_PLTE);
- mng_RemoveChunk(hPngMemory, mng_tRNS);
- mng_RemoveChunk(hPngMemory, mng_bKGD);
- // insert global "PLTE" chunk in its entirety before "IDAT"
- mng_InsertChunk(hPngMemory, mng_IDAT, PLTE_file_chunk, PLTE_file_size);
- }
-
- if(dib) FreeImage_Unload(dib);
- dib = mng_LoadFromMemoryHandle(hPngMemory, flags);
-
- // stop after the first image
- mEnd = TRUE;
- break;
-
- case JHDR:
- if(mLength == 16) {
- memcpy(&jng_width, &mChunk[0], 4);
- memcpy(&jng_height, &mChunk[4], 4);
- mng_SwapLong(&jng_width);
- mng_SwapLong(&jng_height);
-
- jng_color_type = mChunk[8];
- jng_image_sample_depth = mChunk[9];
- jng_image_compression_method = mChunk[10];
- //BYTE jng_image_interlace_method = mChunk[11]; // for debug only
-
- jng_alpha_sample_depth = mChunk[12];
- jng_alpha_compression_method = mChunk[13];
- jng_alpha_filter_method = mChunk[14];
- jng_alpha_interlace_method = mChunk[15];
- } else {
- FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: invalid chunk length", mChunkName);
- throw (const char*)NULL;
- }
- break;
-
- case JDAT:
- if(hJpegMemory == NULL) {
- hJpegMemory = FreeImage_OpenMemory();
- }
- // as there may be several JDAT chunks, concatenate them
- FreeImage_WriteMemory(mChunk, 1, mLength, hJpegMemory);
- break;
-
- case IDAT:
- if(!header_only && (jng_alpha_compression_method == 0)) {
- // PNG grayscale IDAT format
- if(hIDATMemory == NULL) {
- hIDATMemory = FreeImage_OpenMemory();
- mHasIDAT = TRUE;
- }
- // as there may be several IDAT chunks, concatenate them
- FreeImage_WriteMemory(mChunk, 1, mLength, hIDATMemory);
- }
- break;
-
- case IEND:
- if(!hJpegMemory) {
- mEnd = TRUE;
- break;
- }
- // load the JPEG
- if(dib) {
- FreeImage_Unload(dib);
- }
- dib = mng_LoadFromMemoryHandle(hJpegMemory, flags);
-
- // load the PNG alpha layer
- if(mHasIDAT) {
- BYTE *data = NULL;
- DWORD size_in_bytes = 0;
-
- // get a pointer to the IDAT buffer
- FreeImage_AcquireMemory(hIDATMemory, &data, &size_in_bytes);
- if(data && size_in_bytes) {
- // wrap the IDAT chunk as a PNG stream
- if(hPngMemory == NULL) {
- hPngMemory = FreeImage_OpenMemory();
- }
- mng_WritePNGStream(jng_width, jng_height, jng_alpha_sample_depth, data, size_in_bytes, hPngMemory);
- // load the PNG
- if(dib_alpha) {
- FreeImage_Unload(dib_alpha);
- }
- dib_alpha = mng_LoadFromMemoryHandle(hPngMemory, flags);
- }
- }
- // stop the parsing
- mEnd = TRUE;
- break;
-
- case JDAA:
- break;
-
- case gAMA:
- break;
-
- case pHYs:
- // unit is pixels per meter
- memcpy(&res_x, &mChunk[0], 4);
- mng_SwapLong(&res_x);
- memcpy(&res_y, &mChunk[4], 4);
- mng_SwapLong(&res_y);
- break;
-
- case bKGD:
- memcpy(&bk_red, &mChunk[0], 2);
- mng_SwapShort(&bk_red);
- rgbBkColor.rgbRed = (BYTE)bk_red;
- memcpy(&bk_green, &mChunk[2], 2);
- mng_SwapShort(&bk_green);
- rgbBkColor.rgbGreen = (BYTE)bk_green;
- memcpy(&bk_blue, &mChunk[4], 2);
- mng_SwapShort(&bk_blue);
- rgbBkColor.rgbBlue = (BYTE)bk_blue;
- hasBkColor = TRUE;
- break;
-
- case tEXt:
- mng_SetMetadata_tEXt(key_value_pair, mChunk, mLength);
- break;
-
- case UNKNOWN_CHUNCK:
- default:
- break;
-
-
- } // 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);
- dib = dst;
- }
- FreeImage_Unload(dib_alpha);
-
- if(dib) {
- // set metadata
- FreeImage_SetDotsPerMeterX(dib, res_x);
- FreeImage_SetDotsPerMeterY(dib, res_y);
- if(hasBkColor) {
- FreeImage_SetBackgroundColor(dib, &rgbBkColor);
- }
- if(key_value_pair.size()) {
- for(tEXtMAP::iterator j = key_value_pair.begin(); j != key_value_pair.end(); j++) {
- std::string key = (*j).first;
- std::string value = (*j).second;
- mng_SetKeyValue(FIMD_COMMENTS, dib, key.c_str(), value.c_str());
- }
- }
- }
-
- return dib;
-
- } catch(const char *text) {
- FreeImage_CloseMemory(hJpegMemory);
- FreeImage_CloseMemory(hPngMemory);
- FreeImage_CloseMemory(hIDATMemory);
- free(mChunk);
- free(PLTE_file_chunk);
- FreeImage_Unload(dib);
- FreeImage_Unload(dib_alpha);
- if(text) {
- FreeImage_OutputMessageProc(format_id, text);
- }
- return NULL;
- }
-}
-
-// --------------------------------------------------------------------------
-
-/**
-Write a FIBITMAP to a JNG stream
-@param format_id ID of the caller
-@param io Stream i/o functions
-@param dib Image to be saved
-@param handle Stream handle
-@param flags Saving flags
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-BOOL
-mng_WriteJNG(int format_id, FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int flags) {
- DWORD jng_width = 0;
- DWORD jng_height = 0;
- BYTE jng_color_type = 0;
- BYTE jng_image_sample_depth = 8;
- BYTE jng_image_compression_method = 8; // 8: ISO-10918-1 Huffman-coded baseline JPEG.
- BYTE jng_image_interlace_method = 0;
-
- BYTE jng_alpha_sample_depth = 0;
- BYTE jng_alpha_compression_method = 0;
- BYTE jng_alpha_filter_method = 0;
- BYTE jng_alpha_interlace_method = 0;
-
- BYTE buffer[16];
-
- FIMEMORY *hJngMemory = NULL;
- FIMEMORY *hJpegMemory = NULL;
- FIMEMORY *hPngMemory = NULL;
-
- FIBITMAP *dib_rgb = NULL;
- FIBITMAP *dib_alpha = NULL;
-
- if(!dib || (FreeImage_GetImageType(dib) != FIT_BITMAP)) {
- return FALSE;
- }
-
- unsigned bpp = FreeImage_GetBPP(dib);
-
- switch(bpp) {
- case 8:
- if(FreeImage_GetColorType(dib) == FIC_MINISBLACK) {
- dib_rgb = dib;
- jng_color_type = MNG_COLORTYPE_JPEGGRAY;
- } else {
- // JPEG plugin will convert other types (FIC_MINISWHITE, FIC_PALETTE) to 24-bit on the fly
- //dib_rgb = FreeImage_ConvertTo24Bits(dib);
- dib_rgb = dib;
- jng_color_type = MNG_COLORTYPE_JPEGCOLOR;
-
- }
- break;
- case 24:
- dib_rgb = dib;
- jng_color_type = MNG_COLORTYPE_JPEGCOLOR;
- break;
- case 32:
- dib_rgb = FreeImage_ConvertTo24Bits(dib);
- jng_color_type = MNG_COLORTYPE_JPEGCOLORA;
- jng_alpha_sample_depth = 8;
- break;
- default:
- return FALSE;
- }
-
- jng_width = (DWORD)FreeImage_GetWidth(dib);
- jng_height = (DWORD)FreeImage_GetHeight(dib);
-
- try {
- hJngMemory = FreeImage_OpenMemory();
-
- // --- write JNG file signature ---
- FreeImage_WriteMemory(g_jng_signature, 1, 8, hJngMemory);
-
- // --- write a JHDR chunk ---
- SwapLong(&jng_width);
- SwapLong(&jng_height);
- memcpy(&buffer[0], &jng_width, 4);
- memcpy(&buffer[4], &jng_height, 4);
- SwapLong(&jng_width);
- SwapLong(&jng_height);
- buffer[8] = jng_color_type;
- buffer[9] = jng_image_sample_depth;
- buffer[10] = jng_image_compression_method;
- buffer[11] = jng_image_interlace_method;
- buffer[12] = jng_alpha_sample_depth;
- buffer[13] = jng_alpha_compression_method;
- buffer[14] = jng_alpha_filter_method;
- buffer[15] = jng_alpha_interlace_method;
- mng_WriteChunk(mng_JHDR, &buffer[0], 16, hJngMemory);
-
- // --- write a sequence of JDAT chunks ---
- hJpegMemory = FreeImage_OpenMemory();
- flags |= JPEG_BASELINE;
- if(!FreeImage_SaveToMemory(FIF_JPEG, dib_rgb, hJpegMemory, flags)) {
- throw (const char*)NULL;
- }
- if(dib_rgb != dib) {
- FreeImage_Unload(dib_rgb);
- dib_rgb = NULL;
- }
- {
- BYTE *jpeg_data = NULL;
- DWORD size_in_bytes = 0;
-
- // get a pointer to the stream buffer
- FreeImage_AcquireMemory(hJpegMemory, &jpeg_data, &size_in_bytes);
- // write chunks
- for(DWORD k = 0; k < size_in_bytes;) {
- DWORD bytes_left = size_in_bytes - k;
- DWORD chunk_size = MIN(JPEG_CHUNK_SIZE, bytes_left);
- mng_WriteChunk(mng_JDAT, &jpeg_data[k], chunk_size, hJngMemory);
- k += chunk_size;
- }
- }
- FreeImage_CloseMemory(hJpegMemory);
- hJpegMemory = NULL;
-
- // --- write alpha layer as a sequence of IDAT chunk ---
- if((bpp == 32) && (jng_color_type == MNG_COLORTYPE_JPEGCOLORA)) {
- dib_alpha = FreeImage_GetChannel(dib, FICC_ALPHA);
-
- hPngMemory = FreeImage_OpenMemory();
- if(!FreeImage_SaveToMemory(FIF_PNG, dib_alpha, hPngMemory, PNG_DEFAULT)) {
- throw (const char*)NULL;
- }
- FreeImage_Unload(dib_alpha);
- dib_alpha = NULL;
- // get the IDAT chunk
- {
- BOOL bResult = FALSE;
- DWORD start_pos = 0;
- DWORD next_pos = 0;
- long offset = 8;
-
- do {
- // find the next IDAT chunk from 'offset' position
- bResult = mng_FindChunk(hPngMemory, mng_IDAT, offset, &start_pos, &next_pos);
- if(!bResult) break;
-
- BYTE *png_data = NULL;
- DWORD size_in_bytes = 0;
-
- // get a pointer to the stream buffer
- FreeImage_AcquireMemory(hPngMemory, &png_data, &size_in_bytes);
- // write the IDAT chunk
- mng_WriteChunk(mng_IDAT, &png_data[start_pos+8], next_pos - start_pos - 12, hJngMemory);
-
- offset = next_pos;
-
- } while(bResult);
- }
-
- FreeImage_CloseMemory(hPngMemory);
- hPngMemory = NULL;
- }
-
- // --- write a IEND chunk ---
- mng_WriteChunk(mng_IEND, NULL, 0, hJngMemory);
-
- // write the JNG on output stream
- {
- BYTE *jng_data = NULL;
- DWORD size_in_bytes = 0;
- FreeImage_AcquireMemory(hJngMemory, &jng_data, &size_in_bytes);
- io->write_proc(jng_data, 1, size_in_bytes, handle);
- }
-
- FreeImage_CloseMemory(hJngMemory);
- FreeImage_CloseMemory(hJpegMemory);
- FreeImage_CloseMemory(hPngMemory);
-
- return TRUE;
-
- } catch(const char *text) {
- FreeImage_CloseMemory(hJngMemory);
- FreeImage_CloseMemory(hJpegMemory);
- FreeImage_CloseMemory(hPngMemory);
- if(dib_rgb && (dib_rgb != dib)) {
- FreeImage_Unload(dib_rgb);
- }
- FreeImage_Unload(dib_alpha);
- if(text) {
- FreeImage_OutputMessageProc(format_id, text);
- }
- return FALSE;
- }
-}
diff --git a/plugins/AdvaImg/src/FreeImage/MemoryIO.cpp b/plugins/AdvaImg/src/FreeImage/MemoryIO.cpp
deleted file mode 100644
index 7f587d3fa3..0000000000
--- a/plugins/AdvaImg/src/FreeImage/MemoryIO.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-// ==========================================================
-// Memory Input/Output functions
-//
-// Design and implementation by
-// - Ryan Rubley <ryan@lostreality.org>
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "FreeImageIO.h"
-
-// =====================================================================
-
-
-// =====================================================================
-// Open and close a memory handle
-// =====================================================================
-
-FIMEMORY * DLL_CALLCONV
-FreeImage_OpenMemory(BYTE *data, DWORD size_in_bytes) {
- // allocate a memory handle
- FIMEMORY *stream = (FIMEMORY*)malloc(sizeof(FIMEMORY));
- if(stream) {
- stream->data = (BYTE*)malloc(sizeof(FIMEMORYHEADER));
-
- if(stream->data) {
- FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(stream->data);
-
- // initialize the memory header
- memset(mem_header, 0, sizeof(FIMEMORYHEADER));
-
- if(data && size_in_bytes) {
- // wrap a user buffer
- mem_header->delete_me = FALSE;
- mem_header->data = (BYTE*)data;
- mem_header->data_length = mem_header->file_length = size_in_bytes;
- } else {
- mem_header->delete_me = TRUE;
- }
-
- return stream;
- }
- free(stream);
- }
-
- return NULL;
-}
-
-
-void DLL_CALLCONV
-FreeImage_CloseMemory(FIMEMORY *stream) {
- if(stream && stream->data) {
- FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(stream->data);
- if(mem_header->delete_me) {
- free(mem_header->data);
- }
- free(mem_header);
- free(stream);
- }
-}
-
-// =====================================================================
-// Memory stream load/save functions
-// =====================================================================
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_LoadFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags) {
- if (stream && stream->data) {
- FreeImageIO io;
- SetMemoryIO(&io);
-
- return FreeImage_LoadFromHandle(fif, &io, (fi_handle)stream, flags);
- }
-
- return NULL;
-}
-
-
-BOOL DLL_CALLCONV
-FreeImage_SaveToMemory(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FIMEMORY *stream, int flags) {
- if (stream) {
- FreeImageIO io;
- SetMemoryIO(&io);
-
- FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(stream->data);
-
- if(mem_header->delete_me == TRUE) {
- return FreeImage_SaveToHandle(fif, dib, &io, (fi_handle)stream, flags);
- } else {
- // do not save in a user buffer
- FreeImage_OutputMessageProc(fif, "Memory buffer is read only");
- }
- }
-
- return FALSE;
-}
-
-// =====================================================================
-// Memory stream buffer access
-// =====================================================================
-
-BOOL DLL_CALLCONV
-FreeImage_AcquireMemory(FIMEMORY *stream, BYTE **data, DWORD *size_in_bytes) {
- if (stream) {
- FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(stream->data);
-
- *data = (BYTE*)mem_header->data;
- *size_in_bytes = mem_header->file_length;
- return TRUE;
- }
-
- return FALSE;
-}
-
-// =====================================================================
-// Memory stream file type access
-// =====================================================================
-
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_GetFileTypeFromMemory(FIMEMORY *stream, int size) {
- FreeImageIO io;
- SetMemoryIO(&io);
-
- if (stream != NULL) {
- return FreeImage_GetFileTypeFromHandle(&io, (fi_handle)stream, size);
- }
-
- return FIF_UNKNOWN;
-}
-
-// =====================================================================
-// Seeking in Memory stream
-// =====================================================================
-
-/**
-Moves the memory pointer to a specified location
-@param stream Pointer to FIMEMORY structure
-@param offset Number of bytes from origin
-@param origin Initial position
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-BOOL DLL_CALLCONV
-FreeImage_SeekMemory(FIMEMORY *stream, long offset, int origin) {
- FreeImageIO io;
- SetMemoryIO(&io);
-
- if (stream != NULL) {
- int success = io.seek_proc((fi_handle)stream, offset, origin);
- return (success == 0) ? TRUE : FALSE;
- }
-
- return FALSE;
-}
-
-/**
-Gets the current position of a memory pointer
-@param stream Target FIMEMORY structure
-@return Returns the current file position if successful, -1 otherwise
-*/
-long DLL_CALLCONV
-FreeImage_TellMemory(FIMEMORY *stream) {
- FreeImageIO io;
- SetMemoryIO(&io);
-
- if (stream != NULL) {
- return io.tell_proc((fi_handle)stream);
- }
-
- return -1L;
-}
-
-// =====================================================================
-// Reading or Writing in Memory stream
-// =====================================================================
-
-/**
-Reads data from a memory stream
-@param buffer Storage location for data
-@param size Item size in bytes
-@param count Maximum number of items to be read
-@param stream Pointer to FIMEMORY structure
-@return Returns the number of full items actually read, which may be less than count if an error occurs
-*/
-unsigned DLL_CALLCONV
-FreeImage_ReadMemory(void *buffer, unsigned size, unsigned count, FIMEMORY *stream) {
- FreeImageIO io;
- SetMemoryIO(&io);
-
- if (stream != NULL) {
- return io.read_proc(buffer, size, count, stream);
- }
-
- return 0;
-}
-
-/**
-Writes data to a memory stream.
-@param buffer Pointer to data to be written
-@param size Item size in bytes
-@param count Maximum number of items to be written
-@param stream Pointer to FIMEMORY structure
-@return Returns the number of full items actually written, which may be less than count if an error occurs
-*/
-unsigned DLL_CALLCONV
-FreeImage_WriteMemory(const void *buffer, unsigned size, unsigned count, FIMEMORY *stream) {
- if (stream != NULL) {
- FreeImageIO io;
- SetMemoryIO(&io);
-
- FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)stream)->data);
-
- if(mem_header->delete_me == TRUE) {
- return io.write_proc((void *)buffer, size, count, stream);
- } else {
- // do not write in a user buffer
- FreeImage_OutputMessageProc(FIF_UNKNOWN, "Memory buffer is read only");
- }
- }
-
- return 0;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/MultiPage.cpp b/plugins/AdvaImg/src/FreeImage/MultiPage.cpp
deleted file mode 100644
index 8c49d45396..0000000000
--- a/plugins/AdvaImg/src/FreeImage/MultiPage.cpp
+++ /dev/null
@@ -1,990 +0,0 @@
-// ==========================================================
-// Multi-Page functions
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Laurent Rocher (rocherl@club-internet.fr)
-// - Steve Johnson (steve@parisgroup.net)
-// - Petr Pytelka (pyta@lightcomp.com)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Vadim Alexandrov (vadimalexandrov@users.sourceforge.net
-// - Martin Dyring-Andersen (mda@spamfighter.com)
-// - Volodymyr Goncharov (volodymyr.goncharov@gmail.com)
-//
-// 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 "CacheFile.h"
-#include "FreeImageIO.h"
-#include "Plugin.h"
-#include "Utilities.h"
-#include "FreeImage.h"
-
-// ----------------------------------------------------------
-
-enum BlockType { BLOCK_CONTINUEUS, BLOCK_REFERENCE };
-
-// ----------------------------------------------------------
-
-struct BlockTypeS {
- BlockType m_type;
-
- BlockTypeS(BlockType type) : m_type(type) {
- }
- virtual ~BlockTypeS() {}
-};
-
-struct BlockContinueus : public BlockTypeS {
- int m_start;
- int m_end;
-
- BlockContinueus(int s, int e) : BlockTypeS(BLOCK_CONTINUEUS),
- m_start(s),
- m_end(e) {
- }
-};
-
-struct BlockReference : public BlockTypeS {
- int m_reference;
- int m_size;
-
- BlockReference(int r, int size) : BlockTypeS(BLOCK_REFERENCE),
- m_reference(r),
- m_size(size) {
- }
-};
-
-// ----------------------------------------------------------
-
-typedef std::list<BlockTypeS *> BlockList;
-typedef std::list<BlockTypeS *>::iterator BlockListIterator;
-
-// ----------------------------------------------------------
-
-FI_STRUCT (MULTIBITMAPHEADER) {
- PluginNode *node;
- FREE_IMAGE_FORMAT fif;
- FreeImageIO *io;
- fi_handle handle;
- CacheFile *m_cachefile;
- std::map<FIBITMAP *, int> locked_pages;
- BOOL changed;
- int page_count;
- BlockList m_blocks;
- char *m_filename;
- BOOL read_only;
- FREE_IMAGE_FORMAT cache_fif;
- int load_flags;
-};
-
-// =====================================================================
-// Helper functions
-// =====================================================================
-
-inline void
-ReplaceExtension(std::string& dst_filename, const std::string& src_filename, const std::string& dst_extension) {
- size_t lastDot = src_filename.find_last_of('.');
- if (lastDot == std::string::npos) {
- dst_filename = src_filename;
- dst_filename += ".";
- dst_filename += dst_extension;
- }
- else {
- dst_filename = src_filename.substr(0, lastDot + 1);
- dst_filename += dst_extension;
- }
-}
-
-// =====================================================================
-// Internal Multipage functions
-// =====================================================================
-
-inline MULTIBITMAPHEADER *
-FreeImage_GetMultiBitmapHeader(FIMULTIBITMAP *bitmap) {
- return (MULTIBITMAPHEADER *)bitmap->data;
-}
-
-static BlockListIterator DLL_CALLCONV
-FreeImage_FindBlock(FIMULTIBITMAP *bitmap, int position) {
- assert(NULL != bitmap);
-
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- // step 1: find the block that matches the given position
-
- int prev_count = 0;
- int count = 0;
- BlockListIterator i;
- BlockTypeS *current_block = NULL;
-
- for (i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
- prev_count = count;
-
- switch((*i)->m_type) {
- case BLOCK_CONTINUEUS :
- count += ((BlockContinueus *)(*i))->m_end - ((BlockContinueus *)(*i))->m_start + 1;
- break;
-
- case BLOCK_REFERENCE :
- count++;
- break;
- }
-
- current_block = *i;
-
- if (count > position)
- break;
- }
-
- // step 2: make sure we found the node. from here it gets a little complicated:
- // * if the block is there, just return it
- // * if the block is a series of blocks, split it in max 3 new blocks
- // and return the splitted block
-
- if ((current_block) && (count > position)) {
- switch(current_block->m_type) {
- case BLOCK_REFERENCE :
- return i;
-
- case BLOCK_CONTINUEUS :
- {
- BlockContinueus *block = (BlockContinueus *)current_block;
-
- if (block->m_start != block->m_end) {
- int item = block->m_start + (position - prev_count);
-
- // left part
-
- if (item != block->m_start) {
- BlockContinueus *block_a = new BlockContinueus(block->m_start, item - 1);
- header->m_blocks.insert(i, (BlockTypeS *)block_a);
- }
-
- // middle part
-
- BlockContinueus *block_b = new BlockContinueus(item, item);
- BlockListIterator block_target = header->m_blocks.insert(i, (BlockTypeS *)block_b);
-
- // right part
-
- if (item != block->m_end) {
- BlockContinueus *block_c = new BlockContinueus(item + 1, block->m_end);
- header->m_blocks.insert(i, (BlockTypeS *)block_c);
- }
-
- // remove the old block that was just splitted
-
- header->m_blocks.remove((BlockTypeS *)block);
- delete block;
-
- // return the splitted block
-
- return block_target;
- }
-
- return i;
- }
- }
- }
- // we should never go here ...
- assert(false);
- return header->m_blocks.end();
-}
-
-int DLL_CALLCONV
-FreeImage_InternalGetPageCount(FIMULTIBITMAP *bitmap) {
- if (bitmap) {
- if (((MULTIBITMAPHEADER *)bitmap->data)->handle) {
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- header->io->seek_proc(header->handle, 0, SEEK_SET);
-
- void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE);
-
- int page_count = (header->node->m_plugin->pagecount_proc != NULL) ? header->node->m_plugin->pagecount_proc(header->io, header->handle, data) : 1;
-
- FreeImage_Close(header->node, header->io, header->handle, data);
-
- return page_count;
- }
- }
-
- return 0;
-}
-
-// =====================================================================
-// Multipage functions
-// =====================================================================
-
-FIMULTIBITMAP * DLL_CALLCONV
-FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory, int flags) {
-
- FILE *handle = NULL;
- try {
- // sanity check on the parameters
-
- if (create_new) {
- read_only = FALSE;
- }
-
- // retrieve the plugin list to find the node belonging to this plugin
-
- PluginList *list = FreeImage_GetPluginList();
-
- if (list) {
- PluginNode *node = list->FindNodeFromFIF(fif);
-
- if (node) {
- std::auto_ptr<FreeImageIO> io (new FreeImageIO);
-
- SetDefaultIO(io.get());
-
- if (!create_new) {
- handle = fopen(filename, "rb");
- if (handle == NULL) {
- return NULL;
- }
- }
-
- std::auto_ptr<FIMULTIBITMAP> bitmap (new FIMULTIBITMAP);
- std::auto_ptr<MULTIBITMAPHEADER> header (new MULTIBITMAPHEADER);
- header->m_filename = new char[strlen(filename) + 1];
- strcpy(header->m_filename, filename);
- header->node = node;
- header->fif = fif;
- header->io = io.get ();
- header->handle = handle;
- header->changed = FALSE;
- header->read_only = read_only;
- header->m_cachefile = NULL;
- header->cache_fif = fif;
- header->load_flags = flags;
-
- // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
-
- bitmap->data = header.get();
-
- // cache the page count
-
- header->page_count = FreeImage_InternalGetPageCount(bitmap.get());
-
- // allocate a continueus block to describe the bitmap
-
- if (!create_new) {
- header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
- }
-
- // set up the cache
-
- if (!read_only) {
- std::string cache_name;
- ReplaceExtension(cache_name, filename, "ficache");
-
- std::auto_ptr<CacheFile> cache_file (new CacheFile(cache_name, keep_cache_in_memory));
-
- if (cache_file->open()) {
- // we can use release() as std::bad_alloc won't be thrown from here on
- header->m_cachefile = cache_file.release();
- } else {
- // an error occured ...
- fclose(handle);
- return NULL;
- }
- }
- // return the multibitmap
- // std::bad_alloc won't be thrown from here on
- header.release(); // now owned by bitmap
- io.release(); // now owned by bitmap
- return bitmap.release(); // now owned by caller
- }
- }
- } catch (std::bad_alloc &) {
- /** @todo report error */
- }
- if (handle)
- fclose(handle);
- return NULL;
-}
-
-FIMULTIBITMAP * DLL_CALLCONV
-FreeImage_OpenMultiBitmapU(FREE_IMAGE_FORMAT fif, const wchar_t *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory, int flags) {
-
- // convert to single character - no national chars in extensions
- char *extension = (char *)malloc(wcslen(filename)+1);
- unsigned int i=0;
- for (; i < wcslen(filename); i++) // convert 16-bit to 8-bit
- extension[i] = (char)(filename[i] & 0x00FF);
- // set terminating 0
- extension[i]=0;
- FIMULTIBITMAP *fRet = FreeImage_OpenMultiBitmap(fif, extension, create_new, read_only, keep_cache_in_memory, flags);
- free(extension);
-
- return fRet;
-}
-
-FIMULTIBITMAP * DLL_CALLCONV
-FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags) {
- try {
- BOOL read_only = FALSE; // modifications (if any) will be stored into the memory cache
-
- if (io && handle) {
-
- // retrieve the plugin list to find the node belonging to this plugin
- PluginList *list = FreeImage_GetPluginList();
-
- if (list) {
- PluginNode *node = list->FindNodeFromFIF(fif);
-
- if (node) {
- std::auto_ptr<FIMULTIBITMAP> bitmap (new FIMULTIBITMAP);
- std::auto_ptr<MULTIBITMAPHEADER> header (new MULTIBITMAPHEADER);
- std::auto_ptr<FreeImageIO> tmp_io (new FreeImageIO (*io));
- header->io = tmp_io.get();
- header->m_filename = NULL;
- header->node = node;
- header->fif = fif;
- header->handle = handle;
- header->changed = FALSE;
- header->read_only = read_only;
- header->m_cachefile = NULL;
- header->cache_fif = fif;
- header->load_flags = flags;
-
- // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
-
- bitmap->data = header.get();
-
- // cache the page count
-
- header->page_count = FreeImage_InternalGetPageCount(bitmap.get());
-
- // allocate a continueus block to describe the bitmap
-
- header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
-
- if (!read_only) {
- // set up the cache
- std::auto_ptr<CacheFile> cache_file (new CacheFile("", TRUE));
-
- if (cache_file->open()) {
- header->m_cachefile = cache_file.release();
- }
- }
- tmp_io.release();
- header.release();
- return bitmap.release();
- }
- }
- }
- } catch (std::bad_alloc &) {
- /** @todo report error */
- }
- return NULL;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SaveMultiBitmapToHandle(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FreeImageIO *io, fi_handle handle, int flags) {
- if(!bitmap || !bitmap->data || !io || !handle) {
- return FALSE;
- }
-
- BOOL success = TRUE;
-
- // retrieve the plugin list to find the node belonging to this plugin
- PluginList *list = FreeImage_GetPluginList();
-
- if (list) {
- PluginNode *node = list->FindNodeFromFIF(fif);
-
- if(node) {
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- // dst data
- void *data = FreeImage_Open(node, io, handle, FALSE);
- // src data
- void *data_read = NULL;
-
- if(header->handle) {
- // open src
- header->io->seek_proc(header->handle, 0, SEEK_SET);
- data_read = FreeImage_Open(header->node, header->io, header->handle, TRUE);
- }
-
- // write all the pages to the file using handle and io
-
- int count = 0;
-
- for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); i++) {
- if (success) {
- switch((*i)->m_type) {
- case BLOCK_CONTINUEUS:
- {
- BlockContinueus *block = (BlockContinueus *)(*i);
-
- for (int j = block->m_start; j <= block->m_end; j++) {
-
- // load the original source data
- FIBITMAP *dib = header->node->m_plugin->load_proc(header->io, header->handle, j, header->load_flags, data_read);
-
- // save the data
- success = node->m_plugin->save_proc(io, dib, handle, count, flags, data);
- count++;
-
- FreeImage_Unload(dib);
- }
-
- break;
- }
-
- case BLOCK_REFERENCE:
- {
- BlockReference *ref = (BlockReference *)(*i);
-
- // read the compressed data
-
- BYTE *compressed_data = (BYTE*)malloc(ref->m_size * sizeof(BYTE));
-
- header->m_cachefile->readFile((BYTE *)compressed_data, ref->m_reference, ref->m_size);
-
- // uncompress the data
-
- FIMEMORY *hmem = FreeImage_OpenMemory(compressed_data, ref->m_size);
- FIBITMAP *dib = FreeImage_LoadFromMemory(header->cache_fif, hmem, 0);
- FreeImage_CloseMemory(hmem);
-
- // get rid of the buffer
- free(compressed_data);
-
- // save the data
-
- success = node->m_plugin->save_proc(io, dib, handle, count, flags, data);
- count++;
-
- // unload the dib
-
- FreeImage_Unload(dib);
-
- break;
- }
- }
- } else {
- break;
- }
- }
-
- // close the files
-
- FreeImage_Close(header->node, header->io, header->handle, data_read);
-
- FreeImage_Close(node, io, handle, data);
-
- return success;
- }
- }
-
- return FALSE;
-}
-
-
-BOOL DLL_CALLCONV
-FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) {
- if (bitmap) {
- BOOL success = TRUE;
-
- if (bitmap->data) {
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- // saves changes only of images loaded directly from a file
- if (header->changed && header->m_filename) {
- try {
- // open a temp file
-
- std::string spool_name;
-
- ReplaceExtension(spool_name, header->m_filename, "fispool");
-
- // open the spool file and the source file
-
- FILE *f = fopen(spool_name.c_str(), "w+b");
-
- // saves changes
- if (f == NULL) {
- FreeImage_OutputMessageProc(header->fif, "Failed to open %s, %s", spool_name.c_str(), strerror(errno));
- success = FALSE;
- } else {
- success = FreeImage_SaveMultiBitmapToHandle(header->fif, bitmap, header->io, (fi_handle)f, flags);
-
- // close the files
-
- if (fclose(f) != 0) {
- success = FALSE;
- FreeImage_OutputMessageProc(header->fif, "Failed to close %s, %s", spool_name.c_str(), strerror(errno));
- }
- }
- if (header->handle) {
- fclose((FILE *)header->handle);
- }
-
- // applies changes to the destination file
-
- if (success) {
- remove(header->m_filename);
- success = (rename(spool_name.c_str(), header->m_filename) == 0) ? TRUE:FALSE;
- if(!success) {
- FreeImage_OutputMessageProc(header->fif, "Failed to rename %s to %s", spool_name.c_str(), header->m_filename);
- }
- } else {
- remove(spool_name.c_str());
- }
- } catch (std::bad_alloc &) {
- success = FALSE;
- }
-
- } else {
- if (header->handle && header->m_filename) {
- fclose((FILE *)header->handle);
- }
- }
-
- // clear the blocks list
-
- for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
- delete *i;
- }
-
- // flush and dispose the cache
-
- if (header->m_cachefile) {
- header->m_cachefile->close();
- delete header->m_cachefile;
- }
-
- // delete the last open bitmaps
-
- while (!header->locked_pages.empty()) {
- FreeImage_Unload(header->locked_pages.begin()->first);
-
- header->locked_pages.erase(header->locked_pages.begin()->first);
- }
-
- // get rid of the IO structure
-
- delete header->io;
-
- // delete the filename
-
- if(header->m_filename) {
- delete[] header->m_filename;
- }
-
- // delete the FIMULTIBITMAPHEADER
-
- delete header;
- }
-
- delete bitmap;
-
- return success;
- }
-
- return FALSE;
-}
-
-int DLL_CALLCONV
-FreeImage_GetPageCount(FIMULTIBITMAP *bitmap) {
- if (bitmap) {
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- if (header->page_count == -1) {
- header->page_count = 0;
-
- for (BlockListIterator i = header->m_blocks.begin(); i != header->m_blocks.end(); ++i) {
- switch((*i)->m_type) {
- case BLOCK_CONTINUEUS :
- header->page_count += ((BlockContinueus *)(*i))->m_end - ((BlockContinueus *)(*i))->m_start + 1;
- break;
-
- case BLOCK_REFERENCE :
- header->page_count++;
- break;
- }
- }
- }
-
- return header->page_count;
- }
-
- return 0;
-}
-
-static BlockReference*
-FreeImage_SavePageToBlock(MULTIBITMAPHEADER *header, FIBITMAP *data) {
- if (header->read_only || !header->locked_pages.empty())
- return NULL;
-
- DWORD compressed_size = 0;
- BYTE *compressed_data = NULL;
-
- // compress the bitmap data
-
- // open a memory handle
- FIMEMORY *hmem = FreeImage_OpenMemory();
- if(hmem==NULL) return NULL;
- // save the file to memory
- if(!FreeImage_SaveToMemory(header->cache_fif, data, hmem, 0)) {
- FreeImage_CloseMemory(hmem);
- return NULL;
- }
- // get the buffer from the memory stream
- if(!FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size)) {
- FreeImage_CloseMemory(hmem);
- return NULL;
- }
-
- // write the compressed data to the cache
- int ref = header->m_cachefile->writeFile(compressed_data, compressed_size);
- // get rid of the compressed data
- FreeImage_CloseMemory(hmem);
-
- return new(std::nothrow) BlockReference(ref, compressed_size);
-}
-
-void DLL_CALLCONV
-FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data) {
- if (!bitmap || !data)
- return;
-
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- BlockReference *block = FreeImage_SavePageToBlock(header, data);
- if(block==NULL) return;
-
- // add the block
- header->m_blocks.push_back((BlockTypeS *)block);
- header->changed = TRUE;
- header->page_count = -1;
-}
-
-void DLL_CALLCONV
-FreeImage_InsertPage(FIMULTIBITMAP *bitmap, int page, FIBITMAP *data) {
- if (!bitmap || !data)
- return;
-
- if (page >= FreeImage_GetPageCount(bitmap))
- return;
-
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- BlockReference *block = FreeImage_SavePageToBlock(header, data);
- if(block==NULL) return;
-
- // add a block
- if (page > 0) {
- BlockListIterator block_source = FreeImage_FindBlock(bitmap, page);
-
- header->m_blocks.insert(block_source, (BlockTypeS *)block);
- } else {
- header->m_blocks.push_front((BlockTypeS *)block);
- }
-
- header->changed = TRUE;
- header->page_count = -1;
-}
-
-void DLL_CALLCONV
-FreeImage_DeletePage(FIMULTIBITMAP *bitmap, int page) {
- if (bitmap) {
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- if ((!header->read_only) && (header->locked_pages.empty())) {
- if (FreeImage_GetPageCount(bitmap) > 1) {
- BlockListIterator i = FreeImage_FindBlock(bitmap, page);
-
- if (i != header->m_blocks.end()) {
- switch((*i)->m_type) {
- case BLOCK_CONTINUEUS :
- delete *i;
- header->m_blocks.erase(i);
- break;
-
- case BLOCK_REFERENCE :
- header->m_cachefile->deleteFile(((BlockReference *)(*i))->m_reference);
- delete *i;
- header->m_blocks.erase(i);
- break;
- }
-
- header->changed = TRUE;
- header->page_count = -1;
- }
- }
- }
- }
-}
-
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_LockPage(FIMULTIBITMAP *bitmap, int page) {
- if (bitmap) {
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- // only lock if the page wasn't locked before...
-
- for (std::map<FIBITMAP *, int>::iterator i = header->locked_pages.begin(); i != header->locked_pages.end(); ++i) {
- if (i->second == page) {
- return NULL;
- }
- }
-
- // open the bitmap
-
- header->io->seek_proc(header->handle, 0, SEEK_SET);
-
- void *data = FreeImage_Open(header->node, header->io, header->handle, TRUE);
-
- // load the bitmap data
-
- if (data != NULL) {
- FIBITMAP *dib = (header->node->m_plugin->load_proc != NULL) ? header->node->m_plugin->load_proc(header->io, header->handle, page, header->load_flags, data) : NULL;
-
- // close the file
-
- FreeImage_Close(header->node, header->io, header->handle, data);
-
- // if there was still another bitmap open, get rid of it
-
- if (dib) {
- header->locked_pages[dib] = page;
-
- return dib;
- }
-
- return NULL;
- }
- }
-
- return NULL;
-}
-
-void DLL_CALLCONV
-FreeImage_UnlockPage(FIMULTIBITMAP *bitmap, FIBITMAP *page, BOOL changed) {
- if ((bitmap) && (page)) {
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- // find out if the page we try to unlock is actually locked...
-
- if (header->locked_pages.find(page) != header->locked_pages.end()) {
- // store the bitmap compressed in the cache for later writing
-
- if (changed && !header->read_only) {
- header->changed = TRUE;
-
- // cut loose the block from the rest
-
- BlockListIterator i = FreeImage_FindBlock(bitmap, header->locked_pages[page]);
-
- // compress the data
-
- DWORD compressed_size = 0;
- BYTE *compressed_data = NULL;
-
- // open a memory handle
- FIMEMORY *hmem = FreeImage_OpenMemory();
- // save the page to memory
- FreeImage_SaveToMemory(header->cache_fif, page, hmem, 0);
- // get the buffer from the memory stream
- FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size);
-
- // write the data to the cache
-
- switch ((*i)->m_type) {
- case BLOCK_CONTINUEUS :
- {
- int iPage = header->m_cachefile->writeFile(compressed_data, compressed_size);
-
- delete (*i);
-
- *i = (BlockTypeS *)new BlockReference(iPage, compressed_size);
-
- break;
- }
-
- case BLOCK_REFERENCE :
- {
- BlockReference *reference = (BlockReference *)(*i);
-
- header->m_cachefile->deleteFile(reference->m_reference);
-
- delete (*i);
-
- int iPage = header->m_cachefile->writeFile(compressed_data, compressed_size);
-
- *i = (BlockTypeS *)new BlockReference(iPage, compressed_size);
-
- break;
- }
- }
-
- // get rid of the compressed data
-
- FreeImage_CloseMemory(hmem);
- }
-
- // reset the locked page so that another page can be locked
-
- FreeImage_Unload(page);
-
- header->locked_pages.erase(page);
- }
- }
-}
-
-BOOL DLL_CALLCONV
-FreeImage_MovePage(FIMULTIBITMAP *bitmap, int target, int source) {
- if (bitmap) {
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- if ((!header->read_only) && (header->locked_pages.empty())) {
- if ((target != source) && ((target >= 0) && (target < FreeImage_GetPageCount(bitmap))) && ((source >= 0) && (source < FreeImage_GetPageCount(bitmap)))) {
- BlockListIterator block_source = FreeImage_FindBlock(bitmap, target);
- BlockListIterator block_target = FreeImage_FindBlock(bitmap, source);
-
- header->m_blocks.insert(block_target, *block_source);
- header->m_blocks.erase(block_source);
-
- header->changed = TRUE;
-
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_GetLockedPageNumbers(FIMULTIBITMAP *bitmap, int *pages, int *count) {
- if ((bitmap) && (count)) {
- MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
-
- if ((pages == NULL) || (*count == 0)) {
- *count = (int)header->locked_pages.size();
- } else {
- int c = 0;
-
- for (std::map<FIBITMAP *, int>::iterator i = header->locked_pages.begin(); i != header->locked_pages.end(); ++i) {
- pages[c] = i->second;
-
- c++;
-
- if (c == *count)
- break;
- }
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-// =====================================================================
-// Memory IO Multipage functions
-// =====================================================================
-
-FIMULTIBITMAP * DLL_CALLCONV
-FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int flags) {
- BOOL read_only = FALSE; // modifications (if any) will be stored into the memory cache
-
- // retrieve the plugin list to find the node belonging to this plugin
-
- PluginList *list = FreeImage_GetPluginList();
-
- if (list) {
- PluginNode *node = list->FindNodeFromFIF(fif);
-
- if (node) {
- FreeImageIO *io = new(std::nothrow) FreeImageIO;
-
- if (io) {
- SetMemoryIO(io);
-
- FIMULTIBITMAP *bitmap = new(std::nothrow) FIMULTIBITMAP;
-
- if (bitmap) {
- MULTIBITMAPHEADER *header = new(std::nothrow) MULTIBITMAPHEADER;
-
- if (header) {
- header->m_filename = NULL;
- header->node = node;
- header->fif = fif;
- header->io = io;
- header->handle = (fi_handle)stream;
- header->changed = FALSE;
- header->read_only = read_only;
- header->m_cachefile = NULL;
- header->cache_fif = fif;
- header->load_flags = flags;
-
- // store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
-
- bitmap->data = header;
-
- // cache the page count
-
- header->page_count = FreeImage_InternalGetPageCount(bitmap);
-
- // allocate a continueus block to describe the bitmap
-
- header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
-
- if (!read_only) {
- // set up the cache
- CacheFile *cache_file = new(std::nothrow) CacheFile("", TRUE);
-
- if (cache_file && cache_file->open()) {
- header->m_cachefile = cache_file;
- }
- }
-
- return bitmap;
- }
-
- delete bitmap;
- }
-
- delete io;
- }
- }
- }
-
- return NULL;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SaveMultiBitmapToMemory(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP *bitmap, FIMEMORY *stream, int flags) {
- if (stream && stream->data) {
- FreeImageIO io;
- SetMemoryIO(&io);
-
- return FreeImage_SaveMultiBitmapToHandle(fif, bitmap, &io, (fi_handle)stream, flags);
- }
-
- return FALSE;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/NNQuantizer.cpp b/plugins/AdvaImg/src/FreeImage/NNQuantizer.cpp
deleted file mode 100644
index 4f02446d8e..0000000000
--- a/plugins/AdvaImg/src/FreeImage/NNQuantizer.cpp
+++ /dev/null
@@ -1,507 +0,0 @@
-// NeuQuant Neural-Net Quantization Algorithm
-// ------------------------------------------
-//
-// Copyright (c) 1994 Anthony Dekker
-//
-// NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
-// See "Kohonen neural networks for optimal colour quantization"
-// in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
-// for a discussion of the algorithm.
-//
-// Any party obtaining a copy of these files from the author, directly or
-// indirectly, is granted, free of charge, a full and unrestricted irrevocable,
-// world-wide, paid up, royalty-free, nonexclusive right and license to deal
-// in this software and documentation files (the "Software"), including without
-// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons who receive
-// copies from any such party to do so, with the only requirement being
-// that this copyright notice remain intact.
-
-///////////////////////////////////////////////////////////////////////
-// History
-// -------
-// January 2001: Adaptation of the Neural-Net Quantization Algorithm
-// for the FreeImage 2 library
-// Author: Hervé Drolon (drolon@infonie.fr)
-// March 2004: Adaptation for the FreeImage 3 library (port to big endian processors)
-// Author: Hervé Drolon (drolon@infonie.fr)
-// April 2004: Algorithm rewritten as a C++ class.
-// Fixed a bug in the algorithm with handling of 4-byte boundary alignment.
-// Author: Hervé Drolon (drolon@infonie.fr)
-///////////////////////////////////////////////////////////////////////
-
-#include "Quantizers.h"
-#include "FreeImage.h"
-#include "Utilities.h"
-
-
-// Four primes near 500 - assume no image has a length so large
-// that it is divisible by all four primes
-// ==========================================================
-
-#define prime1 499
-#define prime2 491
-#define prime3 487
-#define prime4 503
-
-// ----------------------------------------------------------------
-
-NNQuantizer::NNQuantizer(int PaletteSize)
-{
- netsize = PaletteSize;
- maxnetpos = netsize - 1;
- initrad = netsize < 8 ? 1 : (netsize >> 3);
- initradius = (initrad * radiusbias);
-
- network = NULL;
-
- network = (pixel *)malloc(netsize * sizeof(pixel));
- bias = (int *)malloc(netsize * sizeof(int));
- freq = (int *)malloc(netsize * sizeof(int));
- radpower = (int *)malloc(initrad * sizeof(int));
-
- if( !network || !bias || !freq || !radpower ) {
- if(network) free(network);
- if(bias) free(bias);
- if(freq) free(freq);
- if(radpower) free(radpower);
- throw FI_MSG_ERROR_MEMORY;
- }
-}
-
-NNQuantizer::~NNQuantizer()
-{
- if(network) free(network);
- if(bias) free(bias);
- if(freq) free(freq);
- if(radpower) free(radpower);
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Initialise network in range (0,0,0) to (255,255,255) and set parameters
-// -----------------------------------------------------------------------
-
-void NNQuantizer::initnet() {
- int i, *p;
-
- for (i = 0; i < netsize; i++) {
- p = network[i];
- p[FI_RGBA_BLUE] = p[FI_RGBA_GREEN] = p[FI_RGBA_RED] = (i << (netbiasshift+8))/netsize;
- freq[i] = intbias/netsize; /* 1/netsize */
- bias[i] = 0;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-// Unbias network to give byte values 0..255 and record position i to prepare for sort
-// ------------------------------------------------------------------------------------
-
-void NNQuantizer::unbiasnet() {
- int i, j, temp;
-
- for (i = 0; i < netsize; i++) {
- for (j = 0; j < 3; j++) {
- // OLD CODE: network[i][j] >>= netbiasshift;
- // Fix based on bug report by Juergen Weigert jw@suse.de
- temp = (network[i][j] + (1 << (netbiasshift - 1))) >> netbiasshift;
- if (temp > 255) temp = 255;
- network[i][j] = temp;
- }
- network[i][3] = i; // record colour no
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Insertion sort of network and building of netindex[0..255] (to do after unbias)
-// -------------------------------------------------------------------------------
-
-void NNQuantizer::inxbuild() {
- int i,j,smallpos,smallval;
- int *p,*q;
- int previouscol,startpos;
-
- previouscol = 0;
- startpos = 0;
- for (i = 0; i < netsize; i++) {
- p = network[i];
- smallpos = i;
- smallval = p[FI_RGBA_GREEN]; // index on g
- // find smallest in i..netsize-1
- for (j = i+1; j < netsize; j++) {
- q = network[j];
- if (q[FI_RGBA_GREEN] < smallval) { // index on g
- smallpos = j;
- smallval = q[FI_RGBA_GREEN]; // index on g
- }
- }
- q = network[smallpos];
- // swap p (i) and q (smallpos) entries
- if (i != smallpos) {
- j = q[FI_RGBA_BLUE]; q[FI_RGBA_BLUE] = p[FI_RGBA_BLUE]; p[FI_RGBA_BLUE] = j;
- j = q[FI_RGBA_GREEN]; q[FI_RGBA_GREEN] = p[FI_RGBA_GREEN]; p[FI_RGBA_GREEN] = j;
- j = q[FI_RGBA_RED]; q[FI_RGBA_RED] = p[FI_RGBA_RED]; p[FI_RGBA_RED] = j;
- j = q[3]; q[3] = p[3]; p[3] = j;
- }
- // smallval entry is now in position i
- if (smallval != previouscol) {
- netindex[previouscol] = (startpos+i)>>1;
- for (j = previouscol+1; j < smallval; j++)
- netindex[j] = i;
- previouscol = smallval;
- startpos = i;
- }
- }
- netindex[previouscol] = (startpos+maxnetpos)>>1;
- for (j = previouscol+1; j < 256; j++)
- netindex[j] = maxnetpos; // really 256
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Search for BGR values 0..255 (after net is unbiased) and return colour index
-// ----------------------------------------------------------------------------
-
-int NNQuantizer::inxsearch(int b, int g, int r) {
- int i, j, dist, a, bestd;
- int *p;
- int best;
-
- bestd = 1000; // biggest possible dist is 256*3
- best = -1;
- i = netindex[g]; // index on g
- j = i-1; // start at netindex[g] and work outwards
-
- while ((i < netsize) || (j >= 0)) {
- if (i < netsize) {
- p = network[i];
- dist = p[FI_RGBA_GREEN] - g; // inx key
- if (dist >= bestd)
- i = netsize; // stop iter
- else {
- i++;
- if (dist < 0)
- dist = -dist;
- a = p[FI_RGBA_BLUE] - b;
- if (a < 0)
- a = -a;
- dist += a;
- if (dist < bestd) {
- a = p[FI_RGBA_RED] - r;
- if (a<0)
- a = -a;
- dist += a;
- if (dist < bestd) {
- bestd = dist;
- best = p[3];
- }
- }
- }
- }
- if (j >= 0) {
- p = network[j];
- dist = g - p[FI_RGBA_GREEN]; // inx key - reverse dif
- if (dist >= bestd)
- j = -1; // stop iter
- else {
- j--;
- if (dist < 0)
- dist = -dist;
- a = p[FI_RGBA_BLUE] - b;
- if (a<0)
- a = -a;
- dist += a;
- if (dist < bestd) {
- a = p[FI_RGBA_RED] - r;
- if (a<0)
- a = -a;
- dist += a;
- if (dist < bestd) {
- bestd = dist;
- best = p[3];
- }
- }
- }
- }
- }
- return best;
-}
-
-///////////////////////////////
-// Search for biased BGR values
-// ----------------------------
-
-int NNQuantizer::contest(int b, int g, int r) {
- // finds closest neuron (min dist) and updates freq
- // finds best neuron (min dist-bias) and returns position
- // for frequently chosen neurons, freq[i] is high and bias[i] is negative
- // bias[i] = gamma*((1/netsize)-freq[i])
-
- int i,dist,a,biasdist,betafreq;
- int bestpos,bestbiaspos,bestd,bestbiasd;
- int *p,*f, *n;
-
- bestd = ~(((int) 1)<<31);
- bestbiasd = bestd;
- bestpos = -1;
- bestbiaspos = bestpos;
- p = bias;
- f = freq;
-
- for (i = 0; i < netsize; i++) {
- n = network[i];
- dist = n[FI_RGBA_BLUE] - b;
- if (dist < 0)
- dist = -dist;
- a = n[FI_RGBA_GREEN] - g;
- if (a < 0)
- a = -a;
- dist += a;
- a = n[FI_RGBA_RED] - r;
- if (a < 0)
- a = -a;
- dist += a;
- if (dist < bestd) {
- bestd = dist;
- bestpos = i;
- }
- biasdist = dist - ((*p)>>(intbiasshift-netbiasshift));
- if (biasdist < bestbiasd) {
- bestbiasd = biasdist;
- bestbiaspos = i;
- }
- betafreq = (*f >> betashift);
- *f++ -= betafreq;
- *p++ += (betafreq << gammashift);
- }
- freq[bestpos] += beta;
- bias[bestpos] -= betagamma;
- return bestbiaspos;
-}
-
-///////////////////////////////////////////////////////
-// Move neuron i towards biased (b,g,r) by factor alpha
-// ----------------------------------------------------
-
-void NNQuantizer::altersingle(int alpha, int i, int b, int g, int r) {
- int *n;
-
- n = network[i]; // alter hit neuron
- n[FI_RGBA_BLUE] -= (alpha * (n[FI_RGBA_BLUE] - b)) / initalpha;
- n[FI_RGBA_GREEN] -= (alpha * (n[FI_RGBA_GREEN] - g)) / initalpha;
- n[FI_RGBA_RED] -= (alpha * (n[FI_RGBA_RED] - r)) / initalpha;
-}
-
-////////////////////////////////////////////////////////////////////////////////////
-// Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]
-// ---------------------------------------------------------------------------------
-
-void NNQuantizer::alterneigh(int rad, int i, int b, int g, int r) {
- int j, k, lo, hi, a;
- int *p, *q;
-
- lo = i - rad; if (lo < -1) lo = -1;
- hi = i + rad; if (hi > netsize) hi = netsize;
-
- j = i+1;
- k = i-1;
- q = radpower;
- while ((j < hi) || (k > lo)) {
- a = (*(++q));
- if (j < hi) {
- p = network[j];
- p[FI_RGBA_BLUE] -= (a * (p[FI_RGBA_BLUE] - b)) / alpharadbias;
- p[FI_RGBA_GREEN] -= (a * (p[FI_RGBA_GREEN] - g)) / alpharadbias;
- p[FI_RGBA_RED] -= (a * (p[FI_RGBA_RED] - r)) / alpharadbias;
- j++;
- }
- if (k > lo) {
- p = network[k];
- p[FI_RGBA_BLUE] -= (a * (p[FI_RGBA_BLUE] - b)) / alpharadbias;
- p[FI_RGBA_GREEN] -= (a * (p[FI_RGBA_GREEN] - g)) / alpharadbias;
- p[FI_RGBA_RED] -= (a * (p[FI_RGBA_RED] - r)) / alpharadbias;
- k--;
- }
- }
-}
-
-/////////////////////
-// Main Learning Loop
-// ------------------
-
-/**
- Get a pixel sample at position pos. Handle 4-byte boundary alignment.
- @param pos pixel position in a WxHx3 pixel buffer
- @param b blue pixel component
- @param g green pixel component
- @param r red pixel component
-*/
-void NNQuantizer::getSample(long pos, int *b, int *g, int *r) {
- // get equivalent pixel coordinates
- // - assume it's a 24-bit image -
- int x = pos % img_line;
- int y = pos / img_line;
-
- BYTE *bits = FreeImage_GetScanLine(dib_ptr, y) + x;
-
- *b = bits[FI_RGBA_BLUE] << netbiasshift;
- *g = bits[FI_RGBA_GREEN] << netbiasshift;
- *r = bits[FI_RGBA_RED] << netbiasshift;
-}
-
-void NNQuantizer::learn(int sampling_factor) {
- int i, j, b, g, r;
- int radius, rad, alpha, step, delta, samplepixels;
- int alphadec; // biased by 10 bits
- long pos, lengthcount;
-
- // image size as viewed by the scan algorithm
- lengthcount = img_width * img_height * 3;
-
- // number of samples used for the learning phase
- samplepixels = lengthcount / (3 * sampling_factor);
-
- // decrease learning rate after delta pixel presentations
- delta = samplepixels / ncycles;
- if(delta == 0) {
- // avoid a 'divide by zero' error with very small images
- delta = 1;
- }
-
- // initialize learning parameters
- alphadec = 30 + ((sampling_factor - 1) / 3);
- alpha = initalpha;
- radius = initradius;
-
- rad = radius >> radiusbiasshift;
- if (rad <= 1) rad = 0;
- for (i = 0; i < rad; i++)
- radpower[i] = alpha*(((rad*rad - i*i)*radbias)/(rad*rad));
-
- // initialize pseudo-random scan
- if ((lengthcount % prime1) != 0)
- step = 3*prime1;
- else {
- if ((lengthcount % prime2) != 0)
- step = 3*prime2;
- else {
- if ((lengthcount % prime3) != 0)
- step = 3*prime3;
- else
- step = 3*prime4;
- }
- }
-
- i = 0; // iteration
- pos = 0; // pixel position
-
- while (i < samplepixels) {
- // get next learning sample
- getSample(pos, &b, &g, &r);
-
- // find winning neuron
- j = contest(b, g, r);
-
- // alter winner
- altersingle(alpha, j, b, g, r);
-
- // alter neighbours
- if (rad) alterneigh(rad, j, b, g, r);
-
- // next sample
- pos += step;
- while (pos >= lengthcount) pos -= lengthcount;
-
- i++;
- if (i % delta == 0) {
- // decrease learning rate and also the neighborhood
- alpha -= alpha / alphadec;
- radius -= radius / radiusdec;
- rad = radius >> radiusbiasshift;
- if (rad <= 1) rad = 0;
- for (j = 0; j < rad; j++)
- radpower[j] = alpha * (((rad*rad - j*j) * radbias) / (rad*rad));
- }
- }
-
-}
-
-//////////////
-// Quantizer
-// -----------
-
-FIBITMAP* NNQuantizer::Quantize(FIBITMAP *dib, int ReserveSize, RGBQUAD *ReservePalette, int sampling) {
-
- if ((!dib) || (FreeImage_GetBPP(dib) != 24)) {
- return NULL;
- }
-
- // 1) Select a sampling factor in range 1..30 (input parameter 'sampling')
- // 1 => slower, 30 => faster. Default value is 1
-
-
- // 2) Get DIB parameters
-
- dib_ptr = dib;
-
- img_width = FreeImage_GetWidth(dib); // DIB width
- img_height = FreeImage_GetHeight(dib); // DIB height
- img_line = FreeImage_GetLine(dib); // DIB line length in bytes (should be equal to 3 x W)
-
- // For small images, adjust the sampling factor to avoid a 'divide by zero' error later
- // (see delta in learn() routine)
- int adjust = (img_width * img_height) / ncycles;
- if(sampling >= adjust)
- sampling = 1;
-
-
- // 3) Initialize the network and apply the learning algorithm
-
- if( netsize > ReserveSize ) {
- netsize -= ReserveSize;
- initnet();
- learn(sampling);
- unbiasnet();
- netsize += ReserveSize;
- }
-
- // 3.5) Overwrite the last few palette entries with the reserved ones
- for (int i = 0; i < ReserveSize; i++) {
- network[netsize - ReserveSize + i][FI_RGBA_BLUE] = ReservePalette[i].rgbBlue;
- network[netsize - ReserveSize + i][FI_RGBA_GREEN] = ReservePalette[i].rgbGreen;
- network[netsize - ReserveSize + i][FI_RGBA_RED] = ReservePalette[i].rgbRed;
- network[netsize - ReserveSize + i][3] = netsize - ReserveSize + i;
- }
-
- // 4) Allocate a new 8-bit DIB
-
- FIBITMAP *new_dib = FreeImage_Allocate(img_width, img_height, 8);
-
- if (new_dib == NULL)
- return NULL;
-
- // 5) Write the quantized palette
-
- RGBQUAD *new_pal = FreeImage_GetPalette(new_dib);
-
- for (int j = 0; j < netsize; j++) {
- new_pal[j].rgbBlue = (BYTE)network[j][FI_RGBA_BLUE];
- new_pal[j].rgbGreen = (BYTE)network[j][FI_RGBA_GREEN];
- new_pal[j].rgbRed = (BYTE)network[j][FI_RGBA_RED];
- }
-
- inxbuild();
-
- // 6) Write output image using inxsearch(b,g,r)
-
- for (WORD rows = 0; rows < img_height; rows++) {
- BYTE *new_bits = FreeImage_GetScanLine(new_dib, rows);
- BYTE *bits = FreeImage_GetScanLine(dib_ptr, rows);
-
- for (WORD cols = 0; cols < img_width; cols++) {
- new_bits[cols] = (BYTE)inxsearch(bits[FI_RGBA_BLUE], bits[FI_RGBA_GREEN], bits[FI_RGBA_RED]);
-
- bits += 3;
- }
- }
-
- return (FIBITMAP*) new_dib;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/PSDParser.cpp b/plugins/AdvaImg/src/FreeImage/PSDParser.cpp
deleted file mode 100644
index fba54c2421..0000000000
--- a/plugins/AdvaImg/src/FreeImage/PSDParser.cpp
+++ /dev/null
@@ -1,1057 +0,0 @@
-// ==========================================================
-// Photoshop Loader
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
-//
-// Based on LGPL code created and published by http://sourceforge.net/projects/elynx/
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "PSDParser.h"
-
-// --------------------------------------------------------------------------
-
-// PSD signature (= '8BPS')
-#define PSD_SIGNATURE 0x38425053
-// Image resource block signature (= '8BIM')
-#define PSD_RESOURCE 0x3842494D
-
-// PSD color modes
-#define PSDP_BITMAP 0
-#define PSDP_GRAYSCALE 1
-#define PSDP_INDEXED 2
-#define PSDP_RGB 3
-#define PSDP_CMYK 4
-#define PSDP_MULTICHANNEL 7
-#define PSDP_DUOTONE 8
-#define PSDP_LAB 9
-
-// PSD compression schemes
-#define PSDP_COMPRESSION_NONE 0 // Raw data
-#define PSDP_COMPRESSION_RLE 1 // RLE compression (same as TIFF packed bits)
-
-#define SAFE_DELETE_ARRAY(_p_) { if (NULL != (_p_)) { delete [] (_p_); (_p_) = NULL; } }
-
-// --------------------------------------------------------------------------
-
-static inline int
-psdGetValue(const BYTE * iprBuffer, const int iBytes) {
- int v = iprBuffer[0];
- for (int i=1; i<iBytes; ++i) {
- v = (v << 8) | iprBuffer[i];
- }
- return v;
-}
-
-// --------------------------------------------------------------------------
-
-psdHeaderInfo::psdHeaderInfo() : _Channels(-1), _Height(-1), _Width(-1), _BitsPerChannel(-1), _ColourMode(-1) {
-}
-
-psdHeaderInfo::~psdHeaderInfo() {
-}
-
-bool psdHeaderInfo::Read(FreeImageIO *io, fi_handle handle) {
- psdHeader header;
-
- const int n = (int)io->read_proc(&header, sizeof(header), 1, handle);
- if(!n) {
- return false;
- }
-
- // check the signature
- int nSignature = psdGetValue(header.Signature, sizeof(header.Signature));
- if (PSD_SIGNATURE == nSignature) {
- // check the version
- int nVersion = psdGetValue( header.Version, sizeof(header.Version) );
- if (1 == nVersion) {
- // header.Reserved must be zero
- BYTE psd_reserved[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- if(memcmp(header.Reserved, psd_reserved, 6) != 0) {
- FreeImage_OutputMessageProc(FIF_PSD, "Warning: file header reserved member is not equal to zero");
- }
- // read the header
- _Channels = (short)psdGetValue( header.Channels, sizeof(header.Channels) );
- _Height = psdGetValue( header.Rows, sizeof(header.Rows) );
- _Width = psdGetValue( header.Columns, sizeof(header.Columns) );
- _BitsPerChannel = (short)psdGetValue( header.Depth, sizeof(header.Depth) );
- _ColourMode = (short)psdGetValue( header.Mode, sizeof(header.Mode) );
-
- return true;
- }
- }
-
- return false;
-}
-
-// --------------------------------------------------------------------------
-
-psdColourModeData::psdColourModeData() : _Length(-1), _plColourData(NULL) {
-}
-
-psdColourModeData::~psdColourModeData() {
- SAFE_DELETE_ARRAY(_plColourData);
-}
-
-bool psdColourModeData::Read(FreeImageIO *io, fi_handle handle) {
- if (0 < _Length) {
- SAFE_DELETE_ARRAY(_plColourData);
- }
-
- BYTE Length[4];
- io->read_proc(&Length, sizeof(Length), 1, handle);
-
- _Length = psdGetValue( Length, sizeof(_Length) );
- if (0 < _Length) {
- _plColourData = new BYTE[_Length];
- io->read_proc(_plColourData, _Length, 1, handle);
- }
-
- return true;
-}
-
-bool psdColourModeData::FillPalette(FIBITMAP *dib) {
- RGBQUAD *pal = FreeImage_GetPalette(dib);
- if(pal) {
- for (int i = 0; i < 256; i++) {
- pal[i].rgbRed = _plColourData[i + 0*256];
- pal[i].rgbGreen = _plColourData[i + 1*256];
- pal[i].rgbBlue = _plColourData[i + 2*256];
- }
- return true;
- }
- return false;
-}
-
-// --------------------------------------------------------------------------
-
-psdImageResource::psdImageResource() : _plName (0) {
- Reset();
-}
-
-psdImageResource::~psdImageResource() {
- SAFE_DELETE_ARRAY(_plName);
-}
-
-void psdImageResource::Reset() {
- _Length = -1;
- memset( _OSType, '\0', sizeof(_OSType) );
- _ID = -1;
- SAFE_DELETE_ARRAY(_plName);
- _Size = -1;
-}
-
-// --------------------------------------------------------------------------
-
-psdResolutionInfo::psdResolutionInfo() : _widthUnit(-1), _heightUnit(-1), _hRes(-1), _vRes(-1), _hResUnit(-1), _vResUnit(-1) {
-}
-
-psdResolutionInfo::~psdResolutionInfo() {
-}
-
-int psdResolutionInfo::Read(FreeImageIO *io, fi_handle handle) {
- BYTE IntValue[4], ShortValue[2];
- int nBytes=0, n;
-
- // Horizontal resolution in pixels per inch.
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _hRes = (short)psdGetValue(ShortValue, sizeof(_hRes) );
- // 1=display horizontal resolution in pixels per inch; 2=display horizontal resolution in pixels per cm.
- n = (int)io->read_proc(&IntValue, sizeof(IntValue), 1, handle);
- nBytes += n * sizeof(IntValue);
- _hResUnit = psdGetValue(IntValue, sizeof(_hResUnit) );
- // Display width as 1=inches; 2=cm; 3=points; 4=picas; 5=columns.
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _widthUnit = (short)psdGetValue(ShortValue, sizeof(_widthUnit) );
- // Vertical resolution in pixels per inch.
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _vRes = (short)psdGetValue(ShortValue, sizeof(_vRes) );
- // 1=display vertical resolution in pixels per inch; 2=display vertical resolution in pixels per cm.
- n = (int)io->read_proc(&IntValue, sizeof(IntValue), 1, handle);
- nBytes += n * sizeof(IntValue);
- _vResUnit = psdGetValue(IntValue, sizeof(_vResUnit) );
- // Display height as 1=inches; 2=cm; 3=points; 4=picas; 5=columns.
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _heightUnit = (short)psdGetValue(ShortValue, sizeof(_heightUnit) );
-
- return nBytes;
-}
-
-void psdResolutionInfo::GetResolutionInfo(unsigned &res_x, unsigned &res_y) {
- if(_hResUnit == 1) {
- // convert pixels / inch to pixel / m
- res_x = (unsigned) (_hRes / 0.0254000 + 0.5);
- } else if(_hResUnit == 2) {
- // convert pixels / cm to pixel / m
- res_x = (unsigned) (_hRes * 100.0 + 0.5);
- }
- if(_vResUnit == 1) {
- // convert pixels / inch to pixel / m
- res_y = (unsigned) (_vRes / 0.0254000 + 0.5);
- } else if(_vResUnit == 2) {
- // convert pixels / cm to pixel / m
- res_y = (unsigned) (_vRes * 100.0 + 0.5);
- }
-}
-
-// --------------------------------------------------------------------------
-
-psdResolutionInfo_v2::psdResolutionInfo_v2() {
- _Channels = _Rows = _Columns = _Depth = _Mode = -1;
-}
-
-psdResolutionInfo_v2::~psdResolutionInfo_v2() {
-}
-
-int psdResolutionInfo_v2::Read(FreeImageIO *io, fi_handle handle) {
- BYTE ShortValue[2];
- int nBytes=0, n;
-
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _Channels = (short)psdGetValue(ShortValue, sizeof(_Channels) );
-
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _Rows = (short)psdGetValue(ShortValue, sizeof(_Rows) );
-
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _Columns = (short)psdGetValue(ShortValue, sizeof(_Columns) );
-
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _Depth = (short)psdGetValue(ShortValue, sizeof(_Depth) );
-
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _Mode = (short)psdGetValue(ShortValue, sizeof(_Mode) );
-
- return nBytes;
-}
-
-// --------------------------------------------------------------------------
-
-psdDisplayInfo::psdDisplayInfo() {
- _Opacity = _ColourSpace = -1;
- for (unsigned n = 0; n < 4; ++n) {
- _Colour[n] = 0;
- }
- _Kind = 0;
- _padding = '0';
-}
-
-psdDisplayInfo::~psdDisplayInfo() {
-}
-
-int psdDisplayInfo::Read(FreeImageIO *io, fi_handle handle) {
- BYTE ShortValue[2];
- int nBytes=0, n;
-
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _ColourSpace = (short)psdGetValue(ShortValue, sizeof(_ColourSpace) );
-
- for (unsigned i = 0; i < 4; ++i) {
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _Colour[i] = (short)psdGetValue(ShortValue, sizeof(_Colour[i]) );
- }
-
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _Opacity = (short)psdGetValue(ShortValue, sizeof(_Opacity) );
- if((_Opacity < 0) || (_Opacity > 100)) {
- throw "Invalid DisplayInfo::Opacity value";
- }
-
- BYTE c[1];
- n = (int)io->read_proc(&c, sizeof(c), 1, handle);
- nBytes += n * sizeof(c);
- _Kind = (BYTE)psdGetValue(c, sizeof(c));
-
- n = (int)io->read_proc(&c, sizeof(c), 1, handle);
- nBytes += n * sizeof(c);
- _padding = (BYTE)psdGetValue(c, sizeof(c));
- if(_padding != 0) {
- throw "Invalid DisplayInfo::Padding value";
- }
-
- return nBytes;
-}
-
-// --------------------------------------------------------------------------
-
-psdThumbnail::psdThumbnail() :
-_Format(-1), _Width(-1), _Height(-1), _WidthBytes(-1), _Size(-1), _CompressedSize(-1), _BitPerPixel(-1), _Planes(-1), _dib(NULL) {
-}
-
-psdThumbnail::~psdThumbnail() {
- FreeImage_Unload(_dib);
-}
-
-int psdThumbnail::Read(FreeImageIO *io, fi_handle handle, int iResourceSize, bool isBGR) {
- BYTE ShortValue[2], IntValue[4];
- int nBytes=0, n;
-
- // remove the header size (28 bytes) from the total data size
- int iTotalData = iResourceSize - 28;
-
- const long block_end = io->tell_proc(handle) + iTotalData;
-
- n = (int)io->read_proc(&IntValue, sizeof(IntValue), 1, handle);
- nBytes += n * sizeof(IntValue);
- _Format = psdGetValue(IntValue, sizeof(_Format) );
-
- n = (int)io->read_proc(&IntValue, sizeof(IntValue), 1, handle);
- nBytes += n * sizeof(IntValue);
- _Width = psdGetValue(IntValue, sizeof(_Width) );
-
- n = (int)io->read_proc(&IntValue, sizeof(IntValue), 1, handle);
- nBytes += n * sizeof(IntValue);
- _Height = psdGetValue(IntValue, sizeof(_Height) );
-
- n = (int)io->read_proc(&IntValue, sizeof(IntValue), 1, handle);
- nBytes += n * sizeof(IntValue);
- _WidthBytes = psdGetValue(IntValue, sizeof(_WidthBytes) );
-
- n = (int)io->read_proc(&IntValue, sizeof(IntValue), 1, handle);
- nBytes += n * sizeof(IntValue);
- _Size = psdGetValue(IntValue, sizeof(_Size) );
-
- n = (int)io->read_proc(&IntValue, sizeof(IntValue), 1, handle);
- nBytes += n * sizeof(IntValue);
- _CompressedSize = psdGetValue(IntValue, sizeof(_CompressedSize) );
-
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _BitPerPixel = (short)psdGetValue(ShortValue, sizeof(_BitPerPixel) );
-
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _Planes = (short)psdGetValue(ShortValue, sizeof(_Planes) );
-
- const long JFIF_startpos = io->tell_proc(handle);
-
- if(_dib) {
- FreeImage_Unload(_dib);
- }
-
- if(_Format == 1) {
- // kJpegRGB thumbnail image
- _dib = FreeImage_LoadFromHandle(FIF_JPEG, io, handle);
- if(isBGR) {
- SwapRedBlue32(_dib);
- }
- // HACK: manually go to end of thumbnail, because (for some reason) LoadFromHandle consumes more bytes then available!
- io->seek_proc(handle, block_end, SEEK_SET);
- }
- else {
- // kRawRGB thumbnail image
- // ### Unimplemented (should be trivial)
-
- // skip the thumbnail part
- io->seek_proc(handle, iTotalData, SEEK_CUR);
- return iResourceSize;
- }
-
- nBytes += (block_end - JFIF_startpos);
-
- return nBytes;
-}
-
-//---------------------------------------------------------------------------
-
-psdICCProfile::psdICCProfile() : _ProfileSize(0), _ProfileData(NULL) {
-}
-
-psdICCProfile::~psdICCProfile() {
- clear();
-}
-
-void psdICCProfile::clear() { SAFE_DELETE_ARRAY(_ProfileData); _ProfileSize = 0;}
-
-int psdICCProfile::Read(FreeImageIO *io, fi_handle handle, int size) {
- int nBytes = 0, n;
-
- clear();
-
- _ProfileData = new (std::nothrow) BYTE[size];
- if(NULL != _ProfileData) {
- n = (int)io->read_proc(_ProfileData, 1, size, handle);
- _ProfileSize = size;
- nBytes += n * sizeof(BYTE);
- }
-
- return nBytes;
-}
-
-//---------------------------------------------------------------------------
-
-/**
-Invert only color components, skipping Alpha/Black
-(Can be useful as public/utility function)
-*/
-static
-BOOL invertColor(FIBITMAP* dib) {
- FREE_IMAGE_TYPE type = FreeImage_GetImageType(dib);
- const unsigned Bpp = FreeImage_GetBPP(dib)/8;
-
- if((type == FIT_BITMAP && Bpp == 4) || type == FIT_RGBA16) {
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
- BYTE *line_start = FreeImage_GetScanLine(dib, 0);
- const unsigned pitch = FreeImage_GetPitch(dib);
- const unsigned triBpp = Bpp - (Bpp == 4 ? 1 : 2);
-
- for(unsigned y = 0; y < height; y++) {
- BYTE *line = line_start;
-
- for(unsigned x = 0; x < width; x++) {
- for(unsigned b=0; b < triBpp; ++b) {
- line[b] = ~line[b];
- }
-
- line += Bpp;
- }
- line_start += pitch;
- }
-
- return TRUE;
- }
- else {
- return FreeImage_Invert(dib);
- }
-}
-
-//---------------------------------------------------------------------------
-
-psdParser::psdParser() {
- _bThumbnailFilled = false;
- _bDisplayInfoFilled = false;
- _bResolutionInfoFilled = false;
- _bResolutionInfoFilled_v2 = false;
- _bCopyright = false;
- _GlobalAngle = 30;
- _ColourCount = -1;
- _TransparentIndex = -1;
- _fi_flags = 0;
- _fi_format_id = FIF_UNKNOWN;
-}
-
-psdParser::~psdParser() {
-}
-
-bool psdParser::ReadLayerAndMaskInfoSection(FreeImageIO *io, fi_handle handle) {
- bool bSuccess = false;
-
- BYTE DataLength[4];
- int nBytes = 0;
- int n = (int)io->read_proc(&DataLength, sizeof(DataLength), 1, handle);
- int nTotalBytes = psdGetValue( DataLength, sizeof(DataLength) );
-
- BYTE data[1];
- while( n && ( nBytes < nTotalBytes ) ) {
- data[0] = '\0';
- n = (int)io->read_proc(&data, sizeof(data), 1, handle);
- nBytes += n * sizeof(data);
- }
-
- if ( nBytes == nTotalBytes ) {
- bSuccess = true;
- }
-
- return bSuccess;
-}
-
-bool psdParser::ReadImageResources(FreeImageIO *io, fi_handle handle, LONG length) {
- psdImageResource oResource;
- bool bSuccess = false;
-
- if(length > 0) {
- oResource._Length = length;
- } else {
- BYTE Length[4];
- int n = (int)io->read_proc(&Length, sizeof(Length), 1, handle);
-
- oResource._Length = psdGetValue( Length, sizeof(oResource._Length) );
- }
-
- int nBytes = 0;
- int nTotalBytes = oResource._Length;
-
- while(nBytes < nTotalBytes) {
- int n = 0;
- oResource.Reset();
-
- n = (int)io->read_proc(&oResource._OSType, sizeof(oResource._OSType), 1, handle);
- if(n != 1) {
- FreeImage_OutputMessageProc(_fi_format_id, "This file contains damaged data causing an unexpected end-of-file - stop reading resources");
- return false;
- }
- nBytes += n * sizeof(oResource._OSType);
-
- if( (nBytes % 2) != 0 ) {
- return false;
- }
-
- int nOSType = psdGetValue((BYTE*)&oResource._OSType, sizeof(oResource._OSType));
-
- if ( PSD_RESOURCE == nOSType ) {
- BYTE ID[2];
- n = (int)io->read_proc(&ID, sizeof(ID), 1, handle);
- nBytes += n * sizeof(ID);
-
- oResource._ID = (short)psdGetValue( ID, sizeof(ID) );
-
- BYTE SizeOfName;
- n = (int)io->read_proc(&SizeOfName, sizeof(SizeOfName), 1, handle);
- nBytes += n * sizeof(SizeOfName);
-
- int nSizeOfName = psdGetValue( &SizeOfName, sizeof(SizeOfName) );
- if ( 0 < nSizeOfName ) {
- oResource._plName = new BYTE[nSizeOfName];
- n = (int)io->read_proc(oResource._plName, nSizeOfName, 1, handle);
- nBytes += n * nSizeOfName;
- }
-
- if ( 0 == (nSizeOfName % 2) ) {
- n = (int)io->read_proc(&SizeOfName, sizeof(SizeOfName), 1, handle);
- nBytes += n * sizeof(SizeOfName);
- }
-
- BYTE Size[4];
- n = (int)io->read_proc(&Size, sizeof(Size), 1, handle);
- nBytes += n * sizeof(Size);
-
- oResource._Size = psdGetValue( Size, sizeof(oResource._Size) );
-
- if ( 0 != (oResource._Size % 2) ) {
- // resource data must be even
- oResource._Size++;
- }
- if ( 0 < oResource._Size ) {
- BYTE IntValue[4];
- BYTE ShortValue[2];
-
- switch( oResource._ID ) {
- case 1000:
- // Obsolete - Photoshop 2.0
- _bResolutionInfoFilled_v2 = true;
- nBytes += _resolutionInfo_v2.Read(io, handle);
- break;
-
- // ResolutionInfo structure
- case 1005:
- _bResolutionInfoFilled = true;
- nBytes += _resolutionInfo.Read(io, handle);
- break;
-
- // DisplayInfo structure
- case 1007:
- _bDisplayInfoFilled = true;
- nBytes += _displayInfo.Read(io, handle);
- break;
-
- // (Photoshop 4.0) Copyright flag
- // Boolean indicating whether image is copyrighted. Can be set via Property suite or by user in File Info...
- case 1034:
- n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
- nBytes += n * sizeof(ShortValue);
- _bCopyright = (1 == psdGetValue(ShortValue, sizeof(ShortValue)));
- break;
-
- // (Photoshop 4.0) Thumbnail resource for Photoshop 4.0 only
- case 1033:
- // (Photoshop 5.0) Thumbnail resource (supersedes resource 1033)
- case 1036:
- {
- _bThumbnailFilled = true;
- bool bBGR = (1033==oResource._ID);
- nBytes += _thumbnail.Read(io, handle, oResource._Size, bBGR);
- break;
- }
-
- // (Photoshop 5.0) Global Angle
- // 4 bytes that contain an integer between 0 and 359, which is the global
- // lighting angle for effects layer. If not present, assumed to be 30.
- case 1037:
- n = (int)io->read_proc(&IntValue, sizeof(IntValue), 1, handle);
- nBytes += n * sizeof(IntValue);
- _GlobalAngle = psdGetValue(IntValue, sizeof(_GlobalAngle) );
- break;
-
- // ICC profile
- case 1039:
- nBytes += _iccProfile.Read(io, handle, oResource._Size);
- break;
-
- // (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);
- io->seek_proc(handle, skip_length, SEEK_CUR);
- nBytes += skip_length;
- }
- break;
- }
- }
- }
- }
-
- if (nBytes == nTotalBytes) {
- bSuccess = true;
- }
-
- return bSuccess;
-
-}
-
-FIBITMAP* psdParser::ReadImageData(FreeImageIO *io, fi_handle handle) {
- if(handle == NULL)
- return NULL;
-
- bool header_only = (_fi_flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
-
- WORD nCompression = 0;
- io->read_proc(&nCompression, sizeof(nCompression), 1, handle);
-
-#ifndef FREEIMAGE_BIGENDIAN
- SwapShort(&nCompression);
-#endif
-
- if((nCompression != PSDP_COMPRESSION_NONE && nCompression != PSDP_COMPRESSION_RLE)) {
- FreeImage_OutputMessageProc(_fi_format_id, "Unsupported compression %d", nCompression);
- return NULL;
- }
-
- const unsigned nWidth = _headerInfo._Width;
- const unsigned nHeight = _headerInfo._Height;
- const unsigned nChannels = _headerInfo._Channels;
- const unsigned depth = _headerInfo._BitsPerChannel;
- const unsigned bytes = (depth == 1) ? 1 : depth / 8;
-
- // channel(plane) line (BYTE aligned)
- const unsigned lineSize = (_headerInfo._BitsPerChannel == 1) ? (nWidth + 7) / 8 : nWidth * bytes;
-
- if(nCompression == PSDP_COMPRESSION_RLE && depth > 16) {
- FreeImage_OutputMessageProc(_fi_format_id, "Unsupported RLE with depth %d", depth);
- return NULL;
- }
-
- // build output buffer
-
- FIBITMAP* bitmap = NULL;
- unsigned dstCh = 0;
-
- short mode = _headerInfo._ColourMode;
-
- if(mode == PSDP_MULTICHANNEL && nChannels < 3) {
- // CM
- mode = PSDP_GRAYSCALE; // C as gray, M as extra channel
- }
-
- bool needPalette = false;
- switch (mode) {
- case PSDP_BITMAP:
- case PSDP_DUOTONE:
- case PSDP_INDEXED:
- case PSDP_GRAYSCALE:
- dstCh = 1;
- switch(depth) {
- case 16:
- bitmap = FreeImage_AllocateHeaderT(header_only, FIT_UINT16, nWidth, nHeight, depth*dstCh);
- break;
- case 32:
- bitmap = FreeImage_AllocateHeaderT(header_only, FIT_FLOAT, nWidth, nHeight, depth*dstCh);
- break;
- default: // 1-, 8-
- needPalette = true;
- bitmap = FreeImage_AllocateHeader(header_only, nWidth, nHeight, depth*dstCh);
- break;
- }
- break;
- case PSDP_RGB:
- case PSDP_LAB:
- case PSDP_CMYK :
- case PSDP_MULTICHANNEL :
- // force PSDP_MULTICHANNEL CMY as CMYK
- dstCh = (mode == PSDP_MULTICHANNEL && !header_only) ? 4 : MIN<unsigned>(nChannels, 4);
- if(dstCh < 3) {
- throw "Invalid number of channels";
- }
-
- switch(depth) {
- case 16:
- bitmap = FreeImage_AllocateHeaderT(header_only, dstCh < 4 ? FIT_RGB16 : FIT_RGBA16, nWidth, nHeight, depth*dstCh);
- break;
- case 32:
- bitmap = FreeImage_AllocateHeaderT(header_only, dstCh < 4 ? FIT_RGBF : FIT_RGBAF, nWidth, nHeight, depth*dstCh);
- break;
- default:
- bitmap = FreeImage_AllocateHeader(header_only, nWidth, nHeight, depth*dstCh);
- break;
- }
- break;
- default:
- throw "Unsupported color mode";
- break;
- }
- if(!bitmap) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // write thumbnail
- FreeImage_SetThumbnail(bitmap, _thumbnail.getDib());
-
- // @todo Add some metadata model
-
- if(header_only) {
- return bitmap;
- }
-
- // Load pixels data
-
- const unsigned dstChannels = dstCh;
-
- const unsigned dstBpp = (depth == 1) ? 1 : FreeImage_GetBPP(bitmap)/8;
- const unsigned dstLineSize = FreeImage_GetPitch(bitmap);
- BYTE* const dst_first_line = FreeImage_GetScanLine(bitmap, nHeight - 1);//<*** flipped
-
- BYTE* line_start = new BYTE[lineSize]; //< fileline cache
-
- switch ( nCompression ) {
- case PSDP_COMPRESSION_NONE: // raw data
- {
- for(unsigned c = 0; c < nChannels; c++) {
- if(c >= dstChannels) {
- // @todo write extra channels
- break;
- }
-
- const unsigned channelOffset = c * bytes;
-
- BYTE* dst_line_start = dst_first_line;
- for(unsigned h = 0; h < nHeight; ++h, dst_line_start -= dstLineSize) {//<*** flipped
-
- io->read_proc(line_start, lineSize, 1, handle);
-
- for (BYTE *line = line_start, *dst_line = dst_line_start; line < line_start + lineSize;
- line += bytes, dst_line += dstBpp) {
-#ifdef FREEIMAGE_BIGENDIAN
- memcpy(dst_line + channelOffset, line, bytes);
-#else
- // reverse copy bytes
- for (unsigned b = 0; b < bytes; ++b) {
- dst_line[channelOffset + b] = line[(bytes-1) - b];
- }
-#endif // FREEIMAGE_BIGENDIAN
- }
- } //< h
- }//< ch
-
- SAFE_DELETE_ARRAY(line_start);
-
- }
- break;
-
- case PSDP_COMPRESSION_RLE: // RLE compression
- {
-
- // The RLE-compressed data is preceeded by a 2-byte line size for each row in the data,
- // store an array of these
-
- // later use this array as WORD rleLineSizeList[nChannels][nHeight];
- WORD *rleLineSizeList = new (std::nothrow) WORD[nChannels*nHeight];
-
- if(!rleLineSizeList) {
- FreeImage_Unload(bitmap);
- SAFE_DELETE_ARRAY(line_start);
- throw std::bad_alloc();
- }
-
- io->read_proc(rleLineSizeList, 2, nChannels * nHeight, handle);
-
- WORD largestRLELine = 0;
- for(unsigned ch = 0; ch < nChannels; ++ch) {
- for(unsigned h = 0; h < nHeight; ++h) {
- const unsigned index = ch * nHeight + h;
-
-#ifndef FREEIMAGE_BIGENDIAN
- SwapShort(&rleLineSizeList[index]);
-#endif
- if(largestRLELine < rleLineSizeList[index]) {
- largestRLELine = rleLineSizeList[index];
- }
- }
- }
-
- BYTE* rle_line_start = new (std::nothrow) BYTE[largestRLELine];
- if(!rle_line_start) {
- FreeImage_Unload(bitmap);
- SAFE_DELETE_ARRAY(line_start);
- SAFE_DELETE_ARRAY(rleLineSizeList);
- throw std::bad_alloc();
- }
-
- // Read the RLE data (assume 8-bit)
-
- const BYTE* const line_end = line_start + lineSize;
-
- for (unsigned ch = 0; ch < nChannels; ch++) {
- const unsigned channelOffset = ch * bytes;
-
- BYTE* dst_line_start = dst_first_line;
- for(unsigned h = 0; h < nHeight; ++h, dst_line_start -= dstLineSize) {//<*** flipped
- const unsigned index = ch * nHeight + h;
-
- // - read and uncompress line -
-
- const WORD rleLineSize = rleLineSizeList[index];
-
- io->read_proc(rle_line_start, rleLineSize, 1, handle);
-
- for (BYTE* rle_line = rle_line_start, *line = line_start;
- rle_line < rle_line_start + rleLineSize, line < line_end;) {
-
- int len = *rle_line++;
-
- // NOTE len is signed byte in PackBits RLE
-
- if ( len < 128 ) { //<- MSB is not set
- // uncompressed packet
-
- // (len + 1) bytes of data are copied
-
- ++len;
-
- // assert we don't write beyound eol
- memcpy(line, rle_line, line + len > line_end ? line_end - line : len);
- line += len;
- rle_line += len;
- }
- else if ( len > 128 ) { //< MSB is set
-
- // RLE compressed packet
-
- // One byte of data is repeated (–len + 1) times
-
- len ^= 0xFF; // same as (-len + 1) & 0xFF
- len += 2; //
-
- // assert we don't write beyound eol
- memset(line, *rle_line++, line + len > line_end ? line_end - line : len);
- line += len;
-
- }
- else if ( 128 == len ) {
- // Do nothing
- }
- }//< rle_line
-
- // - write line to destination -
-
- if(ch >= dstChannels) {
- // @todo write to extra channels
- break;
- }
-
- // byte by byte copy a single channel to pixel
- for (BYTE *line = line_start, *dst_line = dst_line_start; line < line_start + lineSize;
- line += bytes, dst_line += dstBpp) {
-
-#ifdef FREEIMAGE_BIGENDIAN
- memcpy(dst_line + channelOffset, line, bytes);
-#else
- // reverse copy bytes
- for (unsigned b = 0; b < bytes; ++b) {
- dst_line[channelOffset + b] = line[(bytes-1) - b];
- }
-#endif // FREEIMAGE_BIGENDIAN
- }
- }//< h
- }//< ch
-
- SAFE_DELETE_ARRAY(line_start);
- SAFE_DELETE_ARRAY(rleLineSizeList);
- SAFE_DELETE_ARRAY(rle_line_start);
- }
- break;
-
- case 2: // ZIP without prediction, no specification
- break;
-
- case 3: // ZIP with prediction, no specification
- break;
-
- default: // Unknown format
- break;
-
- }
-
- // --- Further process the bitmap ---
-
- if((mode == PSDP_CMYK || mode == PSDP_MULTICHANNEL)) {
- // CMYK values are "inverted", invert them back
-
- if(mode == PSDP_MULTICHANNEL) {
- invertColor(bitmap);
- } else {
- FreeImage_Invert(bitmap);
- }
-
- if((_fi_flags & PSD_CMYK) == PSD_CMYK) {
- // keep as CMYK
-
- if(mode == PSDP_MULTICHANNEL) {
- //### we force CMY to be CMYK, but CMY has no ICC.
- // Create empty profile and add the flag.
- FreeImage_CreateICCProfile(bitmap, NULL, 0);
- FreeImage_GetICCProfile(bitmap)->flags |= FIICC_COLOR_IS_CMYK;
- }
- }
- else {
- // convert to RGB
-
- ConvertCMYKtoRGBA(bitmap);
-
- // The ICC Profile is no longer valid
- _iccProfile.clear();
-
- // remove the pending A if not present in source
- if(nChannels == 4 || nChannels == 3 ) {
- FIBITMAP* t = RemoveAlphaChannel(bitmap);
- if(t) {
- FreeImage_Unload(bitmap);
- bitmap = t;
- } // else: silently fail
- }
- }
- }
- else if ( mode == PSDP_LAB && !((_fi_flags & PSD_LAB) == PSD_LAB)) {
- ConvertLABtoRGB(bitmap);
- }
- else {
- if (needPalette && FreeImage_GetPalette(bitmap)) {
-
- if(mode == PSDP_BITMAP) {
- CREATE_GREYSCALE_PALETTE_REVERSE(FreeImage_GetPalette(bitmap), 2);
- }
- else if(mode == PSDP_INDEXED) {
- if(!_colourModeData._plColourData || _colourModeData._Length != 768 || _ColourCount < 0) {
- FreeImage_OutputMessageProc(_fi_format_id, "Indexed image has no palette. Using the default grayscale one.");
- } else {
- _colourModeData.FillPalette(bitmap);
- }
- }
- // GRAYSCALE, DUOTONE - use default grayscale palette
- }
-
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
- if(FreeImage_GetImageType(bitmap) == FIT_BITMAP) {
- SwapRedBlue32(bitmap);
- }
-#endif
- }
-
- return bitmap;
-}
-
-FIBITMAP* psdParser::Load(FreeImageIO *io, fi_handle handle, int s_format_id, int flags) {
- FIBITMAP *Bitmap = NULL;
-
- _fi_flags = flags;
- _fi_format_id = s_format_id;
-
- try {
- if (NULL == handle) {
- throw("Cannot open file");
- }
-
- if (!_headerInfo.Read(io, handle)) {
- throw("Error in header");
- }
-
- if (!_colourModeData.Read(io, handle)) {
- throw("Error in ColourMode Data");
- }
-
- if (!ReadImageResources(io, handle)) {
- throw("Error in Image Resource");
- }
-
- if (!ReadLayerAndMaskInfoSection(io, handle)) {
- throw("Error in Mask Info");
- }
-
- Bitmap = ReadImageData(io, handle);
- if (NULL == Bitmap) {
- throw("Error in Image Data");
- }
-
- // set resolution info
- if(NULL != Bitmap) {
- unsigned res_x = 2835; // 72 dpi
- unsigned res_y = 2835; // 72 dpi
- if (_bResolutionInfoFilled) {
- _resolutionInfo.GetResolutionInfo(res_x, res_y);
- }
- FreeImage_SetDotsPerMeterX(Bitmap, res_x);
- FreeImage_SetDotsPerMeterY(Bitmap, res_y);
- }
-
- // set ICC profile
- FreeImage_CreateICCProfile(Bitmap, _iccProfile._ProfileData, _iccProfile._ProfileSize);
- if ((flags & PSD_CMYK) == PSD_CMYK) {
- short mode = _headerInfo._ColourMode;
- if((mode == PSDP_CMYK) || (mode == PSDP_MULTICHANNEL)) {
- FreeImage_GetICCProfile(Bitmap)->flags |= FIICC_COLOR_IS_CMYK;
- }
- }
-
- } catch(const char *text) {
- FreeImage_OutputMessageProc(s_format_id, text);
- }
- catch(const std::exception& e) {
- FreeImage_OutputMessageProc(s_format_id, "%s", e.what());
- }
-
- return Bitmap;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/PSDParser.h b/plugins/AdvaImg/src/FreeImage/PSDParser.h
deleted file mode 100644
index 15ab5425ca..0000000000
--- a/plugins/AdvaImg/src/FreeImage/PSDParser.h
+++ /dev/null
@@ -1,271 +0,0 @@
-// ==========================================================
-// Photoshop Loader
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-// - Mihail Naydenov (mnaydenov@users.sourceforge.net)
-//
-// Based on LGPL code created and published by http://sourceforge.net/projects/elynx/
-//
-// 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!
-// ==========================================================
-
-#ifndef PSDPARSER_H
-#define PSDPARSER_H
-
-/**
-Table 2-12: File header section.
-The file header contains the basic properties of the image.
-*/
-typedef struct psdHeader {
- BYTE Signature[4]; //! Always equal 8BPS, do not try to read the file if the signature does not match this value.
- BYTE Version[2]; //! Always equal 1, do not read file if the version does not match this value.
- char Reserved[6]; //! Must be zero.
- BYTE Channels[2]; //! Number of channels including any alpha channels, supported range is 1 to 24.
- BYTE Rows[4]; //! The height of the image in pixels. Supported range is 1 to 30,000.
- BYTE Columns[4]; //! The width of the image in pixels. Supported range is 1 to 30,000.
- BYTE Depth[2]; //! The number of bits per channel. Supported values are 1, 8, and 16.
- BYTE Mode[2]; //! Colour mode of the file, Bitmap=0, Grayscale=1, Indexed=2, RGB=3, CMYK=4, Multichannel=7, Duotone=8, Lab=9.
-} psdHeader;
-
-/**
-Table 2-12: HeaderInfo Color spaces
-@see psdHeader
-*/
-class psdHeaderInfo {
-public:
- short _Channels; //! Numer of channels including any alpha channels, supported range is 1 to 24.
- int _Height; //! The height of the image in pixels. Supported range is 1 to 30,000.
- int _Width; //! The width of the image in pixels. Supported range is 1 to 30,000.
- short _BitsPerChannel;//! The number of bits per channel. Supported values are 1, 8, and 16.
- short _ColourMode; //! Colour mode of the file, Bitmap=0, Grayscale=1, Indexed=2, RGB=3, CMYK=4, Multichannel=7, Duotone=8, Lab=9.
-
-public:
- psdHeaderInfo();
- ~psdHeaderInfo();
- /**
- @return Returns the number of bytes read
- */
- bool Read(FreeImageIO *io, fi_handle handle);
-};
-
-/**
-Table 2-13 Color mode data section
-
-Only indexed color and duotone have color mode data. For all other modes,
-this section is just 4 bytes: the length field, which is set to zero.
-For indexed color images, the length will be equal to 768, and the color data
-will contain the color table for the image, in non-interleaved order.
-For duotone images, the color data will contain the duotone specification,
-the format of which is not documented. Other applications that read
-Photoshop files can treat a duotone image as a grayscale image, and just
-preserve the contents of the duotone information when reading and writing
-the file.
-*/
-class psdColourModeData {
-public:
- int _Length; //! The length of the following color data
- BYTE * _plColourData; //! The color data
-
-public:
- psdColourModeData();
- ~psdColourModeData();
- /**
- @return Returns the number of bytes read
- */
- bool Read(FreeImageIO *io, fi_handle handle);
- bool FillPalette(FIBITMAP *dib);
-};
-
-/**
-Table 2-1: Image resource block
-NB: Resource data is padded to make size even
-*/
-class psdImageResource {
-public:
- int _Length;
- char _OSType[4]; //! Photoshop always uses its signature, 8BIM
- short _ID; //! Unique identifier. Image resource IDs on page 8
- BYTE * _plName; //! A pascal string, padded to make size even (a null name consists of two bytes of 0)
- int _Size; //! Actual size of resource data. This does not include the Type, ID, Name or Size fields.
-
-public:
- psdImageResource();
- ~psdImageResource();
- void Reset();
-};
-
-/**
-Table A-6: ResolutionInfo structure
-This structure contains information about the resolution of an image. It is
-written as an image resource. See the Document file formats chapter for more
-details.
-*/
-class psdResolutionInfo {
-public:
- short _widthUnit; //! Display width as 1=inches; 2=cm; 3=points; 4=picas; 5=columns.
- short _heightUnit; //! Display height as 1=inches; 2=cm; 3=points; 4=picas; 5=columns.
- short _hRes; //! Horizontal resolution in pixels per inch.
- short _vRes; //! Vertical resolution in pixels per inch.
- int _hResUnit; //! 1=display horizontal resolution in pixels per inch; 2=display horizontal resolution in pixels per cm.
- int _vResUnit; //! 1=display vertical resolution in pixels per inch; 2=display vertical resolution in pixels per cm.
-
-public:
- psdResolutionInfo();
- ~psdResolutionInfo();
- /**
- @return Returns the number of bytes read
- */
- int Read(FreeImageIO *io, fi_handle handle);
- /**
- @param res_x [out] X resolution in pixels/meter
- @param res_y [out] Y resolution in pixels/meter
- */
- void GetResolutionInfo(unsigned &res_x, unsigned &res_y);
-};
-
-// Obsolete - Photoshop 2.0
-class psdResolutionInfo_v2 {
-public:
- short _Channels;
- short _Rows;
- short _Columns;
- short _Depth;
- short _Mode;
-
-public:
- psdResolutionInfo_v2();
- ~psdResolutionInfo_v2();
- /**
- @return Returns the number of bytes read
- */
- int Read(FreeImageIO *io, fi_handle handle);
-};
-
-/**
-Table A-7: DisplayInfo Color spaces
-This structure contains display information about each channel. It is written as an image resource.
-*/
-class psdDisplayInfo {
-public:
- short _ColourSpace;
- short _Colour[4];
- short _Opacity; //! 0..100
- BYTE _Kind; //! selected = 0, protected = 1
- BYTE _padding; //! should be zero
-
-public:
- psdDisplayInfo();
- ~psdDisplayInfo();
- /**
- @return Returns the number of bytes read
- */
- int Read(FreeImageIO *io, fi_handle handle);
-};
-
-/**
-Table 2-5: Thumbnail resource header
-Adobe Photoshop 5.0 and later stores thumbnail information for preview
-display in an image resource block. These resource blocks consist of an initial
-28 byte header, followed by a JFIF thumbnail in RGB (red, green, blue) order
-for both Macintosh and Windows. Adobe Photoshop 4.0 stored the
-thumbnail information in the same format except the data section is BGR
-(blue, green, red). The Adobe Photoshop 4.0 format is at resource ID 1033
-and the Adobe Photoshop 5.0 format is at resource ID 1036.
-*/
-class psdThumbnail {
-public:
- int _Format; //! = 1 (kJpegRGB). Also supports kRawRGB (0).
- int _Width; //! Width of thumbnail in pixels.
- int _Height; //! Height of thumbnail in pixels.
- int _WidthBytes; //! Padded row bytes as (width * bitspixel + 31) / 32 * 4.
- int _Size; //! Total size as widthbytes * height * planes
- int _CompressedSize; //! Size after compression. Used for consistentcy check.
- short _BitPerPixel; //! = 24. Bits per pixel.
- short _Planes; //! = 1. Number of planes.
- FIBITMAP * _dib; //! JFIF data as uncompressed dib. Note: For resource ID 1033 the data is in BGR format.
-
-public:
- psdThumbnail();
- ~psdThumbnail();
- FIBITMAP* getDib() { return _dib; }
- /**
- @return Returns the number of bytes read
- */
- int Read(FreeImageIO *io, fi_handle handle, int iResourceSize, bool isBGR);
-
-private:
- psdThumbnail(const psdThumbnail&);
- psdThumbnail& operator=(const psdThumbnail&);
-};
-
-class psdICCProfile {
-public:
- int _ProfileSize;
- BYTE * _ProfileData;
-public:
- psdICCProfile();
- ~psdICCProfile();
- void clear();
- /**
- @return Returns the number of bytes read
- */
- int Read(FreeImageIO *io, fi_handle handle, int size);
-};
-
-/**
-PSD loader
-*/
-class psdParser {
-private:
- psdHeaderInfo _headerInfo;
- psdColourModeData _colourModeData;
- psdResolutionInfo _resolutionInfo;
- psdResolutionInfo_v2 _resolutionInfo_v2;
- psdDisplayInfo _displayInfo;
- psdThumbnail _thumbnail;
- psdICCProfile _iccProfile;
-
- short _ColourCount;
- short _TransparentIndex;
- int _GlobalAngle;
- bool _bResolutionInfoFilled;
- bool _bResolutionInfoFilled_v2;
- bool _bDisplayInfoFilled;
- bool _bThumbnailFilled;
- bool _bCopyright;
-
- int _fi_flags;
- int _fi_format_id;
-
-private:
- /** Actually ignore it */
- bool ReadLayerAndMaskInfoSection(FreeImageIO *io, fi_handle handle);
- FIBITMAP* ReadImageData(FreeImageIO *io, fi_handle handle);
-
-public:
- psdParser();
- ~psdParser();
- FIBITMAP* Load(FreeImageIO *io, fi_handle handle, int s_format_id, int flags=0);
- /** Also used by the TIFF plugin */
- bool ReadImageResources(FreeImageIO *io, fi_handle handle, LONG length=0);
- /** Used by the TIFF plugin */
- FIBITMAP* GetThumbnail() {
- return _thumbnail.getDib();
- }
-};
-
-#endif // PSDPARSER_H
-
diff --git a/plugins/AdvaImg/src/FreeImage/PixelAccess.cpp b/plugins/AdvaImg/src/FreeImage/PixelAccess.cpp
deleted file mode 100644
index 70b381f105..0000000000
--- a/plugins/AdvaImg/src/FreeImage/PixelAccess.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-// ==========================================================
-// Pixel access functions
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Ryan Rubley (ryan@lostreality.org)
-// - Riley McNiff (rmcniff@marexgroup.com)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-
-BYTE * DLL_CALLCONV
-FreeImage_GetScanLine(FIBITMAP *dib, int scanline) {
- if(!FreeImage_HasPixels(dib)) {
- return NULL;
- }
- return CalculateScanLine(FreeImage_GetBits(dib), FreeImage_GetPitch(dib), scanline);
-}
-
-BOOL DLL_CALLCONV
-FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value) {
- BYTE shift;
-
- if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
- return FALSE;
-
- if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
- BYTE *bits = FreeImage_GetScanLine(dib, y);
-
- switch(FreeImage_GetBPP(dib)) {
- case 1:
- *value = (bits[x >> 3] & (0x80 >> (x & 0x07))) != 0;
- break;
- case 4:
- shift = (BYTE)((1 - x % 2) << 2);
- *value = (bits[x >> 1] & (0x0F << shift)) >> shift;
- break;
- case 8:
- *value = bits[x];
- break;
- default:
- return FALSE;
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value) {
- if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
- return FALSE;
-
- if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
- BYTE *bits = FreeImage_GetScanLine(dib, y);
-
- switch(FreeImage_GetBPP(dib)) {
- case 16:
- {
- bits += 2*x;
- WORD *pixel = (WORD *)bits;
- if((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
- value->rgbBlue = (BYTE)((((*pixel & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F);
- value->rgbGreen = (BYTE)((((*pixel & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F);
- value->rgbRed = (BYTE)((((*pixel & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F);
- value->rgbReserved = 0;
- } else {
- value->rgbBlue = (BYTE)((((*pixel & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
- value->rgbGreen = (BYTE)((((*pixel & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
- value->rgbRed = (BYTE)((((*pixel & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
- value->rgbReserved = 0;
- }
- break;
- }
- case 24:
- bits += 3*x;
- value->rgbBlue = bits[FI_RGBA_BLUE]; // B
- value->rgbGreen = bits[FI_RGBA_GREEN]; // G
- value->rgbRed = bits[FI_RGBA_RED]; // R
- value->rgbReserved = 0;
- break;
- case 32:
- bits += 4*x;
- value->rgbBlue = bits[FI_RGBA_BLUE]; // B
- value->rgbGreen = bits[FI_RGBA_GREEN]; // G
- value->rgbRed = bits[FI_RGBA_RED]; // R
- value->rgbReserved = bits[FI_RGBA_ALPHA]; // A
- break;
- default:
- return FALSE;
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value) {
- BYTE shift;
-
- if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
- return FALSE;
-
- if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
- BYTE *bits = FreeImage_GetScanLine(dib, y);
-
- switch(FreeImage_GetBPP(dib)) {
- case 1:
- *value ? bits[x >> 3] |= (0x80 >> (x & 0x7)) : bits[x >> 3] &= (0xFF7F >> (x & 0x7));
- break;
- case 4:
- shift = (BYTE)((1 - x % 2) << 2);
- bits[x >> 1] &= ~(0x0F << shift);
- bits[x >> 1] |= ((*value & 0x0F) << shift);
- break;
- case 8:
- bits[x] = *value;
- break;
- default:
- return FALSE;
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value) {
- if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP))
- return FALSE;
-
- if((x < FreeImage_GetWidth(dib)) && (y < FreeImage_GetHeight(dib))) {
- BYTE *bits = FreeImage_GetScanLine(dib, y);
-
- switch(FreeImage_GetBPP(dib)) {
- case 16:
- {
- bits += 2*x;
- WORD *pixel = (WORD *)bits;
- if((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) {
- *pixel = ((value->rgbBlue >> 3) << FI16_565_BLUE_SHIFT) |
- ((value->rgbGreen >> 2) << FI16_565_GREEN_SHIFT) |
- ((value->rgbRed >> 3) << FI16_565_RED_SHIFT);
- } else {
- *pixel = ((value->rgbBlue >> 3) << FI16_555_BLUE_SHIFT) |
- ((value->rgbGreen >> 3) << FI16_555_GREEN_SHIFT) |
- ((value->rgbRed >> 3) << FI16_555_RED_SHIFT);
- }
- break;
- }
- case 24:
- bits += 3*x;
- bits[FI_RGBA_BLUE] = value->rgbBlue; // B
- bits[FI_RGBA_GREEN] = value->rgbGreen; // G
- bits[FI_RGBA_RED] = value->rgbRed; // R
- break;
- case 32:
- bits += 4*x;
- bits[FI_RGBA_BLUE] = value->rgbBlue; // B
- bits[FI_RGBA_GREEN] = value->rgbGreen; // G
- bits[FI_RGBA_RED] = value->rgbRed; // R
- bits[FI_RGBA_ALPHA] = value->rgbReserved; // A
- break;
- default:
- return FALSE;
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/Plugin.cpp b/plugins/AdvaImg/src/FreeImage/Plugin.cpp
deleted file mode 100644
index 1bc13412a5..0000000000
--- a/plugins/AdvaImg/src/FreeImage/Plugin.cpp
+++ /dev/null
@@ -1,822 +0,0 @@
-// =====================================================================
-// FreeImage Plugin Interface
-//
-// Design and implementation by
-// - Floris van den Berg (floris@geekhq.nl)
-// - Rui Lopes (ruiglopes@yahoo.com)
-// - Detlev Vendt (detlev.vendt@brillit.de)
-// - Petr Pytelka (pyta@lightcomp.com)
-//
-// 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
-
-#ifdef _WIN32
-#include <windows.h>
-#include <io.h>
-#else
-#include <ctype.h>
-#endif // _WIN32
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "FreeImageIO.h"
-#include "Plugin.h"
-
-#include "../Metadata/FreeImageTag.h"
-
-// =====================================================================
-
-using namespace std;
-
-// =====================================================================
-// Plugin search list
-// =====================================================================
-
-const char *
-s_search_list[] = {
- "",
- "plugins\\",
-};
-
-static int s_search_list_size = sizeof(s_search_list) / sizeof(char *);
-static PluginList *s_plugins = NULL;
-static int s_plugin_reference_count = 0;
-
-
-// =====================================================================
-// Reimplementation of stricmp (it is not supported on some systems)
-// =====================================================================
-
-int
-FreeImage_stricmp(const char *s1, const char *s2) {
- int c1, c2;
-
- do {
- c1 = tolower(*s1++);
- c2 = tolower(*s2++);
- } while (c1 && c1 == c2);
-
- return c1 - c2;
-}
-
-// =====================================================================
-// Implementation of PluginList
-// =====================================================================
-
-PluginList::PluginList() :
-m_plugin_map(),
-m_node_count(0) {
-}
-
-FREE_IMAGE_FORMAT
-PluginList::AddNode(FI_InitProc init_proc, void *instance, const char *format, const char *description, const char *extension, const char *regexpr) {
- if (init_proc != NULL) {
- PluginNode *node = new(std::nothrow) PluginNode;
- Plugin *plugin = new(std::nothrow) Plugin;
- if(!node || !plugin) {
- if(node) delete node;
- if(plugin) delete plugin;
- FreeImage_OutputMessageProc(FIF_UNKNOWN, FI_MSG_ERROR_MEMORY);
- return FIF_UNKNOWN;
- }
-
- memset(plugin, 0, sizeof(Plugin));
-
- // fill-in the plugin structure
- // note we have memset to 0, so all unset pointers should be NULL)
-
- init_proc(plugin, (int)m_plugin_map.size());
-
- // get the format string (two possible ways)
-
- const char *the_format = NULL;
-
- if (format != NULL) {
- the_format = format;
- } else if (plugin->format_proc != NULL) {
- the_format = plugin->format_proc();
- }
-
- // add the node if it wasn't there already
-
- if (the_format != NULL) {
- node->m_id = (int)m_plugin_map.size();
- node->m_instance = instance;
- node->m_plugin = plugin;
- node->m_format = format;
- node->m_description = description;
- node->m_extension = extension;
- node->m_regexpr = regexpr;
- node->m_enabled = TRUE;
-
- m_plugin_map[(const int)m_plugin_map.size()] = node;
-
- return (FREE_IMAGE_FORMAT)node->m_id;
- }
-
- // something went wrong while allocating the plugin... cleanup
-
- delete plugin;
- delete node;
- }
-
- return FIF_UNKNOWN;
-}
-
-PluginNode *
-PluginList::FindNodeFromFormat(const char *format) {
- for (map<int, PluginNode *>::iterator i = m_plugin_map.begin(); i != m_plugin_map.end(); ++i) {
- const char *the_format = ((*i).second->m_format != NULL) ? (*i).second->m_format : (*i).second->m_plugin->format_proc();
-
- if ((*i).second->m_enabled) {
- if (FreeImage_stricmp(the_format, format) == 0) {
- return (*i).second;
- }
- }
- }
-
- return NULL;
-}
-
-PluginNode *
-PluginList::FindNodeFromMime(const char *mime) {
- for (map<int, PluginNode *>::iterator i = m_plugin_map.begin(); i != m_plugin_map.end(); ++i) {
- const char *the_mime = ((*i).second->m_plugin->mime_proc != NULL) ? (*i).second->m_plugin->mime_proc() : "";
-
- if ((*i).second->m_enabled) {
- if ((the_mime != NULL) && (strcmp(the_mime, mime) == 0)) {
- return (*i).second;
- }
- }
- }
-
- return NULL;
-}
-
-PluginNode *
-PluginList::FindNodeFromFIF(int node_id) {
- map<int, PluginNode *>::iterator i = m_plugin_map.find(node_id);
-
- if (i != m_plugin_map.end()) {
- return (*i).second;
- }
-
- return NULL;
-}
-
-int
-PluginList::Size() const {
- return (int)m_plugin_map.size();
-}
-
-BOOL
-PluginList::IsEmpty() const {
- return m_plugin_map.empty();
-}
-
-PluginList::~PluginList() {
- for (map<int, PluginNode *>::iterator i = m_plugin_map.begin(); i != m_plugin_map.end(); ++i) {
-#ifdef _WIN32
- if ((*i).second->m_instance != NULL) {
- FreeLibrary((HINSTANCE)(*i).second->m_instance);
- }
-#endif
- delete (*i).second->m_plugin;
- delete ((*i).second);
- }
-}
-
-// =====================================================================
-// Retrieve a pointer to the plugin list container
-// =====================================================================
-
-PluginList * DLL_CALLCONV
-FreeImage_GetPluginList() {
- return s_plugins;
-}
-
-// =====================================================================
-// Plugin System Initialization
-// =====================================================================
-
-void DLL_CALLCONV
-FreeImage_Initialise(BOOL load_local_plugins_only) {
- if (s_plugin_reference_count++ == 0) {
-
- /*
- Note: initialize all singletons here
- in order to avoid race conditions with multi-threading
- */
-
- // initialise the TagLib singleton
- TagLib& s = TagLib::instance();
-
- // internal plugin initialization
-
- s_plugins = new(std::nothrow) PluginList;
-
- if (s_plugins) {
- /* NOTE :
- The order used to initialize internal plugins below MUST BE the same order
- as the one used to define the FREE_IMAGE_FORMAT enum.
- */
- s_plugins->AddNode(InitBMP);
- s_plugins->AddNode(InitICO);
- s_plugins->AddNode(InitJPEG);
- s_plugins->AddNode(InitPNG);
- s_plugins->AddNode(InitGIF);
- //s_plugins->AddNode(InitJNG);
- //s_plugins->AddNode(InitKOALA);
- //s_plugins->AddNode(InitIFF);
- //s_plugins->AddNode(InitMNG);
- //s_plugins->AddNode(InitPNM, NULL, "PBM", "Portable Bitmap (ASCII)", "pbm", "^P1");
- //s_plugins->AddNode(InitPNM, NULL, "PBMRAW", "Portable Bitmap (RAW)", "pbm", "^P4");
- //s_plugins->AddNode(InitPCD);
- //s_plugins->AddNode(InitPCX);
- //s_plugins->AddNode(InitPNM, NULL, "PGM", "Portable Greymap (ASCII)", "pgm", "^P2");
- //s_plugins->AddNode(InitPNM, NULL, "PGMRAW", "Portable Greymap (RAW)", "pgm", "^P5");
- //s_plugins->AddNode(InitPNM, NULL, "PPM", "Portable Pixelmap (ASCII)", "ppm", "^P3");
- //s_plugins->AddNode(InitPNM, NULL, "PPMRAW", "Portable Pixelmap (RAW)", "ppm", "^P6");
- //s_plugins->AddNode(InitRAS);
- //s_plugins->AddNode(InitTARGA);
- //s_plugins->AddNode(InitTIFF);
- //s_plugins->AddNode(InitWBMP);
- //s_plugins->AddNode(InitPSD);
- //s_plugins->AddNode(InitCUT);
- //s_plugins->AddNode(InitXBM);
- //s_plugins->AddNode(InitXPM);
- //s_plugins->AddNode(InitDDS);
- //s_plugins->AddNode(InitHDR);
- //s_plugins->AddNode(InitG3);
- //s_plugins->AddNode(InitSGI);
- //s_plugins->AddNode(InitEXR);
- //s_plugins->AddNode(InitJ2K);
- //s_plugins->AddNode(InitJP2);
- //s_plugins->AddNode(InitPFM);
- //s_plugins->AddNode(InitPICT);
- //s_plugins->AddNode(InitRAW);
- //s_plugins->AddNode(InitWEBP);
-//#if !(defined(_MSC_VER) && (_MSC_VER <= 1310))
- //s_plugins->AddNode(InitJXR);
-//#endif // unsupported by MS Visual Studio 2003 !!!
-
- // external plugin initialization
-
-#ifdef _WIN32
- if (!load_local_plugins_only) {
- int count = 0;
- char buffer[MAX_PATH + 200];
- wchar_t current_dir[2 * _MAX_PATH], module[2 * _MAX_PATH];
- BOOL bOk = FALSE;
-
- // store the current directory. then set the directory to the application location
-
- if (GetCurrentDirectoryW(2 * _MAX_PATH, current_dir) != 0) {
- if (GetModuleFileNameW(NULL, module, 2 * _MAX_PATH) != 0) {
- wchar_t *last_point = wcsrchr(module, L'\\');
-
- if (last_point) {
- *last_point = L'\0';
-
- bOk = SetCurrentDirectoryW(module);
- }
- }
- }
-
- // search for plugins
-
- while (count < s_search_list_size) {
- _finddata_t find_data;
- long find_handle;
-
- strcpy(buffer, s_search_list[count]);
- strcat(buffer, "*.fip");
-
- if ((find_handle = (long)_findfirst(buffer, &find_data)) != -1L) {
- do {
- strcpy(buffer, s_search_list[count]);
- strncat(buffer, find_data.name, MAX_PATH + 200);
-
- HINSTANCE instance = LoadLibraryA(buffer);
-
- if (instance != NULL) {
- FARPROC proc_address = GetProcAddress(instance, "_Init@8");
-
- if (proc_address != NULL) {
- s_plugins->AddNode((FI_InitProc)proc_address, (void *)instance);
- } else {
- FreeLibrary(instance);
- }
- }
- } while (_findnext(find_handle, &find_data) != -1L);
-
- _findclose(find_handle);
- }
-
- count++;
- }
-
- // restore the current directory
-
- if (bOk) {
- SetCurrentDirectoryW(current_dir);
- }
- }
-#endif // _WIN32
- }
- }
-}
-
-void DLL_CALLCONV
-FreeImage_DeInitialise() {
- --s_plugin_reference_count;
-
- if (s_plugin_reference_count == 0) {
- delete s_plugins;
- }
-}
-
-// =====================================================================
-// Open and close a bitmap
-// =====================================================================
-
-void * DLL_CALLCONV
-FreeImage_Open(PluginNode *node, FreeImageIO *io, fi_handle handle, BOOL open_for_reading) {
- if (node->m_plugin->open_proc != NULL) {
- return node->m_plugin->open_proc(io, handle, open_for_reading);
- }
-
- return NULL;
-}
-
-void DLL_CALLCONV
-FreeImage_Close(PluginNode *node, FreeImageIO *io, fi_handle handle, void *data) {
- if (node->m_plugin->close_proc != NULL) {
- node->m_plugin->close_proc(io, handle, data);
- }
-}
-
-// =====================================================================
-// Plugin System Load/Save Functions
-// =====================================================================
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_LoadFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flags) {
- if ((fif >= 0) && (fif < FreeImage_GetFIFCount())) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- if (node != NULL) {
- if(node->m_plugin->load_proc != NULL) {
- void *data = FreeImage_Open(node, io, handle, TRUE);
-
- FIBITMAP *bitmap = node->m_plugin->load_proc(io, handle, -1, flags, data);
-
- FreeImage_Close(node, io, handle, data);
-
- return bitmap;
- }
- }
- }
-
- return NULL;
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_Load(FREE_IMAGE_FORMAT fif, const char *filename, int flags) {
- FreeImageIO io;
- SetDefaultIO(&io);
-
- FILE *handle = fopen(filename, "rb");
-
- if (handle) {
- FIBITMAP *bitmap = FreeImage_LoadFromHandle(fif, &io, (fi_handle)handle, flags);
-
- fclose(handle);
-
- return bitmap;
- } else {
- FreeImage_OutputMessageProc((int)fif, "FreeImage_Load: failed to open file %s", filename);
- }
-
- return NULL;
-}
-
-FIBITMAP * DLL_CALLCONV
-FreeImage_LoadU(FREE_IMAGE_FORMAT fif, const wchar_t *filename, int flags) {
- FreeImageIO io;
- SetDefaultIO(&io);
-#ifdef _WIN32
- FILE *handle = _wfopen(filename, L"rb");
-
- if (handle) {
- FIBITMAP *bitmap = FreeImage_LoadFromHandle(fif, &io, (fi_handle)handle, flags);
-
- fclose(handle);
-
- return bitmap;
- } else {
- FreeImage_OutputMessageProc((int)fif, "FreeImage_LoadU: failed to open input file");
- }
-#endif
- return NULL;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SaveToHandle(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, FreeImageIO *io, fi_handle handle, int flags) {
- // cannot save "header only" formats
- if(FreeImage_HasPixels(dib) == FALSE) {
- FreeImage_OutputMessageProc((int)fif, "FreeImage_SaveToHandle: cannot save \"header only\" formats");
- return FALSE;
- }
-
- if ((fif >= 0) && (fif < FreeImage_GetFIFCount())) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- if (node) {
- if(node->m_plugin->save_proc != NULL) {
- void *data = FreeImage_Open(node, io, handle, FALSE);
-
- BOOL result = node->m_plugin->save_proc(io, dib, handle, -1, flags, data);
-
- FreeImage_Close(node, io, handle, data);
-
- return result;
- }
- }
- }
-
- return FALSE;
-}
-
-
-BOOL DLL_CALLCONV
-FreeImage_Save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const char *filename, int flags) {
- FreeImageIO io;
- SetDefaultIO(&io);
-
- FILE *handle = fopen(filename, "w+b");
-
- if (handle) {
- BOOL success = FreeImage_SaveToHandle(fif, dib, &io, (fi_handle)handle, flags);
-
- fclose(handle);
-
- return success;
- } else {
- FreeImage_OutputMessageProc((int)fif, "FreeImage_Save: failed to open file %s", filename);
- }
-
- return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_SaveU(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const wchar_t *filename, int flags) {
- FreeImageIO io;
- SetDefaultIO(&io);
-#ifdef _WIN32
- FILE *handle = _wfopen(filename, L"w+b");
-
- if (handle) {
- BOOL success = FreeImage_SaveToHandle(fif, dib, &io, (fi_handle)handle, flags);
-
- fclose(handle);
-
- return success;
- } else {
- FreeImage_OutputMessageProc((int)fif, "FreeImage_SaveU: failed to open output file");
- }
-#endif
- return FALSE;
-}
-
-// =====================================================================
-// Plugin construction + enable/disable functions
-// =====================================================================
-
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_RegisterLocalPlugin(FI_InitProc proc_address, const char *format, const char *description, const char *extension, const char *regexpr) {
- return s_plugins->AddNode(proc_address, NULL, format, description, extension, regexpr);
-}
-
-#ifdef _WIN32
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_RegisterExternalPlugin(const char *path, const char *format, const char *description, const char *extension, const char *regexpr) {
- if (path != NULL) {
- HINSTANCE instance = LoadLibraryA(path);
-
- if (instance != NULL) {
- FARPROC proc_address = GetProcAddress(instance, "_Init@8");
-
- FREE_IMAGE_FORMAT result = s_plugins->AddNode((FI_InitProc)proc_address, (void *)instance, format, description, extension, regexpr);
-
- if (result == FIF_UNKNOWN)
- FreeLibrary(instance);
-
- return result;
- }
- }
-
- return FIF_UNKNOWN;
-}
-#endif // _WIN32
-
-int DLL_CALLCONV
-FreeImage_SetPluginEnabled(FREE_IMAGE_FORMAT fif, BOOL enable) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- if (node != NULL) {
- BOOL previous_state = node->m_enabled;
-
- node->m_enabled = enable;
-
- return previous_state;
- }
- }
-
- return -1;
-}
-
-int DLL_CALLCONV
-FreeImage_IsPluginEnabled(FREE_IMAGE_FORMAT fif) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ? node->m_enabled : FALSE;
- }
-
- return -1;
-}
-
-// =====================================================================
-// Plugin Access Functions
-// =====================================================================
-
-int DLL_CALLCONV
-FreeImage_GetFIFCount() {
- return (s_plugins != NULL) ? s_plugins->Size() : 0;
-}
-
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_GetFIFFromFormat(const char *format) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFormat(format);
-
- return (node != NULL) ? (FREE_IMAGE_FORMAT)node->m_id : FIF_UNKNOWN;
- }
-
- return FIF_UNKNOWN;
-}
-
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_GetFIFFromMime(const char *mime) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromMime(mime);
-
- return (node != NULL) ? (FREE_IMAGE_FORMAT)node->m_id : FIF_UNKNOWN;
- }
-
- return FIF_UNKNOWN;
-}
-
-const char * DLL_CALLCONV
-FreeImage_GetFormatFromFIF(FREE_IMAGE_FORMAT fif) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ? (node->m_format != NULL) ? node->m_format : node->m_plugin->format_proc() : NULL;
- }
-
- return NULL;
-}
-
-const char * DLL_CALLCONV
-FreeImage_GetFIFMimeType(FREE_IMAGE_FORMAT fif) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ? (node->m_plugin != NULL) ? ( node->m_plugin->mime_proc != NULL )? node->m_plugin->mime_proc() : NULL : NULL : NULL;
- }
-
- return NULL;
-}
-
-const char * DLL_CALLCONV
-FreeImage_GetFIFExtensionList(FREE_IMAGE_FORMAT fif) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ? (node->m_extension != NULL) ? node->m_extension : (node->m_plugin->extension_proc != NULL) ? node->m_plugin->extension_proc() : NULL : NULL;
- }
-
- return NULL;
-}
-
-const char * DLL_CALLCONV
-FreeImage_GetFIFDescription(FREE_IMAGE_FORMAT fif) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ? (node->m_description != NULL) ? node->m_description : (node->m_plugin->description_proc != NULL) ? node->m_plugin->description_proc() : NULL : NULL;
- }
-
- return NULL;
-}
-
-const char * DLL_CALLCONV
-FreeImage_GetFIFRegExpr(FREE_IMAGE_FORMAT fif) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ? (node->m_regexpr != NULL) ? node->m_regexpr : (node->m_plugin->regexpr_proc != NULL) ? node->m_plugin->regexpr_proc() : NULL : NULL;
- }
-
- return NULL;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_FIFSupportsReading(FREE_IMAGE_FORMAT fif) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ? node->m_plugin->load_proc != NULL : FALSE;
- }
-
- return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_FIFSupportsWriting(FREE_IMAGE_FORMAT fif) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ? node->m_plugin->save_proc != NULL : FALSE ;
- }
-
- return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_FIFSupportsExportBPP(FREE_IMAGE_FORMAT fif, int depth) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ?
- (node->m_plugin->supports_export_bpp_proc != NULL) ?
- node->m_plugin->supports_export_bpp_proc(depth) : FALSE : FALSE;
- }
-
- return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_FIFSupportsExportType(FREE_IMAGE_FORMAT fif, FREE_IMAGE_TYPE type) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ?
- (node->m_plugin->supports_export_type_proc != NULL) ?
- node->m_plugin->supports_export_type_proc(type) : FALSE : FALSE;
- }
-
- return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_FIFSupportsICCProfiles(FREE_IMAGE_FORMAT fif) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ?
- (node->m_plugin->supports_icc_profiles_proc != NULL) ?
- node->m_plugin->supports_icc_profiles_proc() : FALSE : FALSE;
- }
-
- return FALSE;
-}
-
-BOOL DLL_CALLCONV
-FreeImage_FIFSupportsNoPixels(FREE_IMAGE_FORMAT fif) {
- if (s_plugins != NULL) {
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- return (node != NULL) ?
- (node->m_plugin->supports_no_pixels_proc != NULL) ?
- node->m_plugin->supports_no_pixels_proc() : FALSE : FALSE;
- }
-
- return FALSE;
-}
-
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_GetFIFFromFilename(const char *filename) {
- if (filename != NULL) {
- const char *extension;
-
- // get the proper extension if we received a filename
-
- char *place = strrchr((char *)filename, '.');
- extension = (place != NULL) ? ++place : filename;
-
- // look for the extension in the plugin table
-
- for (int i = 0; i < FreeImage_GetFIFCount(); ++i) {
-
- if (s_plugins->FindNodeFromFIF(i)->m_enabled) {
-
- // compare the format id with the extension
-
- if (FreeImage_stricmp(FreeImage_GetFormatFromFIF((FREE_IMAGE_FORMAT)i), extension) == 0) {
- return (FREE_IMAGE_FORMAT)i;
- } else {
- // make a copy of the extension list and split it
-
- char *copy = (char *)malloc(strlen(FreeImage_GetFIFExtensionList((FREE_IMAGE_FORMAT)i)) + 1);
- memset(copy, 0, strlen(FreeImage_GetFIFExtensionList((FREE_IMAGE_FORMAT)i)) + 1);
- memcpy(copy, FreeImage_GetFIFExtensionList((FREE_IMAGE_FORMAT)i), strlen(FreeImage_GetFIFExtensionList((FREE_IMAGE_FORMAT)i)));
-
- // get the first token
-
- char *token = strtok(copy, ",");
-
- while (token != NULL) {
- if (FreeImage_stricmp(token, extension) == 0) {
- free(copy);
-
- return (FREE_IMAGE_FORMAT)i;
- }
-
- token = strtok(NULL, ",");
- }
-
- // free the copy of the extension list
-
- free(copy);
- }
- }
- }
- }
-
- return FIF_UNKNOWN;
-}
-
-FREE_IMAGE_FORMAT DLL_CALLCONV
-FreeImage_GetFIFFromFilenameU(const wchar_t *filename) {
-#ifdef _WIN32
- if (filename == NULL) return FIF_UNKNOWN;
-
- // get the proper extension if we received a filename
- wchar_t *place = wcsrchr((wchar_t *)filename, '.');
- if (place == NULL) return FIF_UNKNOWN;
- // convert to single character - no national chars in extensions
- char *extension = (char *)malloc(wcslen(place)+1);
- unsigned int i=0;
- for(; i < wcslen(place); i++) // convert 16-bit to 8-bit
- extension[i] = (char)(place[i] & 0x00FF);
- // set terminating 0
- extension[i]=0;
- FREE_IMAGE_FORMAT fRet = FreeImage_GetFIFFromFilename(extension);
- free(extension);
-
- return fRet;
-#else
- return FIF_UNKNOWN;
-#endif // _WIN32
-}
-
-BOOL DLL_CALLCONV
-FreeImage_Validate(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle) {
- if (s_plugins != NULL) {
- BOOL validated = FALSE;
-
- PluginNode *node = s_plugins->FindNodeFromFIF(fif);
-
- if (node) {
- long tell = io->tell_proc(handle);
-
- validated = (node != NULL) ? (node->m_enabled) ? (node->m_plugin->validate_proc != NULL) ? node->m_plugin->validate_proc(io, handle) : FALSE : FALSE : FALSE;
-
- io->seek_proc(handle, tell, SEEK_SET);
- }
-
- return validated;
- }
-
- return FALSE;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/PluginBMP.cpp b/plugins/AdvaImg/src/FreeImage/PluginBMP.cpp
deleted file mode 100644
index 13206f7b71..0000000000
--- a/plugins/AdvaImg/src/FreeImage/PluginBMP.cpp
+++ /dev/null
@@ -1,1494 +0,0 @@
-// ==========================================================
-// BMP Loader and Writer
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Markus Loibl (markus.loibl@epost.de)
-// - Martin Weber (martweb@gmx.net)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Michal Novotny (michal@etc.cz)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// Constants + headers
-// ----------------------------------------------------------
-
-static const BYTE RLE_COMMAND = 0;
-static const BYTE RLE_ENDOFLINE = 0;
-static const BYTE RLE_ENDOFBITMAP = 1;
-static const BYTE RLE_DELTA = 2;
-
-static const BYTE BI_RGB = 0; // compression: none
-static const BYTE BI_RLE8 = 1; // compression: RLE 8-bit/pixel
-static const BYTE BI_RLE4 = 2; // compression: RLE 4-bit/pixel
-static const BYTE BI_BITFIELDS = 3; // compression: Bit field or Huffman 1D compression for BITMAPCOREHEADER2
-static const BYTE BI_JPEG = 4; // compression: JPEG or RLE-24 compression for BITMAPCOREHEADER2
-static const BYTE BI_PNG = 5; // compression: PNG
-static const BYTE BI_ALPHABITFIELDS = 6; // compression: Bit field (this value is valid in Windows CE .NET 4.0 and later)
-
-// ----------------------------------------------------------
-
-#ifdef _WIN32
-#pragma pack(push, 1)
-#else
-#pragma pack(1)
-#endif
-
-typedef struct tagBITMAPCOREHEADER {
- DWORD bcSize;
- WORD bcWidth;
- WORD bcHeight;
- WORD bcPlanes;
- WORD bcBitCnt;
-} BITMAPCOREHEADER, *PBITMAPCOREHEADER;
-
-typedef struct tagBITMAPINFOOS2_1X_HEADER {
- DWORD biSize;
- WORD biWidth;
- WORD biHeight;
- WORD biPlanes;
- WORD biBitCount;
-} BITMAPINFOOS2_1X_HEADER, *PBITMAPINFOOS2_1X_HEADER;
-
-typedef struct tagBITMAPFILEHEADER {
- WORD bfType; //! The file type
- DWORD bfSize; //! The size, in bytes, of the bitmap file
- WORD bfReserved1; //! Reserved; must be zero
- WORD bfReserved2; //! Reserved; must be zero
- DWORD bfOffBits; //! The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits
-} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
-
-#ifdef _WIN32
-#pragma pack(pop)
-#else
-#pragma pack()
-#endif
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
-// Internal functions
-// ==========================================================
-
-#ifdef FREEIMAGE_BIGENDIAN
-static void
-SwapInfoHeader(BITMAPINFOHEADER *header) {
- SwapLong(&header->biSize);
- SwapLong((DWORD *)&header->biWidth);
- SwapLong((DWORD *)&header->biHeight);
- SwapShort(&header->biPlanes);
- SwapShort(&header->biBitCount);
- SwapLong(&header->biCompression);
- SwapLong(&header->biSizeImage);
- SwapLong((DWORD *)&header->biXPelsPerMeter);
- SwapLong((DWORD *)&header->biYPelsPerMeter);
- SwapLong(&header->biClrUsed);
- SwapLong(&header->biClrImportant);
-}
-
-static void
-SwapCoreHeader(BITMAPCOREHEADER *header) {
- SwapLong(&header->bcSize);
- SwapShort(&header->bcWidth);
- SwapShort(&header->bcHeight);
- SwapShort(&header->bcPlanes);
- SwapShort(&header->bcBitCnt);
-}
-
-static void
-SwapOS21XHeader(BITMAPINFOOS2_1X_HEADER *header) {
- SwapLong(&header->biSize);
- SwapShort(&header->biWidth);
- SwapShort(&header->biHeight);
- SwapShort(&header->biPlanes);
- SwapShort(&header->biBitCount);
-}
-
-static void
-SwapFileHeader(BITMAPFILEHEADER *header) {
- SwapShort(&header->bfType);
- SwapLong(&header->bfSize);
- SwapShort(&header->bfReserved1);
- SwapShort(&header->bfReserved2);
- SwapLong(&header->bfOffBits);
-}
-#endif
-
-// --------------------------------------------------------------------------
-
-/**
-Load uncompressed image pixels for 1-, 4-, 8-, 16-, 24- and 32-bit dib
-@param io FreeImage IO
-@param handle FreeImage IO handle
-@param dib Image to be loaded
-@param height Image height
-@param pitch Image pitch
-@param bit_count Image bit-depth (1-, 4-, 8-, 16-, 24- or 32-bit)
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-LoadPixelData(FreeImageIO *io, fi_handle handle, FIBITMAP *dib, int height, unsigned pitch, unsigned bit_count) {
- unsigned count = 0;
-
- // Load pixel data
- // NB: height can be < 0 for BMP data
- if (height > 0) {
- count = io->read_proc((void *)FreeImage_GetBits(dib), height * pitch, 1, handle);
- if(count != 1) {
- return FALSE;
- }
- } else {
- int positiveHeight = abs(height);
- for (int c = 0; c < positiveHeight; ++c) {
- count = io->read_proc((void *)FreeImage_GetScanLine(dib, positiveHeight - c - 1), pitch, 1, handle);
- if(count != 1) {
- return FALSE;
- }
- }
- }
-
- // swap as needed
-#ifdef FREEIMAGE_BIGENDIAN
- if (bit_count == 16) {
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
- WORD *pixel = (WORD *)FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
- SwapShort(pixel);
- pixel++;
- }
- }
- }
-#endif
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
- if (bit_count == 24 || bit_count == 32) {
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
- BYTE *pixel = FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
- INPLACESWAP(pixel[0], pixel[2]);
- pixel += (bit_count >> 3);
- }
- }
- }
-#endif
-
- return TRUE;
-}
-
-/**
-Load image pixels for 4-bit RLE compressed dib
-@param io FreeImage IO
-@param handle FreeImage IO handle
-@param width Image width
-@param height Image height
-@param dib Image to be loaded
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-LoadPixelDataRLE4(FreeImageIO *io, fi_handle handle, int width, int height, FIBITMAP *dib) {
- int status_byte = 0;
- BYTE second_byte = 0;
- int bits = 0;
-
- BYTE *pixels = NULL; // temporary 8-bit buffer
-
- try {
- height = abs(height);
-
- pixels = (BYTE*)malloc(width * height * sizeof(BYTE));
- if(!pixels) throw(1);
- memset(pixels, 0, width * height * sizeof(BYTE));
-
- BYTE *q = pixels;
- BYTE *end = pixels + height * width;
-
- for (int scanline = 0; scanline < height; ) {
- if (q < pixels || q >= end) {
- break;
- }
- if(io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
- throw(1);
- }
- if (status_byte != 0) {
- status_byte = (int)MIN((size_t)status_byte, (size_t)(end - q));
- // Encoded mode
- if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
- throw(1);
- }
- for (int i = 0; i < status_byte; i++) {
- *q++=(BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
- }
- bits += status_byte;
- }
- else {
- // Escape mode
- if(io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
- throw(1);
- }
- switch (status_byte) {
- case RLE_ENDOFLINE:
- {
- // End of line
- bits = 0;
- scanline++;
- q = pixels + scanline*width;
- }
- break;
-
- case RLE_ENDOFBITMAP:
- // End of bitmap
- q = end;
- break;
-
- case RLE_DELTA:
- {
- // read the delta values
-
- BYTE delta_x = 0;
- BYTE delta_y = 0;
-
- if(io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) {
- throw(1);
- }
- if(io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) {
- throw(1);
- }
-
- // apply them
-
- bits += delta_x;
- scanline += delta_y;
- q = pixels + scanline*width+bits;
- }
- break;
-
- default:
- {
- // Absolute mode
- status_byte = (int)MIN((size_t)status_byte, (size_t)(end - q));
- for (int i = 0; i < status_byte; i++) {
- if ((i & 0x01) == 0) {
- if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
- throw(1);
- }
- }
- *q++=(BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
- }
- bits += status_byte;
- // Read pad byte
- if (((status_byte & 0x03) == 1) || ((status_byte & 0x03) == 2)) {
- BYTE padding = 0;
- if(io->read_proc(&padding, sizeof(BYTE), 1, handle) != 1) {
- throw(1);
- }
- }
- }
- break;
- }
- }
- }
-
- {
- // Convert to 4-bit
- for(int y = 0; y < height; y++) {
- const BYTE *src = (BYTE*)pixels + y * width;
- BYTE *dst = FreeImage_GetScanLine(dib, y);
-
- BOOL hinibble = TRUE;
-
- for (int cols = 0; cols < width; cols++){
- if (hinibble) {
- dst[cols >> 1] = (src[cols] << 4);
- } else {
- dst[cols >> 1] |= src[cols];
- }
-
- hinibble = !hinibble;
- }
- }
- }
-
- free(pixels);
-
- return TRUE;
-
- } catch(int) {
- if(pixels) free(pixels);
- return FALSE;
- }
-}
-
-/**
-Load image pixels for 8-bit RLE compressed dib
-@param io FreeImage IO
-@param handle FreeImage IO handle
-@param width Image width
-@param height Image height
-@param dib Image to be loaded
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-LoadPixelDataRLE8(FreeImageIO *io, fi_handle handle, int width, int height, FIBITMAP *dib) {
- BYTE status_byte = 0;
- BYTE second_byte = 0;
- int scanline = 0;
- int bits = 0;
-
- for (;;) {
- if( io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
- return FALSE;
- }
-
- switch (status_byte) {
- case RLE_COMMAND :
- if(io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
- return FALSE;
- }
-
- switch (status_byte) {
- case RLE_ENDOFLINE :
- bits = 0;
- scanline++;
- break;
-
- case RLE_ENDOFBITMAP :
- return TRUE;
-
- case RLE_DELTA :
- {
- // read the delta values
-
- BYTE delta_x = 0;
- BYTE delta_y = 0;
-
- if(io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) {
- return FALSE;
- }
- if(io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) {
- return FALSE;
- }
-
- // apply them
-
- bits += delta_x;
- scanline += delta_y;
-
- break;
- }
-
- default :
- {
- if(scanline >= abs(height)) {
- return TRUE;
- }
-
- int count = MIN((int)status_byte, width - bits);
-
- BYTE *sline = FreeImage_GetScanLine(dib, scanline);
-
- if(io->read_proc((void *)(sline + bits), sizeof(BYTE) * count, 1, handle) != 1) {
- return FALSE;
- }
-
- // align run length to even number of bytes
-
- if ((status_byte & 1) == 1) {
- if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
- return FALSE;
- }
- }
-
- bits += status_byte;
-
- break;
- }
- }
-
- break;
-
- default :
- {
- if(scanline >= abs(height)) {
- return TRUE;
- }
-
- int count = MIN((int)status_byte, width - bits);
-
- BYTE *sline = FreeImage_GetScanLine(dib, scanline);
-
- if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
- return FALSE;
- }
-
- for (int i = 0; i < count; i++) {
- *(sline + bits) = second_byte;
-
- bits++;
- }
-
- break;
- }
- }
- }
-}
-
-// --------------------------------------------------------------------------
-
-static FIBITMAP *
-LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_offset, int type) {
- FIBITMAP *dib = NULL;
-
- try {
- BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
-
- // load the info header
-
- BITMAPINFOHEADER bih;
-
- io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapInfoHeader(&bih);
-#endif
-
- // keep some general information about the bitmap
-
- unsigned used_colors = bih.biClrUsed;
- int width = bih.biWidth;
- int height = bih.biHeight; // WARNING: height can be < 0 => check each call using 'height' as a parameter
- unsigned bit_count = bih.biBitCount;
- unsigned compression = bih.biCompression;
- unsigned pitch = CalculatePitch(CalculateLine(width, bit_count));
-
- switch (bit_count) {
- case 1 :
- case 4 :
- case 8 :
- {
- if ((used_colors == 0) || (used_colors > CalculateUsedPaletteEntries(bit_count))) {
- used_colors = CalculateUsedPaletteEntries(bit_count);
- }
-
- // allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette
-
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count);
- if (dib == NULL) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // set resolution information
- FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
- FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
-
- // seek to the end of the header (depending on the BMP header version)
- // type == sizeof(BITMAPVxINFOHEADER)
- switch(type) {
- case 40: // sizeof(BITMAPINFOHEADER) - all Windows versions since Windows 3.0
- break;
- case 52: // sizeof(BITMAPV2INFOHEADER) (undocumented)
- case 56: // sizeof(BITMAPV3INFOHEADER) (undocumented)
- case 108: // sizeof(BITMAPV4HEADER) - all Windows versions since Windows 95/NT4 (not supported)
- case 124: // sizeof(BITMAPV5HEADER) - Windows 98/2000 and newer (not supported)
- io->seek_proc(handle, (long)(type - sizeof(BITMAPINFOHEADER)), SEEK_CUR);
- break;
- }
-
- // load the palette
-
- io->read_proc(FreeImage_GetPalette(dib), used_colors * sizeof(RGBQUAD), 1, handle);
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
- RGBQUAD *pal = FreeImage_GetPalette(dib);
- for(int i = 0; i < used_colors; i++) {
- INPLACESWAP(pal[i].rgbRed, pal[i].rgbBlue);
- }
-#endif
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- // seek to the actual pixel data.
- // this is needed because sometimes the palette is larger than the entries it contains predicts
- io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
-
- // read the pixel data
-
- switch (compression) {
- case BI_RGB :
- if( LoadPixelData(io, handle, dib, height, pitch, bit_count) ) {
- return dib;
- } else {
- throw "Error encountered while decoding BMP data";
- }
- break;
-
- case BI_RLE4 :
- if( LoadPixelDataRLE4(io, handle, width, height, dib) ) {
- return dib;
- } else {
- throw "Error encountered while decoding RLE4 BMP data";
- }
- break;
-
- case BI_RLE8 :
- if( LoadPixelDataRLE8(io, handle, width, height, dib) ) {
- return dib;
- } else {
- throw "Error encountered while decoding RLE8 BMP data";
- }
- break;
-
- default :
- throw FI_MSG_ERROR_UNSUPPORTED_COMPRESSION;
- }
- }
- break; // 1-, 4-, 8-bit
-
- case 16 :
- {
- int use_bitfields = 0;
- if (bih.biCompression == BI_BITFIELDS) use_bitfields = 3;
- else if (bih.biCompression == BI_ALPHABITFIELDS) use_bitfields = 4;
- else if (type == 52) use_bitfields = 3;
- else if (type >= 56) use_bitfields = 4;
-
- if (use_bitfields > 0) {
- DWORD bitfields[4];
- io->read_proc(bitfields, use_bitfields * sizeof(DWORD), 1, handle);
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
- } else {
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
- }
-
- if (dib == NULL) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // set resolution information
- FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
- FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- // seek to the actual pixel data
- io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
-
- // load pixel data and swap as needed if OS is Big Endian
- LoadPixelData(io, handle, dib, height, pitch, bit_count);
-
- return dib;
- }
- break; // 16-bit
-
- case 24 :
- case 32 :
- {
- int use_bitfields = 0;
- if (bih.biCompression == BI_BITFIELDS) use_bitfields = 3;
- else if (bih.biCompression == BI_ALPHABITFIELDS) use_bitfields = 4;
- else if (type == 52) use_bitfields = 3;
- else if (type >= 56) use_bitfields = 4;
-
- if (use_bitfields > 0) {
- DWORD bitfields[4];
- io->read_proc(bitfields, use_bitfields * sizeof(DWORD), 1, handle);
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
- } else {
- if( bit_count == 32 ) {
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- } else {
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- }
- }
-
- if (dib == NULL) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // set resolution information
- FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
- FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- // Skip over the optional palette
- // A 24 or 32 bit DIB may contain a palette for faster color reduction
- // i.e. you can have (FreeImage_GetColorsUsed(dib) > 0)
-
- // seek to the actual pixel data
- io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
-
- // read in the bitmap bits
- // load pixel data and swap as needed if OS is Big Endian
- LoadPixelData(io, handle, dib, height, pitch, bit_count);
-
- // check if the bitmap contains transparency, if so enable it in the header
-
- FreeImage_SetTransparent(dib, (FreeImage_GetColorType(dib) == FIC_RGBALPHA));
-
- return dib;
- }
- break; // 24-, 32-bit
- }
- } catch(const char *message) {
- if(dib) {
- FreeImage_Unload(dib);
- }
- if(message) {
- FreeImage_OutputMessageProc(s_format_id, message);
- }
- }
-
- return NULL;
-}
-
-// --------------------------------------------------------------------------
-
-static FIBITMAP *
-LoadOS22XBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_offset) {
- FIBITMAP *dib = NULL;
-
- try {
- BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
-
- // load the info header
-
- BITMAPINFOHEADER bih;
-
- io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapInfoHeader(&bih);
-#endif
-
- // keep some general information about the bitmap
-
- unsigned used_colors = bih.biClrUsed;
- int width = bih.biWidth;
- int height = bih.biHeight; // WARNING: height can be < 0 => check each read_proc using 'height' as a parameter
- unsigned bit_count = bih.biBitCount;
- unsigned compression = bih.biCompression;
- unsigned pitch = CalculatePitch(CalculateLine(width, bit_count));
-
- switch (bit_count) {
- case 1 :
- case 4 :
- case 8 :
- {
- if ((used_colors == 0) || (used_colors > CalculateUsedPaletteEntries(bit_count)))
- used_colors = CalculateUsedPaletteEntries(bit_count);
-
- // allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette
-
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count);
-
- if (dib == NULL) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // set resolution information
- FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
- FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
-
- // load the palette
- // note that it may contain RGB or RGBA values : we will calculate this
- unsigned pal_size = (bitmap_bits_offset - sizeof(BITMAPFILEHEADER) - bih.biSize) / used_colors;
-
- io->seek_proc(handle, sizeof(BITMAPFILEHEADER) + bih.biSize, SEEK_SET);
-
- RGBQUAD *pal = FreeImage_GetPalette(dib);
-
- if(pal_size == 4) {
- for (unsigned count = 0; count < used_colors; count++) {
- FILE_BGRA bgra;
-
- io->read_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
-
- pal[count].rgbRed = bgra.r;
- pal[count].rgbGreen = bgra.g;
- pal[count].rgbBlue = bgra.b;
- }
- } else if(pal_size == 3) {
- for (unsigned count = 0; count < used_colors; count++) {
- FILE_BGR bgr;
-
- io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle);
-
- pal[count].rgbRed = bgr.r;
- pal[count].rgbGreen = bgr.g;
- pal[count].rgbBlue = bgr.b;
- }
- }
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- // seek to the actual pixel data.
- // this is needed because sometimes the palette is larger than the entries it contains predicts
-
- if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) {
- io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
- }
-
- // read the pixel data
-
- switch (compression) {
- case BI_RGB :
- // load pixel data
- LoadPixelData(io, handle, dib, height, pitch, bit_count);
- return dib;
-
- case BI_RLE4 :
- if( LoadPixelDataRLE4(io, handle, width, height, dib) ) {
- return dib;
- } else {
- throw "Error encountered while decoding RLE4 BMP data";
- }
- break;
-
- case BI_RLE8 :
- if( LoadPixelDataRLE8(io, handle, width, height, dib) ) {
- return dib;
- } else {
- throw "Error encountered while decoding RLE8 BMP data";
- }
- break;
-
- default :
- throw FI_MSG_ERROR_UNSUPPORTED_COMPRESSION;
- }
- }
-
- case 16 :
- {
- if (bih.biCompression == 3) {
- DWORD bitfields[3];
-
- io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle);
-
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
- } else {
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
- }
-
- if (dib == NULL) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // set resolution information
- FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
- FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) {
- io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
- }
-
- // load pixel data and swap as needed if OS is Big Endian
- LoadPixelData(io, handle, dib, height, pitch, bit_count);
-
- return dib;
- }
-
- case 24 :
- case 32 :
- {
- if( bit_count == 32 ) {
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- } else {
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- }
-
- if (dib == NULL) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // set resolution information
- FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
- FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- // Skip over the optional palette
- // A 24 or 32 bit DIB may contain a palette for faster color reduction
-
- if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) {
- io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
- }
-
- // read in the bitmap bits
- // load pixel data and swap as needed if OS is Big Endian
- LoadPixelData(io, handle, dib, height, pitch, bit_count);
-
- // check if the bitmap contains transparency, if so enable it in the header
-
- FreeImage_SetTransparent(dib, (FreeImage_GetColorType(dib) == FIC_RGBALPHA));
-
- return dib;
- }
- }
- } catch(const char *message) {
- if(dib)
- FreeImage_Unload(dib);
-
- FreeImage_OutputMessageProc(s_format_id, message);
- }
-
- return NULL;
-}
-
-// --------------------------------------------------------------------------
-
-static FIBITMAP *
-LoadOS21XBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_offset) {
- FIBITMAP *dib = NULL;
-
- try {
- BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
-
- BITMAPINFOOS2_1X_HEADER bios2_1x;
-
- io->read_proc(&bios2_1x, sizeof(BITMAPINFOOS2_1X_HEADER), 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapOS21XHeader(&bios2_1x);
-#endif
- // keep some general information about the bitmap
-
- unsigned used_colors = 0;
- unsigned width = bios2_1x.biWidth;
- unsigned height = bios2_1x.biHeight; // WARNING: height can be < 0 => check each read_proc using 'height' as a parameter
- unsigned bit_count = bios2_1x.biBitCount;
- unsigned pitch = CalculatePitch(CalculateLine(width, bit_count));
-
- switch (bit_count) {
- case 1 :
- case 4 :
- case 8 :
- {
- used_colors = CalculateUsedPaletteEntries(bit_count);
-
- // allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette
-
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count);
-
- if (dib == NULL) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // set resolution information to default values (72 dpi in english units)
- FreeImage_SetDotsPerMeterX(dib, 2835);
- FreeImage_SetDotsPerMeterY(dib, 2835);
-
- // load the palette
-
- RGBQUAD *pal = FreeImage_GetPalette(dib);
-
- for (unsigned count = 0; count < used_colors; count++) {
- FILE_BGR bgr;
-
- io->read_proc(&bgr, sizeof(FILE_BGR), 1, handle);
-
- pal[count].rgbRed = bgr.r;
- pal[count].rgbGreen = bgr.g;
- pal[count].rgbBlue = bgr.b;
- }
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- // Skip over the optional palette
- // A 24 or 32 bit DIB may contain a palette for faster color reduction
-
- io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
-
- // read the pixel data
-
- // load pixel data
- LoadPixelData(io, handle, dib, height, pitch, bit_count);
-
- return dib;
- }
-
- case 16 :
- {
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
-
- if (dib == NULL) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // set resolution information to default values (72 dpi in english units)
- FreeImage_SetDotsPerMeterX(dib, 2835);
- FreeImage_SetDotsPerMeterY(dib, 2835);
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- // load pixel data and swap as needed if OS is Big Endian
- LoadPixelData(io, handle, dib, height, pitch, bit_count);
-
- return dib;
- }
-
- case 24 :
- case 32 :
- {
- if( bit_count == 32 ) {
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- } else {
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- }
-
- if (dib == NULL) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- // set resolution information to default values (72 dpi in english units)
- FreeImage_SetDotsPerMeterX(dib, 2835);
- FreeImage_SetDotsPerMeterY(dib, 2835);
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- // Skip over the optional palette
- // A 24 or 32 bit DIB may contain a palette for faster color reduction
-
- // load pixel data and swap as needed if OS is Big Endian
- LoadPixelData(io, handle, dib, height, pitch, bit_count);
-
- // check if the bitmap contains transparency, if so enable it in the header
-
- FreeImage_SetTransparent(dib, (FreeImage_GetColorType(dib) == FIC_RGBALPHA));
-
- return dib;
- }
- }
- } catch(const char *message) {
- if(dib)
- FreeImage_Unload(dib);
-
- FreeImage_OutputMessageProc(s_format_id, message);
- }
-
- return NULL;
-}
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
- return "BMP";
-}
-
-static const char * DLL_CALLCONV
-Description() {
- return "Windows or OS/2 Bitmap";
-}
-
-static const char * DLL_CALLCONV
-Extension() {
- return "bmp";
-}
-
-static const char * DLL_CALLCONV
-RegExpr() {
- return "^BM";
-}
-
-static const char * DLL_CALLCONV
-MimeType() {
- return "image/bmp";
-}
-
-static BOOL DLL_CALLCONV
-Validate(FreeImageIO *io, fi_handle handle) {
- BYTE bmp_signature1[] = { 0x42, 0x4D };
- BYTE bmp_signature2[] = { 0x42, 0x41 };
- BYTE signature[2] = { 0, 0 };
-
- io->read_proc(signature, 1, sizeof(bmp_signature1), handle);
-
- if (memcmp(bmp_signature1, signature, sizeof(bmp_signature1)) == 0)
- return TRUE;
-
- if (memcmp(bmp_signature2, signature, sizeof(bmp_signature2)) == 0)
- return TRUE;
-
- return FALSE;
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportDepth(int depth) {
- return (
- (depth == 1) ||
- (depth == 4) ||
- (depth == 8) ||
- (depth == 16) ||
- (depth == 24) ||
- (depth == 32)
- );
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportType(FREE_IMAGE_TYPE type) {
- return (type == FIT_BITMAP) ? TRUE : FALSE;
-}
-
-static BOOL DLL_CALLCONV
-SupportsNoPixels() {
- return TRUE;
-}
-
-// ----------------------------------------------------------
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
- if (handle != NULL) {
- BITMAPFILEHEADER bitmapfileheader;
- DWORD type = 0;
-
- // we use this offset value to make seemingly absolute seeks relative in the file
-
- long offset_in_file = io->tell_proc(handle);
-
- // read the fileheader
-
- io->read_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapFileHeader(&bitmapfileheader);
-#endif
-
- // check the signature
-
- if((bitmapfileheader.bfType != 0x4D42) && (bitmapfileheader.bfType != 0x4142)) {
- FreeImage_OutputMessageProc(s_format_id, FI_MSG_ERROR_MAGIC_NUMBER);
- return NULL;
- }
-
- // read the first byte of the infoheader
-
- io->read_proc(&type, sizeof(DWORD), 1, handle);
- io->seek_proc(handle, 0 - (long)sizeof(DWORD), SEEK_CUR);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapLong(&type);
-#endif
-
- // call the appropriate load function for the found bitmap type
-
- switch(type) {
- case 12:
- // OS/2 and also all Windows versions since Windows 3.0
- return LoadOS21XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);
-
- case 64:
- // OS/2
- return LoadOS22XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);
-
- case 40: // BITMAPINFOHEADER - all Windows versions since Windows 3.0
- case 52: // BITMAPV2INFOHEADER (undocumented, partially supported)
- case 56: // BITMAPV3INFOHEADER (undocumented, partially supported)
- case 108: // BITMAPV4HEADER - all Windows versions since Windows 95/NT4 (partially supported)
- case 124: // BITMAPV5HEADER - Windows 98/2000 and newer (partially supported)
- return LoadWindowsBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits, type);
-
- default:
- break;
- }
-
- FreeImage_OutputMessageProc(s_format_id, "unknown bmp subtype with id %d", type);
- }
-
- return NULL;
-}
-
-// ----------------------------------------------------------
-
-/**
-Encode a 8-bit source buffer into a 8-bit target buffer using a RLE compression algorithm.
-The size of the target buffer must be equal to the size of the source buffer.
-On return, the function will return the real size of the target buffer, which should be less that or equal to the source buffer size.
-@param target 8-bit Target buffer
-@param source 8-bit Source buffer
-@param size Source/Target input buffer size
-@return Returns the target buffer size
-*/
-static int
-RLEEncodeLine(BYTE *target, BYTE *source, int size) {
- BYTE buffer[256];
- int buffer_size = 0;
- int target_pos = 0;
-
- for (int i = 0; i < size; ++i) {
- if ((i < size - 1) && (source[i] == source[i + 1])) {
- // find a solid block of same bytes
-
- int j = i + 1;
- int jmax = 254 + i;
-
- while ((j < size - 1) && (j < jmax) && (source[j] == source[j + 1]))
- ++j;
-
- // if the block is larger than 3 bytes, use it
- // else put the data into the larger pool
-
- if (((j - i) + 1) > 3) {
- // don't forget to write what we already have in the buffer
-
- switch(buffer_size) {
- case 0 :
- break;
-
- case RLE_DELTA :
- target[target_pos++] = 1;
- target[target_pos++] = buffer[0];
- target[target_pos++] = 1;
- target[target_pos++] = buffer[1];
- break;
-
- case RLE_ENDOFBITMAP :
- target[target_pos++] = (BYTE)buffer_size;
- target[target_pos++] = buffer[0];
- break;
-
- default :
- target[target_pos++] = RLE_COMMAND;
- target[target_pos++] = (BYTE)buffer_size;
- memcpy(target + target_pos, buffer, buffer_size);
-
- // prepare for next run
-
- target_pos += buffer_size;
-
- if ((buffer_size & 1) == 1)
- target_pos++;
-
- break;
- }
-
- // write the continuous data
-
- target[target_pos++] = (BYTE)((j - i) + 1);
- target[target_pos++] = source[i];
-
- buffer_size = 0;
- } else {
- for (int k = 0; k < (j - i) + 1; ++k) {
- buffer[buffer_size++] = source[i + k];
-
- if (buffer_size == 254) {
- // write what we have
-
- target[target_pos++] = RLE_COMMAND;
- target[target_pos++] = (BYTE)buffer_size;
- memcpy(target + target_pos, buffer, buffer_size);
-
- // prepare for next run
-
- target_pos += buffer_size;
- buffer_size = 0;
- }
- }
- }
-
- i = j;
- } else {
- buffer[buffer_size++] = source[i];
- }
-
- // write the buffer if it's full
-
- if (buffer_size == 254) {
- target[target_pos++] = RLE_COMMAND;
- target[target_pos++] = (BYTE)buffer_size;
- memcpy(target + target_pos, buffer, buffer_size);
-
- // prepare for next run
-
- target_pos += buffer_size;
- buffer_size = 0;
- }
- }
-
- // write the last bytes
-
- switch(buffer_size) {
- case 0 :
- break;
-
- case RLE_DELTA :
- target[target_pos++] = 1;
- target[target_pos++] = buffer[0];
- target[target_pos++] = 1;
- target[target_pos++] = buffer[1];
- break;
-
- case RLE_ENDOFBITMAP :
- target[target_pos++] = (BYTE)buffer_size;
- target[target_pos++] = buffer[0];
- break;
-
- default :
- target[target_pos++] = RLE_COMMAND;
- target[target_pos++] = (BYTE)buffer_size;
- memcpy(target + target_pos, buffer, buffer_size);
-
- // prepare for next run
-
- target_pos += buffer_size;
-
- if ((buffer_size & 1) == 1)
- target_pos++;
-
- break;
- }
-
- // write the END_OF_LINE marker
-
- target[target_pos++] = RLE_COMMAND;
- target[target_pos++] = RLE_ENDOFLINE;
-
- // return the written size
-
- return target_pos;
-}
-
-static BOOL DLL_CALLCONV
-Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
- if ((dib != NULL) && (handle != NULL)) {
- // write the file header
-
- BITMAPFILEHEADER bitmapfileheader;
- bitmapfileheader.bfType = 0x4D42;
- bitmapfileheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD);
- bitmapfileheader.bfSize = bitmapfileheader.bfOffBits + FreeImage_GetHeight(dib) * FreeImage_GetPitch(dib);
- bitmapfileheader.bfReserved1 = 0;
- bitmapfileheader.bfReserved2 = 0;
-
- // take care of the bit fields data of any
-
- bool bit_fields = (FreeImage_GetBPP(dib) == 16);
-
- if (bit_fields) {
- bitmapfileheader.bfSize += 3 * sizeof(DWORD);
- bitmapfileheader.bfOffBits += 3 * sizeof(DWORD);
- }
-
-#ifdef FREEIMAGE_BIGENDIAN
- SwapFileHeader(&bitmapfileheader);
-#endif
- if (io->write_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle) != 1)
- return FALSE;
-
- // update the bitmap info header
-
- BITMAPINFOHEADER bih;
- memcpy(&bih, FreeImage_GetInfoHeader(dib), sizeof(BITMAPINFOHEADER));
-
- if (bit_fields)
- bih.biCompression = BI_BITFIELDS;
- else if ((bih.biBitCount == 8) && (flags & BMP_SAVE_RLE))
- bih.biCompression = BI_RLE8;
- else
- bih.biCompression = BI_RGB;
-
- // write the bitmap info header
-
-#ifdef FREEIMAGE_BIGENDIAN
- SwapInfoHeader(&bih);
-#endif
- if (io->write_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle) != 1)
- return FALSE;
-
- // write the bit fields when we are dealing with a 16 bit BMP
-
- if (bit_fields) {
- DWORD d;
-
- d = FreeImage_GetRedMask(dib);
-
- if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1)
- return FALSE;
-
- d = FreeImage_GetGreenMask(dib);
-
- if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1)
- return FALSE;
-
- d = FreeImage_GetBlueMask(dib);
-
- if (io->write_proc(&d, sizeof(DWORD), 1, handle) != 1)
- return FALSE;
- }
-
- // write the palette
-
- if (FreeImage_GetPalette(dib) != NULL) {
- RGBQUAD *pal = FreeImage_GetPalette(dib);
- FILE_BGRA bgra;
- for(unsigned i = 0; i < FreeImage_GetColorsUsed(dib); i++ ) {
- bgra.b = pal[i].rgbBlue;
- bgra.g = pal[i].rgbGreen;
- bgra.r = pal[i].rgbRed;
- bgra.a = pal[i].rgbReserved;
- if (io->write_proc(&bgra, sizeof(FILE_BGRA), 1, handle) != 1)
- return FALSE;
- }
- }
-
- // write the bitmap data... if RLE compression is enable, use it
-
- unsigned bpp = FreeImage_GetBPP(dib);
- if ((bpp == 8) && (flags & BMP_SAVE_RLE)) {
- BYTE *buffer = (BYTE*)malloc(FreeImage_GetPitch(dib) * 2 * sizeof(BYTE));
-
- for (DWORD i = 0; i < FreeImage_GetHeight(dib); ++i) {
- int size = RLEEncodeLine(buffer, FreeImage_GetScanLine(dib, i), FreeImage_GetLine(dib));
-
- if (io->write_proc(buffer, size, 1, handle) != 1) {
- free(buffer);
- return FALSE;
- }
- }
-
- buffer[0] = RLE_COMMAND;
- buffer[1] = RLE_ENDOFBITMAP;
-
- if (io->write_proc(buffer, 2, 1, handle) != 1) {
- free(buffer);
- return FALSE;
- }
-
- free(buffer);
-#ifdef FREEIMAGE_BIGENDIAN
- } else if (bpp == 16) {
- int padding = FreeImage_GetPitch(dib) - FreeImage_GetWidth(dib) * sizeof(WORD);
- WORD pad = 0;
- WORD pixel;
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
- BYTE *line = FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
- pixel = ((WORD *)line)[x];
- SwapShort(&pixel);
- if (io->write_proc(&pixel, sizeof(WORD), 1, handle) != 1)
- return FALSE;
- }
- if(padding != 0) {
- if(io->write_proc(&pad, padding, 1, handle) != 1) {
- return FALSE;
- }
- }
- }
-#endif
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
- } else if (bpp == 24) {
- int padding = FreeImage_GetPitch(dib) - FreeImage_GetWidth(dib) * sizeof(FILE_BGR);
- DWORD pad = 0;
- FILE_BGR bgr;
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
- BYTE *line = FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
- RGBTRIPLE *triple = ((RGBTRIPLE *)line)+x;
- bgr.b = triple->rgbtBlue;
- bgr.g = triple->rgbtGreen;
- bgr.r = triple->rgbtRed;
- if (io->write_proc(&bgr, sizeof(FILE_BGR), 1, handle) != 1)
- return FALSE;
- }
- if(padding != 0) {
- if(io->write_proc(&pad, padding, 1, handle) != 1) {
- return FALSE;
- }
- }
- }
- } else if (bpp == 32) {
- FILE_BGRA bgra;
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
- BYTE *line = FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
- RGBQUAD *quad = ((RGBQUAD *)line)+x;
- bgra.b = quad->rgbBlue;
- bgra.g = quad->rgbGreen;
- bgra.r = quad->rgbRed;
- bgra.a = quad->rgbReserved;
- if (io->write_proc(&bgra, sizeof(FILE_BGRA), 1, handle) != 1)
- return FALSE;
- }
- }
-#endif
- } else if (io->write_proc(FreeImage_GetBits(dib), FreeImage_GetHeight(dib) * FreeImage_GetPitch(dib), 1, handle) != 1) {
- return FALSE;
- }
-
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-// ==========================================================
-// Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitBMP(Plugin *plugin, int format_id) {
- s_format_id = format_id;
-
- plugin->format_proc = Format;
- plugin->description_proc = Description;
- plugin->extension_proc = Extension;
- plugin->regexpr_proc = RegExpr;
- plugin->open_proc = NULL;
- plugin->close_proc = NULL;
- plugin->pagecount_proc = NULL;
- plugin->pagecapability_proc = NULL;
- plugin->load_proc = Load;
- plugin->save_proc = Save;
- plugin->validate_proc = Validate;
- plugin->mime_proc = MimeType;
- plugin->supports_export_bpp_proc = SupportsExportDepth;
- plugin->supports_export_type_proc = SupportsExportType;
- plugin->supports_icc_profiles_proc = NULL; // not implemented yet;
- plugin->supports_no_pixels_proc = SupportsNoPixels;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/PluginGIF.cpp b/plugins/AdvaImg/src/FreeImage/PluginGIF.cpp
deleted file mode 100644
index d9b430eac5..0000000000
--- a/plugins/AdvaImg/src/FreeImage/PluginGIF.cpp
+++ /dev/null
@@ -1,1406 +0,0 @@
-// ==========================================================
-// GIF Loader and Writer
-//
-// Design and implementation by
-// - Ryan Rubley <ryan@lostreality.org>
-// - Raphaлl Gaquer <raphael.gaquer@alcer.com>
-// - Aaron Shumate <aaron@shumate.us>
-//
-// 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 "FreeImage.h"
-#include "Utilities.h"
-#include "../Metadata/FreeImageTag.h"
-
-// ==========================================================
-// Metadata declarations
-// ==========================================================
-
-#define GIF_DISPOSAL_UNSPECIFIED 0
-#define GIF_DISPOSAL_LEAVE 1
-#define GIF_DISPOSAL_BACKGROUND 2
-#define GIF_DISPOSAL_PREVIOUS 3
-
-// ==========================================================
-// Constant/Typedef declarations
-// ==========================================================
-
-struct GIFinfo {
- BOOL read;
- //only really used when reading
- size_t global_color_table_offset;
- int global_color_table_size;
- BYTE background_color;
- std::vector<size_t> application_extension_offsets;
- std::vector<size_t> comment_extension_offsets;
- std::vector<size_t> graphic_control_extension_offsets;
- std::vector<size_t> image_descriptor_offsets;
-
- GIFinfo() : read(0), global_color_table_offset(0), global_color_table_size(0), background_color(0)
- {
- }
-};
-
-struct PageInfo {
- PageInfo(int d, int l, int t, int w, int h) {
- disposal_method = d; left = (WORD)l; top = (WORD)t; width = (WORD)w; height = (WORD)h;
- }
- int disposal_method;
- WORD left, top, width, height;
-};
-
-//GIF defines a max of 12 bits per code
-#define MAX_LZW_CODE 4096
-
-class StringTable
-{
-public:
- StringTable();
- ~StringTable();
- void Initialize(int minCodeSize);
- BYTE *FillInputBuffer(int len);
- void CompressStart(int bpp, int width);
- int CompressEnd(BYTE *buf); //0-4 bytes
- bool Compress(BYTE *buf, int *len);
- bool Decompress(BYTE *buf, int *len);
- void Done(void);
-
-protected:
- bool m_done;
-
- int m_minCodeSize, m_clearCode, m_endCode, m_nextCode;
-
- int m_bpp, m_slack; //Compressor information
-
- int m_prefix; //Compressor state variable
- int m_codeSize, m_codeMask; //Compressor/Decompressor state variables
- int m_oldCode; //Decompressor state variable
- int m_partial, m_partialSize; //Compressor/Decompressor bit buffer
-
- int firstPixelPassed; // A specific flag that indicates if the first pixel
- // of the whole image had already been read
-
- std::string m_strings[MAX_LZW_CODE]; //This is what is really the "string table" data for the Decompressor
- int* m_strmap;
-
- //input buffer
- BYTE *m_buffer;
- int m_bufferSize, m_bufferRealSize, m_bufferPos, m_bufferShift;
-
- void ClearCompressorTable(void);
- void ClearDecompressorTable(void);
-};
-
-#define GIF_PACKED_LSD_HAVEGCT 0x80
-#define GIF_PACKED_LSD_COLORRES 0x70
-#define GIF_PACKED_LSD_GCTSORTED 0x08
-#define GIF_PACKED_LSD_GCTSIZE 0x07
-#define GIF_PACKED_ID_HAVELCT 0x80
-#define GIF_PACKED_ID_INTERLACED 0x40
-#define GIF_PACKED_ID_LCTSORTED 0x20
-#define GIF_PACKED_ID_RESERVED 0x18
-#define GIF_PACKED_ID_LCTSIZE 0x07
-#define GIF_PACKED_GCE_RESERVED 0xE0
-#define GIF_PACKED_GCE_DISPOSAL 0x1C
-#define GIF_PACKED_GCE_WAITINPUT 0x02
-#define GIF_PACKED_GCE_HAVETRANS 0x01
-
-#define GIF_BLOCK_IMAGE_DESCRIPTOR 0x2C
-#define GIF_BLOCK_EXTENSION 0x21
-#define GIF_BLOCK_TRAILER 0x3B
-
-#define GIF_EXT_PLAINTEXT 0x01
-#define GIF_EXT_GRAPHIC_CONTROL 0xF9
-#define GIF_EXT_COMMENT 0xFE
-#define GIF_EXT_APPLICATION 0xFF
-
-#define GIF_INTERLACE_PASSES 4
-static int g_GifInterlaceOffset[GIF_INTERLACE_PASSES] = {0, 4, 2, 1};
-static int g_GifInterlaceIncrement[GIF_INTERLACE_PASSES] = {8, 8, 4, 2};
-
-// ==========================================================
-// Helpers Functions
-// ==========================================================
-
-static BOOL
-FreeImage_SetMetadataEx(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, WORD id, FREE_IMAGE_MDTYPE type, DWORD count, DWORD length, const void *value)
-{
- BOOL bResult = FALSE;
- FITAG *tag = FreeImage_CreateTag();
- if(tag) {
- FreeImage_SetTagKey(tag, key);
- FreeImage_SetTagID(tag, id);
- FreeImage_SetTagType(tag, type);
- FreeImage_SetTagCount(tag, count);
- FreeImage_SetTagLength(tag, length);
- FreeImage_SetTagValue(tag, value);
- if(model == FIMD_ANIMATION) {
- TagLib& s = TagLib::instance();
- // get the tag description
- const char *description = s.getTagDescription(TagLib::ANIMATION, id);
- FreeImage_SetTagDescription(tag, description);
- }
- // store the tag
- bResult = FreeImage_SetMetadata(model, dib, key, tag);
- FreeImage_DeleteTag(tag);
- }
- return bResult;
-}
-
-static BOOL
-FreeImage_GetMetadataEx(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FREE_IMAGE_MDTYPE type, FITAG **tag)
-{
- if( FreeImage_GetMetadata(model, dib, key, tag) ) {
- if( FreeImage_GetTagType(*tag) == type ) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-StringTable::StringTable()
-{
- m_buffer = NULL;
- firstPixelPassed = 0; // Still no pixel read
- // Maximum number of entries in the map is MAX_LZW_CODE * 256
- // (aka 2**12 * 2**8 => a 20 bits key)
- // This Map could be optmized to only handle MAX_LZW_CODE * 2**(m_bpp)
- m_strmap = new(std::nothrow) int[1<<20];
-}
-
-StringTable::~StringTable()
-{
- if( m_buffer != NULL ) {
- delete [] m_buffer;
- }
- if( m_strmap != NULL ) {
- delete [] m_strmap;
- m_strmap = NULL;
- }
-}
-
-void StringTable::Initialize(int minCodeSize)
-{
- m_done = false;
-
- m_bpp = 8;
- m_minCodeSize = minCodeSize;
- m_clearCode = 1 << m_minCodeSize;
- if(m_clearCode > MAX_LZW_CODE) {
- m_clearCode = MAX_LZW_CODE;
- }
- m_endCode = m_clearCode + 1;
-
- m_partial = 0;
- m_partialSize = 0;
-
- m_bufferSize = 0;
- ClearCompressorTable();
- ClearDecompressorTable();
-}
-
-BYTE *StringTable::FillInputBuffer(int len)
-{
- if( m_buffer == NULL ) {
- m_buffer = new(std::nothrow) BYTE[len];
- m_bufferRealSize = len;
- } else if( len > m_bufferRealSize ) {
- delete [] m_buffer;
- m_buffer = new(std::nothrow) BYTE[len];
- m_bufferRealSize = len;
- }
- m_bufferSize = len;
- m_bufferPos = 0;
- m_bufferShift = 8 - m_bpp;
- return m_buffer;
-}
-
-void StringTable::CompressStart(int bpp, int width)
-{
- m_bpp = bpp;
- m_slack = (8 - ((width * bpp) % 8)) % 8;
-
- m_partial |= m_clearCode << m_partialSize;
- m_partialSize += m_codeSize;
- ClearCompressorTable();
-}
-
-int StringTable::CompressEnd(BYTE *buf)
-{
- int len = 0;
-
- //output code for remaining prefix
- m_partial |= m_prefix << m_partialSize;
- m_partialSize += m_codeSize;
- while( m_partialSize >= 8 ) {
- *buf++ = (BYTE)m_partial;
- m_partial >>= 8;
- m_partialSize -= 8;
- len++;
- }
-
- //add the end of information code and flush the entire buffer out
- m_partial |= m_endCode << m_partialSize;
- m_partialSize += m_codeSize;
- while( m_partialSize > 0 ) {
- *buf++ = (BYTE)m_partial;
- m_partial >>= 8;
- m_partialSize -= 8;
- len++;
- }
-
- //most this can be is 4 bytes. 7 bits in m_partial to start + 12 for the
- //last code + 12 for the end code = 31 bits total.
- return len;
-}
-
-bool StringTable::Compress(BYTE *buf, int *len)
-{
- if( m_bufferSize == 0 || m_done ) {
- return false;
- }
-
- int mask = (1 << m_bpp) - 1;
- BYTE *bufpos = buf;
- while( m_bufferPos < m_bufferSize ) {
- //get the current pixel value
- char ch = (char)((m_buffer[m_bufferPos] >> m_bufferShift) & mask);
-
- // The next prefix is :
- // <the previous LZW code (on 12 bits << 8)> | <the code of the current pixel (on 8 bits)>
- int nextprefix = (((m_prefix)<<8)&0xFFF00) + (ch & 0x000FF);
- if(firstPixelPassed) {
-
- if( m_strmap[nextprefix] > 0) {
- m_prefix = m_strmap[nextprefix];
- } else {
- m_partial |= m_prefix << m_partialSize;
- m_partialSize += m_codeSize;
- //grab full bytes for the output buffer
- while( m_partialSize >= 8 && bufpos - buf < *len ) {
- *bufpos++ = (BYTE)m_partial;
- m_partial >>= 8;
- m_partialSize -= 8;
- }
-
- //add the code to the "table map"
- m_strmap[nextprefix] = m_nextCode;
-
- //increment the next highest valid code, increase the code size
- if( m_nextCode == (1 << m_codeSize) ) {
- m_codeSize++;
- }
- m_nextCode++;
-
- //if we're out of codes, restart the string table
- if( m_nextCode == MAX_LZW_CODE ) {
- m_partial |= m_clearCode << m_partialSize;
- m_partialSize += m_codeSize;
- ClearCompressorTable();
- }
-
- // Only keep the 8 lowest bits (prevent problems with "negative chars")
- m_prefix = ch & 0x000FF;
- }
-
- //increment to the next pixel
- if( m_bufferShift > 0 && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack) ) {
- m_bufferShift -= m_bpp;
- } else {
- m_bufferPos++;
- m_bufferShift = 8 - m_bpp;
- }
-
- //jump out here if the output buffer is full
- if( bufpos - buf == *len ) {
- return true;
- }
-
- } else {
- // Specific behavior for the first pixel of the whole image
-
- firstPixelPassed=1;
- // Only keep the 8 lowest bits (prevent problems with "negative chars")
- m_prefix = ch & 0x000FF;
-
- //increment to the next pixel
- if( m_bufferShift > 0 && !(m_bufferPos + 1 == m_bufferSize && m_bufferShift <= m_slack) ) {
- m_bufferShift -= m_bpp;
- } else {
- m_bufferPos++;
- m_bufferShift = 8 - m_bpp;
- }
-
- //jump out here if the output buffer is full
- if( bufpos - buf == *len ) {
- return true;
- }
- }
- }
-
- m_bufferSize = 0;
- *len = (int)(bufpos - buf);
-
- return true;
-}
-
-bool StringTable::Decompress(BYTE *buf, int *len)
-{
- if( m_bufferSize == 0 || m_done ) {
- return false;
- }
-
- BYTE *bufpos = buf;
- for( ; m_bufferPos < m_bufferSize; m_bufferPos++ ) {
- m_partial |= (int)m_buffer[m_bufferPos] << m_partialSize;
- m_partialSize += 8;
- while( m_partialSize >= m_codeSize ) {
- int code = m_partial & m_codeMask;
- m_partial >>= m_codeSize;
- m_partialSize -= m_codeSize;
-
- if( code > m_nextCode || /*(m_nextCode == MAX_LZW_CODE && code != m_clearCode) || */code == m_endCode ) {
- m_done = true;
- *len = (int)(bufpos - buf);
- return true;
- }
- if( code == m_clearCode ) {
- ClearDecompressorTable();
- continue;
- }
-
- //add new string to string table, if not the first pass since a clear code
- if( m_oldCode != MAX_LZW_CODE && m_nextCode < MAX_LZW_CODE) {
- m_strings[m_nextCode] = m_strings[m_oldCode] + m_strings[code == m_nextCode ? m_oldCode : code][0];
- }
-
- if( (int)m_strings[code].size() > *len - (bufpos - buf) ) {
- //out of space, stuff the code back in for next time
- m_partial <<= m_codeSize;
- m_partialSize += m_codeSize;
- m_partial |= code;
- m_bufferPos++;
- *len = (int)(bufpos - buf);
- return true;
- }
-
- //output the string into the buffer
- memcpy(bufpos, m_strings[code].data(), m_strings[code].size());
- bufpos += m_strings[code].size();
-
- //increment the next highest valid code, add a bit to the mask if we need to increase the code size
- if( m_oldCode != MAX_LZW_CODE && m_nextCode < MAX_LZW_CODE ) {
- if( ++m_nextCode < MAX_LZW_CODE ) {
- if( (m_nextCode & m_codeMask) == 0 ) {
- m_codeSize++;
- m_codeMask |= m_nextCode;
- }
- }
- }
-
- m_oldCode = code;
- }
- }
-
- m_bufferSize = 0;
- *len = (int)(bufpos - buf);
-
- return true;
-}
-
-void StringTable::Done(void)
-{
- m_done = true;
-}
-
-void StringTable::ClearCompressorTable(void)
-{
- if(m_strmap) {
- memset(m_strmap, 0xFF, sizeof(unsigned int)*(1<<20));
- }
- m_nextCode = m_endCode + 1;
-
- m_prefix = 0;
- m_codeSize = m_minCodeSize + 1;
-}
-
-void StringTable::ClearDecompressorTable(void)
-{
- for( int i = 0; i < m_clearCode; i++ ) {
- m_strings[i].resize(1);
- m_strings[i][0] = (char)i;
- }
- m_nextCode = m_endCode + 1;
-
- m_codeSize = m_minCodeSize + 1;
- m_codeMask = (1 << m_codeSize) - 1;
- m_oldCode = MAX_LZW_CODE;
-}
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
- return "GIF";
-}
-
-static const char * DLL_CALLCONV
-Description() {
- return "Graphics Interchange Format";
-}
-
-static const char * DLL_CALLCONV
-Extension() {
- return "gif";
-}
-
-static const char * DLL_CALLCONV
-RegExpr() {
- return "^GIF";
-}
-
-static const char * DLL_CALLCONV
-MimeType() {
- return "image/gif";
-}
-
-static BOOL DLL_CALLCONV
-Validate(FreeImageIO *io, fi_handle handle) {
- char buf[6];
- if( io->read_proc(buf, 6, 1, handle) < 1 ) {
- return FALSE;
- }
-
- BOOL bResult = FALSE;
- if( !strncmp(buf, "GIF", 3) ) {
- if( buf[3] >= '0' && buf[3] <= '9' && buf[4] >= '0' && buf[4] <= '9' && buf[5] >= 'a' && buf[5] <= 'z' ) {
- bResult = TRUE;
- }
- }
-
- io->seek_proc(handle, -6, SEEK_CUR);
-
- return bResult;
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportDepth(int depth) {
- return (depth == 1) ||
- (depth == 4) ||
- (depth == 8);
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportType(FREE_IMAGE_TYPE type) {
- return (type == FIT_BITMAP) ? TRUE : FALSE;
-}
-
-// ----------------------------------------------------------
-
-static void *DLL_CALLCONV
-Open(FreeImageIO *io, fi_handle handle, BOOL read) {
- GIFinfo *info = new(std::nothrow) GIFinfo;
- if( info == NULL ) {
- return NULL;
- }
-
- // 25/02/2008 MDA: Not safe to memset GIFinfo structure with VS 2008 (safe iterators),
- // perform initialization in constructor instead.
- // memset(info, 0, sizeof(GIFinfo));
-
- info->read = read;
- if( read ) {
- try {
- //Header
- if( !Validate(io, handle) ) {
- throw FI_MSG_ERROR_MAGIC_NUMBER;
- }
- io->seek_proc(handle, 6, SEEK_CUR);
-
- //Logical Screen Descriptor
- io->seek_proc(handle, 4, SEEK_CUR);
- BYTE packed;
- if( io->read_proc(&packed, 1, 1, handle) < 1 ) {
- throw "EOF reading Logical Screen Descriptor";
- }
- if( io->read_proc(&info->background_color, 1, 1, handle) < 1 ) {
- throw "EOF reading Logical Screen Descriptor";
- }
- io->seek_proc(handle, 1, SEEK_CUR);
-
- //Global Color Table
- if( packed & GIF_PACKED_LSD_HAVEGCT ) {
- info->global_color_table_offset = io->tell_proc(handle);
- info->global_color_table_size = 2 << (packed & GIF_PACKED_LSD_GCTSIZE);
- io->seek_proc(handle, 3 * info->global_color_table_size, SEEK_CUR);
- }
-
- //Scan through all the rest of the blocks, saving offsets
- size_t gce_offset = 0;
- BYTE block = 0;
- while( block != GIF_BLOCK_TRAILER ) {
- if( io->read_proc(&block, 1, 1, handle) < 1 ) {
- throw "EOF reading blocks";
- }
- if( block == GIF_BLOCK_IMAGE_DESCRIPTOR ) {
- info->image_descriptor_offsets.push_back(io->tell_proc(handle));
- //GCE may be 0, meaning no GCE preceded this ID
- info->graphic_control_extension_offsets.push_back(gce_offset);
- gce_offset = 0;
-
- io->seek_proc(handle, 8, SEEK_CUR);
- if( io->read_proc(&packed, 1, 1, handle) < 1 ) {
- throw "EOF reading Image Descriptor";
- }
-
- //Local Color Table
- if( packed & GIF_PACKED_ID_HAVELCT ) {
- io->seek_proc(handle, 3 * (2 << (packed & GIF_PACKED_ID_LCTSIZE)), SEEK_CUR);
- }
-
- //LZW Minimum Code Size
- io->seek_proc(handle, 1, SEEK_CUR);
- } else if( block == GIF_BLOCK_EXTENSION ) {
- BYTE ext;
- if( io->read_proc(&ext, 1, 1, handle) < 1 ) {
- throw "EOF reading extension";
- }
-
- if( ext == GIF_EXT_GRAPHIC_CONTROL ) {
- //overwrite previous offset if more than one GCE found before an ID
- gce_offset = io->tell_proc(handle);
- } else if( ext == GIF_EXT_COMMENT ) {
- info->comment_extension_offsets.push_back(io->tell_proc(handle));
- } else if( ext == GIF_EXT_APPLICATION ) {
- info->application_extension_offsets.push_back(io->tell_proc(handle));
- }
- } else if( block == GIF_BLOCK_TRAILER ) {
- continue;
- } else {
- throw "Invalid GIF block found";
- }
-
- //Data Sub-blocks
- BYTE len;
- if( io->read_proc(&len, 1, 1, handle) < 1 ) {
- throw "EOF reading sub-block";
- }
- while( len != 0 ) {
- io->seek_proc(handle, len, SEEK_CUR);
- if( io->read_proc(&len, 1, 1, handle) < 1 ) {
- throw "EOF reading sub-block";
- }
- }
- }
- } catch (const char *msg) {
- FreeImage_OutputMessageProc(s_format_id, msg);
- delete info;
- return NULL;
- }
- } else {
- //Header
- io->write_proc((void *)"GIF89a", 6, 1, handle);
- }
-
- return info;
-}
-
-static void DLL_CALLCONV
-Close(FreeImageIO *io, fi_handle handle, void *data) {
- if( data == NULL ) {
- return;
- }
- GIFinfo *info = (GIFinfo *)data;
-
- if( !info->read ) {
- //Trailer
- BYTE b = GIF_BLOCK_TRAILER;
- io->write_proc(&b, 1, 1, handle);
- }
-
- delete info;
-}
-
-static int DLL_CALLCONV
-PageCount(FreeImageIO *io, fi_handle handle, void *data) {
- if( data == NULL ) {
- return 0;
- }
- GIFinfo *info = (GIFinfo *)data;
-
- return (int) info->image_descriptor_offsets.size();
-}
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
- if( data == NULL ) {
- return NULL;
- }
- GIFinfo *info = (GIFinfo *)data;
-
- 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);
- io->read_proc(&logicalheight, 2, 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&logicalwidth);
- SwapShort(&logicalheight);
-#endif
- //set the background color with 0 alpha
- RGBQUAD background;
- if( info->global_color_table_offset != 0 && info->background_color < info->global_color_table_size ) {
- io->seek_proc(handle, (long)(info->global_color_table_offset + (info->background_color * 3)), SEEK_SET);
- io->read_proc(&background.rgbRed, 1, 1, handle);
- io->read_proc(&background.rgbGreen, 1, 1, handle);
- io->read_proc(&background.rgbBlue, 1, 1, handle);
- } else {
- background.rgbRed = 0;
- background.rgbGreen = 0;
- background.rgbBlue = 0;
- }
- background.rgbReserved = 0;
-
- //allocate entire logical area
- dib = FreeImage_Allocate(logicalwidth, logicalheight, 32);
- if( dib == NULL ) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- //fill with background color to start
- int x, y;
- RGBQUAD *scanline;
- for( y = 0; y < logicalheight; y++ ) {
- scanline = (RGBQUAD *)FreeImage_GetScanLine(dib, y);
- for( x = 0; x < logicalwidth; x++ ) {
- *scanline++ = background;
- }
- }
-
- //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);
- SwapShort(&width);
- SwapShort(&height);
-#endif
-
- 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;
- }
-
- //draw each page into the logical area
- delay_time = 0;
- for( page = start; page <= end; page++ ) {
- PageInfo &info = pageinfo[end - page];
- //things we can skip having to decode
- if( page != end ) {
- if( info.disposal_method == GIF_DISPOSAL_PREVIOUS ) {
- continue;
- }
- if( info.disposal_method == GIF_DISPOSAL_BACKGROUND ) {
- 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;
- for( x = 0; x < info.width; x++ ) {
- *scanline++ = background;
- }
- }
- 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;
- if( FreeImage_GetMetadataEx(FIMD_ANIMATION, pagedib, "FrameTime", FIDT_LONG, &tag) ) {
- delay_time = *(LONG *)FreeImage_GetTagValue(tag);
- }
- }
- FreeImage_Unload(pagedib);
- }
- }
-
- //setup frame time
- FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "FrameTime", ANIMTAG_FRAMETIME, FIDT_LONG, 1, 4, &delay_time);
- return dib;
- }
-
- //get the actual frame image data for a single frame
-
- //Image Descriptor
- io->seek_proc(handle, (long)info->image_descriptor_offsets[page], 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);
- SwapShort(&width);
- SwapShort(&height);
-#endif
- io->read_proc(&packed, 1, 1, handle);
- interlaced = (packed & GIF_PACKED_ID_INTERLACED) ? true : false;
- no_local_palette = (packed & GIF_PACKED_ID_HAVELCT) ? false : true;
-
- int bpp = 8;
- if( (flags & GIF_LOAD256) == 0 ) {
- if( !no_local_palette ) {
- int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE);
- if( size <= 2 ) bpp = 1;
- else if( size <= 16 ) bpp = 4;
- } else if( info->global_color_table_offset != 0 ) {
- if( info->global_color_table_size <= 2 ) bpp = 1;
- else if( info->global_color_table_size <= 16 ) bpp = 4;
- }
- }
- dib = FreeImage_Allocate(width, height, bpp);
- if( dib == NULL ) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
-
- FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "FrameLeft", ANIMTAG_FRAMELEFT, FIDT_SHORT, 1, 2, &left);
- FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "FrameTop", ANIMTAG_FRAMETOP, FIDT_SHORT, 1, 2, &top);
- b = no_local_palette ? 1 : 0;
- FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "NoLocalPalette", ANIMTAG_NOLOCALPALETTE, FIDT_BYTE, 1, 1, &b);
- b = interlaced ? 1 : 0;
- FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "Interlaced", ANIMTAG_INTERLACED, FIDT_BYTE, 1, 1, &b);
-
- //Palette
- RGBQUAD *pal = FreeImage_GetPalette(dib);
- if( !no_local_palette ) {
- int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE);
-
- int i = 0;
- while( i < size ) {
- io->read_proc(&pal[i].rgbRed, 1, 1, handle);
- io->read_proc(&pal[i].rgbGreen, 1, 1, handle);
- io->read_proc(&pal[i].rgbBlue, 1, 1, handle);
- i++;
- }
- } else if( info->global_color_table_offset != 0 ) {
- long pos = io->tell_proc(handle);
- io->seek_proc(handle, (long)info->global_color_table_offset, SEEK_SET);
-
- int i = 0;
- while( i < info->global_color_table_size ) {
- io->read_proc(&pal[i].rgbRed, 1, 1, handle);
- io->read_proc(&pal[i].rgbGreen, 1, 1, handle);
- io->read_proc(&pal[i].rgbBlue, 1, 1, handle);
- i++;
- }
-
- io->seek_proc(handle, pos, SEEK_SET);
- } else {
- //its legal to have no palette, but we're going to generate *something*
- for( int i = 0; i < 256; i++ ) {
- pal[i].rgbRed = (BYTE)i;
- pal[i].rgbGreen = (BYTE)i;
- pal[i].rgbBlue = (BYTE)i;
- }
- }
-
- //LZW Minimum Code Size
- io->read_proc(&b, 1, 1, handle);
- StringTable *stringtable = new(std::nothrow) StringTable;
- stringtable->Initialize(b);
-
- //Image Data Sub-blocks
- int x = 0, xpos = 0, y = 0, shift = 8 - bpp, mask = (1 << bpp) - 1, interlacepass = 0;
- BYTE *scanline = FreeImage_GetScanLine(dib, height - 1);
- BYTE buf[4096];
- io->read_proc(&b, 1, 1, handle);
- while( b ) {
- io->read_proc(stringtable->FillInputBuffer(b), b, 1, handle);
- int size = sizeof(buf);
- while( stringtable->Decompress(buf, &size) ) {
- for( int i = 0; i < size; i++ ) {
- scanline[xpos] |= (buf[i] & mask) << shift;
- if( shift > 0 ) {
- shift -= bpp;
- } else {
- xpos++;
- shift = 8 - bpp;
- }
- if( ++x >= width ) {
- if( interlaced ) {
- y += g_GifInterlaceIncrement[interlacepass];
- if( y >= height && ++interlacepass < GIF_INTERLACE_PASSES ) {
- y = g_GifInterlaceOffset[interlacepass];
- }
- } else {
- y++;
- }
- if( y >= height ) {
- stringtable->Done();
- break;
- }
- x = xpos = 0;
- shift = 8 - bpp;
- scanline = FreeImage_GetScanLine(dib, height - y - 1);
- }
- }
- size = sizeof(buf);
- }
- io->read_proc(&b, 1, 1, handle);
- }
-
- if( page == 0 ) {
- size_t idx;
-
- //Logical Screen Descriptor
- io->seek_proc(handle, 6, SEEK_SET);
- WORD logicalwidth, logicalheight;
- io->read_proc(&logicalwidth, 2, 1, handle);
- io->read_proc(&logicalheight, 2, 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&logicalwidth);
- SwapShort(&logicalheight);
-#endif
- FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "LogicalWidth", ANIMTAG_LOGICALWIDTH, FIDT_SHORT, 1, 2, &logicalwidth);
- FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "LogicalHeight", ANIMTAG_LOGICALHEIGHT, FIDT_SHORT, 1, 2, &logicalheight);
-
- //Global Color Table
- if( info->global_color_table_offset != 0 ) {
- RGBQUAD globalpalette[256];
- io->seek_proc(handle, (long)info->global_color_table_offset, SEEK_SET);
- int i = 0;
- while( i < info->global_color_table_size ) {
- io->read_proc(&globalpalette[i].rgbRed, 1, 1, handle);
- io->read_proc(&globalpalette[i].rgbGreen, 1, 1, handle);
- io->read_proc(&globalpalette[i].rgbBlue, 1, 1, handle);
- globalpalette[i].rgbReserved = 0;
- i++;
- }
- FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "GlobalPalette", ANIMTAG_GLOBALPALETTE, FIDT_PALETTE, info->global_color_table_size, info->global_color_table_size * 4, globalpalette);
- //background color
- if( info->background_color < info->global_color_table_size ) {
- FreeImage_SetBackgroundColor(dib, &globalpalette[info->background_color]);
- }
- }
-
- //Application Extension
- LONG loop = 1; //If no AE with a loop count is found, the default must be 1
- for( idx = 0; idx < info->application_extension_offsets.size(); idx++ ) {
- io->seek_proc(handle, (long)info->application_extension_offsets[idx], SEEK_SET);
- io->read_proc(&b, 1, 1, handle);
- if( b == 11 ) { //All AEs start with an 11 byte sub-block to determine what type of AE it is
- char buf[11];
- io->read_proc(buf, 11, 1, handle);
- if( !memcmp(buf, "NETSCAPE2.0", 11) || !memcmp(buf, "ANIMEXTS1.0", 11) ) { //Not everybody recognizes ANIMEXTS1.0 but it is valid
- io->read_proc(&b, 1, 1, handle);
- if( b == 3 ) { //we're supposed to have a 3 byte sub-block now
- io->read_proc(&b, 1, 1, handle); //this should be 0x01 but isn't really important
- io->read_proc(&w, 2, 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&w);
-#endif
- loop = w;
- if( loop > 0 ) loop++;
- break;
- }
- }
- }
- }
- FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "Loop", ANIMTAG_LOOP, FIDT_LONG, 1, 4, &loop);
-
- // Comment Extension
- for (idx = 0; idx < info->comment_extension_offsets.size(); idx++) {
- io->seek_proc(handle, (long)info->comment_extension_offsets[idx], SEEK_SET);
- std::string comment;
- char buf[255];
- io->read_proc(&b, 1, 1, handle);
- while (b) {
- io->read_proc(buf, b, 1, handle);
- comment.append(buf, b);
- io->read_proc(&b, 1, 1, handle);
- }
- comment.append(1, '\0');
- sprintf(buf, "Comment%d", (int)idx);
- DWORD comment_size = (DWORD)comment.size();
- FreeImage_SetMetadataEx(FIMD_COMMENTS, dib, buf, 1, FIDT_ASCII, comment_size, comment_size, comment.c_str());
- }
- }
-
- //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;
-
- } catch (const char *msg) {
- if( dib != NULL ) {
- FreeImage_Unload(dib);
- }
- FreeImage_OutputMessageProc(s_format_id, msg);
- return NULL;
- }
-
- return dib;
-}
-
-static BOOL DLL_CALLCONV
-Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
- if( data == NULL ) {
- return FALSE;
- }
- //GIFinfo *info = (GIFinfo *)data;
-
- if( page == -1 ) {
- page = 0;
- }
-
- 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;
- }
- if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "Interlaced", FIDT_BYTE, &tag) ) {
- interlaced = *(BYTE *)FreeImage_GetTagValue(tag) ? true : false;
- }
- if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "FrameTime", FIDT_LONG, &tag) ) {
- delay_time = *(LONG *)FreeImage_GetTagValue(tag);
- }
- if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "DisposalMethod", FIDT_BYTE, &tag) ) {
- disposal_method = *(BYTE *)FreeImage_GetTagValue(tag);
- }
-
- RGBQUAD *pal = FreeImage_GetPalette(dib);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&left);
- SwapShort(&top);
- SwapShort(&width);
- SwapShort(&height);
-#endif
-
- if( page == 0 ) {
- //gather some info
- WORD logicalwidth = width; // width has already been swapped...
- if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "LogicalWidth", FIDT_SHORT, &tag) ) {
- logicalwidth = *(WORD *)FreeImage_GetTagValue(tag);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&logicalwidth);
-#endif
- }
- WORD logicalheight = height; // height has already been swapped...
- if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "LogicalHeight", FIDT_SHORT, &tag) ) {
- logicalheight = *(WORD *)FreeImage_GetTagValue(tag);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&logicalheight);
-#endif
- }
- RGBQUAD *globalpalette = NULL;
- int globalpalette_size = 0;
- if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "GlobalPalette", FIDT_PALETTE, &tag) ) {
- globalpalette_size = FreeImage_GetTagCount(tag);
- if( globalpalette_size >= 2 ) {
- globalpalette = (RGBQUAD *)FreeImage_GetTagValue(tag);
- }
- }
-
- //Logical Screen Descriptor
- io->write_proc(&logicalwidth, 2, 1, handle);
- io->write_proc(&logicalheight, 2, 1, handle);
- packed = GIF_PACKED_LSD_COLORRES;
- b = 0;
- RGBQUAD background_color;
- if( globalpalette != NULL ) {
- packed |= GIF_PACKED_LSD_HAVEGCT;
- if( globalpalette_size < 4 ) {
- globalpalette_size = 2;
- packed |= 0 & GIF_PACKED_LSD_GCTSIZE;
- } else if( globalpalette_size < 8 ) {
- globalpalette_size = 4;
- packed |= 1 & GIF_PACKED_LSD_GCTSIZE;
- } else if( globalpalette_size < 16 ) {
- globalpalette_size = 8;
- packed |= 2 & GIF_PACKED_LSD_GCTSIZE;
- } else if( globalpalette_size < 32 ) {
- globalpalette_size = 16;
- packed |= 3 & GIF_PACKED_LSD_GCTSIZE;
- } else if( globalpalette_size < 64 ) {
- globalpalette_size = 32;
- packed |= 4 & GIF_PACKED_LSD_GCTSIZE;
- } else if( globalpalette_size < 128 ) {
- globalpalette_size = 64;
- packed |= 5 & GIF_PACKED_LSD_GCTSIZE;
- } else if( globalpalette_size < 256 ) {
- globalpalette_size = 128;
- packed |= 6 & GIF_PACKED_LSD_GCTSIZE;
- } else {
- globalpalette_size = 256;
- packed |= 7 & GIF_PACKED_LSD_GCTSIZE;
- }
- if( FreeImage_GetBackgroundColor(dib, &background_color) ) {
- for( int i = 0; i < globalpalette_size; i++ ) {
- if( background_color.rgbRed == globalpalette[i].rgbRed &&
- background_color.rgbGreen == globalpalette[i].rgbGreen &&
- background_color.rgbBlue == globalpalette[i].rgbBlue ) {
-
- b = (BYTE)i;
- break;
- }
- }
- }
- } else {
- packed |= (bpp - 1) & GIF_PACKED_LSD_GCTSIZE;
- }
- io->write_proc(&packed, 1, 1, handle);
- io->write_proc(&b, 1, 1, handle);
- b = 0;
- io->write_proc(&b, 1, 1, handle);
-
- //Global Color Table
- if( globalpalette != NULL ) {
- int i = 0;
- while( i < globalpalette_size ) {
- io->write_proc(&globalpalette[i].rgbRed, 1, 1, handle);
- io->write_proc(&globalpalette[i].rgbGreen, 1, 1, handle);
- io->write_proc(&globalpalette[i].rgbBlue, 1, 1, handle);
- i++;
- }
- }
-
- //Application Extension
- LONG loop = 0;
- if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "Loop", FIDT_LONG, &tag) ) {
- loop = *(LONG *)FreeImage_GetTagValue(tag);
- }
- if( loop != 1 ) {
- //the Netscape extension is really "repeats" not "loops"
- if( loop > 1 ) loop--;
- if( loop > 0xFFFF ) loop = 0xFFFF;
- w = (WORD)loop;
-#ifdef FREEIMAGE_BIGENDIAN
- SwapShort(&w);
-#endif
- io->write_proc((void *)"\x21\xFF\x0BNETSCAPE2.0\x03\x01", 16, 1, handle);
- io->write_proc(&w, 2, 1, handle);
- b = 0;
- io->write_proc(&b, 1, 1, handle);
- }
-
- //Comment Extension
- FIMETADATA *mdhandle = NULL;
- FITAG *tag = NULL;
- mdhandle = FreeImage_FindFirstMetadata(FIMD_COMMENTS, dib, &tag);
- if( mdhandle ) {
- do {
- if( FreeImage_GetTagType(tag) == FIDT_ASCII ) {
- int length = FreeImage_GetTagLength(tag) - 1;
- char *value = (char *)FreeImage_GetTagValue(tag);
- io->write_proc((void *)"\x21\xFE", 2, 1, handle);
- while( length > 0 ) {
- b = (BYTE)(length >= 255 ? 255 : length);
- io->write_proc(&b, 1, 1, handle);
- io->write_proc(value, b, 1, handle);
- value += b;
- length -= b;
- }
- b = 0;
- io->write_proc(&b, 1, 1, handle);
- }
- } while(FreeImage_FindNextMetadata(mdhandle, &tag));
-
- 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);
- io->write_proc(&height, 2, 1, handle);
- packed = 0;
- if( !no_local_palette ) packed |= GIF_PACKED_ID_HAVELCT | ((bpp - 1) & GIF_PACKED_ID_LCTSIZE);
- if( interlaced ) packed |= GIF_PACKED_ID_INTERLACED;
- io->write_proc(&packed, 1, 1, handle);
-
- //Local Color Table
- if( !no_local_palette ) {
- int palsize = 1 << bpp;
- for( int i = 0; i < palsize; i++ ) {
- io->write_proc(&pal[i].rgbRed, 1, 1, handle);
- io->write_proc(&pal[i].rgbGreen, 1, 1, handle);
- io->write_proc(&pal[i].rgbBlue, 1, 1, handle);
- }
- }
-
-
- //LZW Minimum Code Size
- b = (BYTE)(bpp == 1 ? 2 : bpp);
- io->write_proc(&b, 1, 1, handle);
- StringTable *stringtable = new(std::nothrow) StringTable;
- stringtable->Initialize(b);
- stringtable->CompressStart(bpp, width);
-
- //Image Data Sub-blocks
- int y = 0, interlacepass = 0, line = FreeImage_GetLine(dib);
- BYTE buf[255], *bufptr = buf; //255 is the max sub-block length
- int size = sizeof(buf);
- b = sizeof(buf);
- while( y < output_height ) {
- memcpy(stringtable->FillInputBuffer(line), FreeImage_GetScanLine(dib, output_height - y - 1), line);
- while( stringtable->Compress(bufptr, &size) ) {
- bufptr += size;
- if( bufptr - buf == sizeof(buf) ) {
- io->write_proc(&b, 1, 1, handle);
- io->write_proc(buf, sizeof(buf), 1, handle);
- size = sizeof(buf);
- bufptr = buf;
- } else {
- size = (int)(sizeof(buf) - (bufptr - buf));
- }
- }
- if( interlaced ) {
- y += g_GifInterlaceIncrement[interlacepass];
- if( y >= output_height && ++interlacepass < GIF_INTERLACE_PASSES ) {
- y = g_GifInterlaceOffset[interlacepass];
- }
- } else {
- y++;
- }
- }
- size = (int)(bufptr - buf);
- BYTE last[4];
- w = (WORD)stringtable->CompressEnd(last);
- if( size + w >= sizeof(buf) ) {
- //one last full size sub-block
- io->write_proc(&b, 1, 1, handle);
- io->write_proc(buf, size, 1, handle);
- io->write_proc(last, sizeof(buf) - size, 1, handle);
- //and possibly a tiny additional sub-block
- b = (BYTE)(w - (sizeof(buf) - size));
- if( b > 0 ) {
- io->write_proc(&b, 1, 1, handle);
- io->write_proc(last + w - b, b, 1, handle);
- }
- } else {
- //last sub-block less than full size
- b = (BYTE)(size + w);
- io->write_proc(&b, 1, 1, handle);
- io->write_proc(buf, size, 1, handle);
- io->write_proc(last, w, 1, handle);
- }
-
- //Block Terminator
- b = 0;
- io->write_proc(&b, 1, 1, handle);
-
- delete stringtable;
-
- } catch (const char *msg) {
- FreeImage_OutputMessageProc(s_format_id, msg);
- return FALSE;
- }
-
- return TRUE;
-}
-
-// ==========================================================
-// Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitGIF(Plugin *plugin, int format_id) {
- s_format_id = format_id;
-
- plugin->format_proc = Format;
- plugin->description_proc = Description;
- plugin->extension_proc = Extension;
- plugin->regexpr_proc = RegExpr;
- plugin->open_proc = Open;
- plugin->close_proc = Close;
- plugin->pagecount_proc = PageCount;
- plugin->pagecapability_proc = NULL;
- plugin->load_proc = Load;
- plugin->save_proc = Save;
- plugin->validate_proc = Validate;
- plugin->mime_proc = MimeType;
- plugin->supports_export_bpp_proc = SupportsExportDepth;
- plugin->supports_export_type_proc = SupportsExportType;
- plugin->supports_icc_profiles_proc = NULL;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/PluginICO.cpp b/plugins/AdvaImg/src/FreeImage/PluginICO.cpp
deleted file mode 100644
index 5c4673e4de..0000000000
--- a/plugins/AdvaImg/src/FreeImage/PluginICO.cpp
+++ /dev/null
@@ -1,824 +0,0 @@
-// ==========================================================
-// ICO Loader and Writer
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-// ----------------------------------------------------------
-// Constants + headers
-// ----------------------------------------------------------
-
-#ifdef _WIN32
-#pragma pack(push, 1)
-#else
-#pragma pack(1)
-#endif
-
-// These next two structs represent how the icon information is stored
-// in an ICO file.
-
-typedef struct tagICONHEADER {
- WORD idReserved; // reserved
- WORD idType; // resource type (1 for icons)
- WORD idCount; // how many images?
-} ICONHEADER;
-
-typedef struct tagICONDIRECTORYENTRY {
- BYTE bWidth; // width of the image
- BYTE bHeight; // height of the image (times 2)
- BYTE bColorCount; // number of colors in image (0 if >=8bpp)
- BYTE bReserved; // reserved
- WORD wPlanes; // color Planes
- WORD wBitCount; // bits per pixel
- DWORD dwBytesInRes; // how many bytes in this resource?
- DWORD dwImageOffset; // where in the file is this image
-} ICONDIRENTRY;
-
-#ifdef _WIN32
-#pragma pack(pop)
-#else
-#pragma pack()
-#endif
-
-// ==========================================================
-// Static helpers
-// ==========================================================
-
-/** How wide, in bytes, would this many bits be, DWORD aligned ?
-*/
-static int
-WidthBytes(int bits) {
- return ((((bits) + 31)>>5)<<2);
-}
-
-/** Calculates the size of a single icon image
-@return Returns the size for that image
-*/
-static DWORD
-CalculateImageSize(FIBITMAP* icon_dib) {
- DWORD dwNumBytes = 0;
-
- unsigned colors = FreeImage_GetColorsUsed(icon_dib);
- unsigned width = FreeImage_GetWidth(icon_dib);
- unsigned height = FreeImage_GetHeight(icon_dib);
- unsigned pitch = FreeImage_GetPitch(icon_dib);
-
- dwNumBytes = sizeof( BITMAPINFOHEADER ); // header
- dwNumBytes += colors * sizeof(RGBQUAD); // palette
- dwNumBytes += height * pitch; // XOR mask
- dwNumBytes += height * WidthBytes(width); // AND mask
-
- return dwNumBytes;
-}
-
-/** Calculates the file offset for an icon image
-@return Returns the file offset for that image
-*/
-static DWORD
-CalculateImageOffset(std::vector<FIBITMAP*>& vPages, int nIndex ) {
- DWORD dwSize;
-
- // calculate the ICO header size
- dwSize = sizeof(ICONHEADER);
- // add the ICONDIRENTRY's
- dwSize += (DWORD)( vPages.size() * sizeof(ICONDIRENTRY) );
- // add the sizes of the previous images
- for(int k = 0; k < nIndex; k++) {
- FIBITMAP *icon_dib = (FIBITMAP*)vPages[k];
- dwSize += CalculateImageSize(icon_dib);
- }
-
- return dwSize;
-}
-
-/**
-Vista icon support
-@return Returns TRUE if the bitmap data is stored in PNG format
-*/
-static BOOL
-IsPNG(FreeImageIO *io, fi_handle handle) {
- BYTE png_signature[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
- BYTE signature[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- long tell = io->tell_proc(handle);
- io->read_proc(&signature, 1, 8, handle);
- BOOL bIsPNG = (memcmp(png_signature, signature, 8) == 0);
- io->seek_proc(handle, tell, SEEK_SET);
-
- return bIsPNG;
-}
-
-#ifdef FREEIMAGE_BIGENDIAN
-static void
-SwapInfoHeader(BITMAPINFOHEADER *header) {
- SwapLong(&header->biSize);
- SwapLong((DWORD *)&header->biWidth);
- SwapLong((DWORD *)&header->biHeight);
- SwapShort(&header->biPlanes);
- SwapShort(&header->biBitCount);
- SwapLong(&header->biCompression);
- SwapLong(&header->biSizeImage);
- SwapLong((DWORD *)&header->biXPelsPerMeter);
- SwapLong((DWORD *)&header->biYPelsPerMeter);
- SwapLong(&header->biClrUsed);
- SwapLong(&header->biClrImportant);
-}
-
-static void
-SwapIconHeader(ICONHEADER *header) {
- SwapShort(&header->idReserved);
- SwapShort(&header->idType);
- SwapShort(&header->idCount);
-}
-
-static void
-SwapIconDirEntries(ICONDIRENTRY *ent, int num) {
- while(num) {
- SwapShort(&ent->wPlanes);
- SwapShort(&ent->wBitCount);
- SwapLong(&ent->dwBytesInRes);
- SwapLong(&ent->dwImageOffset);
- num--;
- ent++;
- }
-}
-#endif
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
- return "ICO";
-}
-
-static const char * DLL_CALLCONV
-Description() {
- return "Windows Icon";
-}
-
-static const char * DLL_CALLCONV
-Extension() {
- return "ico";
-}
-
-static const char * DLL_CALLCONV
-RegExpr() {
- return NULL;
-}
-
-static const char * DLL_CALLCONV
-MimeType() {
- return "image/vnd.microsoft.icon";
-}
-
-static BOOL DLL_CALLCONV
-Validate(FreeImageIO *io, fi_handle handle) {
- ICONHEADER icon_header;
-
- io->read_proc(&icon_header, sizeof(ICONHEADER), 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapIconHeader(&icon_header);
-#endif
-
- return ((icon_header.idReserved == 0) && (icon_header.idType == 1) && (icon_header.idCount > 0));
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportDepth(int depth) {
- return (
- (depth == 1) ||
- (depth == 4) ||
- (depth == 8) ||
- (depth == 16) ||
- (depth == 24) ||
- (depth == 32)
- );
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportType(FREE_IMAGE_TYPE type) {
- return (type == FIT_BITMAP) ? TRUE : FALSE;
-}
-
-static BOOL DLL_CALLCONV
-SupportsNoPixels() {
- return TRUE;
-}
-
-// ----------------------------------------------------------
-
-static void * DLL_CALLCONV
-Open(FreeImageIO *io, fi_handle handle, BOOL read) {
- // Allocate memory for the header structure
- ICONHEADER *lpIH = (ICONHEADER*)malloc(sizeof(ICONHEADER));
- if(lpIH == NULL) {
- return NULL;
- }
-
- if (read) {
- // Read in the header
- io->read_proc(lpIH, 1, sizeof(ICONHEADER), handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapIconHeader(lpIH);
-#endif
-
- if(!(lpIH->idReserved == 0) || !(lpIH->idType == 1)) {
- // Not an ICO file
- free(lpIH);
- return NULL;
- }
- }
- else {
- // Fill the header
- lpIH->idReserved = 0;
- lpIH->idType = 1;
- lpIH->idCount = 0;
- }
-
- return lpIH;
-}
-
-static void DLL_CALLCONV
-Close(FreeImageIO *io, fi_handle handle, void *data) {
- // free the header structure
- ICONHEADER *lpIH = (ICONHEADER*)data;
- free(lpIH);
-}
-
-// ----------------------------------------------------------
-
-static int DLL_CALLCONV
-PageCount(FreeImageIO *io, fi_handle handle, void *data) {
- ICONHEADER *lpIH = (ICONHEADER*)data;
-
- if(lpIH) {
- return lpIH->idCount;
- }
- return 1;
-}
-
-// ----------------------------------------------------------
-
-static FIBITMAP*
-LoadStandardIcon(FreeImageIO *io, fi_handle handle, int flags, BOOL header_only) {
- FIBITMAP *dib = NULL;
-
- // load the BITMAPINFOHEADER
- BITMAPINFOHEADER bmih;
- io->read_proc(&bmih, sizeof(BITMAPINFOHEADER), 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapInfoHeader(&bmih);
-#endif
-
- // allocate the bitmap
- int width = bmih.biWidth;
- int height = bmih.biHeight / 2; // height == xor + and mask
- unsigned bit_count = bmih.biBitCount;
- unsigned line = CalculateLine(width, bit_count);
- unsigned pitch = CalculatePitch(line);
-
- // allocate memory for one icon
-
- dib = FreeImage_AllocateHeader(header_only, width, height, bit_count);
-
- if (dib == NULL) {
- return NULL;
- }
-
- if( bmih.biBitCount <= 8 ) {
- // read the palette data
- io->read_proc(FreeImage_GetPalette(dib), CalculateUsedPaletteEntries(bit_count) * sizeof(RGBQUAD), 1, handle);
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
- RGBQUAD *pal = FreeImage_GetPalette(dib);
- for(unsigned i = 0; i < CalculateUsedPaletteEntries(bit_count); i++) {
- INPLACESWAP(pal[i].rgbRed, pal[i].rgbBlue);
- }
-#endif
- }
-
- if(header_only) {
- // header only mode
- return dib;
- }
-
- // read the icon
- io->read_proc(FreeImage_GetBits(dib), height * pitch, 1, handle);
-
-#ifdef FREEIMAGE_BIGENDIAN
- if (bit_count == 16) {
- for(int y = 0; y < height; y++) {
- WORD *pixel = (WORD *)FreeImage_GetScanLine(dib, y);
- for(int x = 0; x < width; x++) {
- SwapShort(pixel);
- pixel++;
- }
- }
- }
-#endif
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
- if (bit_count == 24 || bit_count == 32) {
- for(int y = 0; y < height; y++) {
- BYTE *pixel = FreeImage_GetScanLine(dib, y);
- for(int x = 0; x < width; x++) {
- INPLACESWAP(pixel[0], pixel[2]);
- pixel += (bit_count>>3);
- }
- }
- }
-#endif
- // bitmap has been loaded successfully!
-
- // convert to 32bpp and generate an alpha channel
- // apply the AND mask only if the image is not 32 bpp
- if(((flags & ICO_MAKEALPHA) == ICO_MAKEALPHA) && (bit_count < 32)) {
- FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(dib);
- FreeImage_Unload(dib);
-
- if (dib32 == NULL) {
- return NULL;
- }
-
- int width_and = WidthBytes(width);
- BYTE *line_and = (BYTE *)malloc(width_and);
-
- if( line_and == NULL ) {
- FreeImage_Unload(dib32);
- return NULL;
- }
-
- //loop through each line of the AND-mask generating the alpha channel, invert XOR-mask
- for(int y = 0; y < height; y++) {
- RGBQUAD *quad = (RGBQUAD *)FreeImage_GetScanLine(dib32, y);
- io->read_proc(line_and, width_and, 1, handle);
- for(int x = 0; x < width; x++) {
- quad->rgbReserved = (line_and[x>>3] & (0x80 >> (x & 0x07))) != 0 ? 0 : 0xFF;
- if( quad->rgbReserved == 0 ) {
- quad->rgbBlue ^= 0xFF;
- quad->rgbGreen ^= 0xFF;
- quad->rgbRed ^= 0xFF;
- }
- quad++;
- }
- }
- free(line_and);
-
- return dib32;
- }
-
- return dib;
-}
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
- if (page == -1) {
- page = 0;
- }
-
- BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
-
- if (handle != NULL) {
- FIBITMAP *dib = NULL;
-
- // get the icon header
- ICONHEADER *icon_header = (ICONHEADER*)data;
-
- if (icon_header) {
- // load the icon descriptions
- ICONDIRENTRY *icon_list = (ICONDIRENTRY*)malloc(icon_header->idCount * sizeof(ICONDIRENTRY));
- if(icon_list == NULL) {
- return NULL;
- }
- io->seek_proc(handle, sizeof(ICONHEADER), SEEK_SET);
- io->read_proc(icon_list, icon_header->idCount * sizeof(ICONDIRENTRY), 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapIconDirEntries(icon_list, icon_header->idCount);
-#endif
-
- // load the requested icon
- if (page < icon_header->idCount) {
- // seek to the start of the bitmap data for the icon
- io->seek_proc(handle, icon_list[page].dwImageOffset, SEEK_SET);
-
- if( IsPNG(io, handle) ) {
- // Vista icon support
- // see http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
- dib = FreeImage_LoadFromHandle(FIF_PNG, io, handle, header_only ? FIF_LOAD_NOPIXELS : PNG_DEFAULT);
- }
- else {
- // standard icon support
- // see http://msdn.microsoft.com/en-us/library/ms997538.aspx
- // see http://blogs.msdn.com/b/oldnewthing/archive/2010/10/18/10077133.aspx
- dib = LoadStandardIcon(io, handle, flags, header_only);
- }
-
- free(icon_list);
-
- return dib;
-
- } else {
- free(icon_list);
- FreeImage_OutputMessageProc(s_format_id, "Page doesn't exist");
- }
- } else {
- FreeImage_OutputMessageProc(s_format_id, "File is not an ICO file");
- }
- }
-
- return NULL;
-}
-
-// ----------------------------------------------------------
-
-static BOOL
-SaveStandardIcon(FreeImageIO *io, FIBITMAP *dib, fi_handle handle) {
- BITMAPINFOHEADER *bmih = NULL;
-
- // write the BITMAPINFOHEADER
- bmih = FreeImage_GetInfoHeader(dib);
- bmih->biHeight *= 2; // height == xor + and mask
-#ifdef FREEIMAGE_BIGENDIAN
- SwapInfoHeader(bmih);
-#endif
- io->write_proc(bmih, sizeof(BITMAPINFOHEADER), 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapInfoHeader(bmih);
-#endif
- bmih->biHeight /= 2;
-
- // write the palette data
- if (FreeImage_GetPalette(dib) != NULL) {
- RGBQUAD *pal = FreeImage_GetPalette(dib);
- FILE_BGRA bgra;
- for(unsigned i = 0; i < FreeImage_GetColorsUsed(dib); i++) {
- bgra.b = pal[i].rgbBlue;
- bgra.g = pal[i].rgbGreen;
- bgra.r = pal[i].rgbRed;
- bgra.a = pal[i].rgbReserved;
- io->write_proc(&bgra, sizeof(FILE_BGRA), 1, handle);
- }
- }
-
- // write the bits
- int width = bmih->biWidth;
- int height = bmih->biHeight;
- unsigned bit_count = bmih->biBitCount;
- unsigned line = CalculateLine(width, bit_count);
- unsigned pitch = CalculatePitch(line);
- int size_xor = height * pitch;
- int size_and = height * WidthBytes(width);
-
- // XOR mask
-#ifdef FREEIMAGE_BIGENDIAN
- if (bit_count == 16) {
- WORD pixel;
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
- BYTE *line = FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
- pixel = ((WORD *)line)[x];
- SwapShort(&pixel);
- if (io->write_proc(&pixel, sizeof(WORD), 1, handle) != 1)
- return FALSE;
- }
- }
- } else
-#endif
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
- if (bit_count == 24) {
- FILE_BGR bgr;
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
- BYTE *line = FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
- RGBTRIPLE *triple = ((RGBTRIPLE *)line)+x;
- bgr.b = triple->rgbtBlue;
- bgr.g = triple->rgbtGreen;
- bgr.r = triple->rgbtRed;
- if (io->write_proc(&bgr, sizeof(FILE_BGR), 1, handle) != 1)
- return FALSE;
- }
- }
- } else if (bit_count == 32) {
- FILE_BGRA bgra;
- for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
- BYTE *line = FreeImage_GetScanLine(dib, y);
- for(unsigned x = 0; x < FreeImage_GetWidth(dib); x++) {
- RGBQUAD *quad = ((RGBQUAD *)line)+x;
- bgra.b = quad->rgbBlue;
- bgra.g = quad->rgbGreen;
- bgra.r = quad->rgbRed;
- bgra.a = quad->rgbReserved;
- if (io->write_proc(&bgra, sizeof(FILE_BGRA), 1, handle) != 1)
- return FALSE;
- }
- }
- } else
-#endif
-#if defined(FREEIMAGE_BIGENDIAN) || FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
- {
-#endif
- BYTE *xor_mask = FreeImage_GetBits(dib);
- io->write_proc(xor_mask, size_xor, 1, handle);
-#if defined(FREEIMAGE_BIGENDIAN) || FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
- }
-#endif
- // AND mask
- BYTE *and_mask = (BYTE*)malloc(size_and);
- if(!and_mask) {
- return FALSE;
- }
-
- if(FreeImage_IsTransparent(dib)) {
-
- if(bit_count == 32) {
- // create the AND mask from the alpha channel
-
- int width_and = WidthBytes(width);
- 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
-
- BYTE *trns = FreeImage_GetTransparencyTable(dib);
-
- int width_and = WidthBytes(width);
- BYTE *and_bits = and_mask;
-
- // clear the mask
- memset(and_mask, 0, size_and);
-
- 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;
-
- }
- }
- }
- else {
- // empty AND mask
- memset(and_mask, 0, size_and);
- }
-
- io->write_proc(and_mask, size_and, 1, handle);
- free(and_mask);
-
- return TRUE;
-}
-
-static BOOL DLL_CALLCONV
-Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
- ICONHEADER *icon_header = NULL;
- std::vector<FIBITMAP*> vPages;
- int k;
-
- if(!dib || !handle || !data) {
- return FALSE;
- }
-
- // check format limits
- unsigned w = FreeImage_GetWidth(dib);
- unsigned h = FreeImage_GetHeight(dib);
- if((w < 16) || (w > 256) || (h < 16) || (h > 256) || (w != h)) {
- FreeImage_OutputMessageProc(s_format_id, "Unsupported icon size: width x height = %d x %d", w, h);
- return FALSE;
- }
-
- if (page == -1) {
- page = 0;
- }
-
- // get the icon header
- icon_header = (ICONHEADER*)data;
-
- try {
- FIBITMAP *icon_dib = NULL;
-
- // load all icons
- for(k = 0; k < icon_header->idCount; k++) {
- icon_dib = Load(io, handle, k, flags, data);
- if(!icon_dib) {
- throw FI_MSG_ERROR_DIB_MEMORY;
- }
- vPages.push_back(icon_dib);
- }
-
- // add the page
- icon_dib = FreeImage_Clone(dib);
- vPages.push_back(icon_dib);
- icon_header->idCount++;
-
- // write the header
- io->seek_proc(handle, 0, SEEK_SET);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapIconHeader(icon_header);
-#endif
- io->write_proc(icon_header, sizeof(ICONHEADER), 1, handle);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapIconHeader(icon_header);
-#endif
-
- // write all icons
- // ...
-
- // save the icon descriptions
-
- ICONDIRENTRY *icon_list = (ICONDIRENTRY *)malloc(icon_header->idCount * sizeof(ICONDIRENTRY));
- if(!icon_list) {
- throw FI_MSG_ERROR_MEMORY;
- }
- memset(icon_list, 0, icon_header->idCount * sizeof(ICONDIRENTRY));
-
- for(k = 0; k < icon_header->idCount; k++) {
- icon_dib = (FIBITMAP*)vPages[k];
-
- // convert internal format to ICONDIRENTRY
- // take into account Vista icons whose size is 256x256
- const BITMAPINFOHEADER *bmih = FreeImage_GetInfoHeader(icon_dib);
- icon_list[k].bWidth = (bmih->biWidth > 255) ? 0 : (BYTE)bmih->biWidth;
- icon_list[k].bHeight = (bmih->biHeight > 255) ? 0 : (BYTE)bmih->biHeight;
- icon_list[k].bReserved = 0;
- icon_list[k].wPlanes = bmih->biPlanes;
- icon_list[k].wBitCount = bmih->biBitCount;
- if( (icon_list[k].wPlanes * icon_list[k].wBitCount) >= 8 ) {
- icon_list[k].bColorCount = 0;
- } else {
- icon_list[k].bColorCount = (BYTE)(1 << (icon_list[k].wPlanes * icon_list[k].wBitCount));
- }
- // initial guess (correct only for standard icons)
- icon_list[k].dwBytesInRes = CalculateImageSize(icon_dib);
- icon_list[k].dwImageOffset = CalculateImageOffset(vPages, k);
- }
-
- // make a room for icon dir entries, until later update
- const long directory_start = io->tell_proc(handle);
- io->write_proc(icon_list, sizeof(ICONDIRENTRY) * icon_header->idCount, 1, handle);
-
- // write the image bits for each image
-
- DWORD dwImageOffset = (DWORD)io->tell_proc(handle);
-
- for(k = 0; k < icon_header->idCount; k++) {
- icon_dib = (FIBITMAP*)vPages[k];
-
- if((icon_list[k].bWidth == 0) && (icon_list[k].bHeight == 0)) {
- // Vista icon support
- FreeImage_SaveToHandle(FIF_PNG, icon_dib, io, handle, PNG_DEFAULT);
- }
- else {
- // standard icon support
- // see http://msdn.microsoft.com/en-us/library/ms997538.aspx
- SaveStandardIcon(io, icon_dib, handle);
- }
-
- // update ICONDIRENTRY members
- DWORD dwBytesInRes = (DWORD)io->tell_proc(handle) - dwImageOffset;
- icon_list[k].dwImageOffset = dwImageOffset;
- icon_list[k].dwBytesInRes = dwBytesInRes;
- dwImageOffset += dwBytesInRes;
- }
-
- // update the icon descriptions
- const long current_pos = io->tell_proc(handle);
- io->seek_proc(handle, directory_start, SEEK_SET);
-#ifdef FREEIMAGE_BIGENDIAN
- SwapIconDirEntries(icon_list, icon_header->idCount);
-#endif
- io->write_proc(icon_list, sizeof(ICONDIRENTRY) * icon_header->idCount, 1, handle);
- io->seek_proc(handle, current_pos, SEEK_SET);
-
- free(icon_list);
-
- // free the vector class
- for(k = 0; k < icon_header->idCount; k++) {
- icon_dib = (FIBITMAP*)vPages[k];
- FreeImage_Unload(icon_dib);
- }
-
- return TRUE;
-
- } catch(const char *text) {
- // free the vector class
- for(size_t k = 0; k < vPages.size(); k++) {
- FIBITMAP *icon_dib = (FIBITMAP*)vPages[k];
- FreeImage_Unload(icon_dib);
- }
- FreeImage_OutputMessageProc(s_format_id, text);
- return FALSE;
- }
-}
-
-// ==========================================================
-// Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitICO(Plugin *plugin, int format_id) {
- s_format_id = format_id;
-
- plugin->format_proc = Format;
- plugin->description_proc = Description;
- plugin->extension_proc = Extension;
- plugin->regexpr_proc = RegExpr;
- plugin->open_proc = Open;
- plugin->close_proc = Close;
- plugin->pagecount_proc = PageCount;
- plugin->pagecapability_proc = NULL;
- plugin->load_proc = Load;
- plugin->save_proc = Save;
- plugin->validate_proc = Validate;
- plugin->mime_proc = MimeType;
- plugin->supports_export_bpp_proc = SupportsExportDepth;
- plugin->supports_export_type_proc = SupportsExportType;
- plugin->supports_icc_profiles_proc = NULL;
- plugin->supports_no_pixels_proc = SupportsNoPixels;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/PluginJPEG.cpp b/plugins/AdvaImg/src/FreeImage/PluginJPEG.cpp
deleted file mode 100644
index 19e4a070a5..0000000000
--- a/plugins/AdvaImg/src/FreeImage/PluginJPEG.cpp
+++ /dev/null
@@ -1,1706 +0,0 @@
-// ==========================================================
-// JPEG Loader and writer
-// Based on code developed by The Independent JPEG Group
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Jan L. Nauta (jln@magentammt.com)
-// - Markus Loibl (markus.loibl@epost.de)
-// - Karl-Heinz Bussian (khbussian@moss.de)
-// - Hervé Drolon (drolon@infonie.fr)
-// - Jascha Wetzel (jascha@mainia.de)
-// - 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
-
-extern "C" {
-#define XMD_H
-#undef FAR
-#include <setjmp.h>
-
-#include "../LibJPEG/jinclude.h"
-#include "../LibJPEG/jpeglib.h"
-#include "../LibJPEG/jerror.h"
-}
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-#include "../Metadata/FreeImageTag.h"
-
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ----------------------------------------------------------
-// Constant declarations
-// ----------------------------------------------------------
-
-#define INPUT_BUF_SIZE 4096 // choose an efficiently fread'able size
-#define OUTPUT_BUF_SIZE 4096 // choose an efficiently fwrite'able size
-
-#define EXIF_MARKER (JPEG_APP0+1) // EXIF marker / Adobe XMP marker
-#define ICC_MARKER (JPEG_APP0+2) // ICC profile marker
-#define IPTC_MARKER (JPEG_APP0+13) // IPTC marker / BIM marker
-
-#define ICC_HEADER_SIZE 14 // size of non-profile data in APP2
-#define MAX_BYTES_IN_MARKER 65533L // maximum data length of a JPEG marker
-#define MAX_DATA_BYTES_IN_MARKER 65519L // maximum data length of a JPEG APP2 marker
-
-#define MAX_JFXX_THUMB_SIZE (MAX_BYTES_IN_MARKER - 5 - 1)
-
-#define JFXX_TYPE_JPEG 0x10 // JFIF extension marker: JPEG-compressed thumbnail image
-#define JFXX_TYPE_8bit 0x11 // JFIF extension marker: palette thumbnail image
-#define JFXX_TYPE_24bit 0x13 // JFIF extension marker: RGB thumbnail image
-
-// ----------------------------------------------------------
-// Typedef declarations
-// ----------------------------------------------------------
-
-typedef struct tagErrorManager {
- /// "public" fields
- struct jpeg_error_mgr pub;
- /// for return to caller
- jmp_buf setjmp_buffer;
-} ErrorManager;
-
-typedef struct tagSourceManager {
- /// public fields
- struct jpeg_source_mgr pub;
- /// source stream
- fi_handle infile;
- FreeImageIO *m_io;
- /// start of buffer
- JOCTET * buffer;
- /// have we gotten any data yet ?
- boolean start_of_file;
-} SourceManager;
-
-typedef struct tagDestinationManager {
- /// public fields
- struct jpeg_destination_mgr pub;
- /// destination stream
- fi_handle outfile;
- FreeImageIO *m_io;
- /// start of buffer
- JOCTET * buffer;
-} DestinationManager;
-
-typedef SourceManager* freeimage_src_ptr;
-typedef DestinationManager* freeimage_dst_ptr;
-typedef ErrorManager* freeimage_error_ptr;
-
-// ----------------------------------------------------------
-// Error handling
-// ----------------------------------------------------------
-
-/** Fatal errors (print message and exit) */
-static inline void
-JPEG_EXIT(j_common_ptr cinfo, int code) {
- freeimage_error_ptr error_ptr = (freeimage_error_ptr)cinfo->err;
- error_ptr->pub.msg_code = code;
- error_ptr->pub.error_exit(cinfo);
-}
-
-/** Nonfatal errors (we can keep going, but the data is probably corrupt) */
-static inline void
-JPEG_WARNING(j_common_ptr cinfo, int code) {
- freeimage_error_ptr error_ptr = (freeimage_error_ptr)cinfo->err;
- error_ptr->pub.msg_code = code;
- error_ptr->pub.emit_message(cinfo, -1);
-}
-
-/**
- Receives control for a fatal error. Information sufficient to
- generate the error message has been stored in cinfo->err; call
- output_message to display it. Control must NOT return to the caller;
- generally this routine will exit() or longjmp() somewhere.
-*/
-METHODDEF(void)
-jpeg_error_exit (j_common_ptr cinfo) {
- freeimage_error_ptr error_ptr = (freeimage_error_ptr)cinfo->err;
-
- // always display the message
- error_ptr->pub.output_message(cinfo);
-
- // allow JPEG with unknown markers
- if(error_ptr->pub.msg_code != JERR_UNKNOWN_MARKER) {
-
- // let the memory manager delete any temp files before we die
- jpeg_destroy(cinfo);
-
- // return control to the setjmp point
- longjmp(error_ptr->setjmp_buffer, 1);
- }
-}
-
-/**
- Actual output of any JPEG message. Note that this method does not know
- how to generate a message, only where to send it.
-*/
-METHODDEF(void)
-jpeg_output_message (j_common_ptr cinfo) {
- char buffer[JMSG_LENGTH_MAX];
- freeimage_error_ptr error_ptr = (freeimage_error_ptr)cinfo->err;
-
- // create the message
- error_ptr->pub.format_message(cinfo, buffer);
- // send it to user's message proc
- FreeImage_OutputMessageProc(s_format_id, buffer);
-}
-
-// ----------------------------------------------------------
-// Destination manager
-// ----------------------------------------------------------
-
-/**
- Initialize destination. This is called by jpeg_start_compress()
- before any data is actually written. It must initialize
- next_output_byte and free_in_buffer. free_in_buffer must be
- initialized to a positive value.
-*/
-METHODDEF(void)
-init_destination (j_compress_ptr cinfo) {
- freeimage_dst_ptr dest = (freeimage_dst_ptr) cinfo->dest;
-
- dest->buffer = (JOCTET *)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
- OUTPUT_BUF_SIZE * sizeof(JOCTET));
-
- dest->pub.next_output_byte = dest->buffer;
- dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
-}
-
-/**
- This is called whenever the buffer has filled (free_in_buffer
- reaches zero). In typical applications, it should write out the
- *entire* buffer (use the saved start address and buffer length;
- ignore the current state of next_output_byte and free_in_buffer).
- Then reset the pointer & count to the start of the buffer, and
- return TRUE indicating that the buffer has been dumped.
- free_in_buffer must be set to a positive value when TRUE is
- returned. A FALSE return should only be used when I/O suspension is
- desired.
-*/
-METHODDEF(boolean)
-empty_output_buffer (j_compress_ptr cinfo) {
- freeimage_dst_ptr dest = (freeimage_dst_ptr) cinfo->dest;
-
- if (dest->m_io->write_proc(dest->buffer, 1, OUTPUT_BUF_SIZE, dest->outfile) != OUTPUT_BUF_SIZE) {
- // let the memory manager delete any temp files before we die
- jpeg_destroy((j_common_ptr)cinfo);
-
- JPEG_EXIT((j_common_ptr)cinfo, JERR_FILE_WRITE);
- }
-
- dest->pub.next_output_byte = dest->buffer;
- dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
-
- return TRUE;
-}
-
-/**
- Terminate destination --- called by jpeg_finish_compress() after all
- data has been written. In most applications, this must flush any
- data remaining in the buffer. Use either next_output_byte or
- free_in_buffer to determine how much data is in the buffer.
-*/
-METHODDEF(void)
-term_destination (j_compress_ptr cinfo) {
- freeimage_dst_ptr dest = (freeimage_dst_ptr) cinfo->dest;
-
- size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
-
- // write any data remaining in the buffer
-
- if (datacount > 0) {
- if (dest->m_io->write_proc(dest->buffer, 1, (unsigned int)datacount, dest->outfile) != datacount) {
- // let the memory manager delete any temp files before we die
- jpeg_destroy((j_common_ptr)cinfo);
-
- JPEG_EXIT((j_common_ptr)cinfo, JERR_FILE_WRITE);
- }
- }
-}
-
-// ----------------------------------------------------------
-// Source manager
-// ----------------------------------------------------------
-
-/**
- Initialize source. This is called by jpeg_read_header() before any
- data is actually read. Unlike init_destination(), it may leave
- bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
- will occur immediately).
-*/
-METHODDEF(void)
-init_source (j_decompress_ptr cinfo) {
- freeimage_src_ptr src = (freeimage_src_ptr) cinfo->src;
-
- /* We reset the empty-input-file flag for each image,
- * but we don't clear the input buffer.
- * This is correct behavior for reading a series of images from one source.
- */
-
- src->start_of_file = TRUE;
-}
-
-/**
- This is called whenever bytes_in_buffer has reached zero and more
- data is wanted. In typical applications, it should read fresh data
- into the buffer (ignoring the current state of next_input_byte and
- bytes_in_buffer), reset the pointer & count to the start of the
- buffer, and return TRUE indicating that the buffer has been reloaded.
- It is not necessary to fill the buffer entirely, only to obtain at
- least one more byte. bytes_in_buffer MUST be set to a positive value
- if TRUE is returned. A FALSE return should only be used when I/O
- suspension is desired.
-*/
-METHODDEF(boolean)
-fill_input_buffer (j_decompress_ptr cinfo) {
- freeimage_src_ptr src = (freeimage_src_ptr) cinfo->src;
-
- size_t nbytes = src->m_io->read_proc(src->buffer, 1, INPUT_BUF_SIZE, src->infile);
-
- if (nbytes <= 0) {
- if (src->start_of_file) {
- // treat empty input file as fatal error
-
- // let the memory manager delete any temp files before we die
- jpeg_destroy((j_common_ptr)cinfo);
-
- JPEG_EXIT((j_common_ptr)cinfo, JERR_INPUT_EMPTY);
- }
-
- JPEG_WARNING((j_common_ptr)cinfo, JWRN_JPEG_EOF);
-
- /* Insert a fake EOI marker */
-
- src->buffer[0] = (JOCTET) 0xFF;
- src->buffer[1] = (JOCTET) JPEG_EOI;
-
- nbytes = 2;
- }
-
- src->pub.next_input_byte = src->buffer;
- src->pub.bytes_in_buffer = nbytes;
- src->start_of_file = FALSE;
-
- return TRUE;
-}
-
-/**
- Skip num_bytes worth of data. The buffer pointer and count should
- be advanced over num_bytes input bytes, refilling the buffer as
- needed. This is used to skip over a potentially large amount of
- uninteresting data (such as an APPn marker). In some applications
- it may be possible to optimize away the reading of the skipped data,
- but it's not clear that being smart is worth much trouble; large
- skips are uncommon. bytes_in_buffer may be zero on return.
- A zero or negative skip count should be treated as a no-op.
-*/
-METHODDEF(void)
-skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
- freeimage_src_ptr src = (freeimage_src_ptr) cinfo->src;
-
- /* Just a dumb implementation for now. Could use fseek() except
- * it doesn't work on pipes. Not clear that being smart is worth
- * any trouble anyway --- large skips are infrequent.
- */
-
- if (num_bytes > 0) {
- while (num_bytes > (long) src->pub.bytes_in_buffer) {
- num_bytes -= (long) src->pub.bytes_in_buffer;
-
- (void) fill_input_buffer(cinfo);
-
- /* note we assume that fill_input_buffer will never return FALSE,
- * so suspension need not be handled.
- */
- }
-
- src->pub.next_input_byte += (size_t) num_bytes;
- src->pub.bytes_in_buffer -= (size_t) num_bytes;
- }
-}
-
-/**
- Terminate source --- called by jpeg_finish_decompress
- after all data has been read. Often a no-op.
-
- NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
- application must deal with any cleanup that should happen even
- for error exit.
-*/
-METHODDEF(void)
-term_source (j_decompress_ptr cinfo) {
- // no work necessary here
-}
-
-// ----------------------------------------------------------
-// Source manager & Destination manager setup
-// ----------------------------------------------------------
-
-/**
- Prepare for input from a stdio stream.
- The caller must have already opened the stream, and is responsible
- for closing it after finishing decompression.
-*/
-GLOBAL(void)
-jpeg_freeimage_src (j_decompress_ptr cinfo, fi_handle infile, FreeImageIO *io) {
- freeimage_src_ptr src;
-
- // allocate memory for the buffer. is released automatically in the end
-
- if (cinfo->src == NULL) {
- cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
- ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(SourceManager));
-
- src = (freeimage_src_ptr) cinfo->src;
-
- src->buffer = (JOCTET *) (*cinfo->mem->alloc_small)
- ((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * sizeof(JOCTET));
- }
-
- // initialize the jpeg pointer struct with pointers to functions
-
- src = (freeimage_src_ptr) cinfo->src;
- src->pub.init_source = init_source;
- src->pub.fill_input_buffer = fill_input_buffer;
- src->pub.skip_input_data = skip_input_data;
- src->pub.resync_to_restart = jpeg_resync_to_restart; // use default method
- src->pub.term_source = term_source;
- src->infile = infile;
- src->m_io = io;
- src->pub.bytes_in_buffer = 0; // forces fill_input_buffer on first read
- src->pub.next_input_byte = NULL; // until buffer loaded
-}
-
-/**
- Prepare for output to a stdio stream.
- The caller must have already opened the stream, and is responsible
- for closing it after finishing compression.
-*/
-GLOBAL(void)
-jpeg_freeimage_dst (j_compress_ptr cinfo, fi_handle outfile, FreeImageIO *io) {
- freeimage_dst_ptr dest;
-
- if (cinfo->dest == NULL) {
- cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small)
- ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(DestinationManager));
- }
-
- dest = (freeimage_dst_ptr) cinfo->dest;
- dest->pub.init_destination = init_destination;
- dest->pub.empty_output_buffer = empty_output_buffer;
- dest->pub.term_destination = term_destination;
- dest->outfile = outfile;
- dest->m_io = io;
-}
-
-// ----------------------------------------------------------
-// Special markers read functions
-// ----------------------------------------------------------
-
-/**
- Read JPEG_COM marker (comment)
-*/
-static BOOL
-jpeg_read_comment(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
- size_t length = datalen;
- BYTE *profile = (BYTE*)dataptr;
-
- // read the comment
- char *value = (char*)malloc((length + 1) * sizeof(char));
- if(value == NULL) return FALSE;
- memcpy(value, profile, length);
- value[length] = '\0';
-
- // create a tag
- FITAG *tag = FreeImage_CreateTag();
- if(tag) {
- unsigned int count = (unsigned int)length + 1; // includes the null value
-
- FreeImage_SetTagID(tag, JPEG_COM);
- FreeImage_SetTagKey(tag, "Comment");
- FreeImage_SetTagLength(tag, count);
- FreeImage_SetTagCount(tag, count);
- FreeImage_SetTagType(tag, FIDT_ASCII);
- FreeImage_SetTagValue(tag, value);
-
- // store the tag
- FreeImage_SetMetadata(FIMD_COMMENTS, dib, FreeImage_GetTagKey(tag), tag);
-
- // destroy the tag
- FreeImage_DeleteTag(tag);
- }
-
- free(value);
-
- return TRUE;
-}
-
-/**
- Read JPEG_APP2 marker (ICC profile)
-*/
-
-/**
-Handy subroutine to test whether a saved marker is an ICC profile marker.
-*/
-static BOOL
-marker_is_icc(jpeg_saved_marker_ptr marker) {
- // marker identifying string "ICC_PROFILE" (null-terminated)
- const BYTE icc_signature[12] = { 0x49, 0x43, 0x43, 0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45, 0x00 };
-
- if(marker->marker == ICC_MARKER) {
- // verify the identifying string
- if(marker->data_length >= ICC_HEADER_SIZE) {
- if(memcmp(icc_signature, marker->data, sizeof(icc_signature)) == 0) {
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-/**
- See if there was an ICC profile in the JPEG file being read;
- if so, reassemble and return the profile data.
-
- TRUE is returned if an ICC profile was found, FALSE if not.
- If TRUE is returned, *icc_data_ptr is set to point to the
- returned data, and *icc_data_len is set to its length.
-
- IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
- and must be freed by the caller with free() when the caller no longer
- needs it. (Alternatively, we could write this routine to use the
- IJG library's memory allocator, so that the data would be freed implicitly
- at jpeg_finish_decompress() time. But it seems likely that many apps
- will prefer to have the data stick around after decompression finishes.)
-
- NOTE: if the file contains invalid ICC APP2 markers, we just silently
- return FALSE. You might want to issue an error message instead.
-*/
-static BOOL
-jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr, unsigned *icc_data_len) {
- jpeg_saved_marker_ptr marker;
- int num_markers = 0;
- int seq_no;
- JOCTET *icc_data;
- unsigned total_length;
-
- const int MAX_SEQ_NO = 255; // sufficient since marker numbers are bytes
- BYTE marker_present[MAX_SEQ_NO+1]; // 1 if marker found
- unsigned data_length[MAX_SEQ_NO+1]; // size of profile data in marker
- unsigned data_offset[MAX_SEQ_NO+1]; // offset for data in marker
-
- *icc_data_ptr = NULL; // avoid confusion if FALSE return
- *icc_data_len = 0;
-
- /**
- this first pass over the saved markers discovers whether there are
- any ICC markers and verifies the consistency of the marker numbering.
- */
-
- memset(marker_present, 0, (MAX_SEQ_NO + 1));
-
- for(marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
- if (marker_is_icc(marker)) {
- if (num_markers == 0) {
- // number of markers
- num_markers = GETJOCTET(marker->data[13]);
- }
- else if (num_markers != GETJOCTET(marker->data[13])) {
- return FALSE; // inconsistent num_markers fields
- }
- // sequence number
- seq_no = GETJOCTET(marker->data[12]);
- if (seq_no <= 0 || seq_no > num_markers) {
- return FALSE; // bogus sequence number
- }
- if (marker_present[seq_no]) {
- return FALSE; // duplicate sequence numbers
- }
- marker_present[seq_no] = 1;
- data_length[seq_no] = marker->data_length - ICC_HEADER_SIZE;
- }
- }
-
- if (num_markers == 0)
- return FALSE;
-
- /**
- check for missing markers, count total space needed,
- compute offset of each marker's part of the data.
- */
-
- total_length = 0;
- for(seq_no = 1; seq_no <= num_markers; seq_no++) {
- if (marker_present[seq_no] == 0) {
- return FALSE; // missing sequence number
- }
- data_offset[seq_no] = total_length;
- total_length += data_length[seq_no];
- }
-
- if (total_length <= 0)
- return FALSE; // found only empty markers ?
-
- // allocate space for assembled data
- icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET));
- if (icc_data == NULL)
- return FALSE; // out of memory
-
- // and fill it in
- for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
- if (marker_is_icc(marker)) {
- JOCTET FAR *src_ptr;
- JOCTET *dst_ptr;
- unsigned length;
- seq_no = GETJOCTET(marker->data[12]);
- dst_ptr = icc_data + data_offset[seq_no];
- src_ptr = marker->data + ICC_HEADER_SIZE;
- length = data_length[seq_no];
- while (length--) {
- *dst_ptr++ = *src_ptr++;
- }
- }
- }
-
- *icc_data_ptr = icc_data;
- *icc_data_len = total_length;
-
- return TRUE;
-}
-
-/**
- Read JPEG_APPD marker (IPTC or Adobe Photoshop profile)
-*/
-static BOOL
-jpeg_read_iptc_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
- return read_iptc_profile(dib, dataptr, datalen);
-}
-
-/**
- Read JPEG_APP1 marker (XMP profile)
- @param dib Input FIBITMAP
- @param dataptr Pointer to the APP1 marker
- @param datalen APP1 marker length
- @return Returns TRUE if successful, FALSE otherwise
-*/
-static BOOL
-jpeg_read_xmp_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
- // marker identifying string for XMP (null terminated)
- const char *xmp_signature = "http://ns.adobe.com/xap/1.0/";
- // XMP signature is 29 bytes long
- const size_t xmp_signature_size = strlen(xmp_signature) + 1;
-
- size_t length = datalen;
- BYTE *profile = (BYTE*)dataptr;
-
- if(length <= xmp_signature_size) {
- // avoid reading corrupted or empty data
- return FALSE;
- }
-
- // verify the identifying string
-
- if(memcmp(xmp_signature, profile, strlen(xmp_signature)) == 0) {
- // XMP profile
-
- profile += xmp_signature_size;
- length -= xmp_signature_size;
-
- // create a tag
- FITAG *tag = FreeImage_CreateTag();
- if(tag) {
- FreeImage_SetTagID(tag, JPEG_APP0+1); // 0xFFE1
- FreeImage_SetTagKey(tag, g_TagLib_XMPFieldName);
- FreeImage_SetTagLength(tag, (DWORD)length);
- FreeImage_SetTagCount(tag, (DWORD)length);
- FreeImage_SetTagType(tag, FIDT_ASCII);
- FreeImage_SetTagValue(tag, profile);
-
- // store the tag
- FreeImage_SetMetadata(FIMD_XMP, dib, FreeImage_GetTagKey(tag), tag);
-
- // destroy the tag
- FreeImage_DeleteTag(tag);
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- Read JFIF "JFXX" extension APP0 marker
- @param dib Input FIBITMAP
- @param dataptr Pointer to the APP0 marker
- @param datalen APP0 marker length
- @return Returns TRUE if successful, FALSE otherwise
-*/
-static BOOL
-jpeg_read_jfxx(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
- if(datalen < 6) {
- return FALSE;
- }
-
- const int id_length = 5;
- const BYTE *data = dataptr + id_length;
- unsigned remaining = datalen - id_length;
-
- const BYTE type = *data;
- ++data, --remaining;
-
- switch(type) {
- case JFXX_TYPE_JPEG:
- {
- // load the thumbnail
- FIMEMORY* hmem = FreeImage_OpenMemory(const_cast<BYTE*>(data), remaining);
- FIBITMAP* thumbnail = FreeImage_LoadFromMemory(FIF_JPEG, hmem);
- FreeImage_CloseMemory(hmem);
- // store the thumbnail
- FreeImage_SetThumbnail(dib, thumbnail);
- // then delete it
- FreeImage_Unload(thumbnail);
- break;
- }
- case JFXX_TYPE_8bit:
- // colormapped uncompressed thumbnail (no supported)
- break;
- case JFXX_TYPE_24bit:
- // truecolor uncompressed thumbnail (no supported)
- break;
- default:
- break;
- }
-
- return TRUE;
-}
-
-
-/**
- Read JPEG special markers
-*/
-static BOOL
-read_markers(j_decompress_ptr cinfo, FIBITMAP *dib) {
- jpeg_saved_marker_ptr marker;
-
- for(marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
- switch(marker->marker) {
- case JPEG_APP0:
- // JFIF is handled by libjpeg already, handle JFXX
- if(memcmp(marker->data, "JFIF" , 5) == 0) {
- continue;
- }
- if(memcmp(marker->data, "JFXX" , 5) == 0) {
- if(!cinfo->saw_JFIF_marker || cinfo->JFIF_minor_version < 2) {
- FreeImage_OutputMessageProc(s_format_id, "Warning: non-standard JFXX segment");
- }
- jpeg_read_jfxx(dib, marker->data, marker->data_length);
- }
- // other values such as 'Picasa' : ignore safely unknown APP0 marker
- break;
- case JPEG_COM:
- // JPEG comment
- jpeg_read_comment(dib, marker->data, marker->data_length);
- break;
- case EXIF_MARKER:
- // Exif or Adobe XMP profile
- jpeg_read_exif_profile(dib, marker->data, marker->data_length);
- jpeg_read_xmp_profile(dib, marker->data, marker->data_length);
- jpeg_read_exif_profile_raw(dib, marker->data, marker->data_length);
- break;
- case IPTC_MARKER:
- // IPTC/NAA or Adobe Photoshop profile
- jpeg_read_iptc_profile(dib, marker->data, marker->data_length);
- break;
- }
- }
-
- // ICC profile
- BYTE *icc_profile = NULL;
- unsigned icc_length = 0;
-
- if( jpeg_read_icc_profile(cinfo, &icc_profile, &icc_length) ) {
- // copy ICC profile data
- FreeImage_CreateICCProfile(dib, icc_profile, icc_length);
- // clean up
- free(icc_profile);
- }
-
- return TRUE;
-}
-
-// ----------------------------------------------------------
-// Special markers write functions
-// ----------------------------------------------------------
-
-/**
- Write JPEG_COM marker (comment)
-*/
-static BOOL
-jpeg_write_comment(j_compress_ptr cinfo, FIBITMAP *dib) {
- FITAG *tag = NULL;
-
- // write user comment as a JPEG_COM marker
- FreeImage_GetMetadata(FIMD_COMMENTS, dib, "Comment", &tag);
- if(tag) {
- const char *tag_value = (char*)FreeImage_GetTagValue(tag);
-
- if(NULL != tag_value) {
- for(long i = 0; i < (long)strlen(tag_value); i+= MAX_BYTES_IN_MARKER) {
- jpeg_write_marker(cinfo, JPEG_COM, (BYTE*)tag_value + i, MIN((long)strlen(tag_value + i), MAX_BYTES_IN_MARKER));
- }
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/**
- Write JPEG_APP2 marker (ICC profile)
-*/
-static BOOL
-jpeg_write_icc_profile(j_compress_ptr cinfo, FIBITMAP *dib) {
- // marker identifying string "ICC_PROFILE" (null-terminated)
- BYTE icc_signature[12] = { 0x49, 0x43, 0x43, 0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45, 0x00 };
-
- FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(dib);
-
- if (iccProfile->size && iccProfile->data) {
- // ICC_HEADER_SIZE: ICC signature is 'ICC_PROFILE' + 2 bytes
-
- BYTE *profile = (BYTE*)malloc((iccProfile->size + ICC_HEADER_SIZE) * sizeof(BYTE));
- if(profile == NULL) return FALSE;
- memcpy(profile, icc_signature, 12);
-
- for(long i = 0; i < (long)iccProfile->size; i += MAX_DATA_BYTES_IN_MARKER) {
- unsigned length = MIN((long)(iccProfile->size - i), MAX_DATA_BYTES_IN_MARKER);
- // sequence number
- profile[12] = (BYTE) ((i / MAX_DATA_BYTES_IN_MARKER) + 1);
- // number of markers
- profile[13] = (BYTE) (iccProfile->size / MAX_DATA_BYTES_IN_MARKER + 1);
-
- memcpy(profile + ICC_HEADER_SIZE, (BYTE*)iccProfile->data + i, length);
- jpeg_write_marker(cinfo, ICC_MARKER, profile, (length + ICC_HEADER_SIZE));
- }
-
- free(profile);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- Write JPEG_APPD marker (IPTC or Adobe Photoshop profile)
- @return Returns TRUE if successful, FALSE otherwise
-*/
-static BOOL
-jpeg_write_iptc_profile(j_compress_ptr cinfo, FIBITMAP *dib) {
- //const char *ps_header = "Photoshop 3.0\x08BIM\x04\x04\x0\x0\x0\x0";
- const unsigned tag_length = 26;
-
- if(FreeImage_GetMetadataCount(FIMD_IPTC, dib)) {
- BYTE *profile = NULL;
- unsigned profile_size = 0;
-
- // create a binary profile
- if(write_iptc_profile(dib, &profile, &profile_size)) {
-
- // write the profile
- for(long i = 0; i < (long)profile_size; i += 65517L) {
- unsigned length = MIN((long)profile_size - i, 65517L);
- unsigned roundup = length & 0x01; // needed for Photoshop
- BYTE *iptc_profile = (BYTE*)malloc(length + roundup + tag_length);
- if(iptc_profile == NULL) break;
- // Photoshop identification string
- memcpy(&iptc_profile[0], "Photoshop 3.0\x0", 14);
- // 8BIM segment type
- memcpy(&iptc_profile[14], "8BIM\x04\x04\x0\x0\x0\x0", 10);
- // segment size
- iptc_profile[24] = (BYTE)(length >> 8);
- iptc_profile[25] = (BYTE)(length & 0xFF);
- // segment data
- memcpy(&iptc_profile[tag_length], &profile[i], length);
- if(roundup)
- iptc_profile[length + tag_length] = 0;
- jpeg_write_marker(cinfo, IPTC_MARKER, iptc_profile, length + roundup + tag_length);
- free(iptc_profile);
- }
-
- // release profile
- free(profile);
-
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- Write JPEG_APP1 marker (XMP profile)
- @return Returns TRUE if successful, FALSE otherwise
-*/
-static BOOL
-jpeg_write_xmp_profile(j_compress_ptr cinfo, FIBITMAP *dib) {
- // marker identifying string for XMP (null terminated)
- const char *xmp_signature = "http://ns.adobe.com/xap/1.0/";
-
- FITAG *tag_xmp = NULL;
- FreeImage_GetMetadata(FIMD_XMP, dib, g_TagLib_XMPFieldName, &tag_xmp);
-
- if(tag_xmp) {
- const BYTE *tag_value = (BYTE*)FreeImage_GetTagValue(tag_xmp);
-
- if(NULL != tag_value) {
- // XMP signature is 29 bytes long
- unsigned int xmp_header_size = (unsigned int)strlen(xmp_signature) + 1;
-
- DWORD tag_length = FreeImage_GetTagLength(tag_xmp);
-
- BYTE *profile = (BYTE*)malloc((tag_length + xmp_header_size) * sizeof(BYTE));
- if(profile == NULL) return FALSE;
- memcpy(profile, xmp_signature, xmp_header_size);
-
- for(DWORD i = 0; i < tag_length; i += 65504L) {
- unsigned length = MIN((long)(tag_length - i), 65504L);
-
- memcpy(profile + xmp_header_size, tag_value + i, length);
- jpeg_write_marker(cinfo, EXIF_MARKER, profile, (length + xmp_header_size));
- }
-
- free(profile);
-
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- Write JPEG_APP1 marker (Exif profile)
- @return Returns TRUE if successful, FALSE otherwise
-*/
-static BOOL
-jpeg_write_exif_profile_raw(j_compress_ptr cinfo, FIBITMAP *dib) {
- // marker identifying string for Exif = "Exif\0\0"
- BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
-
- FITAG *tag_exif = NULL;
- FreeImage_GetMetadata(FIMD_EXIF_RAW, dib, g_TagLib_ExifRawFieldName, &tag_exif);
-
- if(tag_exif) {
- const BYTE *tag_value = (BYTE*)FreeImage_GetTagValue(tag_exif);
-
- // verify the identifying string
- if(memcmp(exif_signature, tag_value, sizeof(exif_signature)) != 0) {
- // not an Exif profile
- return FALSE;
- }
-
- if(NULL != tag_value) {
- DWORD tag_length = FreeImage_GetTagLength(tag_exif);
-
- BYTE *profile = (BYTE*)malloc(tag_length * sizeof(BYTE));
- if(profile == NULL) return FALSE;
-
- for(DWORD i = 0; i < tag_length; i += 65504L) {
- unsigned length = MIN((long)(tag_length - i), 65504L);
-
- memcpy(profile, tag_value + i, length);
- jpeg_write_marker(cinfo, EXIF_MARKER, profile, length);
- }
-
- free(profile);
-
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- Write thumbnail (JFXX segment, JPEG compressed)
-*/
-static BOOL
-jpeg_write_jfxx(j_compress_ptr cinfo, FIBITMAP *dib) {
- // get the thumbnail to be stored
- FIBITMAP* thumbnail = FreeImage_GetThumbnail(dib);
- if(!thumbnail) {
- return TRUE;
- }
- // check for a compatible output format
- if((FreeImage_GetImageType(thumbnail) != FIT_BITMAP) || (FreeImage_GetBPP(thumbnail) != 8) && (FreeImage_GetBPP(thumbnail) != 24)) {
- FreeImage_OutputMessageProc(s_format_id, FI_MSG_WARNING_INVALID_THUMBNAIL);
- return FALSE;
- }
-
- // stores the thumbnail as a baseline JPEG into a memory block
- // return the memory block only if its size is within JFXX marker size limit!
- FIMEMORY *stream = FreeImage_OpenMemory();
-
- if(FreeImage_SaveToMemory(FIF_JPEG, thumbnail, stream, JPEG_BASELINE)) {
- // check that the memory block size is within JFXX marker size limit
- FreeImage_SeekMemory(stream, 0, SEEK_END);
- const long eof = FreeImage_TellMemory(stream);
- if(eof > MAX_JFXX_THUMB_SIZE) {
- FreeImage_OutputMessageProc(s_format_id, "Warning: attached thumbnail is %d bytes larger than maximum supported size - Thumbnail saving aborted", eof - MAX_JFXX_THUMB_SIZE);
- FreeImage_CloseMemory(stream);
- return FALSE;
- }
- } else {
- FreeImage_CloseMemory(stream);
- return FALSE;
- }
-
- BYTE* thData = NULL;
- DWORD thSize = 0;
-
- FreeImage_AcquireMemory(stream, &thData, &thSize);
-
- BYTE id_length = 5; //< "JFXX"
- BYTE type = JFXX_TYPE_JPEG;
-
- DWORD totalsize = id_length + sizeof(type) + thSize;
- jpeg_write_m_header(cinfo, JPEG_APP0, totalsize);
-
- jpeg_write_m_byte(cinfo, 'J');
- jpeg_write_m_byte(cinfo, 'F');
- jpeg_write_m_byte(cinfo, 'X');
- jpeg_write_m_byte(cinfo, 'X');
- jpeg_write_m_byte(cinfo, '\0');
-
- jpeg_write_m_byte(cinfo, type);
-
- // write thumbnail to destination.
- // We "cram it straight into the data destination module", because write_m_byte is slow
-
- freeimage_dst_ptr dest = (freeimage_dst_ptr) cinfo->dest;
-
- BYTE* & out = dest->pub.next_output_byte;
- size_t & bufRemain = dest->pub.free_in_buffer;
-
- const BYTE *thData_end = thData + thSize;
-
- while(thData < thData_end) {
- *(out)++ = *(thData)++;
- if (--bufRemain == 0) {
- // buffer full - flush
- if (!dest->pub.empty_output_buffer(cinfo)) {
- break;
- }
- }
- }
-
- FreeImage_CloseMemory(stream);
-
- return TRUE;
-}
-
-/**
- Write JPEG special markers
-*/
-static BOOL
-write_markers(j_compress_ptr cinfo, FIBITMAP *dib) {
- // write thumbnail as a JFXX marker
- jpeg_write_jfxx(cinfo, dib);
-
- // write user comment as a JPEG_COM marker
- jpeg_write_comment(cinfo, dib);
-
- // write ICC profile
- jpeg_write_icc_profile(cinfo, dib);
-
- // write IPTC profile
- jpeg_write_iptc_profile(cinfo, dib);
-
- // write Adobe XMP profile
- jpeg_write_xmp_profile(cinfo, dib);
-
- // write Exif raw data
- jpeg_write_exif_profile_raw(cinfo, dib);
-
- return TRUE;
-}
-
-// ------------------------------------------------------------
-// Keep original size info when using scale option on loading
-// ------------------------------------------------------------
-static void
-store_size_info(FIBITMAP *dib, JDIMENSION width, JDIMENSION height) {
- char buffer[256];
- // create a tag
- FITAG *tag = FreeImage_CreateTag();
- if(tag) {
- size_t length = 0;
- // set the original width
- sprintf(buffer, "%d", (int)width);
- length = strlen(buffer) + 1; // include the NULL/0 value
- FreeImage_SetTagKey(tag, "OriginalJPEGWidth");
- FreeImage_SetTagLength(tag, (DWORD)length);
- FreeImage_SetTagCount(tag, (DWORD)length);
- FreeImage_SetTagType(tag, FIDT_ASCII);
- FreeImage_SetTagValue(tag, buffer);
- FreeImage_SetMetadata(FIMD_COMMENTS, dib, FreeImage_GetTagKey(tag), tag);
- // set the original height
- sprintf(buffer, "%d", (int)height);
- length = strlen(buffer) + 1; // include the NULL/0 value
- FreeImage_SetTagKey(tag, "OriginalJPEGHeight");
- FreeImage_SetTagLength(tag, (DWORD)length);
- FreeImage_SetTagCount(tag, (DWORD)length);
- FreeImage_SetTagType(tag, FIDT_ASCII);
- FreeImage_SetTagValue(tag, buffer);
- FreeImage_SetMetadata(FIMD_COMMENTS, dib, FreeImage_GetTagKey(tag), tag);
- // destroy the tag
- FreeImage_DeleteTag(tag);
- }
-}
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
- return "JPEG";
-}
-
-static const char * DLL_CALLCONV
-Description() {
- return "JPEG - JFIF Compliant";
-}
-
-static const char * DLL_CALLCONV
-Extension() {
- return "jpg,jif,jpeg,jpe";
-}
-
-static const char * DLL_CALLCONV
-RegExpr() {
- return "^\377\330\377";
-}
-
-static const char * DLL_CALLCONV
-MimeType() {
- return "image/jpeg";
-}
-
-static BOOL DLL_CALLCONV
-Validate(FreeImageIO *io, fi_handle handle) {
- BYTE jpeg_signature[] = { 0xFF, 0xD8 };
- BYTE signature[2] = { 0, 0 };
-
- io->read_proc(signature, 1, sizeof(jpeg_signature), handle);
-
- return (memcmp(jpeg_signature, signature, sizeof(jpeg_signature)) == 0);
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportDepth(int depth) {
- return (
- (depth == 8) ||
- (depth == 24)
- );
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportType(FREE_IMAGE_TYPE type) {
- return (type == FIT_BITMAP) ? TRUE : FALSE;
-}
-
-static BOOL DLL_CALLCONV
-SupportsICCProfiles() {
- return TRUE;
-}
-
-static BOOL DLL_CALLCONV
-SupportsNoPixels() {
- return TRUE;
-}
-
-// ----------------------------------------------------------
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
- if (handle) {
- FIBITMAP *dib = NULL;
-
- BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
-
- // set up the jpeglib structures
-
- struct jpeg_decompress_struct cinfo;
- ErrorManager fi_error_mgr;
-
- try {
-
- // step 1: allocate and initialize JPEG decompression object
-
- // we set up the normal JPEG error routines, then override error_exit & output_message
- cinfo.err = jpeg_std_error(&fi_error_mgr.pub);
- fi_error_mgr.pub.error_exit = jpeg_error_exit;
- fi_error_mgr.pub.output_message = jpeg_output_message;
-
- // establish the setjmp return context for jpeg_error_exit to use
- if (setjmp(fi_error_mgr.setjmp_buffer)) {
- // If we get here, the JPEG code has signaled an error.
- // We need to clean up the JPEG object, close the input file, and return.
- jpeg_destroy_decompress(&cinfo);
- throw (const char*)NULL;
- }
-
- jpeg_create_decompress(&cinfo);
-
- // step 2a: specify data source (eg, a handle)
-
- jpeg_freeimage_src(&cinfo, handle, io);
-
- // step 2b: save special markers for later reading
-
- jpeg_save_markers(&cinfo, JPEG_COM, 0xFFFF);
- for(int m = 0; m < 16; m++) {
- jpeg_save_markers(&cinfo, JPEG_APP0 + m, 0xFFFF);
- }
-
- // step 3: read handle parameters with jpeg_read_header()
-
- jpeg_read_header(&cinfo, TRUE);
-
- // step 4: set parameters for decompression
-
- unsigned int scale_denom = 1; // fraction by which to scale image
- int requested_size = flags >> 16; // requested user size in pixels
- if(requested_size > 0) {
- // the JPEG codec can perform x2, x4 or x8 scaling on loading
- // try to find the more appropriate scaling according to user's need
- double scale = MAX((double)cinfo.image_width, (double)cinfo.image_height) / (double)requested_size;
- if(scale >= 8) {
- scale_denom = 8;
- } else if(scale >= 4) {
- scale_denom = 4;
- } else if(scale >= 2) {
- scale_denom = 2;
- }
- }
- cinfo.scale_num = 1;
- cinfo.scale_denom = scale_denom;
-
- if ((flags & JPEG_ACCURATE) != JPEG_ACCURATE) {
- cinfo.dct_method = JDCT_IFAST;
- cinfo.do_fancy_upsampling = FALSE;
- }
-
- if ((flags & JPEG_GREYSCALE) == JPEG_GREYSCALE) {
- // force loading as a 8-bit greyscale image
- cinfo.out_color_space = JCS_GRAYSCALE;
- }
-
- // step 5a: start decompressor and calculate output width and height
-
- jpeg_start_decompress(&cinfo);
-
- // step 5b: allocate dib and init header
-
- if((cinfo.output_components == 4) && (cinfo.out_color_space == JCS_CMYK)) {
- // CMYK image
- if((flags & JPEG_CMYK) == JPEG_CMYK) {
- // load as CMYK
- dib = FreeImage_AllocateHeader(header_only, cinfo.output_width, cinfo.output_height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(!dib) throw FI_MSG_ERROR_DIB_MEMORY;
- FreeImage_GetICCProfile(dib)->flags |= FIICC_COLOR_IS_CMYK;
- } else {
- // load as CMYK and convert to RGB
- dib = FreeImage_AllocateHeader(header_only, cinfo.output_width, cinfo.output_height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(!dib) throw FI_MSG_ERROR_DIB_MEMORY;
- }
- } else {
- // RGB or greyscale image
- dib = FreeImage_AllocateHeader(header_only, cinfo.output_width, cinfo.output_height, 8 * cinfo.output_components, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(!dib) throw FI_MSG_ERROR_DIB_MEMORY;
-
- if (cinfo.output_components == 1) {
- // build a greyscale palette
- RGBQUAD *colors = FreeImage_GetPalette(dib);
-
- for (int i = 0; i < 256; i++) {
- colors[i].rgbRed = (BYTE)i;
- colors[i].rgbGreen = (BYTE)i;
- colors[i].rgbBlue = (BYTE)i;
- }
- }
- }
- if(scale_denom != 1) {
- // store original size info if a scaling was requested
- store_size_info(dib, cinfo.image_width, cinfo.image_height);
- }
-
- // step 5c: handle metrices
-
- if (cinfo.density_unit == 1) {
- // dots/inch
- FreeImage_SetDotsPerMeterX(dib, (unsigned) (((float)cinfo.X_density) / 0.0254000 + 0.5));
- FreeImage_SetDotsPerMeterY(dib, (unsigned) (((float)cinfo.Y_density) / 0.0254000 + 0.5));
- } else if (cinfo.density_unit == 2) {
- // dots/cm
- FreeImage_SetDotsPerMeterX(dib, (unsigned) (cinfo.X_density * 100));
- FreeImage_SetDotsPerMeterY(dib, (unsigned) (cinfo.Y_density * 100));
- }
-
- // step 6: read special markers
-
- read_markers(&cinfo, dib);
-
- // --- header only mode => clean-up and return
-
- if (header_only) {
- // release JPEG decompression object
- jpeg_destroy_decompress(&cinfo);
- // return header data
- return dib;
- }
-
- // step 7a: while (scan lines remain to be read) jpeg_read_scanlines(...);
-
- if((cinfo.out_color_space == JCS_CMYK) && ((flags & JPEG_CMYK) != JPEG_CMYK)) {
- // convert from CMYK to RGB
-
- JSAMPARRAY buffer; // output row buffer
- unsigned row_stride; // physical row width in output buffer
-
- // JSAMPLEs per row in output buffer
- row_stride = cinfo.output_width * cinfo.output_components;
- // make a one-row-high sample array that will go away when done with image
- buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
-
- while (cinfo.output_scanline < cinfo.output_height) {
- JSAMPROW src = buffer[0];
- JSAMPROW dst = FreeImage_GetScanLine(dib, cinfo.output_height - cinfo.output_scanline - 1);
-
- jpeg_read_scanlines(&cinfo, buffer, 1);
-
- for(unsigned x = 0; x < cinfo.output_width; x++) {
- WORD K = (WORD)src[3];
- dst[FI_RGBA_RED] = (BYTE)((K * src[0]) / 255); // C -> R
- dst[FI_RGBA_GREEN] = (BYTE)((K * src[1]) / 255); // M -> G
- dst[FI_RGBA_BLUE] = (BYTE)((K * src[2]) / 255); // Y -> B
- src += 4;
- dst += 3;
- }
- }
- } else if((cinfo.out_color_space == JCS_CMYK) && ((flags & JPEG_CMYK) == JPEG_CMYK)) {
- // convert from LibJPEG CMYK to standard CMYK
-
- JSAMPARRAY buffer; // output row buffer
- unsigned row_stride; // physical row width in output buffer
-
- // JSAMPLEs per row in output buffer
- row_stride = cinfo.output_width * cinfo.output_components;
- // make a one-row-high sample array that will go away when done with image
- buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
-
- while (cinfo.output_scanline < cinfo.output_height) {
- JSAMPROW src = buffer[0];
- JSAMPROW dst = FreeImage_GetScanLine(dib, cinfo.output_height - cinfo.output_scanline - 1);
-
- jpeg_read_scanlines(&cinfo, buffer, 1);
-
- for(unsigned x = 0; x < cinfo.output_width; x++) {
- // CMYK pixels are inverted
- dst[0] = ~src[0]; // C
- dst[1] = ~src[1]; // M
- dst[2] = ~src[2]; // Y
- dst[3] = ~src[3]; // K
- src += 4;
- dst += 4;
- }
- }
-
- } else {
- // normal case (RGB or greyscale image)
-
- while (cinfo.output_scanline < cinfo.output_height) {
- JSAMPROW dst = FreeImage_GetScanLine(dib, cinfo.output_height - cinfo.output_scanline - 1);
-
- jpeg_read_scanlines(&cinfo, &dst, 1);
- }
-
- // step 7b: swap red and blue components (see LibJPEG/jmorecfg.h: #define RGB_RED, ...)
- // The default behavior of the JPEG library is kept "as is" because LibTIFF uses
- // LibJPEG "as is".
-
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
- SwapRedBlue32(dib);
-#endif
- }
-
- // step 8: finish decompression
-
- jpeg_finish_decompress(&cinfo);
-
- // step 9: release JPEG decompression object
-
- jpeg_destroy_decompress(&cinfo);
-
- // check for automatic Exif rotation
- if(!header_only && ((flags & JPEG_EXIFROTATE) == JPEG_EXIFROTATE)) {
- RotateExif(&dib);
- }
-
- // everything went well. return the loaded dib
-
- return dib;
-
- } catch (const char *text) {
- jpeg_destroy_decompress(&cinfo);
- if(NULL != dib) {
- FreeImage_Unload(dib);
- }
- if(NULL != text) {
- FreeImage_OutputMessageProc(s_format_id, text);
- }
- }
- }
-
- return NULL;
-}
-
-// ----------------------------------------------------------
-
-static BOOL DLL_CALLCONV
-Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
- if ((dib) && (handle)) {
- try {
- // Check dib format
-
- const char *sError = "only 24-bit highcolor or 8-bit greyscale/palette bitmaps can be saved as JPEG";
-
- FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
- WORD bpp = (WORD)FreeImage_GetBPP(dib);
-
- if ((bpp != 24) && (bpp != 8)) {
- throw sError;
- }
-
- if(bpp == 8) {
- // allow grey, reverse grey and palette
- if ((color_type != FIC_MINISBLACK) && (color_type != FIC_MINISWHITE) && (color_type != FIC_PALETTE)) {
- throw sError;
- }
- }
-
-
- struct jpeg_compress_struct cinfo;
- ErrorManager fi_error_mgr;
-
- // Step 1: allocate and initialize JPEG compression object
-
- // we set up the normal JPEG error routines, then override error_exit & output_message
- cinfo.err = jpeg_std_error(&fi_error_mgr.pub);
- fi_error_mgr.pub.error_exit = jpeg_error_exit;
- fi_error_mgr.pub.output_message = jpeg_output_message;
-
- // establish the setjmp return context for jpeg_error_exit to use
- if (setjmp(fi_error_mgr.setjmp_buffer)) {
- // If we get here, the JPEG code has signaled an error.
- // We need to clean up the JPEG object, close the input file, and return.
- jpeg_destroy_compress(&cinfo);
- throw (const char*)NULL;
- }
-
- // Now we can initialize the JPEG compression object
-
- jpeg_create_compress(&cinfo);
-
- // Step 2: specify data destination (eg, a file)
-
- jpeg_freeimage_dst(&cinfo, handle, io);
-
- // Step 3: set parameters for compression
-
- cinfo.image_width = FreeImage_GetWidth(dib);
- cinfo.image_height = FreeImage_GetHeight(dib);
-
- switch(color_type) {
- case FIC_MINISBLACK :
- case FIC_MINISWHITE :
- cinfo.in_color_space = JCS_GRAYSCALE;
- cinfo.input_components = 1;
- break;
-
- default :
- cinfo.in_color_space = JCS_RGB;
- cinfo.input_components = 3;
- break;
- }
-
- jpeg_set_defaults(&cinfo);
-
- // progressive-JPEG support
- if((flags & JPEG_PROGRESSIVE) == JPEG_PROGRESSIVE) {
- jpeg_simple_progression(&cinfo);
- }
-
- // compute optimal Huffman coding tables for the image
- if((flags & JPEG_OPTIMIZE) == JPEG_OPTIMIZE) {
- cinfo.optimize_coding = TRUE;
- }
-
- // Set JFIF density parameters from the DIB data
-
- cinfo.X_density = (UINT16) (0.5 + 0.0254 * FreeImage_GetDotsPerMeterX(dib));
- cinfo.Y_density = (UINT16) (0.5 + 0.0254 * FreeImage_GetDotsPerMeterY(dib));
- cinfo.density_unit = 1; // dots / inch
-
- // thumbnail support (JFIF 1.02 extension markers)
- if(FreeImage_GetThumbnail(dib) != NULL) {
- cinfo.write_JFIF_header = 1; //<### force it, though when color is CMYK it will be incorrect
- cinfo.JFIF_minor_version = 2;
- }
-
- // baseline JPEG support
- if ((flags & JPEG_BASELINE) == JPEG_BASELINE) {
- cinfo.write_JFIF_header = 0; // No marker for non-JFIF colorspaces
- cinfo.write_Adobe_marker = 0; // write no Adobe marker by default
- }
-
- // set subsampling options if required
-
- if(cinfo.in_color_space == JCS_RGB) {
- if((flags & JPEG_SUBSAMPLING_411) == JPEG_SUBSAMPLING_411) {
- // 4:1:1 (4x1 1x1 1x1) - CrH 25% - CbH 25% - CrV 100% - CbV 100%
- // the horizontal color resolution is quartered
- cinfo.comp_info[0].h_samp_factor = 4; // Y
- cinfo.comp_info[0].v_samp_factor = 1;
- cinfo.comp_info[1].h_samp_factor = 1; // Cb
- cinfo.comp_info[1].v_samp_factor = 1;
- cinfo.comp_info[2].h_samp_factor = 1; // Cr
- cinfo.comp_info[2].v_samp_factor = 1;
- } else if((flags & JPEG_SUBSAMPLING_420) == JPEG_SUBSAMPLING_420) {
- // 4:2:0 (2x2 1x1 1x1) - CrH 50% - CbH 50% - CrV 50% - CbV 50%
- // the chrominance resolution in both the horizontal and vertical directions is cut in half
- cinfo.comp_info[0].h_samp_factor = 2; // Y
- cinfo.comp_info[0].v_samp_factor = 2;
- cinfo.comp_info[1].h_samp_factor = 1; // Cb
- cinfo.comp_info[1].v_samp_factor = 1;
- cinfo.comp_info[2].h_samp_factor = 1; // Cr
- cinfo.comp_info[2].v_samp_factor = 1;
- } else if((flags & JPEG_SUBSAMPLING_422) == JPEG_SUBSAMPLING_422){ //2x1 (low)
- // 4:2:2 (2x1 1x1 1x1) - CrH 50% - CbH 50% - CrV 100% - CbV 100%
- // half of the horizontal resolution in the chrominance is dropped (Cb & Cr),
- // while the full resolution is retained in the vertical direction, with respect to the luminance
- cinfo.comp_info[0].h_samp_factor = 2; // Y
- cinfo.comp_info[0].v_samp_factor = 1;
- cinfo.comp_info[1].h_samp_factor = 1; // Cb
- cinfo.comp_info[1].v_samp_factor = 1;
- cinfo.comp_info[2].h_samp_factor = 1; // Cr
- cinfo.comp_info[2].v_samp_factor = 1;
- }
- else if((flags & JPEG_SUBSAMPLING_444) == JPEG_SUBSAMPLING_444){ //1x1 (no subsampling)
- // 4:4:4 (1x1 1x1 1x1) - CrH 100% - CbH 100% - CrV 100% - CbV 100%
- // the resolution of chrominance information (Cb & Cr) is preserved
- // at the same rate as the luminance (Y) information
- cinfo.comp_info[0].h_samp_factor = 1; // Y
- cinfo.comp_info[0].v_samp_factor = 1;
- cinfo.comp_info[1].h_samp_factor = 1; // Cb
- cinfo.comp_info[1].v_samp_factor = 1;
- cinfo.comp_info[2].h_samp_factor = 1; // Cr
- cinfo.comp_info[2].v_samp_factor = 1;
- }
- }
-
- // Step 4: set quality
- // the first 7 bits are reserved for low level quality settings
- // the other bits are high level (i.e. enum-ish)
-
- int quality;
-
- if ((flags & JPEG_QUALITYBAD) == JPEG_QUALITYBAD) {
- quality = 10;
- } else if ((flags & JPEG_QUALITYAVERAGE) == JPEG_QUALITYAVERAGE) {
- quality = 25;
- } else if ((flags & JPEG_QUALITYNORMAL) == JPEG_QUALITYNORMAL) {
- quality = 50;
- } else if ((flags & JPEG_QUALITYGOOD) == JPEG_QUALITYGOOD) {
- quality = 75;
- } else if ((flags & JPEG_QUALITYSUPERB) == JPEG_QUALITYSUPERB) {
- quality = 100;
- } else {
- if ((flags & 0x7F) == 0) {
- quality = 75;
- } else {
- quality = flags & 0x7F;
- }
- }
-
- jpeg_set_quality(&cinfo, quality, TRUE); /* limit to baseline-JPEG values */
-
- // Step 5: Start compressor
-
- jpeg_start_compress(&cinfo, TRUE);
-
- // Step 6: Write special markers
-
- if ((flags & JPEG_BASELINE) != JPEG_BASELINE) {
- write_markers(&cinfo, dib);
- }
-
- // Step 7: while (scan lines remain to be written)
-
- if(color_type == FIC_RGB) {
- // 24-bit RGB image : need to swap red and blue channels
- unsigned pitch = FreeImage_GetPitch(dib);
- BYTE *target = (BYTE*)malloc(pitch * sizeof(BYTE));
- if (target == NULL) {
- throw FI_MSG_ERROR_MEMORY;
- }
-
- while (cinfo.next_scanline < cinfo.image_height) {
- // get a copy of the scanline
- memcpy(target, FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - cinfo.next_scanline - 1), pitch);
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
- // swap R and B channels
- BYTE *target_p = target;
- for(unsigned x = 0; x < cinfo.image_width; x++) {
- INPLACESWAP(target_p[0], target_p[2]);
- target_p += 3;
- }
-#endif
- // write the scanline
- jpeg_write_scanlines(&cinfo, &target, 1);
- }
- free(target);
- }
- else if(color_type == FIC_MINISBLACK) {
- // 8-bit standard greyscale images
- while (cinfo.next_scanline < cinfo.image_height) {
- JSAMPROW b = FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - cinfo.next_scanline - 1);
-
- jpeg_write_scanlines(&cinfo, &b, 1);
- }
- }
- else if(color_type == FIC_PALETTE) {
- // 8-bit palettized images are converted to 24-bit images
- RGBQUAD *palette = FreeImage_GetPalette(dib);
- BYTE *target = (BYTE*)malloc(cinfo.image_width * 3);
- if (target == NULL) {
- throw FI_MSG_ERROR_MEMORY;
- }
-
- while (cinfo.next_scanline < cinfo.image_height) {
- BYTE *source = FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - cinfo.next_scanline - 1);
- FreeImage_ConvertLine8To24(target, source, cinfo.image_width, palette);
-
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
- // swap R and B channels
- BYTE *target_p = target;
- for(unsigned x = 0; x < cinfo.image_width; x++) {
- INPLACESWAP(target_p[0], target_p[2]);
- target_p += 3;
- }
-#endif
-
-
- jpeg_write_scanlines(&cinfo, &target, 1);
- }
-
- free(target);
- }
- else if(color_type == FIC_MINISWHITE) {
- // reverse 8-bit greyscale image, so reverse grey value on the fly
- unsigned i;
- BYTE reverse[256];
- BYTE *target = (BYTE *)malloc(cinfo.image_width);
- if (target == NULL) {
- throw FI_MSG_ERROR_MEMORY;
- }
-
- for(i = 0; i < 256; i++) {
- reverse[i] = (BYTE)(255 - i);
- }
-
- while(cinfo.next_scanline < cinfo.image_height) {
- BYTE *source = FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - cinfo.next_scanline - 1);
- for(i = 0; i < cinfo.image_width; i++) {
- target[i] = reverse[ source[i] ];
- }
- jpeg_write_scanlines(&cinfo, &target, 1);
- }
-
- free(target);
- }
-
- // Step 8: Finish compression
-
- jpeg_finish_compress(&cinfo);
-
- // Step 9: release JPEG compression object
-
- jpeg_destroy_compress(&cinfo);
-
- return TRUE;
-
- } catch (const char *text) {
- if(text) {
- FreeImage_OutputMessageProc(s_format_id, text);
- }
- return FALSE;
- }
- }
-
- return FALSE;
-}
-
-// ==========================================================
-// Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitJPEG(Plugin *plugin, int format_id) {
- s_format_id = format_id;
-
- plugin->format_proc = Format;
- plugin->description_proc = Description;
- plugin->extension_proc = Extension;
- plugin->regexpr_proc = RegExpr;
- plugin->open_proc = NULL;
- plugin->close_proc = NULL;
- plugin->pagecount_proc = NULL;
- plugin->pagecapability_proc = NULL;
- plugin->load_proc = Load;
- plugin->save_proc = Save;
- plugin->validate_proc = Validate;
- plugin->mime_proc = MimeType;
- plugin->supports_export_bpp_proc = SupportsExportDepth;
- plugin->supports_export_type_proc = SupportsExportType;
- plugin->supports_icc_profiles_proc = SupportsICCProfiles;
- plugin->supports_no_pixels_proc = SupportsNoPixels;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/PluginPNG.cpp b/plugins/AdvaImg/src/FreeImage/PluginPNG.cpp
deleted file mode 100644
index fe80a2b533..0000000000
--- a/plugins/AdvaImg/src/FreeImage/PluginPNG.cpp
+++ /dev/null
@@ -1,1115 +0,0 @@
-// ==========================================================
-// PNG Loader and Writer
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-// - Herve Drolon (drolon@infonie.fr)
-// - Detlev Vendt (detlev.vendt@brillit.de)
-// - Aaron Shumate (trek@startreker.com)
-// - Tanner Helland (tannerhelland@users.sf.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 "FreeImage.h"
-#include "Utilities.h"
-
-#include "../Metadata/FreeImageTag.h"
-
-// ----------------------------------------------------------
-
-#define PNG_BYTES_TO_CHECK 8
-
-#undef PNG_Z_DEFAULT_COMPRESSION // already used in ../LibPNG/pnglibconf.h
-
-// ----------------------------------------------------------
-
-#include "zlib.h"
-#include "../LibPNG/png.h"
-
-// ----------------------------------------------------------
-
-typedef struct {
- FreeImageIO *s_io;
- fi_handle s_handle;
-} fi_ioStructure, *pfi_ioStructure;
-
-// ==========================================================
-// libpng interface
-// ==========================================================
-
-static void
-_ReadProc(png_structp png_ptr, unsigned char *data, png_size_t size) {
- pfi_ioStructure pfio = (pfi_ioStructure)png_get_io_ptr(png_ptr);
- unsigned n = pfio->s_io->read_proc(data, (unsigned int)size, 1, pfio->s_handle);
- if(size && (n == 0)) {
- throw "Read error: invalid or corrupted PNG file";
- }
-}
-
-static void
-_WriteProc(png_structp png_ptr, unsigned char *data, png_size_t size) {
- pfi_ioStructure pfio = (pfi_ioStructure)png_get_io_ptr(png_ptr);
- pfio->s_io->write_proc(data, (unsigned int)size, 1, pfio->s_handle);
-}
-
-static void
-_FlushProc(png_structp png_ptr) {
- (png_structp)png_ptr;
- // empty flush implementation
-}
-
-static void
-error_handler(png_structp png_ptr, const char *error) {
- (png_structp)png_ptr;
- throw error;
-}
-
-// in FreeImage warnings disabled
-
-static void
-warning_handler(png_structp png_ptr, const char *warning) {
- (png_structp)png_ptr;
- (char*)warning;
-}
-
-// ==========================================================
-// Metadata routines
-// ==========================================================
-
-static BOOL
-ReadMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
- // XMP keyword
- const char *g_png_xmp_keyword = "XML:com.adobe.xmp";
-
- FITAG *tag = NULL;
- png_textp text_ptr = NULL;
- png_timep mod_time = NULL;
- int num_text = 0;
-
- // iTXt/tEXt/zTXt chuncks
- if(png_get_text(png_ptr, info_ptr, &text_ptr, &num_text) > 0) {
- for(int i = 0; i < num_text; i++) {
- // create a tag
- tag = FreeImage_CreateTag();
- if(!tag) return FALSE;
-
- DWORD tag_length = (DWORD) MAX(text_ptr[i].text_length, text_ptr[i].itxt_length);
-
- FreeImage_SetTagLength(tag, tag_length);
- FreeImage_SetTagCount(tag, tag_length);
- FreeImage_SetTagType(tag, FIDT_ASCII);
- FreeImage_SetTagValue(tag, text_ptr[i].text);
-
- if(strcmp(text_ptr[i].key, g_png_xmp_keyword) == 0) {
- // store the tag as XMP
- FreeImage_SetTagKey(tag, g_TagLib_XMPFieldName);
- FreeImage_SetMetadata(FIMD_XMP, dib, FreeImage_GetTagKey(tag), tag);
- } else {
- // store the tag as a comment
- FreeImage_SetTagKey(tag, text_ptr[i].key);
- FreeImage_SetMetadata(FIMD_COMMENTS, dib, FreeImage_GetTagKey(tag), tag);
- }
-
- // destroy the tag
- FreeImage_DeleteTag(tag);
- }
- }
-
- // timestamp chunk
- if(png_get_tIME(png_ptr, info_ptr, &mod_time)) {
- char timestamp[32];
- // create a tag
- tag = FreeImage_CreateTag();
- if(!tag) return FALSE;
-
- // convert as 'yyyy:MM:dd hh:mm:ss'
- sprintf(timestamp, "%4d:%02d:%02d %2d:%02d:%02d", mod_time->year, mod_time->month, mod_time->day, mod_time->hour, mod_time->minute, mod_time->second);
-
- DWORD tag_length = (DWORD)strlen(timestamp) + 1;
- FreeImage_SetTagLength(tag, tag_length);
- FreeImage_SetTagCount(tag, tag_length);
- FreeImage_SetTagType(tag, FIDT_ASCII);
- FreeImage_SetTagID(tag, TAG_DATETIME);
- FreeImage_SetTagValue(tag, timestamp);
-
- // store the tag as Exif-TIFF
- FreeImage_SetTagKey(tag, "DateTime");
- FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, FreeImage_GetTagKey(tag), tag);
-
- // destroy the tag
- FreeImage_DeleteTag(tag);
- }
-
- return TRUE;
-}
-
-static BOOL
-WriteMetadata(png_structp png_ptr, png_infop info_ptr, FIBITMAP *dib) {
- // XMP keyword
- const char *g_png_xmp_keyword = "XML:com.adobe.xmp";
-
- FITAG *tag = NULL;
- FIMETADATA *mdhandle = NULL;
- BOOL bResult = TRUE;
-
- png_text text_metadata;
- png_time mod_time;
-
- // set the 'Comments' metadata as iTXt chuncks
-
- mdhandle = FreeImage_FindFirstMetadata(FIMD_COMMENTS, dib, &tag);
-
- if(mdhandle) {
- do {
- memset(&text_metadata, 0, sizeof(png_text));
- text_metadata.compression = 1; // iTXt, none
- text_metadata.key = (char*)FreeImage_GetTagKey(tag); // keyword, 1-79 character description of "text"
- text_metadata.text = (char*)FreeImage_GetTagValue(tag); // comment, may be an empty string (ie "")
- text_metadata.text_length = FreeImage_GetTagLength(tag);// length of the text string
- text_metadata.itxt_length = FreeImage_GetTagLength(tag);// length of the itxt string
- text_metadata.lang = 0; // language code, 0-79 characters or a NULL pointer
- text_metadata.lang_key = 0; // keyword translated UTF-8 string, 0 or more chars or a NULL pointer
-
- // set the tag
- png_set_text(png_ptr, info_ptr, &text_metadata, 1);
-
- } while(FreeImage_FindNextMetadata(mdhandle, &tag));
-
- FreeImage_FindCloseMetadata(mdhandle);
- bResult &= TRUE;
- }
-
- // set the 'XMP' metadata as iTXt chuncks
- tag = NULL;
- FreeImage_GetMetadata(FIMD_XMP, dib, g_TagLib_XMPFieldName, &tag);
- if(tag && FreeImage_GetTagLength(tag)) {
- memset(&text_metadata, 0, sizeof(png_text));
- text_metadata.compression = 1; // iTXt, none
- text_metadata.key = (char*)g_png_xmp_keyword; // keyword, 1-79 character description of "text"
- text_metadata.text = (char*)FreeImage_GetTagValue(tag); // comment, may be an empty string (ie "")
- text_metadata.text_length = FreeImage_GetTagLength(tag);// length of the text string
- text_metadata.itxt_length = FreeImage_GetTagLength(tag);// length of the itxt string
- text_metadata.lang = 0; // language code, 0-79 characters or a NULL pointer
- text_metadata.lang_key = 0; // keyword translated UTF-8 string, 0 or more chars or a NULL pointer
-
- // set the tag
- png_set_text(png_ptr, info_ptr, &text_metadata, 1);
- bResult &= TRUE;
- }
-
- // set the Exif-TIFF 'DateTime' metadata as a tIME chunk
- tag = NULL;
- FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, "DateTime", &tag);
- if(tag && FreeImage_GetTagLength(tag)) {
- int year, month, day, hour, minute, second;
- const char *value = (char*)FreeImage_GetTagValue(tag);
- if(sscanf(value, "%4d:%02d:%02d %2d:%02d:%02d", &year, &month, &day, &hour, &minute, &second) == 6) {
- mod_time.year = (png_uint_16)year;
- mod_time.month = (png_byte)month;
- mod_time.day = (png_byte)day;
- mod_time.hour = (png_byte)hour;
- mod_time.minute = (png_byte)minute;
- mod_time.second = (png_byte)second;
- png_set_tIME (png_ptr, info_ptr, &mod_time);
- }
- }
-
- return bResult;
-}
-
-// ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
-// Plugin Implementation
-// ==========================================================
-
-static const char * DLL_CALLCONV
-Format() {
- return "PNG";
-}
-
-static const char * DLL_CALLCONV
-Description() {
- return "Portable Network Graphics";
-}
-
-static const char * DLL_CALLCONV
-Extension() {
- return "png";
-}
-
-static const char * DLL_CALLCONV
-RegExpr() {
- return "^.PNG\r";
-}
-
-static const char * DLL_CALLCONV
-MimeType() {
- return "image/png";
-}
-
-static BOOL DLL_CALLCONV
-Validate(FreeImageIO *io, fi_handle handle) {
- BYTE png_signature[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
- BYTE signature[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- io->read_proc(&signature, 1, 8, handle);
-
- return (memcmp(png_signature, signature, 8) == 0);
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportDepth(int depth) {
- return (
- (depth == 1) ||
- (depth == 4) ||
- (depth == 8) ||
- (depth == 24) ||
- (depth == 32)
- );
-}
-
-static BOOL DLL_CALLCONV
-SupportsExportType(FREE_IMAGE_TYPE type) {
- return (
- (type == FIT_BITMAP) ||
- (type == FIT_UINT16) ||
- (type == FIT_RGB16) ||
- (type == FIT_RGBA16)
- );
-}
-
-static BOOL DLL_CALLCONV
-SupportsICCProfiles() {
- return TRUE;
-}
-
-static BOOL DLL_CALLCONV
-SupportsNoPixels() {
- return TRUE;
-}
-
-// --------------------------------------------------------------------------
-
-/**
-Configure the decoder so that decoded pixels are compatible with a FREE_IMAGE_TYPE format.
-Set conversion instructions as needed.
-@param png_ptr PNG handle
-@param info_ptr PNG info handle
-@param flags Decoder flags
-@param output_image_type Returned FreeImage converted image type
-@return Returns TRUE if successful, returns FALSE otherwise
-@see png_read_update_info
-*/
-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:
- case 4:
- case 8:
- // expand grayscale images to the full 8-bit from 2-bit/pixel
- if (pixel_depth == 2) {
- png_set_expand_gray_1_2_4_to_8(png_ptr);
- }
-
- // 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;
-
- default:
- image_type = FIT_UNKNOWN;
- break;
- }
- break;
-
- case PNG_COLOR_TYPE_RGB: // color type '2', bitdepth = 8, 16
- switch(bit_depth) {
- case 8:
- image_type = (pixel_depth == 24) ? FIT_BITMAP : FIT_UNKNOWN;
- break;
- case 16:
- image_type = (pixel_depth == 48) ? FIT_RGB16 : FIT_UNKNOWN;
- break;
- default:
- image_type = FIT_UNKNOWN;
- break;
- }
- // sometimes, 24- or 48-bit images may contain transparency information
- // check for this use case and convert to an alpha-compatible format
- if (bIsTransparent && (image_type != FIT_UNKNOWN)) {
- // if the image is 24-bit RGB, mark it as 32-bit; if it is 48-bit, mark it as 64-bit
- image_type = (pixel_depth == 24) ? FIT_BITMAP : (pixel_depth == 48) ? FIT_RGBA16 : FIT_UNKNOWN;
- // expand tRNS chunk to alpha channel
- png_set_tRNS_to_alpha(png_ptr);
- }
- break;
-
- case PNG_COLOR_TYPE_PALETTE: // color type '3', bitdepth = 1, 2, 4, 8
- switch(bit_depth) {
- case 1:
- case 2:
- case 4:
- case 8:
- // expand palette images to the full 8 bits from 2 bits/pixel
- if (pixel_depth == 2) {
- png_set_packing(png_ptr);
- }
-
- // if a tRNS chunk is provided, we must also expand the palletized 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_packing(png_ptr);
- }
- break;
-
- default:
- image_type = FIT_UNKNOWN;
- break;
- }
- break;
-
- case PNG_COLOR_TYPE_GRAY_ALPHA: // color type '4', bitdepth = 8, 16
- switch(bit_depth) {
- case 8:
- // 8-bit grayscale + 8-bit alpha => convert to 32-bit RGBA
- image_type = (pixel_depth == 16) ? FIT_BITMAP : FIT_UNKNOWN;
- break;
- case 16:
- // 16-bit grayscale + 16-bit alpha => convert to 64-bit RGBA
- image_type = (pixel_depth == 32) ? FIT_RGBA16 : FIT_UNKNOWN;
- break;
- default:
- image_type = FIT_UNKNOWN;
- break;
- }
- // expand 8-bit greyscale + 8-bit alpha to 32-bit
- // expand 16-bit greyscale + 16-bit alpha to 64-bit
- png_set_gray_to_rgb(png_ptr);
- break;
-
- case PNG_COLOR_TYPE_RGB_ALPHA: // color type '6', bitdepth = 8, 16
- switch(bit_depth) {
- case 8:
- break;
- case 16:
- image_type = (pixel_depth == 64) ? FIT_RGBA16 : FIT_UNKNOWN;
- break;
- default:
- image_type = FIT_UNKNOWN;
- break;
- }
- break;
- }
-
- // check for unknown or invalid formats
- if(image_type == FIT_UNKNOWN) {
- *output_image_type = image_type;
- return FALSE;
- }
-
-#ifndef FREEIMAGE_BIGENDIAN
- if((image_type == FIT_UINT16) || (image_type == FIT_RGB16) || (image_type == FIT_RGBA16)) {
- // turn on 16-bit byte swapping
- png_set_swap(png_ptr);
- }
-#endif
-
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
- if((image_type == FIT_BITMAP) && ((color_type == PNG_COLOR_TYPE_RGB) || (color_type == PNG_COLOR_TYPE_RGB_ALPHA))) {
- // flip the RGB pixels to BGR (or RGBA to BGRA)
- png_set_bgr(png_ptr);
- }
-#endif
-
- // gamma correction
- // unlike the example in the libpng documentation, we have *no* idea where
- // this file may have come from--so if it doesn't have a file gamma, don't
- // do any correction ("do no harm")
-
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
- double gamma = 0;
- double screen_gamma = 2.2;
-
- if (png_get_gAMA(png_ptr, info_ptr, &gamma) && ( flags & PNG_IGNOREGAMMA ) != PNG_IGNOREGAMMA) {
- png_set_gamma(png_ptr, screen_gamma, gamma);
- }
- }
-
- // all transformations have been registered; now update info_ptr data
- png_read_update_info(png_ptr, info_ptr);
-
- // return the output image type
- *output_image_type = image_type;
-
- return TRUE;
-}
-
-static FIBITMAP * DLL_CALLCONV
-Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
- png_uint_32 width, height;
- int color_type;
- int bit_depth;
- int pixel_depth = 0; // pixel_depth = bit_depth * channels
-
- FIBITMAP *dib = NULL;
- png_bytepp row_pointers = NULL;
-
- fi_ioStructure fio;
- fio.s_handle = handle;
- fio.s_io = io;
-
- if (handle) {
- BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
-
- try {
- // check to see if the file is in fact a PNG file
-
- BYTE png_check[PNG_BYTES_TO_CHECK];
-
- io->read_proc(png_check, PNG_BYTES_TO_CHECK, 1, handle);
-
- if (png_sig_cmp(png_check, (png_size_t)0, PNG_BYTES_TO_CHECK) != 0) {
- return NULL; // Bad signature
- }
-
- // create the chunk manage structure
-
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, error_handler, warning_handler);
-
- if (!png_ptr) {
- return NULL;
- }
-
- // create the info structure
-
- info_ptr = png_create_info_struct(png_ptr);
-
- if (!info_ptr) {
- png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
- return NULL;
- }
-
- // init the IO
-
- png_set_read_fn(png_ptr, &fio, _ReadProc);
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return NULL;
- }
-
- // because we have already read the signature...
-
- png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
-
- // read the IHDR chunk
-
- png_read_info(png_ptr, info_ptr);
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
-
- // configure the decoder
-
- FREE_IMAGE_TYPE image_type = FIT_BITMAP;
-
- if(!ConfigureDecoder(png_ptr, info_ptr, flags, &image_type)) {
- throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
- }
-
- // update image info
-
- color_type = png_get_color_type(png_ptr, info_ptr);
- bit_depth = png_get_bit_depth(png_ptr, info_ptr);
- pixel_depth = bit_depth * png_get_channels(png_ptr, info_ptr);
-
- // create a dib and write the bitmap header
- // set up the dib palette, if needed
-
- switch (color_type) {
- case PNG_COLOR_TYPE_RGB:
- case PNG_COLOR_TYPE_RGB_ALPHA:
- dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, pixel_depth, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- break;
-
- case PNG_COLOR_TYPE_PALETTE:
- dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, pixel_depth, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(dib) {
- png_colorp png_palette = NULL;
- int palette_entries = 0;
-
- png_get_PLTE(png_ptr,info_ptr, &png_palette, &palette_entries);
-
- palette_entries = MIN((unsigned)palette_entries, FreeImage_GetColorsUsed(dib));
-
- // store the palette
-
- RGBQUAD *palette = FreeImage_GetPalette(dib);
- for(int i = 0; i < palette_entries; i++) {
- palette[i].rgbRed = png_palette[i].red;
- palette[i].rgbGreen = png_palette[i].green;
- palette[i].rgbBlue = png_palette[i].blue;
- }
- }
- break;
-
- case PNG_COLOR_TYPE_GRAY:
- dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, pixel_depth, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
-
- if(dib && (pixel_depth <= 8)) {
- RGBQUAD *palette = FreeImage_GetPalette(dib);
- const int palette_entries = 1 << pixel_depth;
-
- for(int i = 0; i < palette_entries; i++) {
- palette[i].rgbRed =
- palette[i].rgbGreen =
- palette[i].rgbBlue = (BYTE)((i * 255) / (palette_entries - 1));
- }
- }
- break;
-
- default:
- throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
- }
-
- 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;
- rgbBkColor.rgbReserved = 0;
-
- FreeImage_SetBackgroundColor(dib, &rgbBkColor);
- }
- }
-
- // get physical resolution
-
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
- png_uint_32 res_x, res_y;
-
- // we'll overload this var and use 0 to mean no phys data,
- // since if it's not in meters we can't use it anyway
-
- int res_unit_type = PNG_RESOLUTION_UNKNOWN;
-
- png_get_pHYs(png_ptr,info_ptr, &res_x, &res_y, &res_unit_type);
-
- if (res_unit_type == PNG_RESOLUTION_METER) {
- FreeImage_SetDotsPerMeterX(dib, res_x);
- FreeImage_SetDotsPerMeterY(dib, res_y);
- }
- }
-
- // get possible ICC profile
-
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) {
- png_charp profile_name = NULL;
- png_bytep profile_data = NULL;
- png_uint_32 profile_length = 0;
- int compression_type;
-
- png_get_iCCP(png_ptr, info_ptr, &profile_name, &compression_type, &profile_data, &profile_length);
-
- // copy ICC profile data (must be done after FreeImage_AllocateHeader)
-
- FreeImage_CreateICCProfile(dib, profile_data, profile_length);
- }
-
- // --- header only mode => clean-up and return
-
- if (header_only) {
- // get possible metadata (it can be located both before and after the image data)
- ReadMetadata(png_ptr, info_ptr, dib);
- if (png_ptr) {
- // clean up after the read, and free any memory allocated - REQUIRED
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
- }
- return dib;
- }
-
- // set the individual row_pointers to point at the correct offsets
-
- row_pointers = (png_bytepp)malloc(height * sizeof(png_bytep));
-
- if (!row_pointers) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- FreeImage_Unload(dib);
- return NULL;
- }
-
- // read in the bitmap bits via the pointer table
- // allow loading of PNG with minor errors (such as images with several IDAT chunks)
-
- for (png_uint_32 k = 0; k < height; k++) {
- row_pointers[height - 1 - k] = FreeImage_GetScanLine(dib, k);
- }
-
- png_set_benign_errors(png_ptr, 1);
- png_read_image(png_ptr, row_pointers);
-
- // check if the bitmap contains transparency, if so enable it in the header
-
- if (FreeImage_GetBPP(dib) == 32) {
- if (FreeImage_GetColorType(dib) == FIC_RGBALPHA) {
- FreeImage_SetTransparent(dib, TRUE);
- } else {
- FreeImage_SetTransparent(dib, FALSE);
- }
- }
-
- // cleanup
-
- if (row_pointers) {
- free(row_pointers);
- row_pointers = NULL;
- }
-
- // read the rest of the file, getting any additional chunks in info_ptr
-
- png_read_end(png_ptr, info_ptr);
-
- // get possible metadata (it can be located both before and after the image data)
-
- ReadMetadata(png_ptr, info_ptr, dib);
-
- if (png_ptr) {
- // clean up after the read, and free any memory allocated - REQUIRED
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
- }
-
- return dib;
-
- } catch (const char *text) {
- if (png_ptr) {
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
- }
- if (row_pointers) {
- free(row_pointers);
- }
- if (dib) {
- FreeImage_Unload(dib);
- }
- FreeImage_OutputMessageProc(s_format_id, text);
-
- return NULL;
- }
- }
-
- return NULL;
-}
-
-// --------------------------------------------------------------------------
-
-static BOOL DLL_CALLCONV
-Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
- png_structp png_ptr;
- png_infop info_ptr;
- png_colorp palette = NULL;
- png_uint_32 width, height;
- BOOL has_alpha_channel = FALSE;
-
- RGBQUAD *pal; // pointer to dib palette
- int bit_depth, pixel_depth; // pixel_depth = bit_depth * channels
- int palette_entries;
- int interlace_type;
-
- fi_ioStructure fio;
- fio.s_handle = handle;
- fio.s_io = io;
-
- if ((dib) && (handle)) {
- try {
- // create the chunk manage structure
-
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, error_handler, warning_handler);
-
- if (!png_ptr) {
- return FALSE;
- }
-
- // allocate/initialize the image information data.
-
- info_ptr = png_create_info_struct(png_ptr);
-
- if (!info_ptr) {
- png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- return FALSE;
- }
-
- // Set error handling. REQUIRED if you aren't supplying your own
- // error handling functions in the png_create_write_struct() call.
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- // if we get here, we had a problem reading the file
-
- png_destroy_write_struct(&png_ptr, &info_ptr);
-
- return FALSE;
- }
-
- // init the IO
-
- png_set_write_fn(png_ptr, &fio, _WriteProc, _FlushProc);
-
- // set physical resolution
-
- png_uint_32 res_x = (png_uint_32)FreeImage_GetDotsPerMeterX(dib);
- png_uint_32 res_y = (png_uint_32)FreeImage_GetDotsPerMeterY(dib);
-
- if ((res_x > 0) && (res_y > 0)) {
- png_set_pHYs(png_ptr, info_ptr, res_x, res_y, PNG_RESOLUTION_METER);
- }
-
- // Set the image information here. Width and height are up to 2^31,
- // bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
- // the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
- // PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
- // or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
- // PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
- // currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
-
- width = FreeImage_GetWidth(dib);
- height = FreeImage_GetHeight(dib);
- pixel_depth = FreeImage_GetBPP(dib);
-
- BOOL bInterlaced = FALSE;
- if( (flags & PNG_INTERLACED) == PNG_INTERLACED) {
- interlace_type = PNG_INTERLACE_ADAM7;
- bInterlaced = TRUE;
- } else {
- interlace_type = PNG_INTERLACE_NONE;
- }
-
- // set the ZLIB compression level or default to PNG default compression level (ZLIB level = 6)
- int zlib_level = flags & 0x0F;
- if((zlib_level >= 1) && (zlib_level <= 9)) {
- png_set_compression_level(png_ptr, zlib_level);
- } else if((flags & PNG_Z_NO_COMPRESSION) == PNG_Z_NO_COMPRESSION) {
- png_set_compression_level(png_ptr, Z_NO_COMPRESSION);
- }
-
- // filtered strategy works better for high color images
- if(pixel_depth >= 16){
- png_set_compression_strategy(png_ptr, Z_FILTERED);
- png_set_filter(png_ptr, 0, PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_PAETH);
- } else {
- png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
- }
-
- FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
- if(image_type == FIT_BITMAP) {
- // standard image type
- bit_depth = (pixel_depth > 8) ? 8 : pixel_depth;
- } else {
- // 16-bit greyscale or 16-bit RGB(A)
- bit_depth = 16;
- }
-
- // check for transparent images
- BOOL bIsTransparent =
- (image_type == FIT_BITMAP) && FreeImage_IsTransparent(dib) && (FreeImage_GetTransparencyCount(dib) > 0) ? TRUE : FALSE;
-
- switch (FreeImage_GetColorType(dib)) {
- case FIC_MINISWHITE:
- if(!bIsTransparent) {
- // Invert monochrome files to have 0 as black and 1 as white (no break here)
- png_set_invert_mono(png_ptr);
- }
- // (fall through)
-
- case FIC_MINISBLACK:
- if(!bIsTransparent) {
- png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
- PNG_COLOR_TYPE_GRAY, interlace_type,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
- break;
- }
- // 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
-
- palette_entries = 1 << bit_depth;
- palette = (png_colorp)png_malloc(png_ptr, palette_entries * sizeof (png_color));
- pal = FreeImage_GetPalette(dib);
-
- for (int i = 0; i < palette_entries; i++) {
- palette[i].red = pal[i].rgbRed;
- palette[i].green = pal[i].rgbGreen;
- palette[i].blue = pal[i].rgbBlue;
- }
-
- png_set_PLTE(png_ptr, info_ptr, palette, palette_entries);
-
- // You must not free palette here, because png_set_PLTE only makes a link to
- // the palette that you malloced. Wait until you are about to destroy
- // the png structure.
-
- break;
- }
-
- case FIC_RGBALPHA :
- has_alpha_channel = TRUE;
-
- png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
- PNG_COLOR_TYPE_RGBA, interlace_type,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
- // flip BGR pixels to RGB
- if(image_type == FIT_BITMAP) {
- png_set_bgr(png_ptr);
- }
-#endif
- break;
-
- case FIC_RGB:
- png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
- PNG_COLOR_TYPE_RGB, interlace_type,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
-#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
- // flip BGR pixels to RGB
- if(image_type == FIT_BITMAP) {
- png_set_bgr(png_ptr);
- }
-#endif
- break;
-
- case FIC_CMYK:
- break;
- }
-
- // write possible ICC profile
-
- FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(dib);
- if (iccProfile->size && iccProfile->data) {
- png_set_iCCP(png_ptr, info_ptr, "Embedded Profile", 0, (png_const_bytep)iccProfile->data, iccProfile->size);
- }
-
- // write metadata
-
- WriteMetadata(png_ptr, info_ptr, dib);
-
- // Optional gamma chunk is strongly suggested if you have any guess
- // as to the correct gamma of the image.
- // png_set_gAMA(png_ptr, info_ptr, gamma);
-
- // set the transparency table
-
- if (bIsTransparent) {
- png_set_tRNS(png_ptr, info_ptr, FreeImage_GetTransparencyTable(dib), FreeImage_GetTransparencyCount(dib), NULL);
- }
-
- // set the background color
-
- if(FreeImage_HasBackgroundColor(dib)) {
- png_color_16 image_background;
- RGBQUAD rgbBkColor;
-
- FreeImage_GetBackgroundColor(dib, &rgbBkColor);
- memset(&image_background, 0, sizeof(png_color_16));
- image_background.blue = rgbBkColor.rgbBlue;
- image_background.green = rgbBkColor.rgbGreen;
- image_background.red = rgbBkColor.rgbRed;
- image_background.index = rgbBkColor.rgbReserved;
-
- png_set_bKGD(png_ptr, info_ptr, &image_background);
- }
-
- // Write the file header information.
-
- png_write_info(png_ptr, info_ptr);
-
- // write out the image data
-
-#ifndef FREEIMAGE_BIGENDIAN
- if (bit_depth == 16) {
- // turn on 16 bit byte swapping
- png_set_swap(png_ptr);
- }
-#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
- for (int pass = 0; pass < number_passes; pass++) {
- for (png_uint_32 k = 0; k < height; k++) {
- png_write_row(png_ptr, FreeImage_GetScanLine(dib, height - k - 1));
- }
- }
- }
-
- // It is REQUIRED to call this to finish writing the rest of the file
- // Bug with png_flush
-
- png_write_end(png_ptr, info_ptr);
-
- // clean up after the write, and free any memory allocated
- if (palette) {
- png_free(png_ptr, palette);
- }
-
- png_destroy_write_struct(&png_ptr, &info_ptr);
-
- return TRUE;
-
- } catch (const char *text) {
- if(png_ptr) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- }
- FreeImage_OutputMessageProc(s_format_id, text);
- }
- }
-
- return FALSE;
-}
-
-// ==========================================================
-// Init
-// ==========================================================
-
-void DLL_CALLCONV
-InitPNG(Plugin *plugin, int format_id) {
- s_format_id = format_id;
-
- plugin->format_proc = Format;
- plugin->description_proc = Description;
- plugin->extension_proc = Extension;
- plugin->regexpr_proc = RegExpr;
- plugin->open_proc = NULL;
- plugin->close_proc = NULL;
- plugin->pagecount_proc = NULL;
- plugin->pagecapability_proc = NULL;
- plugin->load_proc = Load;
- plugin->save_proc = Save;
- plugin->validate_proc = Validate;
- plugin->mime_proc = MimeType;
- plugin->supports_export_bpp_proc = SupportsExportDepth;
- plugin->supports_export_type_proc = SupportsExportType;
- plugin->supports_icc_profiles_proc = SupportsICCProfiles;
- plugin->supports_no_pixels_proc = SupportsNoPixels;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/TIFFLogLuv.cpp b/plugins/AdvaImg/src/FreeImage/TIFFLogLuv.cpp
deleted file mode 100644
index 3f313232c4..0000000000
--- a/plugins/AdvaImg/src/FreeImage/TIFFLogLuv.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-// ==========================================================
-// XYZ to RGB TIFF conversion routines
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-void tiff_ConvertLineXYZToRGB(BYTE *target, BYTE *source, double stonits, int width_in_pixels) {
- FIRGBF *rgbf = (FIRGBF*)target;
- float *xyz = (float*)source;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- // assume CCIR-709 primaries (matrix from tif_luv.c)
- // LOG Luv XYZ (D65) -> sRGB (CIE Illuminant E)
- rgbf->red = (float)( 2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2]);
- rgbf->green = (float)(-1.022*xyz[0] + 1.978*xyz[1] + 0.044*xyz[2]);
- rgbf->blue = (float)( 0.061*xyz[0] + -0.224*xyz[1] + 1.163*xyz[2]);
-
- /*
- if (stonits != 0.0) {
- rgbf->red = (float)(rgbf->red * stonits);
- rgbf->green = (float)(rgbf->green * stonits);
- rgbf->blue = (float)(rgbf->blue * stonits);
- }
- */
-
- rgbf++;
- xyz += 3;
- }
-}
-
-void tiff_ConvertLineRGBToXYZ(BYTE *target, BYTE *source, int width_in_pixels) {
- FIRGBF *rgbf = (FIRGBF*)source;
- float *xyz = (float*)target;
-
- for (int cols = 0; cols < width_in_pixels; cols++) {
- // assume CCIR-709 primaries, whitepoint x = 1/3 y = 1/3 (D_E)
- // "The LogLuv Encoding for Full Gamut, High Dynamic Range Images" <G.Ward>
- // sRGB ( CIE Illuminant E ) -> LOG Luv XYZ (D65)
- xyz[0] = (float)(0.497*rgbf->red + 0.339*rgbf->green + 0.164*rgbf->blue);
- xyz[1] = (float)(0.256*rgbf->red + 0.678*rgbf->green + 0.066*rgbf->blue);
- xyz[2] = (float)(0.023*rgbf->red + 0.113*rgbf->green + 0.864*rgbf->blue);
-
- rgbf++;
- xyz += 3;
- }
-}
-
diff --git a/plugins/AdvaImg/src/FreeImage/ToneMapping.cpp b/plugins/AdvaImg/src/FreeImage/ToneMapping.cpp
deleted file mode 100644
index aca7961647..0000000000
--- a/plugins/AdvaImg/src/FreeImage/ToneMapping.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-// ==========================================================
-// Tone mapping operators
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-
-/**
-Performs a tone mapping on a 48-bit RGB or a 96-bit RGBF image and returns a 24-bit image.
-The meaning of the parameters depends on the choosen algorithm.
-When both parameters are set to zero, a default set of parameters is used.
-@param dib Input RGB/RGBF image
-@param tmo Tone mapping operator
-@param first_param First parameter of the algorithm
-@param second_param Second parameter of the algorithm
-return Returns a 24-bit tone mapped image if successful, returns NULL otherwise
-*/
-FIBITMAP * DLL_CALLCONV
-FreeImage_ToneMapping(FIBITMAP *dib, FREE_IMAGE_TMO tmo, double first_param, double second_param) {
- if(FreeImage_HasPixels(dib)) {
- switch(tmo) {
- // Adaptive logarithmic mapping (F. Drago, 2003)
- case FITMO_DRAGO03:
- if((first_param == 0) && (second_param == 0)) {
- // use default values (gamma = 2.2, exposure = 0)
- return FreeImage_TmoDrago03(dib, 2.2, 0);
- } else {
- // use user's value
- return FreeImage_TmoDrago03(dib, first_param, second_param);
- }
- break;
- // Dynamic range reduction inspired by photoreceptor phhysiology (E. Reinhard, 2005)
- case FITMO_REINHARD05:
- if((first_param == 0) && (second_param == 0)) {
- // use default values by setting intensity to 0 and contrast to 0
- return FreeImage_TmoReinhard05(dib, 0, 0);
- } else {
- // use user's value
- return FreeImage_TmoReinhard05(dib, first_param, second_param);
- }
- break;
- // Gradient Domain HDR Compression (R. Fattal, 2002)
- case FITMO_FATTAL02:
- if((first_param == 0) && (second_param == 0)) {
- // use default values by setting color saturation to 0.5 and attenuation to 0.85
- return FreeImage_TmoFattal02(dib, 0.5, 0.85);
- } else {
- // use user's value
- return FreeImage_TmoFattal02(dib, first_param, second_param);
- }
- break;
- }
- }
-
- return NULL;
-}
-
-
diff --git a/plugins/AdvaImg/src/FreeImage/WuQuantizer.cpp b/plugins/AdvaImg/src/FreeImage/WuQuantizer.cpp
deleted file mode 100644
index e092f228cc..0000000000
--- a/plugins/AdvaImg/src/FreeImage/WuQuantizer.cpp
+++ /dev/null
@@ -1,559 +0,0 @@
-///////////////////////////////////////////////////////////////////////
-// C Implementation of Wu's Color Quantizer (v. 2)
-// (see Graphics Gems vol. II, pp. 126-133)
-//
-// Author: Xiaolin Wu
-// Dept. of Computer Science
-// Univ. of Western Ontario
-// London, Ontario N6A 5B7
-// wu@csd.uwo.ca
-//
-// Algorithm: Greedy orthogonal bipartition of RGB space for variance
-// minimization aided by inclusion-exclusion tricks.
-// For speed no nearest neighbor search is done. Slightly
-// better performance can be expected by more sophisticated
-// but more expensive versions.
-//
-// The author thanks Tom Lane at Tom_Lane@G.GP.CS.CMU.EDU for much of
-// additional documentation and a cure to a previous bug.
-//
-// Free to distribute, comments and suggestions are appreciated.
-///////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////
-// History
-// -------
-// July 2000: C++ Implementation of Wu's Color Quantizer
-// and adaptation for the FreeImage 2 Library
-// Author: Hervé Drolon (drolon@infonie.fr)
-// March 2004: Adaptation for the FreeImage 3 library (port to big endian processors)
-// Author: Hervé Drolon (drolon@infonie.fr)
-///////////////////////////////////////////////////////////////////////
-
-#include "Quantizers.h"
-#include "FreeImage.h"
-#include "Utilities.h"
-
-///////////////////////////////////////////////////////////////////////
-
-// Size of a 3D array : 33 x 33 x 33
-#define SIZE_3D 35937
-
-// 3D array indexation
-#define INDEX(r, g, b) ((r << 10) + (r << 6) + r + (g << 5) + g + b)
-
-#define MAXCOLOR 256
-
-// Constructor / Destructor
-
-WuQuantizer::WuQuantizer(FIBITMAP *dib) {
- width = FreeImage_GetWidth(dib);
- height = FreeImage_GetHeight(dib);
- pitch = FreeImage_GetPitch(dib);
- m_dib = dib;
-
- gm2 = NULL;
- wt = mr = mg = mb = NULL;
- Qadd = NULL;
-
- // Allocate 3D arrays
- gm2 = (float*)malloc(SIZE_3D * sizeof(float));
- wt = (LONG*)malloc(SIZE_3D * sizeof(LONG));
- mr = (LONG*)malloc(SIZE_3D * sizeof(LONG));
- mg = (LONG*)malloc(SIZE_3D * sizeof(LONG));
- mb = (LONG*)malloc(SIZE_3D * sizeof(LONG));
-
- // Allocate Qadd
- Qadd = (WORD *)malloc(sizeof(WORD) * width * height);
-
- if(!gm2 || !wt || !mr || !mg || !mb || !Qadd) {
- if(gm2) free(gm2);
- if(wt) free(wt);
- if(mr) free(mr);
- if(mg) free(mg);
- if(mb) free(mb);
- if(Qadd) free(Qadd);
- throw FI_MSG_ERROR_MEMORY;
- }
- memset(gm2, 0, SIZE_3D * sizeof(float));
- memset(wt, 0, SIZE_3D * sizeof(LONG));
- memset(mr, 0, SIZE_3D * sizeof(LONG));
- memset(mg, 0, SIZE_3D * sizeof(LONG));
- memset(mb, 0, SIZE_3D * sizeof(LONG));
- memset(Qadd, 0, sizeof(WORD) * width * height);
-}
-
-WuQuantizer::~WuQuantizer() {
- if(gm2) free(gm2);
- if(wt) free(wt);
- if(mr) free(mr);
- if(mg) free(mg);
- if(mb) free(mb);
- if(Qadd) free(Qadd);
-}
-
-
-// Histogram is in elements 1..HISTSIZE along each axis,
-// element 0 is for base or marginal value
-// NB: these must start out 0!
-
-// Build 3-D color histogram of counts, r/g/b, c^2
-void
-WuQuantizer::Hist3D(LONG *vwt, LONG *vmr, LONG *vmg, LONG *vmb, float *m2, int ReserveSize, RGBQUAD *ReservePalette) {
- int ind = 0;
- int inr, ing, inb, table[256];
- int i;
- unsigned y, x;
-
- for(i = 0; i < 256; i++)
- table[i] = i * i;
-
- if (FreeImage_GetBPP(m_dib) == 24) {
- for(y = 0; y < height; y++) {
- BYTE *bits = FreeImage_GetScanLine(m_dib, y);
-
- for(x = 0; x < width; x++) {
- inr = (bits[FI_RGBA_RED] >> 3) + 1;
- ing = (bits[FI_RGBA_GREEN] >> 3) + 1;
- inb = (bits[FI_RGBA_BLUE] >> 3) + 1;
- ind = INDEX(inr, ing, inb);
- Qadd[y*width + x] = (WORD)ind;
- // [inr][ing][inb]
- vwt[ind]++;
- vmr[ind] += bits[FI_RGBA_RED];
- vmg[ind] += bits[FI_RGBA_GREEN];
- vmb[ind] += bits[FI_RGBA_BLUE];
- m2[ind] += (float)(table[bits[FI_RGBA_RED]] + table[bits[FI_RGBA_GREEN]] + table[bits[FI_RGBA_BLUE]]);
- bits += 3;
- }
- }
- } else {
- for(y = 0; y < height; y++) {
- BYTE *bits = FreeImage_GetScanLine(m_dib, y);
-
- for(x = 0; x < width; x++) {
- inr = (bits[FI_RGBA_RED] >> 3) + 1;
- ing = (bits[FI_RGBA_GREEN] >> 3) + 1;
- inb = (bits[FI_RGBA_BLUE] >> 3) + 1;
- ind = INDEX(inr, ing, inb);
- Qadd[y*width + x] = (WORD)ind;
- // [inr][ing][inb]
- vwt[ind]++;
- vmr[ind] += bits[FI_RGBA_RED];
- vmg[ind] += bits[FI_RGBA_GREEN];
- vmb[ind] += bits[FI_RGBA_BLUE];
- m2[ind] += (float)(table[bits[FI_RGBA_RED]] + table[bits[FI_RGBA_GREEN]] + table[bits[FI_RGBA_BLUE]]);
- bits += 4;
- }
- }
- }
-
- if( ReserveSize > 0 ) {
- int max = 0;
- for(i = 0; i < SIZE_3D; i++) {
- if( vwt[i] > max ) max = vwt[i];
- }
- max++;
- for(i = 0; i < ReserveSize; i++) {
- inr = (ReservePalette[i].rgbRed >> 3) + 1;
- ing = (ReservePalette[i].rgbGreen >> 3) + 1;
- inb = (ReservePalette[i].rgbBlue >> 3) + 1;
- ind = INDEX(inr, ing, inb);
- wt[ind] = max;
- mr[ind] = max * ReservePalette[i].rgbRed;
- mg[ind] = max * ReservePalette[i].rgbGreen;
- mb[ind] = max * ReservePalette[i].rgbBlue;
- gm2[ind] = (float)max * (float)(table[ReservePalette[i].rgbRed] + table[ReservePalette[i].rgbGreen] + table[ReservePalette[i].rgbBlue]);
- }
- }
-}
-
-
-// At conclusion of the histogram step, we can interpret
-// wt[r][g][b] = sum over voxel of P(c)
-// mr[r][g][b] = sum over voxel of r*P(c) , similarly for mg, mb
-// m2[r][g][b] = sum over voxel of c^2*P(c)
-// Actually each of these should be divided by 'ImageSize' to give the usual
-// interpretation of P() as ranging from 0 to 1, but we needn't do that here.
-
-
-// We now convert histogram into moments so that we can rapidly calculate
-// the sums of the above quantities over any desired box.
-
-// Compute cumulative moments
-void
-WuQuantizer::M3D(LONG *vwt, LONG *vmr, LONG *vmg, LONG *vmb, float *m2) {
- unsigned ind1, ind2;
- BYTE i, r, g, b;
- LONG line, line_r, line_g, line_b;
- LONG area[33], area_r[33], area_g[33], area_b[33];
- float line2, area2[33];
-
- for(r = 1; r <= 32; r++) {
- for(i = 0; i <= 32; i++) {
- area2[i] = 0;
- area[i] = area_r[i] = area_g[i] = area_b[i] = 0;
- }
- for(g = 1; g <= 32; g++) {
- line2 = 0;
- line = line_r = line_g = line_b = 0;
- for(b = 1; b <= 32; b++) {
- ind1 = INDEX(r, g, b); // [r][g][b]
- line += vwt[ind1];
- line_r += vmr[ind1];
- line_g += vmg[ind1];
- line_b += vmb[ind1];
- line2 += m2[ind1];
- area[b] += line;
- area_r[b] += line_r;
- area_g[b] += line_g;
- area_b[b] += line_b;
- area2[b] += line2;
- ind2 = ind1 - 1089; // [r-1][g][b]
- vwt[ind1] = vwt[ind2] + area[b];
- vmr[ind1] = vmr[ind2] + area_r[b];
- vmg[ind1] = vmg[ind2] + area_g[b];
- vmb[ind1] = vmb[ind2] + area_b[b];
- m2[ind1] = m2[ind2] + area2[b];
- }
- }
- }
-}
-
-// Compute sum over a box of any given statistic
-LONG
-WuQuantizer::Vol( Box *cube, LONG *mmt ) {
- return( mmt[INDEX(cube->r1, cube->g1, cube->b1)]
- - mmt[INDEX(cube->r1, cube->g1, cube->b0)]
- - mmt[INDEX(cube->r1, cube->g0, cube->b1)]
- + mmt[INDEX(cube->r1, cube->g0, cube->b0)]
- - mmt[INDEX(cube->r0, cube->g1, cube->b1)]
- + mmt[INDEX(cube->r0, cube->g1, cube->b0)]
- + mmt[INDEX(cube->r0, cube->g0, cube->b1)]
- - mmt[INDEX(cube->r0, cube->g0, cube->b0)] );
-}
-
-// The next two routines allow a slightly more efficient calculation
-// of Vol() for a proposed subbox of a given box. The sum of Top()
-// and Bottom() is the Vol() of a subbox split in the given direction
-// and with the specified new upper bound.
-
-
-// Compute part of Vol(cube, mmt) that doesn't depend on r1, g1, or b1
-// (depending on dir)
-
-LONG
-WuQuantizer::Bottom(Box *cube, BYTE dir, LONG *mmt) {
- switch(dir)
- {
- case FI_RGBA_RED:
- return( - mmt[INDEX(cube->r0, cube->g1, cube->b1)]
- + mmt[INDEX(cube->r0, cube->g1, cube->b0)]
- + mmt[INDEX(cube->r0, cube->g0, cube->b1)]
- - mmt[INDEX(cube->r0, cube->g0, cube->b0)] );
- break;
- case FI_RGBA_GREEN:
- return( - mmt[INDEX(cube->r1, cube->g0, cube->b1)]
- + mmt[INDEX(cube->r1, cube->g0, cube->b0)]
- + mmt[INDEX(cube->r0, cube->g0, cube->b1)]
- - mmt[INDEX(cube->r0, cube->g0, cube->b0)] );
- break;
- case FI_RGBA_BLUE:
- return( - mmt[INDEX(cube->r1, cube->g1, cube->b0)]
- + mmt[INDEX(cube->r1, cube->g0, cube->b0)]
- + mmt[INDEX(cube->r0, cube->g1, cube->b0)]
- - mmt[INDEX(cube->r0, cube->g0, cube->b0)] );
- break;
- }
-
- return 0;
-}
-
-
-// Compute remainder of Vol(cube, mmt), substituting pos for
-// r1, g1, or b1 (depending on dir)
-
-LONG
-WuQuantizer::Top(Box *cube, BYTE dir, int pos, LONG *mmt) {
- switch(dir)
- {
- case FI_RGBA_RED:
- return( mmt[INDEX(pos, cube->g1, cube->b1)]
- -mmt[INDEX(pos, cube->g1, cube->b0)]
- -mmt[INDEX(pos, cube->g0, cube->b1)]
- +mmt[INDEX(pos, cube->g0, cube->b0)] );
- break;
- case FI_RGBA_GREEN:
- return( mmt[INDEX(cube->r1, pos, cube->b1)]
- -mmt[INDEX(cube->r1, pos, cube->b0)]
- -mmt[INDEX(cube->r0, pos, cube->b1)]
- +mmt[INDEX(cube->r0, pos, cube->b0)] );
- break;
- case FI_RGBA_BLUE:
- return( mmt[INDEX(cube->r1, cube->g1, pos)]
- -mmt[INDEX(cube->r1, cube->g0, pos)]
- -mmt[INDEX(cube->r0, cube->g1, pos)]
- +mmt[INDEX(cube->r0, cube->g0, pos)] );
- break;
- }
-
- return 0;
-}
-
-// Compute the weighted variance of a box
-// NB: as with the raw statistics, this is really the variance * ImageSize
-
-float
-WuQuantizer::Var(Box *cube) {
- float dr = (float) Vol(cube, mr);
- float dg = (float) Vol(cube, mg);
- float db = (float) Vol(cube, mb);
- float xx = gm2[INDEX(cube->r1, cube->g1, cube->b1)]
- -gm2[INDEX(cube->r1, cube->g1, cube->b0)]
- -gm2[INDEX(cube->r1, cube->g0, cube->b1)]
- +gm2[INDEX(cube->r1, cube->g0, cube->b0)]
- -gm2[INDEX(cube->r0, cube->g1, cube->b1)]
- +gm2[INDEX(cube->r0, cube->g1, cube->b0)]
- +gm2[INDEX(cube->r0, cube->g0, cube->b1)]
- -gm2[INDEX(cube->r0, cube->g0, cube->b0)];
-
- return (xx - (dr*dr+dg*dg+db*db)/(float)Vol(cube,wt));
-}
-
-// We want to minimize the sum of the variances of two subboxes.
-// The sum(c^2) terms can be ignored since their sum over both subboxes
-// is the same (the sum for the whole box) no matter where we split.
-// The remaining terms have a minus sign in the variance formula,
-// so we drop the minus sign and MAXIMIZE the sum of the two terms.
-
-float
-WuQuantizer::Maximize(Box *cube, BYTE dir, int first, int last , int *cut, LONG whole_r, LONG whole_g, LONG whole_b, LONG whole_w) {
- LONG half_r, half_g, half_b, half_w;
- int i;
- float temp;
-
- LONG base_r = Bottom(cube, dir, mr);
- LONG base_g = Bottom(cube, dir, mg);
- LONG base_b = Bottom(cube, dir, mb);
- LONG base_w = Bottom(cube, dir, wt);
-
- float max = 0.0;
-
- *cut = -1;
-
- for (i = first; i < last; i++) {
- half_r = base_r + Top(cube, dir, i, mr);
- half_g = base_g + Top(cube, dir, i, mg);
- half_b = base_b + Top(cube, dir, i, mb);
- half_w = base_w + Top(cube, dir, i, wt);
-
- // now half_x is sum over lower half of box, if split at i
-
- if (half_w == 0) { // subbox could be empty of pixels!
- continue; // never split into an empty box
- } else {
- temp = ((float)half_r*half_r + (float)half_g*half_g + (float)half_b*half_b)/half_w;
- }
-
- half_r = whole_r - half_r;
- half_g = whole_g - half_g;
- half_b = whole_b - half_b;
- half_w = whole_w - half_w;
-
- if (half_w == 0) { // subbox could be empty of pixels!
- continue; // never split into an empty box
- } else {
- temp += ((float)half_r*half_r + (float)half_g*half_g + (float)half_b*half_b)/half_w;
- }
-
- if (temp > max) {
- max=temp;
- *cut=i;
- }
- }
-
- return max;
-}
-
-bool
-WuQuantizer::Cut(Box *set1, Box *set2) {
- BYTE dir;
- int cutr, cutg, cutb;
-
- LONG whole_r = Vol(set1, mr);
- LONG whole_g = Vol(set1, mg);
- LONG whole_b = Vol(set1, mb);
- LONG whole_w = Vol(set1, wt);
-
- float maxr = Maximize(set1, FI_RGBA_RED, set1->r0+1, set1->r1, &cutr, whole_r, whole_g, whole_b, whole_w);
- float maxg = Maximize(set1, FI_RGBA_GREEN, set1->g0+1, set1->g1, &cutg, whole_r, whole_g, whole_b, whole_w);
- float maxb = Maximize(set1, FI_RGBA_BLUE, set1->b0+1, set1->b1, &cutb, whole_r, whole_g, whole_b, whole_w);
-
- if ((maxr >= maxg) && (maxr >= maxb)) {
- dir = FI_RGBA_RED;
-
- if (cutr < 0) {
- return false; // can't split the box
- }
- } else if ((maxg >= maxr) && (maxg>=maxb)) {
- dir = FI_RGBA_GREEN;
- } else {
- dir = FI_RGBA_BLUE;
- }
-
- set2->r1 = set1->r1;
- set2->g1 = set1->g1;
- set2->b1 = set1->b1;
-
- switch (dir) {
- case FI_RGBA_RED:
- set2->r0 = set1->r1 = cutr;
- set2->g0 = set1->g0;
- set2->b0 = set1->b0;
- break;
-
- case FI_RGBA_GREEN:
- set2->g0 = set1->g1 = cutg;
- set2->r0 = set1->r0;
- set2->b0 = set1->b0;
- break;
-
- case FI_RGBA_BLUE:
- set2->b0 = set1->b1 = cutb;
- set2->r0 = set1->r0;
- set2->g0 = set1->g0;
- break;
- }
-
- set1->vol = (set1->r1-set1->r0)*(set1->g1-set1->g0)*(set1->b1-set1->b0);
- set2->vol = (set2->r1-set2->r0)*(set2->g1-set2->g0)*(set2->b1-set2->b0);
-
- return true;
-}
-
-
-void
-WuQuantizer::Mark(Box *cube, int label, BYTE *tag) {
- for (int r = cube->r0 + 1; r <= cube->r1; r++) {
- for (int g = cube->g0 + 1; g <= cube->g1; g++) {
- for (int b = cube->b0 + 1; b <= cube->b1; b++) {
- tag[INDEX(r, g, b)] = (BYTE)label;
- }
- }
- }
-}
-
-// Wu Quantization algorithm
-FIBITMAP *
-WuQuantizer::Quantize(int PaletteSize, int ReserveSize, RGBQUAD *ReservePalette) {
- BYTE *tag = NULL;
-
- try {
- Box cube[MAXCOLOR];
- int next;
- LONG i, weight;
- int k;
- float vv[MAXCOLOR], temp;
-
- // Compute 3D histogram
-
- Hist3D(wt, mr, mg, mb, gm2, ReserveSize, ReservePalette);
-
- // Compute moments
-
- M3D(wt, mr, mg, mb, gm2);
-
- cube[0].r0 = cube[0].g0 = cube[0].b0 = 0;
- cube[0].r1 = cube[0].g1 = cube[0].b1 = 32;
- next = 0;
-
- for (i = 1; i < PaletteSize; i++) {
- if(Cut(&cube[next], &cube[i])) {
- // volume test ensures we won't try to cut one-cell box
- vv[next] = (cube[next].vol > 1) ? Var(&cube[next]) : 0;
- vv[i] = (cube[i].vol > 1) ? Var(&cube[i]) : 0;
- } else {
- vv[next] = 0.0; // don't try to split this box again
- i--; // didn't create box i
- }
-
- next = 0; temp = vv[0];
-
- for (k = 1; k <= i; k++) {
- if (vv[k] > temp) {
- temp = vv[k]; next = k;
- }
- }
-
- if (temp <= 0.0) {
- PaletteSize = i + 1;
-
- // Error: "Only got 'PaletteSize' boxes"
-
- break;
- }
- }
-
- // Partition done
-
- // the space for array gm2 can be freed now
-
- free(gm2);
-
- gm2 = NULL;
-
- // Allocate a new dib
-
- FIBITMAP *new_dib = FreeImage_Allocate(width, height, 8);
-
- if (new_dib == NULL) {
- throw FI_MSG_ERROR_MEMORY;
- }
-
- // create an optimized palette
-
- RGBQUAD *new_pal = FreeImage_GetPalette(new_dib);
-
- tag = (BYTE*) malloc(SIZE_3D * sizeof(BYTE));
- if (tag == NULL) {
- throw FI_MSG_ERROR_MEMORY;
- }
- memset(tag, 0, SIZE_3D * sizeof(BYTE));
-
- for (k = 0; k < PaletteSize ; k++) {
- Mark(&cube[k], k, tag);
- weight = Vol(&cube[k], wt);
-
- if (weight) {
- new_pal[k].rgbRed = (BYTE)(((float)Vol(&cube[k], mr) / (float)weight) + 0.5f);
- new_pal[k].rgbGreen = (BYTE)(((float)Vol(&cube[k], mg) / (float)weight) + 0.5f);
- new_pal[k].rgbBlue = (BYTE)(((float)Vol(&cube[k], mb) / (float)weight) + 0.5f);
- } else {
- // Error: bogus box 'k'
-
- new_pal[k].rgbRed = new_pal[k].rgbGreen = new_pal[k].rgbBlue = 0;
- }
- }
-
- int npitch = FreeImage_GetPitch(new_dib);
-
- for (unsigned y = 0; y < height; y++) {
- BYTE *new_bits = FreeImage_GetBits(new_dib) + (y * npitch);
-
- for (unsigned x = 0; x < width; x++) {
- new_bits[x] = tag[Qadd[y*width + x]];
- }
- }
-
- // output 'new_pal' as color look-up table contents,
- // 'new_bits' as the quantized image (array of table addresses).
-
- free(tag);
-
- return (FIBITMAP*) new_dib;
- } catch(...) {
- free(tag);
- }
-
- return NULL;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/ZLibInterface.cpp b/plugins/AdvaImg/src/FreeImage/ZLibInterface.cpp
deleted file mode 100644
index 39c7ac0ecc..0000000000
--- a/plugins/AdvaImg/src/FreeImage/ZLibInterface.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-// ==========================================================
-// ZLib library interface
-//
-// Design and implementation by
-// - Floris van den Berg (flvdberg@wxs.nl)
-//
-// 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!
-// ==========================================================
-
-#include "zlib.h"
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "zutil.h" /* must be the last header because of error C3163 in VS2008 (_vsnprintf defined in stdio.h) */
-
-/**
-Compresses a source buffer into a target buffer, using the ZLib library.
-Upon entry, target_size is the total size of the destination buffer,
-which must be at least 0.1% larger than source_size plus 12 bytes.
-
-@param target Destination buffer
-@param target_size Size of the destination buffer, in bytes
-@param source Source buffer
-@param source_size Size of the source buffer, in bytes
-@return Returns the actual size of the compressed buffer, returns 0 if an error occured
-@see FreeImage_ZLibUncompress
-*/
-DWORD DLL_CALLCONV
-FreeImage_ZLibCompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size) {
- uLongf dest_len = (uLongf)target_size;
-
- int zerr = compress(target, &dest_len, source, source_size);
- switch(zerr) {
- case Z_MEM_ERROR: // not enough memory
- case Z_BUF_ERROR: // not enough room in the output buffer
- FreeImage_OutputMessageProc(FIF_UNKNOWN, "Zlib error : %s", zError(zerr));
- return 0;
- case Z_OK:
- return dest_len;
- }
-
- return 0;
-}
-
-/**
-Decompresses a source buffer into a target buffer, using the ZLib library.
-Upon entry, target_size is the total size of the destination buffer,
-which must be large enough to hold the entire uncompressed data.
-The size of the uncompressed data must have been saved previously by the compressor
-and transmitted to the decompressor by some mechanism outside the scope of this
-compression library.
-
-@param target Destination buffer
-@param target_size Size of the destination buffer, in bytes
-@param source Source buffer
-@param source_size Size of the source buffer, in bytes
-@return Returns the actual size of the uncompressed buffer, returns 0 if an error occured
-@see FreeImage_ZLibCompress
-*/
-DWORD DLL_CALLCONV
-FreeImage_ZLibUncompress(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size) {
- uLongf dest_len = (uLongf)target_size;
-
- int zerr = uncompress(target, &dest_len, source, source_size);
- switch(zerr) {
- case Z_MEM_ERROR: // not enough memory
- case Z_BUF_ERROR: // not enough room in the output buffer
- case Z_DATA_ERROR: // input data was corrupted
- FreeImage_OutputMessageProc(FIF_UNKNOWN, "Zlib error : %s", zError(zerr));
- return 0;
- case Z_OK:
- return dest_len;
- }
-
- return 0;
-}
-
-/**
-Compresses a source buffer into a target buffer, using the ZLib library.
-On success, the target buffer contains a GZIP compatible layout.
-Upon entry, target_size is the total size of the destination buffer,
-which must be at least 0.1% larger than source_size plus 24 bytes.
-
-@param target Destination buffer
-@param target_size Size of the destination buffer, in bytes
-@param source Source buffer
-@param source_size Size of the source buffer, in bytes
-@return Returns the actual size of the compressed buffer, returns 0 if an error occured
-@see FreeImage_ZLibCompress
-*/
-DWORD DLL_CALLCONV
-FreeImage_ZLibGZip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size) {
- uLongf dest_len = (uLongf)target_size - 12;
- DWORD crc = crc32(0L, NULL, 0);
-
- // set up header (stolen from zlib/gzio.c)
- sprintf((char *)target, "%c%c%c%c%c%c%c%c", 0x1f, 0x8b,
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/);
- int zerr = compress2(target + 8, &dest_len, source, source_size, Z_BEST_COMPRESSION);
- switch(zerr) {
- case Z_MEM_ERROR: // not enough memory
- case Z_BUF_ERROR: // not enough room in the output buffer
- FreeImage_OutputMessageProc(FIF_UNKNOWN, "Zlib error : %s", zError(zerr));
- return 0;
- case Z_OK: {
- // patch header, setup crc and length (stolen from mod_trace_output)
- BYTE *p = target + 8; *p++ = 2; *p = OS_CODE; // xflags, os_code
- crc = crc32(crc, source, source_size);
- memcpy(target + 4 + dest_len, &crc, 4);
- memcpy(target + 8 + dest_len, &source_size, 4);
- return dest_len + 12;
- }
- }
- return 0;
-}
-
-/**
-Decompresses a gzipped source buffer into a target buffer, using the ZLib library.
-Upon entry, target_size is the total size of the destination buffer,
-which must be large enough to hold the entire uncompressed data.
-The size of the uncompressed data must have been saved previously by the compressor
-and transmitted to the decompressor by some mechanism outside the scope of this
-compression library.
-
-@param target Destination buffer
-@param target_size Size of the destination buffer, in bytes
-@param source Source buffer
-@param source_size Size of the source buffer, in bytes
-@return Returns the actual size of the uncompressed buffer, returns 0 if an error occured
-@see FreeImage_ZLibGZip
-*/
-
-static int get_byte(z_stream *stream) {
- if (stream->avail_in <= 0) return EOF;
- stream->avail_in--;
- return *(stream->next_in)++;
-}
-
-static int checkheader(z_stream *stream) {
- int flags, c;
- DWORD len;
-
- if (get_byte(stream) != 0x1f || get_byte(stream) != 0x8b)
- return Z_DATA_ERROR;
- if (get_byte(stream) != Z_DEFLATED || ((flags = get_byte(stream)) & 0xE0) != 0)
- return Z_DATA_ERROR;
- for (len = 0; len < 6; len++) (void)get_byte(stream);
-
- if ((flags & 0x04) != 0) { /* skip the extra field */
- len = (DWORD)get_byte(stream);
- len += ((DWORD)get_byte(stream)) << 8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(stream) != EOF) ;
- }
- if ((flags & 0x08) != 0) { /* skip the original file name */
- while ((c = get_byte(stream)) != 0 && c != EOF) ;
- }
- if ((flags & 0x10) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(stream)) != 0 && c != EOF) ;
- }
- if ((flags & 0x02) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(stream);
- }
- return Z_OK;
-}
-
-DWORD DLL_CALLCONV
-FreeImage_ZLibGUnzip(BYTE *target, DWORD target_size, BYTE *source, DWORD source_size) {
- DWORD src_len = source_size;
- DWORD dest_len = target_size;
- int zerr = Z_DATA_ERROR;
-
- if (src_len > 0) {
- z_stream stream;
- memset(&stream, 0, sizeof (stream));
- if ((zerr = inflateInit2(&stream, -MAX_WBITS)) == Z_OK) {
- stream.next_in = source;
- stream.avail_in = source_size;
-
- stream.next_out = target;
- stream.avail_out = target_size;
-
- if ((zerr = checkheader(&stream)) == Z_OK) {
- zerr = inflate (&stream, Z_NO_FLUSH);
- dest_len = target_size - stream.avail_out;
-
- if (zerr == Z_OK || zerr == Z_STREAM_END)
- inflateEnd(&stream);
- }
- }
- }
- if (zerr != Z_OK && zerr != Z_STREAM_END) {
- FreeImage_OutputMessageProc(FIF_UNKNOWN, "Zlib error : %s", zError(zerr));
- return 0;
- }
- return dest_len;
-}
-
-/**
-Update a running crc from source and return the updated crc, using the ZLib library.
-If source is NULL, this function returns the required initial value for the crc.
-
-@param crc Running crc value
-@param source Source buffer
-@param source_size Size of the source buffer, in bytes
-@return Returns the new crc value
-*/
-DWORD DLL_CALLCONV
-FreeImage_ZLibCRC32(DWORD crc, BYTE *source, DWORD source_size) {
-
- return crc32(crc, source, source_size);
-}
diff --git a/plugins/AdvaImg/src/FreeImage/tmoColorConvert.cpp b/plugins/AdvaImg/src/FreeImage/tmoColorConvert.cpp
deleted file mode 100644
index 8770c6f4bf..0000000000
--- a/plugins/AdvaImg/src/FreeImage/tmoColorConvert.cpp
+++ /dev/null
@@ -1,479 +0,0 @@
-// ==========================================================
-// High Dynamic Range bitmap conversion routines
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-// - 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "ToneMapping.h"
-
-// ----------------------------------------------------------
-// Convert RGB to and from Yxy, same as in Reinhard et al. SIGGRAPH 2002
-// References :
-// [1] Radiance Home Page [Online] http://radsite.lbl.gov/radiance/HOME.html
-// [2] E. Reinhard, M. Stark, P. Shirley, and J. Ferwerda,
-// Photographic Tone Reproduction for Digital Images, ACM Transactions on Graphics,
-// 21(3):267-276, 2002 (Proceedings of SIGGRAPH 2002).
-// [3] J. Tumblin and H.E. Rushmeier,
-// Tone Reproduction for Realistic Images. IEEE Computer Graphics and Applications,
-// 13(6):42-48, 1993.
-// ----------------------------------------------------------
-
-/**
-nominal CRT primaries
-*/
-/*
-static const float CIE_x_r = 0.640F;
-static const float CIE_y_r = 0.330F;
-static const float CIE_x_g = 0.290F;
-static const float CIE_y_g = 0.600F;
-static const float CIE_x_b = 0.150F;
-static const float CIE_y_b = 0.060F;
-static const float CIE_x_w = 0.3333F; // use true white
-static const float CIE_y_w = 0.3333F;
-*/
-/**
-sRGB primaries
-*/
-static const float CIE_x_r = 0.640F;
-static const float CIE_y_r = 0.330F;
-static const float CIE_x_g = 0.300F;
-static const float CIE_y_g = 0.600F;
-static const float CIE_x_b = 0.150F;
-static const float CIE_y_b = 0.060F;
-static const float CIE_x_w = 0.3127F; // Illuminant D65
-static const float CIE_y_w = 0.3290F;
-
-static const float CIE_D = ( CIE_x_r*(CIE_y_g - CIE_y_b) + CIE_x_g*(CIE_y_b - CIE_y_r) + CIE_x_b*(CIE_y_r - CIE_y_g) );
-static const float CIE_C_rD = ( (1/CIE_y_w) * ( CIE_x_w*(CIE_y_g - CIE_y_b) - CIE_y_w*(CIE_x_g - CIE_x_b) + CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g) );
-static const float CIE_C_gD = ( (1/CIE_y_w) * ( CIE_x_w*(CIE_y_b - CIE_y_r) - CIE_y_w*(CIE_x_b - CIE_x_r) - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r) );
-static const float CIE_C_bD = ( (1/CIE_y_w) * ( CIE_x_w*(CIE_y_r - CIE_y_g) - CIE_y_w*(CIE_x_r - CIE_x_g) + CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r) );
-
-/**
-RGB to XYZ (no white balance)
-*/
-static const float RGB2XYZ[3][3] = {
- { CIE_x_r*CIE_C_rD / CIE_D,
- CIE_x_g*CIE_C_gD / CIE_D,
- CIE_x_b*CIE_C_bD / CIE_D
- },
- { CIE_y_r*CIE_C_rD / CIE_D,
- CIE_y_g*CIE_C_gD / CIE_D,
- CIE_y_b*CIE_C_bD / CIE_D
- },
- { (1 - CIE_x_r-CIE_y_r)*CIE_C_rD / CIE_D,
- (1 - CIE_x_g-CIE_y_g)*CIE_C_gD / CIE_D,
- (1 - CIE_x_b-CIE_y_b)*CIE_C_bD / CIE_D
- }
-};
-
-/**
-XYZ to RGB (no white balance)
-*/
-static const float XYZ2RGB[3][3] = {
- {(CIE_y_g - CIE_y_b - CIE_x_b*CIE_y_g + CIE_y_b*CIE_x_g) / CIE_C_rD,
- (CIE_x_b - CIE_x_g - CIE_x_b*CIE_y_g + CIE_x_g*CIE_y_b) / CIE_C_rD,
- (CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g) / CIE_C_rD
- },
- {(CIE_y_b - CIE_y_r - CIE_y_b*CIE_x_r + CIE_y_r*CIE_x_b) / CIE_C_gD,
- (CIE_x_r - CIE_x_b - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r) / CIE_C_gD,
- (CIE_x_b*CIE_y_r - CIE_x_r*CIE_y_b) / CIE_C_gD
- },
- {(CIE_y_r - CIE_y_g - CIE_y_r*CIE_x_g + CIE_y_g*CIE_x_r) / CIE_C_bD,
- (CIE_x_g - CIE_x_r - CIE_x_g*CIE_y_r + CIE_x_r*CIE_y_g) / CIE_C_bD,
- (CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r) / CIE_C_bD
- }
-};
-
-/**
-This gives approximately the following matrices :
-
-static const float RGB2XYZ[3][3] = {
- { 0.41239083F, 0.35758433F, 0.18048081F },
- { 0.21263903F, 0.71516865F, 0.072192319F },
- { 0.019330820F, 0.11919473F, 0.95053220F }
-};
-static const float XYZ2RGB[3][3] = {
- { 3.2409699F, -1.5373832F, -0.49861079F },
- { -0.96924376F, 1.8759676F, 0.041555084F },
- { 0.055630036F, -0.20397687F, 1.0569715F }
-};
-*/
-
-// ----------------------------------------------------------
-
-static const float EPSILON = 1e-06F;
-static const float INF = 1e+10F;
-
-/**
-Convert in-place floating point RGB data to Yxy.<br>
-On output, pixel->red == Y, pixel->green == x, pixel->blue == y
-@param dib Input RGBF / Output Yxy image
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-BOOL
-ConvertInPlaceRGBFToYxy(FIBITMAP *dib) {
- float result[3];
-
- if(FreeImage_GetImageType(dib) != FIT_RGBF)
- return FALSE;
-
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
- const unsigned pitch = FreeImage_GetPitch(dib);
-
- BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
- for(unsigned y = 0; y < height; y++) {
- FIRGBF *pixel = (FIRGBF*)bits;
- for(unsigned x = 0; x < width; x++) {
- result[0] = result[1] = result[2] = 0;
- for (int i = 0; i < 3; i++) {
- result[i] += RGB2XYZ[i][0] * pixel[x].red;
- result[i] += RGB2XYZ[i][1] * pixel[x].green;
- result[i] += RGB2XYZ[i][2] * pixel[x].blue;
- }
- const float W = result[0] + result[1] + result[2];
- const float Y = result[1];
- if(W > 0) {
- pixel[x].red = Y; // Y
- pixel[x].green = result[0] / W; // x
- pixel[x].blue = result[1] / W; // y
- } else {
- pixel[x].red = pixel[x].green = pixel[x].blue = 0;
- }
- }
- // next line
- bits += pitch;
- }
-
- return TRUE;
-}
-
-/**
-Convert in-place Yxy image to floating point RGB data.<br>
-On input, pixel->red == Y, pixel->green == x, pixel->blue == y
-@param dib Input Yxy / Output RGBF image
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-BOOL
-ConvertInPlaceYxyToRGBF(FIBITMAP *dib) {
- float result[3];
- float X, Y, Z;
-
- if(FreeImage_GetImageType(dib) != FIT_RGBF)
- return FALSE;
-
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
- const unsigned pitch = FreeImage_GetPitch(dib);
-
- BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
- for(unsigned y = 0; y < height; y++) {
- FIRGBF *pixel = (FIRGBF*)bits;
- for(unsigned x = 0; x < width; x++) {
- Y = pixel[x].red; // Y
- result[1] = pixel[x].green; // x
- result[2] = pixel[x].blue; // y
- if ((Y > EPSILON) && (result[1] > EPSILON) && (result[2] > EPSILON)) {
- X = (result[1] * Y) / result[2];
- Z = (X / result[1]) - X - Y;
- } else {
- X = Z = EPSILON;
- }
- pixel[x].red = X;
- pixel[x].green = Y;
- pixel[x].blue = Z;
- result[0] = result[1] = result[2] = 0;
- for (int i = 0; i < 3; i++) {
- result[i] += XYZ2RGB[i][0] * pixel[x].red;
- result[i] += XYZ2RGB[i][1] * pixel[x].green;
- result[i] += XYZ2RGB[i][2] * pixel[x].blue;
- }
- pixel[x].red = result[0]; // R
- pixel[x].green = result[1]; // G
- pixel[x].blue = result[2]; // B
- }
- // next line
- bits += pitch;
- }
-
- return TRUE;
-}
-
-/**
-Get the maximum, minimum and average luminance.<br>
-On input, pixel->red == Y, pixel->green == x, pixel->blue == y
-@param Yxy Source Yxy image to analyze
-@param maxLum Maximum luminance
-@param minLum Minimum luminance
-@param worldLum Average luminance (world adaptation luminance)
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-BOOL
-LuminanceFromYxy(FIBITMAP *Yxy, float *maxLum, float *minLum, float *worldLum) {
- if(FreeImage_GetImageType(Yxy) != FIT_RGBF)
- return FALSE;
-
- const unsigned width = FreeImage_GetWidth(Yxy);
- const unsigned height = FreeImage_GetHeight(Yxy);
- const unsigned pitch = FreeImage_GetPitch(Yxy);
-
- float max_lum = 0, min_lum = 0;
- double sum = 0;
-
- BYTE *bits = (BYTE*)FreeImage_GetBits(Yxy);
- for(unsigned y = 0; y < height; y++) {
- const FIRGBF *pixel = (FIRGBF*)bits;
- for(unsigned x = 0; x < width; x++) {
- const float Y = MAX(0.0F, pixel[x].red);// avoid negative values
- max_lum = (max_lum < Y) ? Y : max_lum; // max Luminance in the scene
- min_lum = (min_lum < Y) ? min_lum : Y; // min Luminance in the scene
- sum += log(2.3e-5F + Y); // contrast constant in Tumblin paper
- }
- // next line
- bits += pitch;
- }
- // maximum luminance
- *maxLum = max_lum;
- // minimum luminance
- *minLum = min_lum;
- // average log luminance
- double avgLogLum = (sum / (width * height));
- // world adaptation luminance
- *worldLum = (float)exp(avgLogLum);
-
- return TRUE;
-}
-
-/**
-Clamp RGBF image highest values to display white,
-then convert to 24-bit RGB
-*/
-FIBITMAP*
-ClampConvertRGBFTo24(FIBITMAP *src) {
- if(FreeImage_GetImageType(src) != FIT_RGBF)
- return FALSE;
-
- const unsigned width = FreeImage_GetWidth(src);
- const unsigned height = FreeImage_GetHeight(src);
-
- FIBITMAP *dst = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
- if(!dst) return NULL;
-
- const unsigned src_pitch = FreeImage_GetPitch(src);
- const unsigned dst_pitch = FreeImage_GetPitch(dst);
-
- BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const FIRGBF *src_pixel = (FIRGBF*)src_bits;
- BYTE *dst_pixel = (BYTE*)dst_bits;
- for(unsigned x = 0; x < width; x++) {
- const float red = (src_pixel[x].red > 1) ? 1 : src_pixel[x].red;
- const float green = (src_pixel[x].green > 1) ? 1 : src_pixel[x].green;
- const float blue = (src_pixel[x].blue > 1) ? 1 : src_pixel[x].blue;
-
- dst_pixel[FI_RGBA_RED] = (BYTE)(255.0F * red + 0.5F);
- dst_pixel[FI_RGBA_GREEN] = (BYTE)(255.0F * green + 0.5F);
- dst_pixel[FI_RGBA_BLUE] = (BYTE)(255.0F * blue + 0.5F);
- dst_pixel += 3;
- }
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
-
- return dst;
-}
-
-/**
-Extract the luminance channel L from a RGBF image.
-Luminance is calculated from the sRGB model (RGB2XYZ matrix)
-using a D65 white point :
-L = ( 0.2126 * r ) + ( 0.7152 * g ) + ( 0.0722 * b )
-Reference :
-A Standard Default Color Space for the Internet - sRGB.
-[online] http://www.w3.org/Graphics/Color/sRGB
-*/
-FIBITMAP*
-ConvertRGBFToY(FIBITMAP *src) {
- if(FreeImage_GetImageType(src) != FIT_RGBF)
- return FALSE;
-
- const unsigned width = FreeImage_GetWidth(src);
- const unsigned height = FreeImage_GetHeight(src);
-
- FIBITMAP *dst = FreeImage_AllocateT(FIT_FLOAT, width, height);
- if(!dst) return NULL;
-
- const unsigned src_pitch = FreeImage_GetPitch(src);
- const unsigned dst_pitch = FreeImage_GetPitch(dst);
-
-
- BYTE *src_bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *dst_bits = (BYTE*)FreeImage_GetBits(dst);
-
- for(unsigned y = 0; y < height; y++) {
- const FIRGBF *src_pixel = (FIRGBF*)src_bits;
- float *dst_pixel = (float*)dst_bits;
- for(unsigned x = 0; x < width; x++) {
- const float L = LUMA_REC709(src_pixel[x].red, src_pixel[x].green, src_pixel[x].blue);
- dst_pixel[x] = (L > 0) ? L : 0;
- }
- // next line
- src_bits += src_pitch;
- dst_bits += dst_pitch;
- }
-
- return dst;
-}
-
-/**
-Get the maximum, minimum, average luminance and log average luminance from a Y image
-@param dib Source Y image to analyze
-@param maxLum Maximum luminance
-@param minLum Minimum luminance
-@param Lav Average luminance
-@param Llav Log average luminance (also known as 'world adaptation luminance')
-@return Returns TRUE if successful, returns FALSE otherwise
-@see ConvertRGBFToY, FreeImage_TmoReinhard05Ex
-*/
-BOOL
-LuminanceFromY(FIBITMAP *dib, float *maxLum, float *minLum, float *Lav, float *Llav) {
- if(FreeImage_GetImageType(dib) != FIT_FLOAT)
- return FALSE;
-
- unsigned width = FreeImage_GetWidth(dib);
- unsigned height = FreeImage_GetHeight(dib);
- unsigned pitch = FreeImage_GetPitch(dib);
-
- float max_lum = -1e20F, min_lum = 1e20F;
- double sumLum = 0, sumLogLum = 0;
-
- BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
- for(unsigned y = 0; y < height; y++) {
- const float *pixel = (float*)bits;
- for(unsigned x = 0; x < width; x++) {
- const float Y = pixel[x];
- max_lum = (max_lum < Y) ? Y : max_lum; // max Luminance in the scene
- min_lum = ((Y > 0) && (min_lum < Y)) ? min_lum : Y; // min Luminance in the scene
- sumLum += Y; // average luminance
- sumLogLum += log(2.3e-5F + Y); // contrast constant in Tumblin paper
- }
- // next line
- bits += pitch;
- }
-
- // maximum luminance
- *maxLum = max_lum;
- // minimum luminance
- *minLum = min_lum;
- // average luminance
- *Lav = (float)(sumLum / (width * height));
- // average log luminance, a.k.a. world adaptation luminance
- *Llav = (float)exp(sumLogLum / (width * height));
-
- return TRUE;
-}
-// --------------------------------------------------------------------------
-
-static void findMaxMinPercentile(FIBITMAP *Y, float minPrct, float *minLum, float maxPrct, float *maxLum) {
- int x, y;
- int width = FreeImage_GetWidth(Y);
- int height = FreeImage_GetHeight(Y);
- int pitch = FreeImage_GetPitch(Y);
-
- std::vector<float> vY(width * height);
-
- BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
- for(y = 0; y < height; y++) {
- float *pixel = (float*)bits;
- for(x = 0; x < width; x++) {
- if(pixel[x] != 0) {
- vY.push_back(pixel[x]);
- }
- }
- bits += pitch;
- }
-
- std::sort(vY.begin(), vY.end());
-
- *minLum = vY.at( int(minPrct * vY.size()) );
- *maxLum = vY.at( int(maxPrct * vY.size()) );
-}
-
-/**
-Clipping function<br>
-Remove any extremely bright and/or extremely dark pixels
-and normalize between 0 and 1.
-@param Y Input/Output image
-@param minPrct Minimum percentile
-@param maxPrct Maximum percentile
-*/
-void
-NormalizeY(FIBITMAP *Y, float minPrct, float maxPrct) {
- int x, y;
- float maxLum, minLum;
-
- if(minPrct > maxPrct) {
- // swap values
- float t = minPrct; minPrct = maxPrct; maxPrct = t;
- }
- if(minPrct < 0) minPrct = 0;
- if(maxPrct > 1) maxPrct = 1;
-
- int width = FreeImage_GetWidth(Y);
- int height = FreeImage_GetHeight(Y);
- int pitch = FreeImage_GetPitch(Y);
-
- // find max & min luminance values
- if((minPrct > 0) || (maxPrct < 1)) {
- maxLum = 0, minLum = 0;
- findMaxMinPercentile(Y, minPrct, &minLum, maxPrct, &maxLum);
- } else {
- maxLum = -1e20F, minLum = 1e20F;
- BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
- for(y = 0; y < height; y++) {
- const float *pixel = (float*)bits;
- for(x = 0; x < width; x++) {
- const float value = pixel[x];
- maxLum = (maxLum < value) ? value : maxLum; // max Luminance in the scene
- minLum = (minLum < value) ? minLum : value; // min Luminance in the scene
- }
- // next line
- bits += pitch;
- }
- }
- if(maxLum == minLum) return;
-
- // normalize to range 0..1
- const float divider = maxLum - minLum;
- BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
- for(y = 0; y < height; y++) {
- float *pixel = (float*)bits;
- for(x = 0; x < width; x++) {
- pixel[x] = (pixel[x] - minLum) / divider;
- if(pixel[x] <= 0) pixel[x] = EPSILON;
- if(pixel[x] > 1) pixel[x] = 1;
- }
- // next line
- bits += pitch;
- }
-}
diff --git a/plugins/AdvaImg/src/FreeImage/tmoDrago03.cpp b/plugins/AdvaImg/src/FreeImage/tmoDrago03.cpp
deleted file mode 100644
index d1efe9486b..0000000000
--- a/plugins/AdvaImg/src/FreeImage/tmoDrago03.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-// ==========================================================
-// Tone mapping operator (Drago, 2003)
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "ToneMapping.h"
-
-// ----------------------------------------------------------
-// Logarithmic mapping operator
-// Reference:
-// [1] F. Drago, K. Myszkowski, T. Annen, and N. Chiba,
-// Adaptive Logarithmic Mapping for Displaying High Contrast Scenes,
-// Eurographics 2003.
-// ----------------------------------------------------------
-
-/**
-Bias function
-*/
-static inline double
-biasFunction(const double b, const double x) {
- return pow (x, b); // pow(x, log(bias)/log(0.5)
-}
-
-/**
-Padé approximation of log(x + 1)
-x(6+x)/(6+4x) good if x < 1
-x*(6 + 0.7662x)/(5.9897 + 3.7658x) between 1 and 2
-See http://www.nezumi.demon.co.uk/consult/logx.htm
-*/
-static inline double
-pade_log(const double x) {
- if(x < 1) {
- return (x * (6 + x) / (6 + 4 * x));
- } else if(x < 2) {
- return (x * (6 + 0.7662 * x) / (5.9897 + 3.7658 * x));
- }
- return log(x + 1);
-}
-
-/**
-Log mapping operator
-@param dib Input / Output Yxy image
-@param maxLum Maximum luminance
-@param avgLum Average luminance (world adaptation luminance)
-@param biasParam Bias parameter (a zero value default to 0.85)
-@param exposure Exposure parameter (default to 0)
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-ToneMappingDrago03(FIBITMAP *dib, const float maxLum, const float avgLum, float biasParam, const float exposure) {
- const float LOG05 = -0.693147F; // log(0.5)
-
- double Lmax, divider, interpol, biasP;
- unsigned x, y;
- double L;
-
- if(FreeImage_GetImageType(dib) != FIT_RGBF)
- return FALSE;
-
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
- const unsigned pitch = FreeImage_GetPitch(dib);
-
-
- // arbitrary Bias Parameter
- if(biasParam == 0)
- biasParam = 0.85F;
-
- // normalize maximum luminance by average luminance
- Lmax = maxLum / avgLum;
-
- divider = log10(Lmax+1);
- biasP = log(biasParam)/LOG05;
-
-#if !defined(DRAGO03_FAST)
-
- /**
- Normal tone mapping of every pixel
- further acceleration is obtained by a Padé approximation of log(x + 1)
- */
- BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
- for(y = 0; y < height; y++) {
- FIRGBF *pixel = (FIRGBF*)bits;
- for(x = 0; x < width; x++) {
- double Yw = pixel[x].red / avgLum;
- Yw *= exposure;
- interpol = log(2 + biasFunction(biasP, Yw / Lmax) * 8);
- L = pade_log(Yw);// log(Yw + 1)
- pixel[x].red = (float)((L / interpol) / divider);
- }
- // next line
- bits += pitch;
- }
-
-#else
- unsigned index;
- int i, j;
-
- unsigned max_width = width - (width % 3);
- unsigned max_height = height - (height % 3);
- unsigned fpitch = pitch / sizeof(FIRGBF);
-
- /**
- fast tone mapping
- split the image into 3x3 pixel tiles and perform the computation for each group of 9 pixels
- further acceleration is obtained by a Padé approximation of log(x + 1)
- => produce artifacts and not so faster, so the code has been disabled
- */
-#define PIXEL(x, y) image[y*fpitch + x].red
-
- FIRGBF *image = (FIRGBF*)FreeImage_GetBits(dib);
- for(y = 0; y < max_height; y += 3) {
- for(x = 0; x < max_width; x += 3) {
- double average = 0;
- for(i = 0; i < 3; i++) {
- for(j = 0; j < 3; j++) {
- index = (y + i)*fpitch + (x + j);
- image[index].red /= (float)avgLum;
- image[index].red *= exposure;
- average += image[index].red;
- }
- }
- average = average / 9 - PIXEL(x, y);
- if(average > -1 && average < 1) {
- interpol = log(2 + pow(PIXEL(x + 1, y + 1) / Lmax, biasP) * 8);
- for(i = 0; i < 3; i++) {
- for(j = 0; j < 3; j++) {
- index = (y + i)*fpitch + (x + j);
- L = pade_log(image[index].red);// log(image[index].red + 1)
- image[index].red = (float)((L / interpol) / divider);
- }
- }
- }
- else {
- for(i = 0; i < 3; i++) {
- for(j = 0; j < 3; j++) {
- index = (y + i)*fpitch + (x + j);
- interpol = log(2 + pow(image[index].red / Lmax, biasP) * 8);
- L = pade_log(image[index].red);// log(image[index].red + 1)
- image[index].red = (float)((L / interpol) / divider);
- }
- }
- }
- } //x
- } // y
-
- /**
- Normal tone mapping of every pixel for the remaining right and bottom bands
- */
- BYTE *bits;
-
- // right band
- bits = (BYTE*)FreeImage_GetBits(dib);
- for(y = 0; y < height; y++) {
- FIRGBF *pixel = (FIRGBF*)bits;
- for(x = max_width; x < width; x++) {
- double Yw = pixel[x].red / avgLum;
- Yw *= exposure;
- interpol = log(2 + biasFunction(biasP, Yw / Lmax) * 8);
- L = pade_log(Yw);// log(Yw + 1)
- pixel[x].red = (float)((L / interpol) / divider);
- }
- // next line
- bits += pitch;
- }
- // bottom band
- bits = (BYTE*)FreeImage_GetBits(dib);
- for(y = max_height; y < height; y++) {
- FIRGBF *pixel = (FIRGBF*)bits;
- for(x = 0; x < max_width; x++) {
- double Yw = pixel[x].red / avgLum;
- Yw *= exposure;
- interpol = log(2 + biasFunction(biasP, Yw / Lmax) * 8);
- L = pade_log(Yw);// log(Yw + 1)
- pixel[x].red = (float)((L / interpol) / divider);
- }
- // next line
- bits += pitch;
- }
-
-#endif // DRAGO03_FAST
-
- return TRUE;
-}
-
-/**
-Custom gamma correction based on the ITU-R BT.709 standard
-@param dib RGBF image to be corrected
-@param gammaval Gamma value (2.2 is a good default value)
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL
-REC709GammaCorrection(FIBITMAP *dib, const float gammaval) {
- if(FreeImage_GetImageType(dib) != FIT_RGBF)
- return FALSE;
-
- float slope = 4.5F;
- float start = 0.018F;
-
- const float fgamma = (float)((0.45 / gammaval) * 2);
- if(gammaval >= 2.1F) {
- start = (float)(0.018 / ((gammaval - 2) * 7.5));
- slope = (float)(4.5 * ((gammaval - 2) * 7.5));
- } else if (gammaval <= 1.9F) {
- start = (float)(0.018 * ((2 - gammaval) * 7.5));
- slope = (float)(4.5 / ((2 - gammaval) * 7.5));
- }
-
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
- const unsigned pitch = FreeImage_GetPitch(dib);
-
- BYTE *bits = (BYTE*)FreeImage_GetBits(dib);
- for(unsigned y = 0; y < height; y++) {
- float *pixel = (float*)bits;
- for(unsigned x = 0; x < width; x++) {
- for(int i = 0; i < 3; i++) {
- *pixel = (*pixel <= start) ? *pixel * slope : (1.099F * pow(*pixel, fgamma) - 0.099F);
- pixel++;
- }
- }
- bits += pitch;
- }
-
- return TRUE;
-}
-
-// ----------------------------------------------------------
-// Main algorithm
-// ----------------------------------------------------------
-
-/**
-Apply the Adaptive Logarithmic Mapping operator to a HDR image and convert to 24-bit RGB
-@param src Input RGB16 or RGB[A]F image
-@param gamma Gamma correction (gamma > 0). 1 means no correction, 2.2 in the original paper.
-@param exposure Exposure parameter (0 means no correction, 0 in the original paper)
-@return Returns a 24-bit RGB image if successful, returns NULL otherwise
-*/
-FIBITMAP* DLL_CALLCONV
-FreeImage_TmoDrago03(FIBITMAP *src, double gamma, double exposure) {
- float maxLum, minLum, avgLum;
-
- if(!FreeImage_HasPixels(src)) return NULL;
-
- // working RGBF variable
- FIBITMAP *dib = NULL;
-
- dib = FreeImage_ConvertToRGBF(src);
- if(!dib) return NULL;
-
- // default algorithm parameters
- const float biasParam = 0.85F;
- const float expoParam = (float)pow(2.0, exposure); //default exposure is 1, 2^0
-
- // convert to Yxy
- ConvertInPlaceRGBFToYxy(dib);
- // get the luminance
- LuminanceFromYxy(dib, &maxLum, &minLum, &avgLum);
- // perform the tone mapping
- ToneMappingDrago03(dib, maxLum, avgLum, biasParam, expoParam);
- // convert back to RGBF
- ConvertInPlaceYxyToRGBF(dib);
- if(gamma != 1) {
- // perform gamma correction
- REC709GammaCorrection(dib, (float)gamma);
- }
- // clamp image highest values to display white, then convert to 24-bit RGB
- FIBITMAP *dst = ClampConvertRGBFTo24(dib);
-
- // clean-up and return
- FreeImage_Unload(dib);
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- return dst;
-}
diff --git a/plugins/AdvaImg/src/FreeImage/tmoFattal02.cpp b/plugins/AdvaImg/src/FreeImage/tmoFattal02.cpp
deleted file mode 100644
index 27448fce8a..0000000000
--- a/plugins/AdvaImg/src/FreeImage/tmoFattal02.cpp
+++ /dev/null
@@ -1,689 +0,0 @@
-// ==========================================================
-// Tone mapping operator (Fattal, 2002)
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-//
-// 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "ToneMapping.h"
-
-// ----------------------------------------------------------
-// Gradient domain HDR compression
-// Reference:
-// [1] R. Fattal, D. Lischinski, and M.Werman,
-// Gradient domain high dynamic range compression,
-// ACM Transactions on Graphics, special issue on Proc. of ACM SIGGRAPH 2002,
-// San Antonio, Texas, vol. 21(3), pp. 257-266, 2002.
-// ----------------------------------------------------------
-
-static const float EPSILON = 1e-4F;
-
-/**
-Performs a 5 by 5 gaussian filtering using two 1D convolutions,
-followed by a subsampling by 2.
-@param dib Input image
-@return Returns a blurred image of size SIZE(dib)/2
-@see GaussianPyramid
-*/
-static FIBITMAP* GaussianLevel5x5(FIBITMAP *dib) {
- FIBITMAP *h_dib = NULL, *v_dib = NULL, *dst = NULL;
- float *src_pixel, *dst_pixel;
-
- try {
- const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
- if(image_type != FIT_FLOAT) throw(1);
-
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
-
- h_dib = FreeImage_AllocateT(image_type, width, height);
- v_dib = FreeImage_AllocateT(image_type, width, height);
- if(!h_dib || !v_dib) throw(1);
-
- const unsigned pitch = FreeImage_GetPitch(dib) / sizeof(float);
-
- // horizontal convolution dib -> h_dib
-
- src_pixel = (float*)FreeImage_GetBits(dib);
- dst_pixel = (float*)FreeImage_GetBits(h_dib);
-
- for(unsigned y = 0; y < height; y++) {
- // work on line y
- for(unsigned x = 2; x < width - 2; x++) {
- dst_pixel[x] = src_pixel[x-2] + src_pixel[x+2] + 4 * (src_pixel[x-1] + src_pixel[x+1]) + 6 * src_pixel[x];
- dst_pixel[x] /= 16;
- }
- // boundary mirroring
- dst_pixel[0] = (2 * src_pixel[2] + 8 * src_pixel[1] + 6 * src_pixel[0]) / 16;
- dst_pixel[1] = (src_pixel[3] + 4 * (src_pixel[0] + src_pixel[2]) + 7 * src_pixel[1]) / 16;
- dst_pixel[width-2] = (src_pixel[width-4] + 5 * src_pixel[width-1] + 4 * src_pixel[width-3] + 6 * src_pixel[width-2]) / 16;
- dst_pixel[width-1] = (src_pixel[width-3] + 5 * src_pixel[width-2] + 10 * src_pixel[width-1]) / 16;
-
- // next line
- src_pixel += pitch;
- dst_pixel += pitch;
- }
-
- // vertical convolution h_dib -> v_dib
-
- src_pixel = (float*)FreeImage_GetBits(h_dib);
- dst_pixel = (float*)FreeImage_GetBits(v_dib);
-
- for(unsigned x = 0; x < width; x++) {
- // work on column x
- for(unsigned y = 2; y < height - 2; y++) {
- const unsigned index = y*pitch + x;
- dst_pixel[index] = src_pixel[index-2*pitch] + src_pixel[index+2*pitch] + 4 * (src_pixel[index-pitch] + src_pixel[index+pitch]) + 6 * src_pixel[index];
- dst_pixel[index] /= 16;
- }
- // boundary mirroring
- dst_pixel[x] = (2 * src_pixel[x+2*pitch] + 8 * src_pixel[x+pitch] + 6 * src_pixel[x]) / 16;
- dst_pixel[x+pitch] = (src_pixel[x+3*pitch] + 4 * (src_pixel[x] + src_pixel[x+2*pitch]) + 7 * src_pixel[x+pitch]) / 16;
- dst_pixel[(height-2)*pitch+x] = (src_pixel[(height-4)*pitch+x] + 5 * src_pixel[(height-1)*pitch+x] + 4 * src_pixel[(height-3)*pitch+x] + 6 * src_pixel[(height-2)*pitch+x]) / 16;
- dst_pixel[(height-1)*pitch+x] = (src_pixel[(height-3)*pitch+x] + 5 * src_pixel[(height-2)*pitch+x] + 10 * src_pixel[(height-1)*pitch+x]) / 16;
- }
-
- FreeImage_Unload(h_dib); h_dib = NULL;
-
- // perform downsampling
-
- dst = FreeImage_Rescale(v_dib, width/2, height/2, FILTER_BILINEAR);
-
- FreeImage_Unload(v_dib);
-
- return dst;
-
- } catch(int) {
- if(h_dib) FreeImage_Unload(h_dib);
- if(v_dib) FreeImage_Unload(v_dib);
- if(dst) FreeImage_Unload(dst);
- return NULL;
- }
-}
-
-/**
-Compute a Gaussian pyramid using the specified number of levels.
-@param H Original bitmap
-@param pyramid Resulting pyramid array
-@param nlevels Number of resolution levels
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL GaussianPyramid(FIBITMAP *H, FIBITMAP **pyramid, int nlevels) {
- try {
- // first level is the original image
- pyramid[0] = FreeImage_Clone(H);
- if(pyramid[0] == NULL) throw(1);
- // compute next levels
- for(int k = 1; k < nlevels; k++) {
- pyramid[k] = GaussianLevel5x5(pyramid[k-1]);
- if(pyramid[k] == NULL) throw(1);
- }
- return TRUE;
- } catch(int) {
- for(int k = 0; k < nlevels; k++) {
- if(pyramid[k] != NULL) {
- FreeImage_Unload(pyramid[k]);
- pyramid[k] = NULL;
- }
- }
- return FALSE;
- }
-}
-
-/**
-Compute the gradient magnitude of an input image H using central differences,
-and returns the average gradient.
-@param H Input image
-@param avgGrad [out] Average gradient
-@param k Level number
-@return Returns the gradient magnitude if successful, returns NULL otherwise
-@see GradientPyramid
-*/
-static FIBITMAP* GradientLevel(FIBITMAP *H, float *avgGrad, int k) {
- FIBITMAP *G = NULL;
-
- try {
- const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(H);
- if(image_type != FIT_FLOAT) throw(1);
-
- const unsigned width = FreeImage_GetWidth(H);
- const unsigned height = FreeImage_GetHeight(H);
-
- G = FreeImage_AllocateT(image_type, width, height);
- if(!G) throw(1);
-
- const unsigned pitch = FreeImage_GetPitch(H) / sizeof(float);
-
- const float divider = (float)(1 << (k + 1));
- float average = 0;
-
- float *src_pixel = (float*)FreeImage_GetBits(H);
- float *dst_pixel = (float*)FreeImage_GetBits(G);
-
- for(unsigned y = 0; y < height; y++) {
- const unsigned n = (y == 0 ? 0 : y-1);
- const unsigned s = (y+1 == height ? y : y+1);
- for(unsigned x = 0; x < width; x++) {
- const unsigned w = (x == 0 ? 0 : x-1);
- const unsigned e = (x+1 == width ? x : x+1);
- // central difference
- const float gx = (src_pixel[y*pitch+e] - src_pixel[y*pitch+w]) / divider; // [Hk(x+1, y) - Hk(x-1, y)] / 2**(k+1)
- const float gy = (src_pixel[s*pitch+x] - src_pixel[n*pitch+x]) / divider; // [Hk(x, y+1) - Hk(x, y-1)] / 2**(k+1)
- // gradient
- dst_pixel[x] = sqrt(gx*gx + gy*gy);
- // average gradient
- average += dst_pixel[x];
- }
- // next line
- dst_pixel += pitch;
- }
-
- *avgGrad = average / (width * height);
-
- return G;
-
- } catch(int) {
- if(G) FreeImage_Unload(G);
- return NULL;
- }
-}
-
-/**
-Calculate gradient magnitude and its average value on each pyramid level
-@param pyramid Gaussian pyramid (nlevels levels)
-@param nlevels Number of levels
-@param gradients [out] Gradient pyramid (nlevels levels)
-@param avgGrad [out] Average gradient on each level (array of size nlevels)
-@return Returns TRUE if successful, returns FALSE otherwise
-*/
-static BOOL GradientPyramid(FIBITMAP **pyramid, int nlevels, FIBITMAP **gradients, float *avgGrad) {
- try {
- for(int k = 0; k < nlevels; k++) {
- FIBITMAP *Hk = pyramid[k];
- gradients[k] = GradientLevel(Hk, &avgGrad[k], k);
- if(gradients[k] == NULL) throw(1);
- }
- return TRUE;
- } catch(int) {
- for(int k = 0; k < nlevels; k++) {
- if(gradients[k] != NULL) {
- FreeImage_Unload(gradients[k]);
- gradients[k] = NULL;
- }
- }
- return FALSE;
- }
-}
-
-/**
-Compute the gradient attenuation function PHI(x, y)
-@param gradients Gradient pyramid (nlevels levels)
-@param avgGrad Average gradient on each level (array of size nlevels)
-@param nlevels Number of levels
-@param alpha Parameter alpha in the paper
-@param beta Parameter beta in the paper
-@return Returns the attenuation matrix Phi if successful, returns NULL otherwise
-*/
-static FIBITMAP* PhiMatrix(FIBITMAP **gradients, float *avgGrad, int nlevels, float alpha, float beta) {
- float *src_pixel, *dst_pixel;
- FIBITMAP **phi = NULL;
-
- try {
- phi = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
- if(!phi) throw(1);
- memset(phi, 0, nlevels * sizeof(FIBITMAP*));
-
- for(int k = nlevels-1; k >= 0; k--) {
- // compute phi(k)
-
- FIBITMAP *Gk = gradients[k];
-
- const unsigned width = FreeImage_GetWidth(Gk);
- const unsigned height = FreeImage_GetHeight(Gk);
- const unsigned pitch = FreeImage_GetPitch(Gk) / sizeof(float);
-
- // parameter alpha is 0.1 times the average gradient magnitude
- // also, note the factor of 2**k in the denominator;
- // that is there to correct for the fact that an average gradient avgGrad(H) over 2**k pixels
- // in the original image will appear as a gradient grad(Hk) = 2**k*avgGrad(H) over a single pixel in Hk.
- float ALPHA = alpha * avgGrad[k] * (float)((int)1 << k);
- if(ALPHA == 0) ALPHA = EPSILON;
-
- phi[k] = FreeImage_AllocateT(FIT_FLOAT, width, height);
- if(!phi[k]) throw(1);
-
- src_pixel = (float*)FreeImage_GetBits(Gk);
- dst_pixel = (float*)FreeImage_GetBits(phi[k]);
- for(unsigned y = 0; y < height; y++) {
- for(unsigned x = 0; x < width; x++) {
- // compute (alpha / grad) * (grad / alpha) ** beta
- const float v = src_pixel[x] / ALPHA;
- const float value = (float)pow((float)v, (float)(beta-1));
- dst_pixel[x] = (value > 1) ? 1 : value;
- }
- // next line
- src_pixel += pitch;
- dst_pixel += pitch;
- }
-
- if(k < nlevels-1) {
- // compute PHI(k) = L( PHI(k+1) ) * phi(k)
- FIBITMAP *L = FreeImage_Rescale(phi[k+1], width, height, FILTER_BILINEAR);
- if(!L) throw(1);
-
- src_pixel = (float*)FreeImage_GetBits(L);
- dst_pixel = (float*)FreeImage_GetBits(phi[k]);
- for(unsigned y = 0; y < height; y++) {
- for(unsigned x = 0; x < width; x++) {
- dst_pixel[x] *= src_pixel[x];
- }
- // next line
- src_pixel += pitch;
- dst_pixel += pitch;
- }
-
- FreeImage_Unload(L);
-
- // PHI(k+1) is no longer needed
- FreeImage_Unload(phi[k+1]);
- phi[k+1] = NULL;
- }
-
- // next level
- }
-
- // get the final result and return
- FIBITMAP *dst = phi[0];
-
- free(phi);
-
- return dst;
-
- } catch(int) {
- if(phi) {
- for(int k = nlevels-1; k >= 0; k--) {
- if(phi[k]) FreeImage_Unload(phi[k]);
- }
- free(phi);
- }
- return NULL;
- }
-}
-
-/**
-Compute gradients in x and y directions, attenuate them with the attenuation matrix,
-then compute the divergence div G from the attenuated gradient.
-@param H Normalized luminance
-@param PHI Attenuation matrix
-@return Returns the divergence matrix if successful, returns NULL otherwise
-*/
-static FIBITMAP* Divergence(FIBITMAP *H, FIBITMAP *PHI) {
- FIBITMAP *Gx = NULL, *Gy = NULL, *divG = NULL;
- float *phi, *h, *gx, *gy, *divg;
-
- try {
- const FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(H);
- if(image_type != FIT_FLOAT) throw(1);
-
- const unsigned width = FreeImage_GetWidth(H);
- const unsigned height = FreeImage_GetHeight(H);
-
- Gx = FreeImage_AllocateT(image_type, width, height);
- if(!Gx) throw(1);
- Gy = FreeImage_AllocateT(image_type, width, height);
- if(!Gy) throw(1);
-
- const unsigned pitch = FreeImage_GetPitch(H) / sizeof(float);
-
- // perform gradient attenuation
-
- phi = (float*)FreeImage_GetBits(PHI);
- h = (float*)FreeImage_GetBits(H);
- gx = (float*)FreeImage_GetBits(Gx);
- gy = (float*)FreeImage_GetBits(Gy);
-
- for(unsigned y = 0; y < height; y++) {
- const unsigned s = (y+1 == height ? y : y+1);
- for(unsigned x = 0; x < width; x++) {
- const unsigned e = (x+1 == width ? x : x+1);
- // forward difference
- const unsigned index = y*pitch + x;
- const float phi_xy = phi[index];
- const float h_xy = h[index];
- gx[x] = (h[y*pitch+e] - h_xy) * phi_xy; // [H(x+1, y) - H(x, y)] * PHI(x, y)
- gy[x] = (h[s*pitch+x] - h_xy) * phi_xy; // [H(x, y+1) - H(x, y)] * PHI(x, y)
- }
- // next line
- gx += pitch;
- gy += pitch;
- }
-
- // calculate the divergence
-
- divG = FreeImage_AllocateT(image_type, width, height);
- if(!divG) throw(1);
-
- gx = (float*)FreeImage_GetBits(Gx);
- gy = (float*)FreeImage_GetBits(Gy);
- divg = (float*)FreeImage_GetBits(divG);
-
- for(unsigned y = 0; y < height; y++) {
- for(unsigned x = 0; x < width; x++) {
- // backward difference approximation
- // divG = Gx(x, y) - Gx(x-1, y) + Gy(x, y) - Gy(x, y-1)
- const unsigned index = y*pitch + x;
- divg[index] = gx[index] + gy[index];
- if(x > 0) divg[index] -= gx[index-1];
- if(y > 0) divg[index] -= gy[index-pitch];
- }
- }
-
- // no longer needed ...
- FreeImage_Unload(Gx);
- FreeImage_Unload(Gy);
-
- // return the divergence
- return divG;
-
- } catch(int) {
- if(Gx) FreeImage_Unload(Gx);
- if(Gy) FreeImage_Unload(Gy);
- if(divG) FreeImage_Unload(divG);
- return NULL;
- }
-}
-
-/**
-Given the luminance channel, find max & min luminance values,
-normalize to range 0..100 and take the logarithm.
-@param Y Image luminance
-@return Returns the normalized luminance H if successful, returns NULL otherwise
-*/
-static FIBITMAP* LogLuminance(FIBITMAP *Y) {
- FIBITMAP *H = NULL;
-
- try {
- // get the luminance channel
- FIBITMAP *H = FreeImage_Clone(Y);
- if(!H) throw(1);
-
- const unsigned width = FreeImage_GetWidth(H);
- const unsigned height = FreeImage_GetHeight(H);
- const unsigned pitch = FreeImage_GetPitch(H);
-
- // find max & min luminance values
- float maxLum = -1e20F, minLum = 1e20F;
-
- BYTE *bits = (BYTE*)FreeImage_GetBits(H);
- for(unsigned y = 0; y < height; y++) {
- const float *pixel = (float*)bits;
- for(unsigned x = 0; x < width; x++) {
- const float value = pixel[x];
- maxLum = (maxLum < value) ? value : maxLum; // max Luminance in the scene
- minLum = (minLum < value) ? minLum : value; // min Luminance in the scene
- }
- // next line
- bits += pitch;
- }
- if(maxLum == minLum) throw(1);
-
- // normalize to range 0..100 and take the logarithm
- const float scale = 100.F / (maxLum - minLum);
- bits = (BYTE*)FreeImage_GetBits(H);
- for(unsigned y = 0; y < height; y++) {
- float *pixel = (float*)bits;
- for(unsigned x = 0; x < width; x++) {
- const float value = (pixel[x] - minLum) * scale;
- pixel[x] = log(value + EPSILON);
- }
- // next line
- bits += pitch;
- }
-
- return H;
-
- } catch(int) {
- if(H) FreeImage_Unload(H);
- return NULL;
- }
-}
-
-/**
-Given a normalized luminance, perform exponentiation and recover the log compressed image
-@param Y Input/Output luminance image
-*/
-static void ExpLuminance(FIBITMAP *Y) {
- const unsigned width = FreeImage_GetWidth(Y);
- const unsigned height = FreeImage_GetHeight(Y);
- const unsigned pitch = FreeImage_GetPitch(Y);
-
- BYTE *bits = (BYTE*)FreeImage_GetBits(Y);
- for(unsigned y = 0; y < height; y++) {
- float *pixel = (float*)bits;
- for(unsigned x = 0; x < width; x++) {
- pixel[x] = exp(pixel[x]) - EPSILON;
- }
- bits += pitch;
- }
-}
-
-// --------------------------------------------------------------------------
-
-/**
-Gradient Domain HDR tone mapping operator
-@param Y Image luminance values
-@param alpha Parameter alpha of the paper (suggested value is 0.1)
-@param beta Parameter beta of the paper (suggested value is between 0.8 and 0.9)
-@return returns the tone mapped luminance
-*/
-static FIBITMAP* tmoFattal02(FIBITMAP *Y, float alpha, float beta) {
- const unsigned MIN_PYRAMID_SIZE = 32; // minimun size (width or height) of the coarsest level of the pyramid
-
- FIBITMAP *H = NULL;
- FIBITMAP **pyramid = NULL;
- FIBITMAP **gradients = NULL;
- FIBITMAP *phy = NULL;
- FIBITMAP *divG = NULL;
- FIBITMAP *U = NULL;
- float *avgGrad = NULL;
-
- int k;
- int nlevels = 0;
-
- try {
- // get the normalized luminance
- FIBITMAP *H = LogLuminance(Y);
- if(!H) throw(1);
-
- // get the number of levels for the pyramid
- const unsigned width = FreeImage_GetWidth(H);
- const unsigned height = FreeImage_GetHeight(H);
- unsigned minsize = MIN(width, height);
- while(minsize >= MIN_PYRAMID_SIZE) {
- nlevels++;
- minsize /= 2;
- }
-
- // create the Gaussian pyramid
- pyramid = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
- if(!pyramid) throw(1);
- memset(pyramid, 0, nlevels * sizeof(FIBITMAP*));
-
- if(!GaussianPyramid(H, pyramid, nlevels)) throw(1);
-
- // calculate gradient magnitude and its average value on each pyramid level
- gradients = (FIBITMAP**)malloc(nlevels * sizeof(FIBITMAP*));
- if(!gradients) throw(1);
- memset(gradients, 0, nlevels * sizeof(FIBITMAP*));
- avgGrad = (float*)malloc(nlevels * sizeof(float));
- if(!avgGrad) throw(1);
-
- if(!GradientPyramid(pyramid, nlevels, gradients, avgGrad)) throw(1);
-
- // free the Gaussian pyramid
- for(k = 0; k < nlevels; k++) {
- if(pyramid[k]) FreeImage_Unload(pyramid[k]);
- }
- free(pyramid); pyramid = NULL;
-
- // compute the gradient attenuation function PHI(x, y)
- phy = PhiMatrix(gradients, avgGrad, nlevels, alpha, beta);
- if(!phy) throw(1);
-
- // free the gradient pyramid
- for(k = 0; k < nlevels; k++) {
- if(gradients[k]) FreeImage_Unload(gradients[k]);
- }
- free(gradients); gradients = NULL;
- free(avgGrad); avgGrad = NULL;
-
- // compute gradients in x and y directions, attenuate them with the attenuation matrix,
- // then compute the divergence div G from the attenuated gradient.
- divG = Divergence(H, phy);
- if(!divG) throw(1);
-
- // H & phy no longer needed
- FreeImage_Unload(H); H = NULL;
- FreeImage_Unload(phy); phy = NULL;
-
- // solve the PDE (Poisson equation) using a multigrid solver and 3 cycles
- FIBITMAP *U = FreeImage_MultigridPoissonSolver(divG, 3);
- if(!U) throw(1);
-
- FreeImage_Unload(divG);
-
- // perform exponentiation and recover the log compressed image
- ExpLuminance(U);
-
- return U;
-
- } catch(int) {
- if(H) FreeImage_Unload(H);
- if(pyramid) {
- for(int i = 0; i < nlevels; i++) {
- if(pyramid[i]) FreeImage_Unload(pyramid[i]);
- }
- free(pyramid);
- }
- if(gradients) {
- for(int i = 0; i < nlevels; i++) {
- if(gradients[i]) FreeImage_Unload(gradients[i]);
- }
- free(gradients);
- }
- if(avgGrad) free(avgGrad);
- if(phy) FreeImage_Unload(phy);
- if(divG) FreeImage_Unload(divG);
- if(U) FreeImage_Unload(U);
-
- return NULL;
- }
-}
-
-// ----------------------------------------------------------
-// Main algorithm
-// ----------------------------------------------------------
-
-/**
-Apply the Gradient Domain High Dynamic Range Compression to a RGBF image and convert to 24-bit RGB
-@param dib Input RGBF / RGB16 image
-@param color_saturation Color saturation (s parameter in the paper) in [0.4..0.6]
-@param attenuation Atenuation factor (beta parameter in the paper) in [0.8..0.9]
-@return Returns a 24-bit RGB image if successful, returns NULL otherwise
-*/
-FIBITMAP* DLL_CALLCONV
-FreeImage_TmoFattal02(FIBITMAP *dib, double color_saturation, double attenuation) {
- const float alpha = 0.1F; // parameter alpha = 0.1
- const float beta = (float)MAX(0.8, MIN(0.9, attenuation)); // parameter beta = [0.8..0.9]
- const float s = (float)MAX(0.4, MIN(0.6, color_saturation));// exponent s controls color saturation = [0.4..0.6]
-
- FIBITMAP *src = NULL;
- FIBITMAP *Yin = NULL;
- FIBITMAP *Yout = NULL;
- FIBITMAP *dst = NULL;
-
- if(!FreeImage_HasPixels(dib)) return NULL;
-
- try {
-
- // convert to RGBF
- src = FreeImage_ConvertToRGBF(dib);
- if(!src) throw(1);
-
- // get the luminance channel
- Yin = ConvertRGBFToY(src);
- if(!Yin) throw(1);
-
- // perform the tone mapping
- Yout = tmoFattal02(Yin, alpha, beta);
- if(!Yout) throw(1);
-
- // clip low and high values and normalize to [0..1]
- //NormalizeY(Yout, 0.001F, 0.995F);
- NormalizeY(Yout, 0, 1);
-
- // compress the dynamic range
-
- const unsigned width = FreeImage_GetWidth(src);
- const unsigned height = FreeImage_GetHeight(src);
-
- const unsigned rgb_pitch = FreeImage_GetPitch(src);
- const unsigned y_pitch = FreeImage_GetPitch(Yin);
-
- BYTE *bits = (BYTE*)FreeImage_GetBits(src);
- BYTE *bits_yin = (BYTE*)FreeImage_GetBits(Yin);
- BYTE *bits_yout = (BYTE*)FreeImage_GetBits(Yout);
-
- for(unsigned y = 0; y < height; y++) {
- float *Lin = (float*)bits_yin;
- float *Lout = (float*)bits_yout;
- float *color = (float*)bits;
- for(unsigned x = 0; x < width; x++) {
- for(unsigned c = 0; c < 3; c++) {
- *color = (Lin[x] > 0) ? pow(*color/Lin[x], s) * Lout[x] : 0;
- color++;
- }
- }
- bits += rgb_pitch;
- bits_yin += y_pitch;
- bits_yout += y_pitch;
- }
-
- // not needed anymore
- FreeImage_Unload(Yin); Yin = NULL;
- FreeImage_Unload(Yout); Yout = NULL;
-
- // clamp image highest values to display white, then convert to 24-bit RGB
- dst = ClampConvertRGBFTo24(src);
-
- // clean-up and return
- FreeImage_Unload(src); src = NULL;
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, dib);
-
- return dst;
-
- } catch(int) {
- if(src) FreeImage_Unload(src);
- if(Yin) FreeImage_Unload(Yin);
- if(Yout) FreeImage_Unload(Yout);
- return NULL;
- }
-}
diff --git a/plugins/AdvaImg/src/FreeImage/tmoReinhard05.cpp b/plugins/AdvaImg/src/FreeImage/tmoReinhard05.cpp
deleted file mode 100644
index 64607dd5aa..0000000000
--- a/plugins/AdvaImg/src/FreeImage/tmoReinhard05.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-// ==========================================================
-// Tone mapping operator (Reinhard, 2005)
-//
-// Design and implementation by
-// - Hervé Drolon (drolon@infonie.fr)
-// - 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!
-// ==========================================================
-
-#include "FreeImage.h"
-#include "Utilities.h"
-#include "ToneMapping.h"
-
-// ----------------------------------------------------------
-// Global and/or local tone mapping operator
-// References:
-// [1] Erik Reinhard and Kate Devlin, 'Dynamic Range Reduction Inspired by Photoreceptor Physiology',
-// IEEE Transactions on Visualization and Computer Graphics, 11(1), Jan/Feb 2005.
-// [2] Erik Reinhard, 'Parameter estimation for photographic tone reproduction',
-// Journal of Graphics Tools, vol. 7, no. 1, pp. 45–51, 2003.
-// ----------------------------------------------------------
-
-/**
-Tone mapping operator
-@param dib Input / Output RGBF image
-@param Y Input luminance image version of dib
-@param f Overall intensity in range [-8:8] : default to 0
-@param m Contrast in range [0.3:1) : default to 0
-@param a Adaptation in range [0:1] : default to 1
-@param c Color correction in range [0:1] : default to 0
-@return Returns TRUE if successful, returns FALSE otherwise
-@see LuminanceFromY
-*/
-static BOOL
-ToneMappingReinhard05(FIBITMAP *dib, FIBITMAP *Y, float f, float m, float a, float c) {
- float Cav[3]; // channel average
- float Lav = 0; // average luminance
- float Llav = 0; // log average luminance
- float minLum = 1; // min luminance
- float maxLum = 1; // max luminance
-
- float L; // pixel luminance
- float I_g, I_l; // global and local light adaptation
- float I_a; // interpolated pixel light adaptation
- float k; // key (low-key means overall dark image, high-key means overall light image)
-
- // check input parameters
-
- if((FreeImage_GetImageType(dib) != FIT_RGBF) || (FreeImage_GetImageType(Y) != FIT_FLOAT)) {
- return FALSE;
- }
-
- if(f < -8) f = -8; if(f > 8) f = 8;
- if(m < 0) m = 0; if(m > 1) m = 1;
- if(a < 0) a = 0; if(a > 1) a = 1;
- if(c < 0) c = 0; if(c > 1) c = 1;
-
- const unsigned width = FreeImage_GetWidth(dib);
- const unsigned height = FreeImage_GetHeight(dib);
-
- const unsigned dib_pitch = FreeImage_GetPitch(dib);
- const unsigned y_pitch = FreeImage_GetPitch(Y);
-
- int i;
- unsigned x, y;
- BYTE *bits = NULL, *Ybits = NULL;
-
- // get statistics about the data (but only if its really needed)
-
- f = exp(-f);
- if((m == 0) || (a != 1) && (c != 1)) {
- // avoid these calculations if its not needed after ...
- LuminanceFromY(Y, &maxLum, &minLum, &Lav, &Llav);
- k = (log(maxLum) - Llav) / (log(maxLum) - log(minLum));
- if(k < 0) {
- // pow(k, 1.4F) is undefined ...
- // there's an ambiguity about the calculation of Llav between Reinhard papers and the various implementations ...
- // try another world adaptation luminance formula using instead 'worldLum = log(Llav)'
- k = (log(maxLum) - log(Llav)) / (log(maxLum) - log(minLum));
- if(k < 0) m = 0.3F;
- }
- }
- m = (m > 0) ? m : (float)(0.3 + 0.7 * pow(k, 1.4F));
-
- float max_color = -1e6F;
- float min_color = +1e6F;
-
- // tone map image
-
- bits = (BYTE*)FreeImage_GetBits(dib);
- Ybits = (BYTE*)FreeImage_GetBits(Y);
-
- if((a == 1) && (c == 0)) {
- // when using default values, use a fastest code
-
- for(y = 0; y < height; y++) {
- float *Y = (float*)Ybits;
- float *color = (float*)bits;
-
- for(x = 0; x < width; x++) {
- I_a = Y[x]; // luminance(x, y)
- for (i = 0; i < 3; i++) {
- *color /= ( *color + pow(f * I_a, m) );
-
- max_color = (*color > max_color) ? *color : max_color;
- min_color = (*color < min_color) ? *color : min_color;
-
- color++;
- }
- }
- // next line
- bits += dib_pitch;
- Ybits += y_pitch;
- }
- } else {
- // complete algorithm
-
- // channel averages
-
- Cav[0] = Cav[1] = Cav[2] = 0;
- if((a != 1) && (c != 0)) {
- // channel averages are not needed when (a == 1) or (c == 0)
- bits = (BYTE*)FreeImage_GetBits(dib);
- for(y = 0; y < height; y++) {
- float *color = (float*)bits;
- for(x = 0; x < width; x++) {
- for(i = 0; i < 3; i++) {
- Cav[i] += *color;
- color++;
- }
- }
- // next line
- bits += dib_pitch;
- }
- const float image_size = (float)width * height;
- for(i = 0; i < 3; i++) {
- Cav[i] /= image_size;
- }
- }
-
- // perform tone mapping
-
- bits = (BYTE*)FreeImage_GetBits(dib);
- for(y = 0; y < height; y++) {
- const float *Y = (float*)Ybits;
- float *color = (float*)bits;
-
- for(x = 0; x < width; x++) {
- L = Y[x]; // luminance(x, y)
- for (i = 0; i < 3; i++) {
- I_l = c * *color + (1-c) * L;
- I_g = c * Cav[i] + (1-c) * Lav;
- I_a = a * I_l + (1-a) * I_g;
- *color /= ( *color + pow(f * I_a, m) );
-
- max_color = (*color > max_color) ? *color : max_color;
- min_color = (*color < min_color) ? *color : min_color;
-
- color++;
- }
- }
- // next line
- bits += dib_pitch;
- Ybits += y_pitch;
- }
- }
-
- // normalize intensities
-
- if(max_color != min_color) {
- bits = (BYTE*)FreeImage_GetBits(dib);
- const float range = max_color - min_color;
- for(y = 0; y < height; y++) {
- float *color = (float*)bits;
- for(x = 0; x < width; x++) {
- for(i = 0; i < 3; i++) {
- *color = (*color - min_color) / range;
- color++;
- }
- }
- // next line
- bits += dib_pitch;
- }
- }
-
- return TRUE;
-}
-
-// ----------------------------------------------------------
-// Main algorithm
-// ----------------------------------------------------------
-
-/**
-Apply the global/local tone mapping operator to a RGBF image and convert to 24-bit RGB<br>
-User parameters control intensity, contrast, and level of adaptation
-@param src Input RGBF image
-@param intensity Overall intensity in range [-8:8] : default to 0
-@param contrast Contrast in range [0.3:1) : default to 0
-@param adaptation Adaptation in range [0:1] : default to 1
-@param color_correction Color correction in range [0:1] : default to 0
-@return Returns a 24-bit RGB image if successful, returns NULL otherwise
-*/
-FIBITMAP* DLL_CALLCONV
-FreeImage_TmoReinhard05Ex(FIBITMAP *src, double intensity, double contrast, double adaptation, double color_correction) {
- if(!FreeImage_HasPixels(src)) return NULL;
-
- // working RGBF variable
- FIBITMAP *dib = NULL, *Y = NULL;
-
- dib = FreeImage_ConvertToRGBF(src);
- if(!dib) return NULL;
-
- // get the Luminance channel
- Y = ConvertRGBFToY(dib);
- if(!Y) {
- FreeImage_Unload(dib);
- return NULL;
- }
-
- // perform the tone mapping
- ToneMappingReinhard05(dib, Y, (float)intensity, (float)contrast, (float)adaptation, (float)color_correction);
- // not needed anymore
- FreeImage_Unload(Y);
- // clamp image highest values to display white, then convert to 24-bit RGB
- FIBITMAP *dst = ClampConvertRGBFTo24(dib);
-
- // clean-up and return
- FreeImage_Unload(dib);
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- return dst;
-}
-
-/**
-Apply the global tone mapping operator to a RGBF image and convert to 24-bit RGB<br>
-User parameters control intensity and contrast
-@param src Input RGBF image
-@param intensity Overall intensity in range [-8:8] : default to 0
-@param contrast Contrast in range [0.3:1) : default to 0
-@return Returns a 24-bit RGB image if successful, returns NULL otherwise
-*/
-FIBITMAP* DLL_CALLCONV
-FreeImage_TmoReinhard05(FIBITMAP *src, double intensity, double contrast) {
- return FreeImage_TmoReinhard05Ex(src, intensity, contrast, 1, 0);
-}