summaryrefslogtreecommitdiff
path: root/plugins/FreeImage/Source/FreeImageToolkit/Channels.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/FreeImage/Source/FreeImageToolkit/Channels.cpp')
-rw-r--r--plugins/FreeImage/Source/FreeImageToolkit/Channels.cpp976
1 files changed, 488 insertions, 488 deletions
diff --git a/plugins/FreeImage/Source/FreeImageToolkit/Channels.cpp b/plugins/FreeImage/Source/FreeImageToolkit/Channels.cpp
index 36475f5aba..5f01ad815f 100644
--- a/plugins/FreeImage/Source/FreeImageToolkit/Channels.cpp
+++ b/plugins/FreeImage/Source/FreeImageToolkit/Channels.cpp
@@ -1,488 +1,488 @@
-// ==========================================================
-// Channel processing support
-//
-// 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"
-
-
-/** @brief Retrieves the red, green, blue or alpha channel of a BGR[A] image.
-@param src Input image to be processed.
-@param channel Color channel to extract
-@return Returns the extracted channel if successful, returns NULL otherwise.
-*/
-FIBITMAP * DLL_CALLCONV
-FreeImage_GetChannel(FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
-
- if(!FreeImage_HasPixels(src)) return NULL;
-
- FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(src);
- unsigned bpp = FreeImage_GetBPP(src);
-
- // 24- or 32-bit
- if(image_type == FIT_BITMAP && ((bpp == 24) || (bpp == 32))) {
- int c;
-
- // select the channel to extract
- switch(channel) {
- case FICC_BLUE:
- c = FI_RGBA_BLUE;
- break;
- case FICC_GREEN:
- c = FI_RGBA_GREEN;
- break;
- case FICC_RED:
- c = FI_RGBA_RED;
- break;
- case FICC_ALPHA:
- if(bpp != 32) return NULL;
- c = FI_RGBA_ALPHA;
- break;
- default:
- return NULL;
- }
-
- // allocate a 8-bit dib
- unsigned width = FreeImage_GetWidth(src);
- unsigned height = FreeImage_GetHeight(src);
- FIBITMAP *dst = FreeImage_Allocate(width, height, 8) ;
- if(!dst) return NULL;
- // build a greyscale palette
- RGBQUAD *pal = FreeImage_GetPalette(dst);
- for(int i = 0; i < 256; i++) {
- pal[i].rgbBlue = pal[i].rgbGreen = pal[i].rgbRed = (BYTE)i;
- }
-
- // perform extraction
-
- int bytespp = bpp / 8; // bytes / pixel
-
- for(unsigned y = 0; y < height; y++) {
- BYTE *src_bits = FreeImage_GetScanLine(src, y);
- BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- dst_bits[x] = src_bits[c];
- src_bits += bytespp;
- }
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- return dst;
- }
-
- // 48-bit RGB or 64-bit RGBA images
- if((image_type == FIT_RGB16) || (image_type == FIT_RGBA16)) {
- int c;
-
- // select the channel to extract (always RGB[A])
- switch(channel) {
- case FICC_BLUE:
- c = 2;
- break;
- case FICC_GREEN:
- c = 1;
- break;
- case FICC_RED:
- c = 0;
- break;
- case FICC_ALPHA:
- if(bpp != 64) return NULL;
- c = 3;
- break;
- default:
- return NULL;
- }
-
- // allocate a greyscale dib
- unsigned width = FreeImage_GetWidth(src);
- unsigned height = FreeImage_GetHeight(src);
- FIBITMAP *dst = FreeImage_AllocateT(FIT_UINT16, width, height) ;
- if(!dst) return NULL;
-
- // perform extraction
-
- int bytespp = bpp / 16; // words / pixel
-
- for(unsigned y = 0; y < height; y++) {
- unsigned short *src_bits = (unsigned short*)FreeImage_GetScanLine(src, y);
- unsigned short *dst_bits = (unsigned short*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- dst_bits[x] = src_bits[c];
- src_bits += bytespp;
- }
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- return dst;
- }
-
- // 96-bit RGBF or 128-bit RGBAF images
- if((image_type == FIT_RGBF) || (image_type == FIT_RGBAF)) {
- int c;
-
- // select the channel to extract (always RGB[A])
- switch(channel) {
- case FICC_BLUE:
- c = 2;
- break;
- case FICC_GREEN:
- c = 1;
- break;
- case FICC_RED:
- c = 0;
- break;
- case FICC_ALPHA:
- if(bpp != 128) return NULL;
- c = 3;
- break;
- default:
- return NULL;
- }
-
- // allocate a greyscale dib
- unsigned width = FreeImage_GetWidth(src);
- unsigned height = FreeImage_GetHeight(src);
- FIBITMAP *dst = FreeImage_AllocateT(FIT_FLOAT, width, height) ;
- if(!dst) return NULL;
-
- // perform extraction
-
- int bytespp = bpp / 32; // floats / pixel
-
- for(unsigned y = 0; y < height; y++) {
- float *src_bits = (float*)FreeImage_GetScanLine(src, y);
- float *dst_bits = (float*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < width; x++) {
- dst_bits[x] = src_bits[c];
- src_bits += bytespp;
- }
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- return dst;
- }
-
- return NULL;
-}
-
-/** @brief Insert a greyscale dib into a RGB[A] image.
-Both src and dst must have the same width and height.
-@param dst Image to modify (RGB or RGBA)
-@param src Input greyscale image to insert
-@param channel Color channel to modify
-@return Returns TRUE if successful, FALSE otherwise.
-*/
-BOOL DLL_CALLCONV
-FreeImage_SetChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
- int c;
-
- if(!FreeImage_HasPixels(src) || !FreeImage_HasPixels(dst)) return FALSE;
-
- // src and dst images should have the same width and height
- unsigned src_width = FreeImage_GetWidth(src);
- unsigned src_height = FreeImage_GetHeight(src);
- unsigned dst_width = FreeImage_GetWidth(dst);
- unsigned dst_height = FreeImage_GetHeight(dst);
- if((src_width != dst_width) || (src_height != dst_height))
- return FALSE;
-
- // src image should be grayscale, dst image should be RGB or RGBA
- FREE_IMAGE_COLOR_TYPE src_type = FreeImage_GetColorType(src);
- FREE_IMAGE_COLOR_TYPE dst_type = FreeImage_GetColorType(dst);
- if((dst_type != FIC_RGB) && (dst_type != FIC_RGBALPHA) || (src_type != FIC_MINISBLACK)) {
- return FALSE;
- }
-
- FREE_IMAGE_TYPE src_image_type = FreeImage_GetImageType(src);
- FREE_IMAGE_TYPE dst_image_type = FreeImage_GetImageType(dst);
-
- if((dst_image_type == FIT_BITMAP) && (src_image_type == FIT_BITMAP)) {
-
- // src image should be grayscale, dst image should be 24- or 32-bit
- unsigned src_bpp = FreeImage_GetBPP(src);
- unsigned dst_bpp = FreeImage_GetBPP(dst);
- if((src_bpp != 8) || (dst_bpp != 24) && (dst_bpp != 32))
- return FALSE;
-
-
- // select the channel to modify
- switch(channel) {
- case FICC_BLUE:
- c = FI_RGBA_BLUE;
- break;
- case FICC_GREEN:
- c = FI_RGBA_GREEN;
- break;
- case FICC_RED:
- c = FI_RGBA_RED;
- break;
- case FICC_ALPHA:
- if(dst_bpp != 32) return FALSE;
- c = FI_RGBA_ALPHA;
- break;
- default:
- return FALSE;
- }
-
- // perform insertion
-
- int bytespp = dst_bpp / 8; // bytes / pixel
-
- for(unsigned y = 0; y < dst_height; y++) {
- BYTE *src_bits = FreeImage_GetScanLine(src, y);
- BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < dst_width; x++) {
- dst_bits[c] = src_bits[x];
- dst_bits += bytespp;
- }
- }
-
- return TRUE;
- }
-
- if(((dst_image_type == FIT_RGB16) || (dst_image_type == FIT_RGBA16)) && (src_image_type == FIT_UINT16)) {
-
- // src image should be grayscale, dst image should be 48- or 64-bit
- unsigned src_bpp = FreeImage_GetBPP(src);
- unsigned dst_bpp = FreeImage_GetBPP(dst);
- if((src_bpp != 16) || (dst_bpp != 48) && (dst_bpp != 64))
- return FALSE;
-
-
- // select the channel to modify (always RGB[A])
- switch(channel) {
- case FICC_BLUE:
- c = 2;
- break;
- case FICC_GREEN:
- c = 1;
- break;
- case FICC_RED:
- c = 0;
- break;
- case FICC_ALPHA:
- if(dst_bpp != 64) return FALSE;
- c = 3;
- break;
- default:
- return FALSE;
- }
-
- // perform insertion
-
- int bytespp = dst_bpp / 16; // words / pixel
-
- for(unsigned y = 0; y < dst_height; y++) {
- unsigned short *src_bits = (unsigned short*)FreeImage_GetScanLine(src, y);
- unsigned short *dst_bits = (unsigned short*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < dst_width; x++) {
- dst_bits[c] = src_bits[x];
- dst_bits += bytespp;
- }
- }
-
- return TRUE;
- }
-
- if(((dst_image_type == FIT_RGBF) || (dst_image_type == FIT_RGBAF)) && (src_image_type == FIT_FLOAT)) {
-
- // src image should be grayscale, dst image should be 96- or 128-bit
- unsigned src_bpp = FreeImage_GetBPP(src);
- unsigned dst_bpp = FreeImage_GetBPP(dst);
- if((src_bpp != 32) || (dst_bpp != 96) && (dst_bpp != 128))
- return FALSE;
-
-
- // select the channel to modify (always RGB[A])
- switch(channel) {
- case FICC_BLUE:
- c = 2;
- break;
- case FICC_GREEN:
- c = 1;
- break;
- case FICC_RED:
- c = 0;
- break;
- case FICC_ALPHA:
- if(dst_bpp != 128) return FALSE;
- c = 3;
- break;
- default:
- return FALSE;
- }
-
- // perform insertion
-
- int bytespp = dst_bpp / 32; // floats / pixel
-
- for(unsigned y = 0; y < dst_height; y++) {
- float *src_bits = (float*)FreeImage_GetScanLine(src, y);
- float *dst_bits = (float*)FreeImage_GetScanLine(dst, y);
- for(unsigned x = 0; x < dst_width; x++) {
- dst_bits[c] = src_bits[x];
- dst_bits += bytespp;
- }
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-/** @brief Retrieves the real part, imaginary part, magnitude or phase of a complex image.
-@param src Input image to be processed.
-@param channel Channel to extract
-@return Returns the extracted channel if successful, returns NULL otherwise.
-*/
-FIBITMAP * DLL_CALLCONV
-FreeImage_GetComplexChannel(FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
- unsigned x, y;
- double mag, phase;
- FICOMPLEX *src_bits = NULL;
- double *dst_bits = NULL;
- FIBITMAP *dst = NULL;
-
- if(!FreeImage_HasPixels(src)) return NULL;
-
- if(FreeImage_GetImageType(src) == FIT_COMPLEX) {
- // allocate a dib of type FIT_DOUBLE
- unsigned width = FreeImage_GetWidth(src);
- unsigned height = FreeImage_GetHeight(src);
- dst = FreeImage_AllocateT(FIT_DOUBLE, width, height) ;
- if(!dst) return NULL;
-
- // perform extraction
-
- switch(channel) {
- case FICC_REAL: // real part
- for(y = 0; y < height; y++) {
- src_bits = (FICOMPLEX *)FreeImage_GetScanLine(src, y);
- dst_bits = (double *)FreeImage_GetScanLine(dst, y);
- for(x = 0; x < width; x++) {
- dst_bits[x] = src_bits[x].r;
- }
- }
- break;
-
- case FICC_IMAG: // imaginary part
- for(y = 0; y < height; y++) {
- src_bits = (FICOMPLEX *)FreeImage_GetScanLine(src, y);
- dst_bits = (double *)FreeImage_GetScanLine(dst, y);
- for(x = 0; x < width; x++) {
- dst_bits[x] = src_bits[x].i;
- }
- }
- break;
-
- case FICC_MAG: // magnitude
- for(y = 0; y < height; y++) {
- src_bits = (FICOMPLEX *)FreeImage_GetScanLine(src, y);
- dst_bits = (double *)FreeImage_GetScanLine(dst, y);
- for(x = 0; x < width; x++) {
- mag = src_bits[x].r * src_bits[x].r + src_bits[x].i * src_bits[x].i;
- dst_bits[x] = sqrt(mag);
- }
- }
- break;
-
- case FICC_PHASE: // phase
- for(y = 0; y < height; y++) {
- src_bits = (FICOMPLEX *)FreeImage_GetScanLine(src, y);
- dst_bits = (double *)FreeImage_GetScanLine(dst, y);
- for(x = 0; x < width; x++) {
- if((src_bits[x].r == 0) && (src_bits[x].i == 0)) {
- phase = 0;
- } else {
- phase = atan2(src_bits[x].i, src_bits[x].r);
- }
- dst_bits[x] = phase;
- }
- }
- break;
- }
- }
-
- // copy metadata from src to dst
- FreeImage_CloneMetadata(dst, src);
-
- return dst;
-}
-
-/** @brief Set the real or imaginary part of a complex image.
-Both src and dst must have the same width and height.
-@param dst Image to modify (image of type FIT_COMPLEX)
-@param src Input image of type FIT_DOUBLE
-@param channel Channel to modify
-@return Returns TRUE if successful, FALSE otherwise.
-*/
-BOOL DLL_CALLCONV
-FreeImage_SetComplexChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
- unsigned x, y;
- double *src_bits = NULL;
- FICOMPLEX *dst_bits = NULL;
-
- if(!FreeImage_HasPixels(src) || !FreeImage_HasPixels(dst)) return FALSE;
-
- // src image should be of type FIT_DOUBLE, dst image should be of type FIT_COMPLEX
- const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(src);
- const FREE_IMAGE_TYPE dst_type = FreeImage_GetImageType(dst);
- if((src_type != FIT_DOUBLE) || (dst_type != FIT_COMPLEX))
- return FALSE;
-
- // src and dst images should have the same width and height
- unsigned src_width = FreeImage_GetWidth(src);
- unsigned src_height = FreeImage_GetHeight(src);
- unsigned dst_width = FreeImage_GetWidth(dst);
- unsigned dst_height = FreeImage_GetHeight(dst);
- if((src_width != dst_width) || (src_height != dst_height))
- return FALSE;
-
- // select the channel to modify
- switch(channel) {
- case FICC_REAL: // real part
- for(y = 0; y < dst_height; y++) {
- src_bits = (double *)FreeImage_GetScanLine(src, y);
- dst_bits = (FICOMPLEX *)FreeImage_GetScanLine(dst, y);
- for(x = 0; x < dst_width; x++) {
- dst_bits[x].r = src_bits[x];
- }
- }
- break;
- case FICC_IMAG: // imaginary part
- for(y = 0; y < dst_height; y++) {
- src_bits = (double *)FreeImage_GetScanLine(src, y);
- dst_bits = (FICOMPLEX *)FreeImage_GetScanLine(dst, y);
- for(x = 0; x < dst_width; x++) {
- dst_bits[x].i = src_bits[x];
- }
- }
- break;
- }
-
- return TRUE;
-}
+// ==========================================================
+// Channel processing support
+//
+// 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"
+
+
+/** @brief Retrieves the red, green, blue or alpha channel of a BGR[A] image.
+@param src Input image to be processed.
+@param channel Color channel to extract
+@return Returns the extracted channel if successful, returns NULL otherwise.
+*/
+FIBITMAP * DLL_CALLCONV
+FreeImage_GetChannel(FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
+
+ if(!FreeImage_HasPixels(src)) return NULL;
+
+ FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(src);
+ unsigned bpp = FreeImage_GetBPP(src);
+
+ // 24- or 32-bit
+ if(image_type == FIT_BITMAP && ((bpp == 24) || (bpp == 32))) {
+ int c;
+
+ // select the channel to extract
+ switch(channel) {
+ case FICC_BLUE:
+ c = FI_RGBA_BLUE;
+ break;
+ case FICC_GREEN:
+ c = FI_RGBA_GREEN;
+ break;
+ case FICC_RED:
+ c = FI_RGBA_RED;
+ break;
+ case FICC_ALPHA:
+ if(bpp != 32) return NULL;
+ c = FI_RGBA_ALPHA;
+ break;
+ default:
+ return NULL;
+ }
+
+ // allocate a 8-bit dib
+ unsigned width = FreeImage_GetWidth(src);
+ unsigned height = FreeImage_GetHeight(src);
+ FIBITMAP *dst = FreeImage_Allocate(width, height, 8) ;
+ if(!dst) return NULL;
+ // build a greyscale palette
+ RGBQUAD *pal = FreeImage_GetPalette(dst);
+ for(int i = 0; i < 256; i++) {
+ pal[i].rgbBlue = pal[i].rgbGreen = pal[i].rgbRed = (BYTE)i;
+ }
+
+ // perform extraction
+
+ int bytespp = bpp / 8; // bytes / pixel
+
+ for(unsigned y = 0; y < height; y++) {
+ BYTE *src_bits = FreeImage_GetScanLine(src, y);
+ BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+ for(unsigned x = 0; x < width; x++) {
+ dst_bits[x] = src_bits[c];
+ src_bits += bytespp;
+ }
+ }
+
+ // copy metadata from src to dst
+ FreeImage_CloneMetadata(dst, src);
+
+ return dst;
+ }
+
+ // 48-bit RGB or 64-bit RGBA images
+ if((image_type == FIT_RGB16) || (image_type == FIT_RGBA16)) {
+ int c;
+
+ // select the channel to extract (always RGB[A])
+ switch(channel) {
+ case FICC_BLUE:
+ c = 2;
+ break;
+ case FICC_GREEN:
+ c = 1;
+ break;
+ case FICC_RED:
+ c = 0;
+ break;
+ case FICC_ALPHA:
+ if(bpp != 64) return NULL;
+ c = 3;
+ break;
+ default:
+ return NULL;
+ }
+
+ // allocate a greyscale dib
+ unsigned width = FreeImage_GetWidth(src);
+ unsigned height = FreeImage_GetHeight(src);
+ FIBITMAP *dst = FreeImage_AllocateT(FIT_UINT16, width, height) ;
+ if(!dst) return NULL;
+
+ // perform extraction
+
+ int bytespp = bpp / 16; // words / pixel
+
+ for(unsigned y = 0; y < height; y++) {
+ unsigned short *src_bits = (unsigned short*)FreeImage_GetScanLine(src, y);
+ unsigned short *dst_bits = (unsigned short*)FreeImage_GetScanLine(dst, y);
+ for(unsigned x = 0; x < width; x++) {
+ dst_bits[x] = src_bits[c];
+ src_bits += bytespp;
+ }
+ }
+
+ // copy metadata from src to dst
+ FreeImage_CloneMetadata(dst, src);
+
+ return dst;
+ }
+
+ // 96-bit RGBF or 128-bit RGBAF images
+ if((image_type == FIT_RGBF) || (image_type == FIT_RGBAF)) {
+ int c;
+
+ // select the channel to extract (always RGB[A])
+ switch(channel) {
+ case FICC_BLUE:
+ c = 2;
+ break;
+ case FICC_GREEN:
+ c = 1;
+ break;
+ case FICC_RED:
+ c = 0;
+ break;
+ case FICC_ALPHA:
+ if(bpp != 128) return NULL;
+ c = 3;
+ break;
+ default:
+ return NULL;
+ }
+
+ // allocate a greyscale dib
+ unsigned width = FreeImage_GetWidth(src);
+ unsigned height = FreeImage_GetHeight(src);
+ FIBITMAP *dst = FreeImage_AllocateT(FIT_FLOAT, width, height) ;
+ if(!dst) return NULL;
+
+ // perform extraction
+
+ int bytespp = bpp / 32; // floats / pixel
+
+ for(unsigned y = 0; y < height; y++) {
+ float *src_bits = (float*)FreeImage_GetScanLine(src, y);
+ float *dst_bits = (float*)FreeImage_GetScanLine(dst, y);
+ for(unsigned x = 0; x < width; x++) {
+ dst_bits[x] = src_bits[c];
+ src_bits += bytespp;
+ }
+ }
+
+ // copy metadata from src to dst
+ FreeImage_CloneMetadata(dst, src);
+
+ return dst;
+ }
+
+ return NULL;
+}
+
+/** @brief Insert a greyscale dib into a RGB[A] image.
+Both src and dst must have the same width and height.
+@param dst Image to modify (RGB or RGBA)
+@param src Input greyscale image to insert
+@param channel Color channel to modify
+@return Returns TRUE if successful, FALSE otherwise.
+*/
+BOOL DLL_CALLCONV
+FreeImage_SetChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
+ int c;
+
+ if(!FreeImage_HasPixels(src) || !FreeImage_HasPixels(dst)) return FALSE;
+
+ // src and dst images should have the same width and height
+ unsigned src_width = FreeImage_GetWidth(src);
+ unsigned src_height = FreeImage_GetHeight(src);
+ unsigned dst_width = FreeImage_GetWidth(dst);
+ unsigned dst_height = FreeImage_GetHeight(dst);
+ if((src_width != dst_width) || (src_height != dst_height))
+ return FALSE;
+
+ // src image should be grayscale, dst image should be RGB or RGBA
+ FREE_IMAGE_COLOR_TYPE src_type = FreeImage_GetColorType(src);
+ FREE_IMAGE_COLOR_TYPE dst_type = FreeImage_GetColorType(dst);
+ if((dst_type != FIC_RGB) && (dst_type != FIC_RGBALPHA) || (src_type != FIC_MINISBLACK)) {
+ return FALSE;
+ }
+
+ FREE_IMAGE_TYPE src_image_type = FreeImage_GetImageType(src);
+ FREE_IMAGE_TYPE dst_image_type = FreeImage_GetImageType(dst);
+
+ if((dst_image_type == FIT_BITMAP) && (src_image_type == FIT_BITMAP)) {
+
+ // src image should be grayscale, dst image should be 24- or 32-bit
+ unsigned src_bpp = FreeImage_GetBPP(src);
+ unsigned dst_bpp = FreeImage_GetBPP(dst);
+ if((src_bpp != 8) || (dst_bpp != 24) && (dst_bpp != 32))
+ return FALSE;
+
+
+ // select the channel to modify
+ switch(channel) {
+ case FICC_BLUE:
+ c = FI_RGBA_BLUE;
+ break;
+ case FICC_GREEN:
+ c = FI_RGBA_GREEN;
+ break;
+ case FICC_RED:
+ c = FI_RGBA_RED;
+ break;
+ case FICC_ALPHA:
+ if(dst_bpp != 32) return FALSE;
+ c = FI_RGBA_ALPHA;
+ break;
+ default:
+ return FALSE;
+ }
+
+ // perform insertion
+
+ int bytespp = dst_bpp / 8; // bytes / pixel
+
+ for(unsigned y = 0; y < dst_height; y++) {
+ BYTE *src_bits = FreeImage_GetScanLine(src, y);
+ BYTE *dst_bits = FreeImage_GetScanLine(dst, y);
+ for(unsigned x = 0; x < dst_width; x++) {
+ dst_bits[c] = src_bits[x];
+ dst_bits += bytespp;
+ }
+ }
+
+ return TRUE;
+ }
+
+ if(((dst_image_type == FIT_RGB16) || (dst_image_type == FIT_RGBA16)) && (src_image_type == FIT_UINT16)) {
+
+ // src image should be grayscale, dst image should be 48- or 64-bit
+ unsigned src_bpp = FreeImage_GetBPP(src);
+ unsigned dst_bpp = FreeImage_GetBPP(dst);
+ if((src_bpp != 16) || (dst_bpp != 48) && (dst_bpp != 64))
+ return FALSE;
+
+
+ // select the channel to modify (always RGB[A])
+ switch(channel) {
+ case FICC_BLUE:
+ c = 2;
+ break;
+ case FICC_GREEN:
+ c = 1;
+ break;
+ case FICC_RED:
+ c = 0;
+ break;
+ case FICC_ALPHA:
+ if(dst_bpp != 64) return FALSE;
+ c = 3;
+ break;
+ default:
+ return FALSE;
+ }
+
+ // perform insertion
+
+ int bytespp = dst_bpp / 16; // words / pixel
+
+ for(unsigned y = 0; y < dst_height; y++) {
+ unsigned short *src_bits = (unsigned short*)FreeImage_GetScanLine(src, y);
+ unsigned short *dst_bits = (unsigned short*)FreeImage_GetScanLine(dst, y);
+ for(unsigned x = 0; x < dst_width; x++) {
+ dst_bits[c] = src_bits[x];
+ dst_bits += bytespp;
+ }
+ }
+
+ return TRUE;
+ }
+
+ if(((dst_image_type == FIT_RGBF) || (dst_image_type == FIT_RGBAF)) && (src_image_type == FIT_FLOAT)) {
+
+ // src image should be grayscale, dst image should be 96- or 128-bit
+ unsigned src_bpp = FreeImage_GetBPP(src);
+ unsigned dst_bpp = FreeImage_GetBPP(dst);
+ if((src_bpp != 32) || (dst_bpp != 96) && (dst_bpp != 128))
+ return FALSE;
+
+
+ // select the channel to modify (always RGB[A])
+ switch(channel) {
+ case FICC_BLUE:
+ c = 2;
+ break;
+ case FICC_GREEN:
+ c = 1;
+ break;
+ case FICC_RED:
+ c = 0;
+ break;
+ case FICC_ALPHA:
+ if(dst_bpp != 128) return FALSE;
+ c = 3;
+ break;
+ default:
+ return FALSE;
+ }
+
+ // perform insertion
+
+ int bytespp = dst_bpp / 32; // floats / pixel
+
+ for(unsigned y = 0; y < dst_height; y++) {
+ float *src_bits = (float*)FreeImage_GetScanLine(src, y);
+ float *dst_bits = (float*)FreeImage_GetScanLine(dst, y);
+ for(unsigned x = 0; x < dst_width; x++) {
+ dst_bits[c] = src_bits[x];
+ dst_bits += bytespp;
+ }
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** @brief Retrieves the real part, imaginary part, magnitude or phase of a complex image.
+@param src Input image to be processed.
+@param channel Channel to extract
+@return Returns the extracted channel if successful, returns NULL otherwise.
+*/
+FIBITMAP * DLL_CALLCONV
+FreeImage_GetComplexChannel(FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
+ unsigned x, y;
+ double mag, phase;
+ FICOMPLEX *src_bits = NULL;
+ double *dst_bits = NULL;
+ FIBITMAP *dst = NULL;
+
+ if(!FreeImage_HasPixels(src)) return NULL;
+
+ if(FreeImage_GetImageType(src) == FIT_COMPLEX) {
+ // allocate a dib of type FIT_DOUBLE
+ unsigned width = FreeImage_GetWidth(src);
+ unsigned height = FreeImage_GetHeight(src);
+ dst = FreeImage_AllocateT(FIT_DOUBLE, width, height) ;
+ if(!dst) return NULL;
+
+ // perform extraction
+
+ switch(channel) {
+ case FICC_REAL: // real part
+ for(y = 0; y < height; y++) {
+ src_bits = (FICOMPLEX *)FreeImage_GetScanLine(src, y);
+ dst_bits = (double *)FreeImage_GetScanLine(dst, y);
+ for(x = 0; x < width; x++) {
+ dst_bits[x] = src_bits[x].r;
+ }
+ }
+ break;
+
+ case FICC_IMAG: // imaginary part
+ for(y = 0; y < height; y++) {
+ src_bits = (FICOMPLEX *)FreeImage_GetScanLine(src, y);
+ dst_bits = (double *)FreeImage_GetScanLine(dst, y);
+ for(x = 0; x < width; x++) {
+ dst_bits[x] = src_bits[x].i;
+ }
+ }
+ break;
+
+ case FICC_MAG: // magnitude
+ for(y = 0; y < height; y++) {
+ src_bits = (FICOMPLEX *)FreeImage_GetScanLine(src, y);
+ dst_bits = (double *)FreeImage_GetScanLine(dst, y);
+ for(x = 0; x < width; x++) {
+ mag = src_bits[x].r * src_bits[x].r + src_bits[x].i * src_bits[x].i;
+ dst_bits[x] = sqrt(mag);
+ }
+ }
+ break;
+
+ case FICC_PHASE: // phase
+ for(y = 0; y < height; y++) {
+ src_bits = (FICOMPLEX *)FreeImage_GetScanLine(src, y);
+ dst_bits = (double *)FreeImage_GetScanLine(dst, y);
+ for(x = 0; x < width; x++) {
+ if((src_bits[x].r == 0) && (src_bits[x].i == 0)) {
+ phase = 0;
+ } else {
+ phase = atan2(src_bits[x].i, src_bits[x].r);
+ }
+ dst_bits[x] = phase;
+ }
+ }
+ break;
+ }
+ }
+
+ // copy metadata from src to dst
+ FreeImage_CloneMetadata(dst, src);
+
+ return dst;
+}
+
+/** @brief Set the real or imaginary part of a complex image.
+Both src and dst must have the same width and height.
+@param dst Image to modify (image of type FIT_COMPLEX)
+@param src Input image of type FIT_DOUBLE
+@param channel Channel to modify
+@return Returns TRUE if successful, FALSE otherwise.
+*/
+BOOL DLL_CALLCONV
+FreeImage_SetComplexChannel(FIBITMAP *dst, FIBITMAP *src, FREE_IMAGE_COLOR_CHANNEL channel) {
+ unsigned x, y;
+ double *src_bits = NULL;
+ FICOMPLEX *dst_bits = NULL;
+
+ if(!FreeImage_HasPixels(src) || !FreeImage_HasPixels(dst)) return FALSE;
+
+ // src image should be of type FIT_DOUBLE, dst image should be of type FIT_COMPLEX
+ const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(src);
+ const FREE_IMAGE_TYPE dst_type = FreeImage_GetImageType(dst);
+ if((src_type != FIT_DOUBLE) || (dst_type != FIT_COMPLEX))
+ return FALSE;
+
+ // src and dst images should have the same width and height
+ unsigned src_width = FreeImage_GetWidth(src);
+ unsigned src_height = FreeImage_GetHeight(src);
+ unsigned dst_width = FreeImage_GetWidth(dst);
+ unsigned dst_height = FreeImage_GetHeight(dst);
+ if((src_width != dst_width) || (src_height != dst_height))
+ return FALSE;
+
+ // select the channel to modify
+ switch(channel) {
+ case FICC_REAL: // real part
+ for(y = 0; y < dst_height; y++) {
+ src_bits = (double *)FreeImage_GetScanLine(src, y);
+ dst_bits = (FICOMPLEX *)FreeImage_GetScanLine(dst, y);
+ for(x = 0; x < dst_width; x++) {
+ dst_bits[x].r = src_bits[x];
+ }
+ }
+ break;
+ case FICC_IMAG: // imaginary part
+ for(y = 0; y < dst_height; y++) {
+ src_bits = (double *)FreeImage_GetScanLine(src, y);
+ dst_bits = (FICOMPLEX *)FreeImage_GetScanLine(dst, y);
+ for(x = 0; x < dst_width; x++) {
+ dst_bits[x].i = src_bits[x];
+ }
+ }
+ break;
+ }
+
+ return TRUE;
+}