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