diff options
Diffstat (limited to 'plugins/FreeImage/Source/FreeImageToolkit/Colors.cpp')
-rw-r--r-- | plugins/FreeImage/Source/FreeImageToolkit/Colors.cpp | 967 |
1 files changed, 0 insertions, 967 deletions
diff --git a/plugins/FreeImage/Source/FreeImageToolkit/Colors.cpp b/plugins/FreeImage/Source/FreeImageToolkit/Colors.cpp deleted file mode 100644 index 8b9bbd6482..0000000000 --- a/plugins/FreeImage/Source/FreeImageToolkit/Colors.cpp +++ /dev/null @@ -1,967 +0,0 @@ -// ========================================================== -// Color manipulation routines -// -// Design and implementation by -// - Hervé Drolon (drolon@infonie.fr) -// - 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! -// ========================================================== - -#include "FreeImage.h" -#include "Utilities.h" - -// ---------------------------------------------------------- -// Macros + structures -// ---------------------------------------------------------- - -#define GET_HI_NIBBLE(byte) ((byte) >> 4) -#define SET_HI_NIBBLE(byte, n) byte &= 0x0F, byte |= ((n) << 4) -#define GET_LO_NIBBLE(byte) ((byte) & 0x0F) -#define SET_LO_NIBBLE(byte, n) byte &= 0xF0, byte |= ((n) & 0x0F) -#define GET_NIBBLE(cn, byte) ((cn) ? (GET_HI_NIBBLE(byte)) : (GET_LO_NIBBLE(byte))) -#define SET_NIBBLE(cn, byte, n) if (cn) SET_HI_NIBBLE(byte, n); else SET_LO_NIBBLE(byte, n) - -// ---------------------------------------------------------- - - -/** @brief Inverts each pixel data. - -@param src Input image to be processed. -@return Returns TRUE if successful, FALSE otherwise. -*/ -BOOL DLL_CALLCONV -FreeImage_Invert(FIBITMAP *src) { - - if (!FreeImage_HasPixels(src)) return FALSE; - - unsigned i, x, y, k; - - const unsigned width = FreeImage_GetWidth(src); - const unsigned height = FreeImage_GetHeight(src); - const unsigned bpp = FreeImage_GetBPP(src); - - FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(src); - - if(image_type == FIT_BITMAP) { - switch(bpp) { - case 1 : - case 4 : - case 8 : - { - // if the dib has a colormap, just invert it - // else, keep the linear grayscale - - if (FreeImage_GetColorType(src) == FIC_PALETTE) { - RGBQUAD *pal = FreeImage_GetPalette(src); - - for(i = 0; i < FreeImage_GetColorsUsed(src); i++) { - pal[i].rgbRed = 255 - pal[i].rgbRed; - pal[i].rgbGreen = 255 - pal[i].rgbGreen; - pal[i].rgbBlue = 255 - pal[i].rgbBlue; - } - } else { - for(y = 0; y < height; y++) { - BYTE *bits = FreeImage_GetScanLine(src, y); - - for (x = 0; x < FreeImage_GetLine(src); x++) { - bits[x] = ~bits[x]; - } - } - } - - break; - } - - case 24 : - case 32 : - { - // Calculate the number of bytes per pixel (3 for 24-bit or 4 for 32-bit) - const unsigned bytespp = FreeImage_GetLine(src) / width; - - for(y = 0; y < height; y++) { - BYTE *bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < width; x++) { - for(k = 0; k < bytespp; k++) { - bits[k] = ~bits[k]; - } - bits += bytespp; - } - } - - break; - } - default: - return FALSE; - } - } - else if ((image_type == FIT_UINT16) || (image_type == FIT_RGB16) || (image_type == FIT_RGBA16)) { - // Calculate the number of words per pixel (1 for 16-bit, 3 for 48-bit or 4 for 64-bit) - const unsigned wordspp = (FreeImage_GetLine(src) / width) / sizeof(WORD); - - for(y = 0; y < height; y++) { - WORD *bits = (WORD*)FreeImage_GetScanLine(src, y); - for(x = 0; x < width; x++) { - for(k = 0; k < wordspp; k++) { - bits[k] = ~bits[k]; - } - bits += wordspp; - } - } - } - else { - // anything else ... - return FALSE; - } - - return TRUE; -} - -/** @brief Perfoms an histogram transformation on a 8, 24 or 32-bit image -according to the values of a lookup table (LUT). - -The transformation is done as follows.<br> -Image 8-bit : if the image has a color palette, the LUT is applied to this palette, -otherwise, it is applied to the grey values.<br> -Image 24-bit & 32-bit : if channel == FICC_RGB, the same LUT is applied to each color -plane (R,G, and B). Otherwise, the LUT is applied to the specified channel only. -@param src Input image to be processed. -@param LUT Lookup table. <b>The size of 'LUT' is assumed to be 256.</b> -@param channel The color channel to be processed (only used with 24 & 32-bit DIB). -@return Returns TRUE if successful, FALSE otherwise. -@see FREE_IMAGE_COLOR_CHANNEL -*/ -BOOL DLL_CALLCONV -FreeImage_AdjustCurve(FIBITMAP *src, BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel) { - unsigned x, y; - BYTE *bits = NULL; - - if (!FreeImage_HasPixels(src) || !LUT || (FreeImage_GetImageType(src) != FIT_BITMAP)) - return FALSE; - - int bpp = FreeImage_GetBPP(src); - if ((bpp != 8) && (bpp != 24) && (bpp != 32)) - return FALSE; - - // apply the LUT - switch(bpp) { - - case 8 : - { - // if the dib has a colormap, apply the LUT to it - // else, apply the LUT to pixel values - - if(FreeImage_GetColorType(src) == FIC_PALETTE) { - RGBQUAD *rgb = FreeImage_GetPalette(src); - for (unsigned pal = 0; pal < FreeImage_GetColorsUsed(src); pal++) { - rgb->rgbRed = LUT[rgb->rgbRed]; - rgb->rgbGreen = LUT[rgb->rgbGreen]; - rgb->rgbBlue = LUT[rgb->rgbBlue]; - rgb++; - } - } - else { - for(y = 0; y < FreeImage_GetHeight(src); y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < FreeImage_GetWidth(src); x++) { - bits[x] = LUT[ bits[x] ]; - } - } - } - - break; - } - - case 24 : - case 32 : - { - int bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src); - - switch(channel) { - case FICC_RGB : - for(y = 0; y < FreeImage_GetHeight(src); y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < FreeImage_GetWidth(src); x++) { - bits[FI_RGBA_BLUE] = LUT[ bits[FI_RGBA_BLUE] ]; // B - bits[FI_RGBA_GREEN] = LUT[ bits[FI_RGBA_GREEN] ]; // G - bits[FI_RGBA_RED] = LUT[ bits[FI_RGBA_RED] ]; // R - - bits += bytespp; - } - } - break; - - case FICC_BLUE : - for(y = 0; y < FreeImage_GetHeight(src); y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < FreeImage_GetWidth(src); x++) { - bits[FI_RGBA_BLUE] = LUT[ bits[FI_RGBA_BLUE] ]; // B - - bits += bytespp; - } - } - break; - - case FICC_GREEN : - for(y = 0; y < FreeImage_GetHeight(src); y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < FreeImage_GetWidth(src); x++) { - bits[FI_RGBA_GREEN] = LUT[ bits[FI_RGBA_GREEN] ]; // G - - bits += bytespp; - } - } - break; - - case FICC_RED : - for(y = 0; y < FreeImage_GetHeight(src); y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < FreeImage_GetWidth(src); x++) { - bits[FI_RGBA_RED] = LUT[ bits[FI_RGBA_RED] ]; // R - - bits += bytespp; - } - } - break; - - case FICC_ALPHA : - if(32 == bpp) { - for(y = 0; y < FreeImage_GetHeight(src); y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < FreeImage_GetWidth(src); x++) { - bits[FI_RGBA_ALPHA] = LUT[ bits[FI_RGBA_ALPHA] ]; // A - - bits += bytespp; - } - } - } - break; - - default: - break; - } - break; - } - } - - return TRUE; -} - -/** @brief Performs gamma correction on a 8, 24 or 32-bit image. - -@param src Input image to be processed. -@param gamma Gamma value to use. A value of 1.0 leaves the image alone, -less than one darkens it, and greater than one lightens it. -@return Returns TRUE if successful, FALSE otherwise. -*/ -BOOL DLL_CALLCONV -FreeImage_AdjustGamma(FIBITMAP *src, double gamma) { - BYTE LUT[256]; // Lookup table - - if (!FreeImage_HasPixels(src) || (gamma <= 0)) - return FALSE; - - // Build the lookup table - - double exponent = 1 / gamma; - double v = 255.0 * (double)pow((double)255, -exponent); - for(int i = 0; i < 256; i++) { - double color = (double)pow((double)i, exponent) * v; - if(color > 255) - color = 255; - LUT[i] = (BYTE)floor(color + 0.5); - } - - // Apply the gamma correction - return FreeImage_AdjustCurve(src, LUT, FICC_RGB); -} - -/** @brief Adjusts the brightness of a 8, 24 or 32-bit image by a certain amount. - -@param src Input image to be processed. -@param percentage Where -100 <= percentage <= 100<br> -A value 0 means no change, less than 0 will make the image darker -and greater than 0 will make the image brighter. -@return Returns TRUE if successful, FALSE otherwise. -*/ -BOOL DLL_CALLCONV -FreeImage_AdjustBrightness(FIBITMAP *src, double percentage) { - BYTE LUT[256]; // Lookup table - double value; - - if (!FreeImage_HasPixels(src)) - return FALSE; - - // Build the lookup table - const double scale = (100 + percentage) / 100; - for(int i = 0; i < 256; i++) { - value = i * scale; - value = MAX(0.0, MIN(value, 255.0)); - LUT[i] = (BYTE)floor(value + 0.5); - } - return FreeImage_AdjustCurve(src, LUT, FICC_RGB); -} - -/** @brief Adjusts the contrast of a 8, 24 or 32-bit image by a certain amount. - -@param src Input image to be processed. -@param percentage Where -100 <= percentage <= 100<br> -A value 0 means no change, less than 0 will decrease the contrast -and greater than 0 will increase the contrast of the image. -@return Returns TRUE if successful, FALSE otherwise. -*/ -BOOL DLL_CALLCONV -FreeImage_AdjustContrast(FIBITMAP *src, double percentage) { - BYTE LUT[256]; // Lookup table - double value; - - if (!FreeImage_HasPixels(src)) - return FALSE; - - // Build the lookup table - const double scale = (100 + percentage) / 100; - for(int i = 0; i < 256; i++) { - value = 128 + (i - 128) * scale; - value = MAX(0.0, MIN(value, 255.0)); - LUT[i] = (BYTE)floor(value + 0.5); - } - return FreeImage_AdjustCurve(src, LUT, FICC_RGB); -} - -/** @brief Computes image histogram - -For 24-bit and 32-bit images, histogram can be computed from red, green, blue and -black channels. For 8-bit images, histogram is computed from the black channel. Other -bit depth is not supported (nothing is done). -@param src Input image to be processed. -@param histo Histogram array to fill. <b>The size of 'histo' is assumed to be 256.</b> -@param channel Color channel to use -@return Returns TRUE if succesful, returns FALSE if the image bit depth isn't supported. -*/ -BOOL DLL_CALLCONV -FreeImage_GetHistogram(FIBITMAP *src, DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel) { - BYTE pixel; - BYTE *bits = NULL; - unsigned x, y; - - if (!FreeImage_HasPixels(src) || !histo) return FALSE; - - unsigned width = FreeImage_GetWidth(src); - unsigned height = FreeImage_GetHeight(src); - unsigned bpp = FreeImage_GetBPP(src); - - if(bpp == 8) { - // clear histogram array - memset(histo, 0, 256 * sizeof(DWORD)); - // compute histogram for black channel - for(y = 0; y < height; y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < width; x++) { - // get pixel value - pixel = bits[x]; - histo[pixel]++; - } - } - return TRUE; - } - else if ((bpp == 24) || (bpp == 32)) { - int bytespp = bpp / 8; // bytes / pixel - - // clear histogram array - memset(histo, 0, 256 * sizeof(DWORD)); - - switch(channel) { - case FICC_RED: - // compute histogram for red channel - for(y = 0; y < height; y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < width; x++) { - pixel = bits[FI_RGBA_RED]; // R - histo[pixel]++; - bits += bytespp; - } - } - return TRUE; - - case FICC_GREEN: - // compute histogram for green channel - for(y = 0; y < height; y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < width; x++) { - pixel = bits[FI_RGBA_GREEN]; // G - histo[pixel]++; - bits += bytespp; - } - } - return TRUE; - - case FICC_BLUE: - // compute histogram for blue channel - for(y = 0; y < height; y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < width; x++) { - pixel = bits[FI_RGBA_BLUE]; // B - histo[pixel]++; - bits += bytespp; - } - } - return TRUE; - - case FICC_BLACK: - case FICC_RGB: - // compute histogram for black channel - for(y = 0; y < height; y++) { - bits = FreeImage_GetScanLine(src, y); - for(x = 0; x < width; x++) { - // RGB to GREY conversion - pixel = GREY(bits[FI_RGBA_RED], bits[FI_RGBA_GREEN], bits[FI_RGBA_BLUE]); - histo[pixel]++; - bits += bytespp; - } - } - return TRUE; - - default: - return FALSE; - } - } - - return FALSE; -} - -// ---------------------------------------------------------- - - -/** @brief Creates a lookup table to be used with FreeImage_AdjustCurve() which - may adjust brightness and contrast, correct gamma and invert the image with a - single call to FreeImage_AdjustCurve(). - - This function creates a lookup table to be used with FreeImage_AdjustCurve() - which may adjust brightness and contrast, correct gamma and invert the image - with a single call to FreeImage_AdjustCurve(). If more than one of these image - display properties need to be adjusted, using a combined lookup table should be - preferred over calling each adjustment function separately. That's particularly - true for huge images or if performance is an issue. Then, the expensive process - of iterating over all pixels of an image is performed only once and not up to - four times. - - Furthermore, the lookup table created does not depend on the order, in which - each single adjustment operation is performed. Due to rounding and byte casting - issues, it actually matters in which order individual adjustment operations - are performed. Both of the following snippets most likely produce different - results: - - // snippet 1: contrast, brightness - FreeImage_AdjustContrast(dib, 15.0); - FreeImage_AdjustBrightness(dib, 50.0); - - // snippet 2: brightness, contrast - FreeImage_AdjustBrightness(dib, 50.0); - FreeImage_AdjustContrast(dib, 15.0); - - Better and even faster would be snippet 3: - - // snippet 3: - BYTE LUT[256]; - FreeImage_GetAdjustColorsLookupTable(LUT, 50.0, 15.0, 1.0, FALSE); - FreeImage_AdjustCurve(dib, LUT, FICC_RGB); - - This function is also used internally by FreeImage_AdjustColors(), which does - not return the lookup table, but uses it to call FreeImage_AdjustCurve() on the - passed image. - - @param LUT Output lookup table to be used with FreeImage_AdjustCurve(). <b>The - size of 'LUT' is assumed to be 256.</b> - @param brightness Percentage brightness value where -100 <= brightness <= 100<br> - A value of 0 means no change, less than 0 will make the image darker and greater - than 0 will make the image brighter. - @param contrast Percentage contrast value where -100 <= contrast <= 100<br> - A value of 0 means no change, less than 0 will decrease the contrast - and greater than 0 will increase the contrast of the image. - @param gamma Gamma value to be used for gamma correction. A value of 1.0 leaves - the image alone, less than one darkens it, and greater than one lightens it. - This parameter must not be zero or smaller than zero. If so, it will be ignored - and no gamma correction will be performed using the lookup table created. - @param invert If set to TRUE, the image will be inverted. - @return Returns the number of adjustments applied to the resulting lookup table - compared to a blind lookup table. - */ -int DLL_CALLCONV -FreeImage_GetAdjustColorsLookupTable(BYTE *LUT, double brightness, double contrast, double gamma, BOOL invert) { - double dblLUT[256]; - double value; - int result = 0; - - if ((brightness == 0.0) && (contrast == 0.0) && (gamma == 1.0) && (!invert)) { - // nothing to do, if all arguments have their default values - // return a blind LUT - for (int i = 0; i < 256; i++) { - LUT[i] = (BYTE)i; - } - return 0; - } - - // first, create a blind LUT, which does nothing to the image - for (int i = 0; i < 256; i++) { - dblLUT[i] = i; - } - - if (contrast != 0.0) { - // modify lookup table with contrast adjustment data - const double v = (100.0 + contrast) / 100.0; - for (int i = 0; i < 256; i++) { - value = 128 + (dblLUT[i] - 128) * v; - dblLUT[i] = MAX(0.0, MIN(value, 255.0)); - } - result++; - } - - if (brightness != 0.0) { - // modify lookup table with brightness adjustment data - const double v = (100.0 + brightness) / 100.0; - for (int i = 0; i < 256; i++) { - value = dblLUT[i] * v; - dblLUT[i] = MAX(0.0, MIN(value, 255.0)); - } - result++; - } - - if ((gamma > 0) && (gamma != 1.0)) { - // modify lookup table with gamma adjustment data - double exponent = 1 / gamma; - const double v = 255.0 * (double)pow((double)255, -exponent); - for (int i = 0; i < 256; i++) { - value = pow(dblLUT[i], exponent) * v; - dblLUT[i] = MAX(0.0, MIN(value, 255.0)); - } - result++; - } - - if (!invert) { - for (int i = 0; i < 256; i++) { - LUT[i] = (BYTE)floor(dblLUT[i] + 0.5); - } - } else { - for (int i = 0; i < 256; i++) { - LUT[i] = 255 - (BYTE)floor(dblLUT[i] + 0.5); - } - result++; - } - // return the number of adjustments made - return result; -} - -/** @brief Adjusts an image's brightness, contrast and gamma as well as it may - optionally invert the image within a single operation. - - This function adjusts an image's brightness, contrast and gamma as well as it - may optionally invert the image within a single operation. If more than one of - these image display properties need to be adjusted, using this function should - be preferred over calling each adjustment function separately. That's - particularly true for huge images or if performance is an issue. - - This function relies on FreeImage_GetAdjustColorsLookupTable(), which creates a - single lookup table, that combines all adjustment operations requested. - - Furthermore, the lookup table created by FreeImage_GetAdjustColorsLookupTable() - does not depend on the order, in which each single adjustment operation is - performed. Due to rounding and byte casting issues, it actually matters in which - order individual adjustment operations are performed. Both of the following - snippets most likely produce different results: - - // snippet 1: contrast, brightness - FreeImage_AdjustContrast(dib, 15.0); - FreeImage_AdjustBrightness(dib, 50.0); - - // snippet 2: brightness, contrast - FreeImage_AdjustBrightness(dib, 50.0); - FreeImage_AdjustContrast(dib, 15.0); - - Better and even faster would be snippet 3: - - // snippet 3: - FreeImage_AdjustColors(dib, 50.0, 15.0, 1.0, FALSE); - - @param dib Input/output image to be processed. - @param brightness Percentage brightness value where -100 <= brightness <= 100<br> - A value of 0 means no change, less than 0 will make the image darker and greater - than 0 will make the image brighter. - @param contrast Percentage contrast value where -100 <= contrast <= 100<br> - A value of 0 means no change, less than 0 will decrease the contrast - and greater than 0 will increase the contrast of the image. - @param gamma Gamma value to be used for gamma correction. A value of 1.0 leaves - the image alone, less than one darkens it, and greater than one lightens it.<br> - This parameter must not be zero or smaller than zero. If so, it will be ignored - and no gamma correction will be performed on the image. - @param invert If set to TRUE, the image will be inverted. - @return Returns TRUE on success, FALSE otherwise (e.g. when the bitdeph of the - source dib cannot be handled). - */ -BOOL DLL_CALLCONV -FreeImage_AdjustColors(FIBITMAP *dib, double brightness, double contrast, double gamma, BOOL invert) { - BYTE LUT[256]; - - if (!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) { - return FALSE; - } - - int bpp = FreeImage_GetBPP(dib); - if ((bpp != 8) && (bpp != 24) && (bpp != 32)) { - return FALSE; - } - - if (FreeImage_GetAdjustColorsLookupTable(LUT, brightness, contrast, gamma, invert)) { - return FreeImage_AdjustCurve(dib, LUT, FICC_RGB); - } - return FALSE; -} - -/** @brief Applies color mapping for one or several colors on a 1-, 4- or 8-bit - palletized or a 16-, 24- or 32-bit high color image. - - This function maps up to <i>count</i> colors specified in <i>srccolors</i> to - these specified in <i>dstcolors</i>. Thereby, color <i>srccolors[N]</i>, - if found in the image, will be replaced by color <i>dstcolors[N]</i>. If - parameter <i>swap</i> is TRUE, additionally all colors specified in - <i>dstcolors</i> are also mapped to these specified in <i>srccolors</i>. For - high color images, the actual image data will be modified whereas, for - palletized images only the palette will be changed.<br> - - The function returns the number of pixels changed or zero, if no pixels were - changed. - - Both arrays <i>srccolors</i> and <i>dstcolors</i> are assumed not to hold less - than <i>count</i> colors.<br> - - For 16-bit images, all colors specified are transparently converted to their - proper 16-bit representation (either in RGB555 or RGB565 format, which is - determined by the image's red- green- and blue-mask).<br> - - <b>Note, that this behaviour is different from what FreeImage_ApplyPaletteIndexMapping() - does, which modifies the actual image data on palletized images.</b> - - @param dib Input/output image to be processed. - @param srccolors Array of colors to be used as the mapping source. - @param dstcolors Array of colors to be used as the mapping destination. - @param count The number of colors to be mapped. This is the size of both - <i>srccolors</i> and <i>dstcolors</i>. - @param ignore_alpha If TRUE, 32-bit images and colors are treated as 24-bit. - @param swap If TRUE, source and destination colors are swapped, that is, - each destination color is also mapped to the corresponding source color. - @return Returns the total number of pixels changed. - */ -unsigned DLL_CALLCONV -FreeImage_ApplyColorMapping(FIBITMAP *dib, RGBQUAD *srccolors, RGBQUAD *dstcolors, unsigned count, BOOL ignore_alpha, BOOL swap) { - unsigned result = 0; - - if (!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) { - return 0; - } - - // validate parameters - if ((!srccolors) || (!dstcolors)|| (count < 1)) { - return 0; - } - - int bpp = FreeImage_GetBPP(dib); - switch (bpp) { - case 1: - case 4: - case 8: { - unsigned size = FreeImage_GetColorsUsed(dib); - RGBQUAD *pal = FreeImage_GetPalette(dib); - RGBQUAD *a, *b; - for (unsigned x = 0; x < size; x++) { - for (unsigned j = 0; j < count; j++) { - a = srccolors; - b = dstcolors; - for (int i = (swap ? 0 : 1); i < 2; i++) { - if ((pal[x].rgbBlue == a[j].rgbBlue)&&(pal[x].rgbGreen == a[j].rgbGreen) &&(pal[x].rgbRed== a[j].rgbRed)) { - pal[x].rgbBlue = b[j].rgbBlue; - pal[x].rgbGreen = b[j].rgbGreen; - pal[x].rgbRed = b[j].rgbRed; - result++; - j = count; - break; - } - a = dstcolors; - b = srccolors; - } - } - } - return result; - } - case 16: { - WORD *src16 = (WORD *)malloc(sizeof(WORD) * count); - if (NULL == src16) { - return 0; - } - - WORD *dst16 = (WORD *)malloc(sizeof(WORD) * count); - if (NULL == dst16) { - free(src16); - return 0; - } - - for (unsigned j = 0; j < count; j++) { - src16[j] = RGBQUAD_TO_WORD(dib, (srccolors + j)); - dst16[j] = RGBQUAD_TO_WORD(dib, (dstcolors + j)); - } - - unsigned height = FreeImage_GetHeight(dib); - unsigned width = FreeImage_GetWidth(dib); - WORD *a, *b; - for (unsigned y = 0; y < height; y++) { - WORD *bits = (WORD *)FreeImage_GetScanLine(dib, y); - for (unsigned x = 0; x < width; x++, bits++) { - for (unsigned j = 0; j < count; j++) { - a = src16; - b = dst16; - for (int i = (swap ? 0 : 1); i < 2; i++) { - if (*bits == a[j]) { - *bits = b[j]; - result++; - j = count; - break; - } - a = dst16; - b = src16; - } - } - } - } - free(src16); - free(dst16); - return result; - } - case 24: { - unsigned height = FreeImage_GetHeight(dib); - unsigned width = FreeImage_GetWidth(dib); - RGBQUAD *a, *b; - for (unsigned y = 0; y < height; y++) { - BYTE *bits = FreeImage_GetScanLine(dib, y); - for (unsigned x = 0; x < width; x++, bits += 3) { - for (unsigned j = 0; j < count; j++) { - a = srccolors; - b = dstcolors; - for (int i = (swap ? 0 : 1); i < 2; i++) { - if ((bits[FI_RGBA_BLUE] == a[j].rgbBlue) && (bits[FI_RGBA_GREEN] == a[j].rgbGreen) &&(bits[FI_RGBA_RED] == a[j].rgbRed)) { - bits[FI_RGBA_BLUE] = b[j].rgbBlue; - bits[FI_RGBA_GREEN] = b[j].rgbGreen; - bits[FI_RGBA_RED] = b[j].rgbRed; - result++; - j = count; - break; - } - a = dstcolors; - b = srccolors; - } - } - } - } - return result; - } - case 32: { - unsigned height = FreeImage_GetHeight(dib); - unsigned width = FreeImage_GetWidth(dib); - RGBQUAD *a, *b; - for (unsigned y = 0; y < height; y++) { - BYTE *bits = FreeImage_GetScanLine(dib, y); - for (unsigned x = 0; x < width; x++, bits += 4) { - for (unsigned j = 0; j < count; j++) { - a = srccolors; - b = dstcolors; - for (int i = (swap ? 0 : 1); i < 2; i++) { - if ((bits[FI_RGBA_BLUE] == a[j].rgbBlue) &&(bits[FI_RGBA_GREEN] == a[j].rgbGreen) &&(bits[FI_RGBA_RED] == a[j].rgbRed) - &&((ignore_alpha) || (bits[FI_RGBA_ALPHA] == a[j].rgbReserved))) { - bits[FI_RGBA_BLUE] = b[j].rgbBlue; - bits[FI_RGBA_GREEN] = b[j].rgbGreen; - bits[FI_RGBA_RED] = b[j].rgbRed; - if (!ignore_alpha) { - bits[FI_RGBA_ALPHA] = b[j].rgbReserved; - } - result++; - j = count; - break; - } - a = dstcolors; - b = srccolors; - } - } - } - } - return result; - } - default: { - return 0; - } - } -} - -/** @brief Swaps two specified colors on a 1-, 4- or 8-bit palletized - or a 16-, 24- or 32-bit high color image. - - This function swaps the two specified colors <i>color_a</i> and <i>color_b</i> - on a palletized or high color image. For high color images, the actual image - data will be modified whereas, for palletized images only the palette will be - changed.<br> - - <b>Note, that this behaviour is different from what FreeImage_SwapPaletteIndices() - does, which modifies the actual image data on palletized images.</b><br> - - This is just a thin wrapper for FreeImage_ApplyColorMapping() and resolves to:<br> - <i>return FreeImage_ApplyColorMapping(dib, color_a, color_b, 1, ignore_alpha, TRUE);</i> - - @param dib Input/output image to be processed. - @param color_a On of the two colors to be swapped. - @param color_b The other of the two colors to be swapped. - @param ignore_alpha If TRUE, 32-bit images and colors are treated as 24-bit. - @return Returns the total number of pixels changed. - */ -unsigned DLL_CALLCONV -FreeImage_SwapColors(FIBITMAP *dib, RGBQUAD *color_a, RGBQUAD *color_b, BOOL ignore_alpha) { - return FreeImage_ApplyColorMapping(dib, color_a, color_b, 1, ignore_alpha, TRUE); -} - -/** @brief Applies palette index mapping for one or several indices on a 1-, 4- - or 8-bit palletized image. - - This function maps up to <i>count</i> palette indices specified in - <i>srcindices</i> to these specified in <i>dstindices</i>. Thereby, index - <i>srcindices[N]</i>, if present in the image, will be replaced by index - <i>dstindices[N]</i>. If parameter <i>swap</i> is TRUE, additionally all indices - specified in <i>dstindices</i> are also mapped to these specified in - <i>srcindices</i>.<br> - - The function returns the number of pixels changed or zero, if no pixels were - changed. - - Both arrays <i>srcindices</i> and <i>dstindices</i> are assumed not to hold less - than <i>count</i> indices.<br> - - <b>Note, that this behaviour is different from what FreeImage_ApplyColorMapping() - does, which modifies the actual image data on palletized images.</b> - - @param dib Input/output image to be processed. - @param srcindices Array of palette indices to be used as the mapping source. - @param dstindices Array of palette indices to be used as the mapping destination. - @param count The number of palette indices to be mapped. This is the size of both - <i>srcindices</i> and <i>dstindices</i>. - @param swap If TRUE, source and destination palette indices are swapped, that is, - each destination index is also mapped to the corresponding source index. - @return Returns the total number of pixels changed. - */ -unsigned DLL_CALLCONV -FreeImage_ApplyPaletteIndexMapping(FIBITMAP *dib, BYTE *srcindices, BYTE *dstindices, unsigned count, BOOL swap) { - unsigned result = 0; - - if (!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) { - return 0; - } - - // validate parameters - if ((!srcindices) || (!dstindices)|| (count < 1)) { - return 0; - } - - unsigned height = FreeImage_GetHeight(dib); - unsigned width = FreeImage_GetLine(dib); - BYTE *a, *b; - - int bpp = FreeImage_GetBPP(dib); - switch (bpp) { - case 1: { - - return result; - } - case 4: { - int skip_last = (FreeImage_GetWidth(dib) & 0x01); - unsigned max_x = width - 1; - for (unsigned y = 0; y < height; y++) { - BYTE *bits = FreeImage_GetScanLine(dib, y); - for (unsigned x = 0; x < width; x++) { - int start = ((skip_last) && (x == max_x)) ? 1 : 0; - for (int cn = start; cn < 2; cn++) { - for (unsigned j = 0; j < count; j++) { - a = srcindices; - b = dstindices; - for (int i = ((swap) ? 0 : 1); i < 2; i++) { - if (GET_NIBBLE(cn, bits[x]) == (a[j] & 0x0F)) { - SET_NIBBLE(cn, bits[x], b[j]); - result++; - j = count; - break; - } - a = dstindices; - b = srcindices; - } - } - } - } - } - return result; - } - case 8: { - for (unsigned y = 0; y < height; y++) { - BYTE *bits = FreeImage_GetScanLine(dib, y); - for (unsigned x = 0; x < width; x++) { - for (unsigned j = 0; j < count; j++) { - a = srcindices; - b = dstindices; - for (int i = ((swap) ? 0 : 1); i < 2; i++) { - if (bits[x] == a[j]) { - bits[x] = b[j]; - result++; - j = count; - break; - } - a = dstindices; - b = srcindices; - } - } - } - } - return result; - } - default: { - return 0; - } - } -} - -/** @brief Swaps two specified palette indices on a 1-, 4- or 8-bit palletized - image. - - This function swaps the two specified palette indices <i>index_a</i> and - <i>index_b</i> on a palletized image. Therefore, not the palette, but the - actual image data will be modified.<br> - - <b>Note, that this behaviour is different from what FreeImage_SwapColors() does - on palletized images, which only swaps the colors in the palette.</b><br> - - This is just a thin wrapper for FreeImage_ApplyColorMapping() and resolves to:<br> - <i>return FreeImage_ApplyPaletteIndexMapping(dib, index_a, index_b, 1, TRUE);</i> - - @param dib Input/output image to be processed. - @param index_a On of the two palette indices to be swapped. - @param index_b The other of the two palette indices to be swapped. - @return Returns the total number of pixels changed. - */ -unsigned DLL_CALLCONV -FreeImage_SwapPaletteIndices(FIBITMAP *dib, BYTE *index_a, BYTE *index_b) { - return FreeImage_ApplyPaletteIndexMapping(dib, index_a, index_b, 1, TRUE); -} - |