From 88708cffa15662dcd2755fce699112d24a10a087 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 30 May 2012 17:27:49 +0000 Subject: update for zlib & FreeImage git-svn-id: http://svn.miranda-ng.org/main/trunk@238 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/FreeImage/Source/Utilities.h | 968 +++++++++++++++++------------------ 1 file changed, 484 insertions(+), 484 deletions(-) (limited to 'plugins/FreeImage/Source/Utilities.h') diff --git a/plugins/FreeImage/Source/Utilities.h b/plugins/FreeImage/Source/Utilities.h index 3f3cf47ebf..bf836e1e87 100644 --- a/plugins/FreeImage/Source/Utilities.h +++ b/plugins/FreeImage/Source/Utilities.h @@ -1,484 +1,484 @@ -// ========================================================== -// Utility functions -// -// Design and implementation by -// - Floris van den Berg (flvdberg@wxs.nl) -// - Hervé Drolon -// - Ryan Rubley (ryan@lostreality.org) -// -// 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 UTILITIES_H -#define UTILITIES_H - -// ========================================================== -// Standard includes used by the library -// ========================================================== - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// ========================================================== -// Bitmap palette and pixels alignment -// ========================================================== - -#define FIBITMAP_ALIGNMENT 16 // We will use a 16 bytes alignment boundary - -// Memory allocation on a specified alignment boundary -// defined in BitmapAccess.cpp - -void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment); -void FreeImage_Aligned_Free(void* mem); - -#if defined(__cplusplus) -extern "C" { -#endif - -/** -Allocate a FIBITMAP with possibly no pixel data -(i.e. only header data and some or all metadata) -@param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP -@param type Image type -@param width -@param height -@param bpp -@param red_mask -@param green_mask -@param blue_mask -@see FreeImage_AllocateT -*/ -DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeaderT(BOOL header_only, FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); - -/** -Allocate a FIBITMAP of type FIT_BITMAP, with possibly no pixel data -(i.e. only header data and some or all metadata) -@param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP -@param width -@param height -@param bpp -@param red_mask -@param green_mask -@param blue_mask -@see FreeImage_Allocate -*/ -DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeader(BOOL header_only, int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); - -#if defined(__cplusplus) -} -#endif - - -// ========================================================== -// File I/O structs -// ========================================================== - -// these structs are for file I/O and should not be confused with similar -// structs in FreeImage.h which are for in-memory bitmap handling - -#ifdef _WIN32 -#pragma pack(push, 1) -#else -#pragma pack(1) -#endif // _WIN32 - -typedef struct tagFILE_RGBA { - unsigned char r,g,b,a; -} FILE_RGBA; - -typedef struct tagFILE_BGRA { - unsigned char b,g,r,a; -} FILE_BGRA; - -typedef struct tagFILE_RGB { - unsigned char r,g,b; -} FILE_RGB; - -typedef struct tagFILE_BGR { - unsigned char b,g,r; -} FILE_BGR; - -#ifdef _WIN32 -#pragma pack(pop) -#else -#pragma pack() -#endif // _WIN32 - -// ========================================================== -// Template utility functions -// ========================================================== - -/// Max function -template T MAX(T a, T b) { - return (a > b) ? a: b; -} - -/// Min function -template T MIN(T a, T b) { - return (a < b) ? a: b; -} - -/// INPLACESWAP adopted from codeguru.com -template void INPLACESWAP(T& a, T& b) { - a ^= b; b ^= a; a ^= b; -} - -/// Clamp function -template T CLAMP(T value, T min_value, T max_value) { - return ((value < min_value) ? min_value : (value > max_value) ? max_value : value); -} - -/** This procedure computes minimum min and maximum max - of n numbers using only (3n/2) - 2 comparisons. - min = L[i1] and max = L[i2]. - ref: Aho A.V., Hopcroft J.E., Ullman J.D., - The design and analysis of computer algorithms, - Addison-Wesley, Reading, 1974. -*/ -template void -MAXMIN(const T* L, long n, T& max, T& min) { - long i1, i2, i, j; - T x1, x2; - long k1, k2; - - i1 = 0; i2 = 0; min = L[0]; max = L[0]; j = 0; - if((n % 2) != 0) j = 1; - for(i = j; i < n; i+= 2) { - k1 = i; k2 = i+1; - x1 = L[k1]; x2 = L[k2]; - if(x1 > x2) { - k1 = k2; k2 = i; - x1 = x2; x2 = L[k2]; - } - if(x1 < min) { - min = x1; i1 = k1; - } - if(x2 > max) { - max = x2; i2 = k2; - } - } -} - -// ========================================================== -// Utility functions -// ========================================================== - -#ifndef _WIN32 -inline char* -i2a(unsigned i, char *a, unsigned r) { - if (i/r > 0) a = i2a(i/r,a,r); - *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r]; - return a+1; -} - -/** - Transforms integer i into an ascii string and stores the result in a; - string is encoded in the base indicated by r. - @param i Number to be converted - @param a String result - @param r Base of value; must be in the range 2 - 36 - @return Returns a -*/ -inline char * -_itoa(int i, char *a, int r) { - r = ((r < 2) || (r > 36)) ? 10 : r; - if(i < 0) { - *a = '-'; - *i2a(-i, a+1, r) = 0; - } - else *i2a(i, a, r) = 0; - return a; -} - -#endif // !_WIN32 - -inline unsigned char -HINIBBLE (unsigned char byte) { - return byte & 0xF0; -} - -inline unsigned char -LOWNIBBLE (unsigned char byte) { - return byte & 0x0F; -} - -inline int -CalculateUsedBits(int bits) { - int bit_count = 0; - unsigned bit = 1; - - for (unsigned i = 0; i < 32; i++) { - if ((bits & bit) == bit) { - bit_count++; - } - - bit <<= 1; - } - - return bit_count; -} - -inline unsigned -CalculateLine(unsigned width, unsigned bitdepth) { - return ((width * bitdepth) + 7) / 8; -} - -inline unsigned -CalculatePitch(unsigned line) { - return line + 3 & ~3; -} - -inline unsigned -CalculateUsedPaletteEntries(unsigned bit_count) { - if ((bit_count >= 1) && (bit_count <= 8)) - return 1 << bit_count; - - return 0; -} - -inline unsigned char * -CalculateScanLine(unsigned char *bits, unsigned pitch, int scanline) { - return (bits + (pitch * scanline)); -} - -// ---------------------------------------------------------- - -/** -Fast generic assign (faster then for loop) -@param dst Destination pixel -@param src Source pixel -@param bytesperpixel # of bytes per pixel -*/ -inline void -AssignPixel(BYTE* dst, const BYTE* src, unsigned bytesperpixel) { - switch (bytesperpixel) { - case 1: // FIT_BITMAP (8-bit) - *dst = *src; - break; - - case 2: // FIT_UINT16 / FIT_INT16 / 16-bit - *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); - break; - - case 3: // FIT_BITMAP (24-bit) - *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); - dst[2] = src[2]; - break; - - case 4: // FIT_BITMAP (32-bit) / FIT_UINT32 / FIT_INT32 / FIT_FLOAT - *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); - break; - - case 6: // FIT_RGB16 (3 x 16-bit) - *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); - *(reinterpret_cast(dst + 4)) = *(reinterpret_cast (src + 4)); - break; - - // the rest can be speeded up with int64 - - case 8: // FIT_RGBA16 (4 x 16-bit) - *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); - *(reinterpret_cast(dst + 4)) = *(reinterpret_cast (src + 4)); - break; - - case 12: // FIT_RGBF (3 x 32-bit IEEE floating point) - *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); - *(reinterpret_cast(dst + 4)) = *(reinterpret_cast (src + 4)); - *(reinterpret_cast(dst + 8)) = *(reinterpret_cast (src + 8)); - break; - - case 16: // FIT_RGBAF (4 x 32-bit IEEE floating point) - *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); - *(reinterpret_cast(dst + 4)) = *(reinterpret_cast (src + 4)); - *(reinterpret_cast(dst + 8)) = *(reinterpret_cast (src + 8)); - *(reinterpret_cast(dst + 12)) = *(reinterpret_cast (src + 12)); - break; - - default: - assert(FALSE); - } -} - -/** -Swap red and blue channels in a 24- or 32-bit dib. -@return Returns TRUE if successful, returns FALSE otherwise -@see See definition in Conversion.cpp -*/ -BOOL SwapRedBlue32(FIBITMAP* dib); - -/** -Inplace convert CMYK to RGBA.(8- and 16-bit). -Alpha is filled with the first extra channel if any or white otherwise. -@return Returns TRUE if successful, returns FALSE otherwise -@see See definition in Conversion.cpp -*/ -BOOL ConvertCMYKtoRGBA(FIBITMAP* dib); - -/** -Inplace convert CIELab to RGBA (8- and 16-bit). -@return Returns TRUE if successful, returns FALSE otherwise -@see See definition in Conversion.cpp -*/ -BOOL ConvertLABtoRGB(FIBITMAP* dib); - -/** -RGBA to RGB conversion -@see See definition in Conversion.cpp -*/ -FIBITMAP* RemoveAlphaChannel(FIBITMAP* dib); - - -// ========================================================== -// Big Endian / Little Endian utility functions -// ========================================================== - -inline WORD -__SwapUInt16(WORD arg) { -#if defined(_MSC_VER) && _MSC_VER >= 1310 - return _byteswap_ushort(arg); -#elif defined(__i386__) && defined(__GNUC__) - __asm__("xchgb %b0, %h0" : "+q" (arg)); - return arg; -#elif defined(__ppc__) && defined(__GNUC__) - WORD result; - __asm__("lhbrx %0,0,%1" : "=r" (result) : "r" (&arg), "m" (arg)); - return result; -#else - // swap bytes - WORD result; - result = ((arg << 8) & 0xFF00) | ((arg >> 8) & 0x00FF); - return result; -#endif -} - -inline DWORD -__SwapUInt32(DWORD arg) { -#if defined(_MSC_VER) && _MSC_VER >= 1310 - return _byteswap_ulong(arg); -#elif defined(__i386__) && defined(__GNUC__) - __asm__("bswap %0" : "+r" (arg)); - return arg; -#elif defined(__ppc__) && defined(__GNUC__) - DWORD result; - __asm__("lwbrx %0,0,%1" : "=r" (result) : "r" (&arg), "m" (arg)); - return result; -#else - // swap words then bytes - DWORD result; - result = ((arg & 0x000000FF) << 24) | ((arg & 0x0000FF00) << 8) | ((arg >> 8) & 0x0000FF00) | ((arg >> 24) & 0x000000FF); - return result; -#endif -} - -/** -for later use ... -inline uint64_t -SwapInt64(uint64_t arg) { -#if defined(_MSC_VER) && _MSC_VER >= 1310 - return _byteswap_uint64(arg); -#else - union Swap { - uint64_t sv; - uint32_t ul[2]; - } tmp, result; - tmp.sv = arg; - result.ul[0] = SwapInt32(tmp.ul[1]); - result.ul[1] = SwapInt32(tmp.ul[0]); - return result.sv; -#endif -} -*/ - -inline void -SwapShort(WORD *sp) { - *sp = __SwapUInt16(*sp); -} - -inline void -SwapLong(DWORD *lp) { - *lp = __SwapUInt32(*lp); -} - -// ========================================================== -// Greyscale and color conversion -// ========================================================== - -/** -Extract the luminance channel L from a RGBF image. -Luminance is calculated from the sRGB model using a D65 white point, using the Rec.709 formula : -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 -*/ -#define LUMA_REC709(r, g, b) (0.2126F * r + 0.7152F * g + 0.0722F * b) - -#define GREY(r, g, b) (BYTE)LUMA_REC709(r, g, b) -/* -#define GREY(r, g, b) (BYTE)(((WORD)r * 77 + (WORD)g * 150 + (WORD)b * 29) >> 8) // .299R + .587G + .114B -*/ -/* -#define GREY(r, g, b) (BYTE)(((WORD)r * 169 + (WORD)g * 256 + (WORD)b * 87) >> 9) // .33R + 0.5G + .17B -*/ - -#define RGB565(b, g, r) ((((b) >> 3) << FI16_565_BLUE_SHIFT) | (((g) >> 2) << FI16_565_GREEN_SHIFT) | (((r) >> 3) << FI16_565_RED_SHIFT)) -#define RGB555(b, g, r) ((((b) >> 3) << FI16_555_BLUE_SHIFT) | (((g) >> 3) << FI16_555_GREEN_SHIFT) | (((r) >> 3) << FI16_555_RED_SHIFT)) - -#define FORMAT_RGB565(dib) ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) &&(FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) &&(FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) -#define RGBQUAD_TO_WORD(dib, color) (FORMAT_RGB565(dib) ? RGB565((color)->rgbBlue, (color)->rgbGreen, (color)->rgbRed) : RGB555((color)->rgbBlue, (color)->rgbGreen, (color)->rgbRed)) - -#define CREATE_GREYSCALE_PALETTE(palette, entries) \ - for (unsigned i = 0, v = 0; i < entries; i++, v += 0x00FFFFFF / (entries - 1)) { \ - ((unsigned *)palette)[i] = v; \ - } - -#define CREATE_GREYSCALE_PALETTE_REVERSE(palette, entries) \ - for (unsigned i = 0, v = 0x00FFFFFF; i < entries; i++, v -= (0x00FFFFFF / (entries - 1))) { \ - ((unsigned *)palette)[i] = v; \ - } - -// ========================================================== -// Generic error messages -// ========================================================== - -static const char *FI_MSG_ERROR_MEMORY = "Memory allocation failed"; -static const char *FI_MSG_ERROR_DIB_MEMORY = "DIB allocation failed, probably caused by an invalid image"; -static const char *FI_MSG_ERROR_PARSING = "Parsing error"; -static const char *FI_MSG_ERROR_MAGIC_NUMBER = "Invalid magic number"; -static const char *FI_MSG_ERROR_UNSUPPORTED_FORMAT = "Unsupported format"; -static const char *FI_MSG_ERROR_UNSUPPORTED_COMPRESSION = "Unsupported compression type"; -static const char *FI_MSG_WARNING_INVALID_THUMBNAIL = "Warning: attached thumbnail cannot be written to output file (invalid format) - Thumbnail saving aborted"; - -#endif // UTILITIES_H +// ========================================================== +// Utility functions +// +// Design and implementation by +// - Floris van den Berg (flvdberg@wxs.nl) +// - Hervé Drolon +// - Ryan Rubley (ryan@lostreality.org) +// +// 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 UTILITIES_H +#define UTILITIES_H + +// ========================================================== +// Standard includes used by the library +// ========================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// ========================================================== +// Bitmap palette and pixels alignment +// ========================================================== + +#define FIBITMAP_ALIGNMENT 16 // We will use a 16 bytes alignment boundary + +// Memory allocation on a specified alignment boundary +// defined in BitmapAccess.cpp + +void* FreeImage_Aligned_Malloc(size_t amount, size_t alignment); +void FreeImage_Aligned_Free(void* mem); + +#if defined(__cplusplus) +extern "C" { +#endif + +/** +Allocate a FIBITMAP with possibly no pixel data +(i.e. only header data and some or all metadata) +@param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP +@param type Image type +@param width +@param height +@param bpp +@param red_mask +@param green_mask +@param blue_mask +@see FreeImage_AllocateT +*/ +DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeaderT(BOOL header_only, FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); + +/** +Allocate a FIBITMAP of type FIT_BITMAP, with possibly no pixel data +(i.e. only header data and some or all metadata) +@param header_only If TRUE, allocate a 'header only' FIBITMAP, otherwise allocate a full FIBITMAP +@param width +@param height +@param bpp +@param red_mask +@param green_mask +@param blue_mask +@see FreeImage_Allocate +*/ +DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeader(BOOL header_only, int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0)); + +#if defined(__cplusplus) +} +#endif + + +// ========================================================== +// File I/O structs +// ========================================================== + +// these structs are for file I/O and should not be confused with similar +// structs in FreeImage.h which are for in-memory bitmap handling + +#ifdef _WIN32 +#pragma pack(push, 1) +#else +#pragma pack(1) +#endif // _WIN32 + +typedef struct tagFILE_RGBA { + unsigned char r,g,b,a; +} FILE_RGBA; + +typedef struct tagFILE_BGRA { + unsigned char b,g,r,a; +} FILE_BGRA; + +typedef struct tagFILE_RGB { + unsigned char r,g,b; +} FILE_RGB; + +typedef struct tagFILE_BGR { + unsigned char b,g,r; +} FILE_BGR; + +#ifdef _WIN32 +#pragma pack(pop) +#else +#pragma pack() +#endif // _WIN32 + +// ========================================================== +// Template utility functions +// ========================================================== + +/// Max function +template T MAX(const T &a, const T &b) { + return (a > b) ? a: b; +} + +/// Min function +template T MIN(const T &a, const T &b) { + return (a < b) ? a: b; +} + +/// INPLACESWAP adopted from codeguru.com +template void INPLACESWAP(T& a, T& b) { + a ^= b; b ^= a; a ^= b; +} + +/// Clamp function +template T CLAMP(const T &value, const T &min_value, const T &max_value) { + return ((value < min_value) ? min_value : (value > max_value) ? max_value : value); +} + +/** This procedure computes minimum min and maximum max + of n numbers using only (3n/2) - 2 comparisons. + min = L[i1] and max = L[i2]. + ref: Aho A.V., Hopcroft J.E., Ullman J.D., + The design and analysis of computer algorithms, + Addison-Wesley, Reading, 1974. +*/ +template void +MAXMIN(const T* L, long n, T& max, T& min) { + long i1, i2, i, j; + T x1, x2; + long k1, k2; + + i1 = 0; i2 = 0; min = L[0]; max = L[0]; j = 0; + if((n % 2) != 0) j = 1; + for(i = j; i < n; i+= 2) { + k1 = i; k2 = i+1; + x1 = L[k1]; x2 = L[k2]; + if(x1 > x2) { + k1 = k2; k2 = i; + x1 = x2; x2 = L[k2]; + } + if(x1 < min) { + min = x1; i1 = k1; + } + if(x2 > max) { + max = x2; i2 = k2; + } + } +} + +// ========================================================== +// Utility functions +// ========================================================== + +#ifndef _WIN32 +inline char* +i2a(unsigned i, char *a, unsigned r) { + if (i/r > 0) a = i2a(i/r,a,r); + *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r]; + return a+1; +} + +/** + Transforms integer i into an ascii string and stores the result in a; + string is encoded in the base indicated by r. + @param i Number to be converted + @param a String result + @param r Base of value; must be in the range 2 - 36 + @return Returns a +*/ +inline char * +_itoa(int i, char *a, int r) { + r = ((r < 2) || (r > 36)) ? 10 : r; + if(i < 0) { + *a = '-'; + *i2a(-i, a+1, r) = 0; + } + else *i2a(i, a, r) = 0; + return a; +} + +#endif // !_WIN32 + +inline unsigned char +HINIBBLE (unsigned char byte) { + return byte & 0xF0; +} + +inline unsigned char +LOWNIBBLE (unsigned char byte) { + return byte & 0x0F; +} + +inline int +CalculateUsedBits(int bits) { + int bit_count = 0; + unsigned bit = 1; + + for (unsigned i = 0; i < 32; i++) { + if ((bits & bit) == bit) { + bit_count++; + } + + bit <<= 1; + } + + return bit_count; +} + +inline unsigned +CalculateLine(unsigned width, unsigned bitdepth) { + return (unsigned)( ((unsigned __int64)width * bitdepth + 7) / 8 ); +} + +inline unsigned +CalculatePitch(unsigned line) { + return line + 3 & ~3; +} + +inline unsigned +CalculateUsedPaletteEntries(unsigned bit_count) { + if ((bit_count >= 1) && (bit_count <= 8)) + return 1 << bit_count; + + return 0; +} + +inline unsigned char * +CalculateScanLine(unsigned char *bits, unsigned pitch, int scanline) { + return (bits + (pitch * scanline)); +} + +// ---------------------------------------------------------- + +/** +Fast generic assign (faster than for loop) +@param dst Destination pixel +@param src Source pixel +@param bytesperpixel # of bytes per pixel +*/ +inline void +AssignPixel(BYTE* dst, const BYTE* src, unsigned bytesperpixel) { + switch (bytesperpixel) { + case 1: // FIT_BITMAP (8-bit) + *dst = *src; + break; + + case 2: // FIT_UINT16 / FIT_INT16 / 16-bit + *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); + break; + + case 3: // FIT_BITMAP (24-bit) + *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); + dst[2] = src[2]; + break; + + case 4: // FIT_BITMAP (32-bit) / FIT_UINT32 / FIT_INT32 / FIT_FLOAT + *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); + break; + + case 6: // FIT_RGB16 (3 x 16-bit) + *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); + *(reinterpret_cast(dst + 4)) = *(reinterpret_cast (src + 4)); + break; + + // the rest can be speeded up with int64 + + case 8: // FIT_RGBA16 (4 x 16-bit) + *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); + *(reinterpret_cast(dst + 4)) = *(reinterpret_cast (src + 4)); + break; + + case 12: // FIT_RGBF (3 x 32-bit IEEE floating point) + *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); + *(reinterpret_cast(dst + 4)) = *(reinterpret_cast (src + 4)); + *(reinterpret_cast(dst + 8)) = *(reinterpret_cast (src + 8)); + break; + + case 16: // FIT_RGBAF (4 x 32-bit IEEE floating point) + *(reinterpret_cast(dst)) = *(reinterpret_cast (src)); + *(reinterpret_cast(dst + 4)) = *(reinterpret_cast (src + 4)); + *(reinterpret_cast(dst + 8)) = *(reinterpret_cast (src + 8)); + *(reinterpret_cast(dst + 12)) = *(reinterpret_cast (src + 12)); + break; + + default: + assert(FALSE); + } +} + +/** +Swap red and blue channels in a 24- or 32-bit dib. +@return Returns TRUE if successful, returns FALSE otherwise +@see See definition in Conversion.cpp +*/ +BOOL SwapRedBlue32(FIBITMAP* dib); + +/** +Inplace convert CMYK to RGBA.(8- and 16-bit). +Alpha is filled with the first extra channel if any or white otherwise. +@return Returns TRUE if successful, returns FALSE otherwise +@see See definition in Conversion.cpp +*/ +BOOL ConvertCMYKtoRGBA(FIBITMAP* dib); + +/** +Inplace convert CIELab to RGBA (8- and 16-bit). +@return Returns TRUE if successful, returns FALSE otherwise +@see See definition in Conversion.cpp +*/ +BOOL ConvertLABtoRGB(FIBITMAP* dib); + +/** +RGBA to RGB conversion +@see See definition in Conversion.cpp +*/ +FIBITMAP* RemoveAlphaChannel(FIBITMAP* dib); + + +// ========================================================== +// Big Endian / Little Endian utility functions +// ========================================================== + +inline WORD +__SwapUInt16(WORD arg) { +#if defined(_MSC_VER) && _MSC_VER >= 1310 + return _byteswap_ushort(arg); +#elif defined(__i386__) && defined(__GNUC__) + __asm__("xchgb %b0, %h0" : "+q" (arg)); + return arg; +#elif defined(__ppc__) && defined(__GNUC__) + WORD result; + __asm__("lhbrx %0,0,%1" : "=r" (result) : "r" (&arg), "m" (arg)); + return result; +#else + // swap bytes + WORD result; + result = ((arg << 8) & 0xFF00) | ((arg >> 8) & 0x00FF); + return result; +#endif +} + +inline DWORD +__SwapUInt32(DWORD arg) { +#if defined(_MSC_VER) && _MSC_VER >= 1310 + return _byteswap_ulong(arg); +#elif defined(__i386__) && defined(__GNUC__) + __asm__("bswap %0" : "+r" (arg)); + return arg; +#elif defined(__ppc__) && defined(__GNUC__) + DWORD result; + __asm__("lwbrx %0,0,%1" : "=r" (result) : "r" (&arg), "m" (arg)); + return result; +#else + // swap words then bytes + DWORD result; + result = ((arg & 0x000000FF) << 24) | ((arg & 0x0000FF00) << 8) | ((arg >> 8) & 0x0000FF00) | ((arg >> 24) & 0x000000FF); + return result; +#endif +} + +/** +for later use ... +inline uint64_t +SwapInt64(uint64_t arg) { +#if defined(_MSC_VER) && _MSC_VER >= 1310 + return _byteswap_uint64(arg); +#else + union Swap { + uint64_t sv; + uint32_t ul[2]; + } tmp, result; + tmp.sv = arg; + result.ul[0] = SwapInt32(tmp.ul[1]); + result.ul[1] = SwapInt32(tmp.ul[0]); + return result.sv; +#endif +} +*/ + +inline void +SwapShort(WORD *sp) { + *sp = __SwapUInt16(*sp); +} + +inline void +SwapLong(DWORD *lp) { + *lp = __SwapUInt32(*lp); +} + +// ========================================================== +// Greyscale and color conversion +// ========================================================== + +/** +Extract the luminance channel L from a RGBF image. +Luminance is calculated from the sRGB model using a D65 white point, using the Rec.709 formula : +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 +*/ +#define LUMA_REC709(r, g, b) (0.2126F * r + 0.7152F * g + 0.0722F * b) + +#define GREY(r, g, b) (BYTE)LUMA_REC709(r, g, b) +/* +#define GREY(r, g, b) (BYTE)(((WORD)r * 77 + (WORD)g * 150 + (WORD)b * 29) >> 8) // .299R + .587G + .114B +*/ +/* +#define GREY(r, g, b) (BYTE)(((WORD)r * 169 + (WORD)g * 256 + (WORD)b * 87) >> 9) // .33R + 0.5G + .17B +*/ + +#define RGB565(b, g, r) ((((b) >> 3) << FI16_565_BLUE_SHIFT) | (((g) >> 2) << FI16_565_GREEN_SHIFT) | (((r) >> 3) << FI16_565_RED_SHIFT)) +#define RGB555(b, g, r) ((((b) >> 3) << FI16_555_BLUE_SHIFT) | (((g) >> 3) << FI16_555_GREEN_SHIFT) | (((r) >> 3) << FI16_555_RED_SHIFT)) + +#define FORMAT_RGB565(dib) ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) &&(FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) &&(FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) +#define RGBQUAD_TO_WORD(dib, color) (FORMAT_RGB565(dib) ? RGB565((color)->rgbBlue, (color)->rgbGreen, (color)->rgbRed) : RGB555((color)->rgbBlue, (color)->rgbGreen, (color)->rgbRed)) + +#define CREATE_GREYSCALE_PALETTE(palette, entries) \ + for (unsigned i = 0, v = 0; i < entries; i++, v += 0x00FFFFFF / (entries - 1)) { \ + ((unsigned *)palette)[i] = v; \ + } + +#define CREATE_GREYSCALE_PALETTE_REVERSE(palette, entries) \ + for (unsigned i = 0, v = 0x00FFFFFF; i < entries; i++, v -= (0x00FFFFFF / (entries - 1))) { \ + ((unsigned *)palette)[i] = v; \ + } + +// ========================================================== +// Generic error messages +// ========================================================== + +static const char *FI_MSG_ERROR_MEMORY = "Memory allocation failed"; +static const char *FI_MSG_ERROR_DIB_MEMORY = "DIB allocation failed, maybe caused by an invalid image size or by a lack of memory"; +static const char *FI_MSG_ERROR_PARSING = "Parsing error"; +static const char *FI_MSG_ERROR_MAGIC_NUMBER = "Invalid magic number"; +static const char *FI_MSG_ERROR_UNSUPPORTED_FORMAT = "Unsupported format"; +static const char *FI_MSG_ERROR_UNSUPPORTED_COMPRESSION = "Unsupported compression type"; +static const char *FI_MSG_WARNING_INVALID_THUMBNAIL = "Warning: attached thumbnail cannot be written to output file (invalid format) - Thumbnail saving aborted"; + +#endif // UTILITIES_H -- cgit v1.2.3