Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImageToolkit/Channels.cpp view on Meta::CPAN
// ==========================================================
// 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);
src/Source/FreeImageToolkit/Channels.cpp view on Meta::CPAN
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)) {
( run in 1.166 second using v1.01-cache-2.11-cpan-ceb78f64989 )