911 lines
22 KiB
C++
911 lines
22 KiB
C++
// ==========================================================
|
|
// fipImage class implementation
|
|
//
|
|
// 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 "FreeImagePlus.h"
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Protected functions
|
|
|
|
BOOL fipImage::replace(FIBITMAP *new_dib) {
|
|
if(new_dib == NULL)
|
|
return FALSE;
|
|
if(_dib)
|
|
FreeImage_Unload(_dib);
|
|
_dib = new_dib;
|
|
_bHasChanged = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Creation & Destruction
|
|
|
|
fipImage::fipImage(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp) {
|
|
_dib = NULL;
|
|
_bHasChanged = FALSE;
|
|
if(width && height && bpp)
|
|
setSize(image_type, width, height, bpp);
|
|
}
|
|
|
|
fipImage::~fipImage() {
|
|
if(_dib) {
|
|
FreeImage_Unload(_dib);
|
|
_dib = NULL;
|
|
}
|
|
}
|
|
|
|
BOOL fipImage::setSize(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
|
|
if(_dib) {
|
|
FreeImage_Unload(_dib);
|
|
}
|
|
if((_dib = FreeImage_AllocateT(image_type, width, height, bpp, red_mask, green_mask, blue_mask)) == NULL)
|
|
return FALSE;
|
|
|
|
if(image_type == FIT_BITMAP) {
|
|
// Create palette if needed
|
|
switch(bpp) {
|
|
case 1:
|
|
case 4:
|
|
case 8:
|
|
RGBQUAD *pal = FreeImage_GetPalette(_dib);
|
|
for(unsigned i = 0; i < FreeImage_GetColorsUsed(_dib); i++) {
|
|
pal[i].rgbRed = i;
|
|
pal[i].rgbGreen = i;
|
|
pal[i].rgbBlue = i;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
_bHasChanged = TRUE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void fipImage::clear() {
|
|
if(_dib) {
|
|
FreeImage_Unload(_dib);
|
|
_dib = NULL;
|
|
}
|
|
_bHasChanged = TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Copying
|
|
|
|
fipImage::fipImage(const fipImage& Image) {
|
|
_dib = NULL;
|
|
_fif = FIF_UNKNOWN;
|
|
FIBITMAP *clone = FreeImage_Clone((FIBITMAP*)Image._dib);
|
|
replace(clone);
|
|
}
|
|
|
|
fipImage& fipImage::operator=(const fipImage& Image) {
|
|
if(this != &Image) {
|
|
FIBITMAP *clone = FreeImage_Clone((FIBITMAP*)Image._dib);
|
|
replace(clone);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
fipImage& fipImage::operator=(FIBITMAP *dib) {
|
|
if(_dib != dib) {
|
|
replace(dib);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
BOOL fipImage::copySubImage(fipImage& dst, int left, int top, int right, int bottom) const {
|
|
if(_dib) {
|
|
dst = FreeImage_Copy(_dib, left, top, right, bottom);
|
|
return dst.isValid();
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::pasteSubImage(fipImage& src, int left, int top, int alpha) {
|
|
if(_dib) {
|
|
BOOL bResult = FreeImage_Paste(_dib, src._dib, left, top, alpha);
|
|
_bHasChanged = TRUE;
|
|
return bResult;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::crop(int left, int top, int right, int bottom) {
|
|
if(_dib) {
|
|
FIBITMAP *dst = FreeImage_Copy(_dib, left, top, right, bottom);
|
|
return replace(dst);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Information functions
|
|
|
|
FREE_IMAGE_TYPE fipImage::getImageType() const {
|
|
return FreeImage_GetImageType(_dib);
|
|
}
|
|
|
|
unsigned fipImage::getWidth() const {
|
|
return FreeImage_GetWidth(_dib);
|
|
}
|
|
|
|
unsigned fipImage::getHeight() const {
|
|
return FreeImage_GetHeight(_dib);
|
|
}
|
|
|
|
unsigned fipImage::getScanWidth() const {
|
|
return FreeImage_GetPitch(_dib);
|
|
}
|
|
|
|
BOOL fipImage::isValid() const {
|
|
return (_dib != NULL) ? TRUE:FALSE;
|
|
}
|
|
|
|
BITMAPINFO* fipImage::getInfo() const {
|
|
return FreeImage_GetInfo(_dib);
|
|
}
|
|
|
|
BITMAPINFOHEADER* fipImage::getInfoHeader() const {
|
|
return FreeImage_GetInfoHeader(_dib);
|
|
}
|
|
|
|
LONG fipImage::getImageSize() const {
|
|
return FreeImage_GetDIBSize(_dib);
|
|
}
|
|
|
|
unsigned fipImage::getBitsPerPixel() const {
|
|
return FreeImage_GetBPP(_dib);
|
|
}
|
|
|
|
unsigned fipImage::getLine() const {
|
|
return FreeImage_GetLine(_dib);
|
|
}
|
|
|
|
double fipImage::getHorizontalResolution() const {
|
|
return (FreeImage_GetDotsPerMeterX(_dib) / (double)100);
|
|
}
|
|
|
|
double fipImage::getVerticalResolution() const {
|
|
return (FreeImage_GetDotsPerMeterY(_dib) / (double)100);
|
|
}
|
|
|
|
void fipImage::setHorizontalResolution(double value) {
|
|
FreeImage_SetDotsPerMeterX(_dib, (unsigned)(value * 100 + 0.5));
|
|
}
|
|
|
|
void fipImage::setVerticalResolution(double value) {
|
|
FreeImage_SetDotsPerMeterY(_dib, (unsigned)(value * 100 + 0.5));
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Palette operations
|
|
|
|
RGBQUAD* fipImage::getPalette() const {
|
|
return FreeImage_GetPalette(_dib);
|
|
}
|
|
|
|
unsigned fipImage::getPaletteSize() const {
|
|
return FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD);
|
|
}
|
|
|
|
unsigned fipImage::getColorsUsed() const {
|
|
return FreeImage_GetColorsUsed(_dib);
|
|
}
|
|
|
|
FREE_IMAGE_COLOR_TYPE fipImage::getColorType() const {
|
|
return FreeImage_GetColorType(_dib);
|
|
}
|
|
|
|
BOOL fipImage::isGrayscale() const {
|
|
return ((FreeImage_GetBPP(_dib) == 8) && (FreeImage_GetColorType(_dib) != FIC_PALETTE));
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Pixel access
|
|
|
|
BYTE* fipImage::accessPixels() const {
|
|
return FreeImage_GetBits(_dib);
|
|
}
|
|
|
|
BYTE* fipImage::getScanLine(unsigned scanline) const {
|
|
if(scanline < FreeImage_GetHeight(_dib)) {
|
|
return FreeImage_GetScanLine(_dib, scanline);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
BOOL fipImage::getPixelIndex(unsigned x, unsigned y, BYTE *value) const {
|
|
return FreeImage_GetPixelIndex(_dib, x, y, value);
|
|
}
|
|
|
|
BOOL fipImage::getPixelColor(unsigned x, unsigned y, RGBQUAD *value) const {
|
|
return FreeImage_GetPixelColor(_dib, x, y, value);
|
|
}
|
|
|
|
BOOL fipImage::setPixelIndex(unsigned x, unsigned y, BYTE *value) {
|
|
_bHasChanged = TRUE;
|
|
return FreeImage_SetPixelIndex(_dib, x, y, value);
|
|
}
|
|
|
|
BOOL fipImage::setPixelColor(unsigned x, unsigned y, RGBQUAD *value) {
|
|
_bHasChanged = TRUE;
|
|
return FreeImage_SetPixelColor(_dib, x, y, value);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// File type identification
|
|
|
|
FREE_IMAGE_FORMAT fipImage::identifyFIF(const char* lpszPathName) {
|
|
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
|
|
|
// check the file signature and get its format
|
|
// (the second argument is currently not used by FreeImage)
|
|
fif = FreeImage_GetFileType(lpszPathName, 0);
|
|
if(fif == FIF_UNKNOWN) {
|
|
// no signature ?
|
|
// try to guess the file format from the file extension
|
|
fif = FreeImage_GetFIFFromFilename(lpszPathName);
|
|
}
|
|
|
|
return fif;
|
|
}
|
|
|
|
FREE_IMAGE_FORMAT fipImage::identifyFIFU(const wchar_t* lpszPathName) {
|
|
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
|
|
|
// check the file signature and get its format
|
|
// (the second argument is currently not used by FreeImage)
|
|
fif = FreeImage_GetFileTypeU(lpszPathName, 0);
|
|
if(fif == FIF_UNKNOWN) {
|
|
// no signature ?
|
|
// try to guess the file format from the file extension
|
|
fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
|
|
}
|
|
|
|
return fif;
|
|
}
|
|
|
|
FREE_IMAGE_FORMAT fipImage::identifyFIFFromHandle(FreeImageIO *io, fi_handle handle) {
|
|
if(io && handle) {
|
|
// check the file signature and get its format
|
|
return FreeImage_GetFileTypeFromHandle(io, handle, 16);
|
|
}
|
|
return FIF_UNKNOWN;
|
|
}
|
|
|
|
FREE_IMAGE_FORMAT fipImage::identifyFIFFromMemory(FIMEMORY *hmem) {
|
|
if(hmem != NULL) {
|
|
return FreeImage_GetFileTypeFromMemory(hmem, 0);
|
|
}
|
|
return FIF_UNKNOWN;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Loading & Saving
|
|
|
|
BOOL fipImage::load(const char* lpszPathName, int flag) {
|
|
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
|
|
|
// check the file signature and get its format
|
|
// (the second argument is currently not used by FreeImage)
|
|
fif = FreeImage_GetFileType(lpszPathName, 0);
|
|
if(fif == FIF_UNKNOWN) {
|
|
// no signature ?
|
|
// try to guess the file format from the file extension
|
|
fif = FreeImage_GetFIFFromFilename(lpszPathName);
|
|
}
|
|
// check that the plugin has reading capabilities ...
|
|
if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
|
|
// Free the previous dib
|
|
if(_dib) {
|
|
FreeImage_Unload(_dib);
|
|
}
|
|
// Load the file
|
|
_dib = FreeImage_Load(fif, lpszPathName, flag);
|
|
_bHasChanged = TRUE;
|
|
if(_dib == NULL)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::loadU(const wchar_t* lpszPathName, int flag) {
|
|
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
|
|
|
// check the file signature and get its format
|
|
// (the second argument is currently not used by FreeImage)
|
|
fif = FreeImage_GetFileTypeU(lpszPathName, 0);
|
|
if(fif == FIF_UNKNOWN) {
|
|
// no signature ?
|
|
// try to guess the file format from the file extension
|
|
fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
|
|
}
|
|
// check that the plugin has reading capabilities ...
|
|
if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
|
|
// Free the previous dib
|
|
if(_dib) {
|
|
FreeImage_Unload(_dib);
|
|
}
|
|
// Load the file
|
|
_dib = FreeImage_LoadU(fif, lpszPathName, flag);
|
|
_bHasChanged = TRUE;
|
|
if(_dib == NULL)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::loadFromHandle(FreeImageIO *io, fi_handle handle, int flag) {
|
|
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
|
|
|
// check the file signature and get its format
|
|
fif = FreeImage_GetFileTypeFromHandle(io, handle, 16);
|
|
if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
|
|
// Free the previous dib
|
|
if(_dib) {
|
|
FreeImage_Unload(_dib);
|
|
}
|
|
// Load the file
|
|
_dib = FreeImage_LoadFromHandle(fif, io, handle, flag);
|
|
_bHasChanged = TRUE;
|
|
if(_dib == NULL)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::loadFromMemory(fipMemoryIO& memIO, int flag) {
|
|
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
|
|
|
// check the file signature and get its format
|
|
fif = memIO.getFileType();
|
|
if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
|
|
// Free the previous dib
|
|
if(_dib) {
|
|
FreeImage_Unload(_dib);
|
|
}
|
|
// Load the file
|
|
_dib = memIO.load(fif, flag);
|
|
_bHasChanged = TRUE;
|
|
if(_dib == NULL)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::save(const char* lpszPathName, int flag) const {
|
|
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
|
BOOL bSuccess = FALSE;
|
|
|
|
// Try to guess the file format from the file extension
|
|
fif = FreeImage_GetFIFFromFilename(lpszPathName);
|
|
if(fif != FIF_UNKNOWN ) {
|
|
// Check that the dib can be saved in this format
|
|
BOOL bCanSave;
|
|
|
|
FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
|
|
if(image_type == FIT_BITMAP) {
|
|
// standard bitmap type
|
|
WORD bpp = FreeImage_GetBPP(_dib);
|
|
bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
|
|
} else {
|
|
// special bitmap type
|
|
bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
|
|
}
|
|
|
|
if(bCanSave) {
|
|
bSuccess = FreeImage_Save(fif, _dib, lpszPathName, flag);
|
|
return bSuccess;
|
|
}
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
BOOL fipImage::saveU(const wchar_t* lpszPathName, int flag) const {
|
|
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
|
BOOL bSuccess = FALSE;
|
|
|
|
// Try to guess the file format from the file extension
|
|
fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
|
|
if(fif != FIF_UNKNOWN ) {
|
|
// Check that the dib can be saved in this format
|
|
BOOL bCanSave;
|
|
|
|
FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
|
|
if(image_type == FIT_BITMAP) {
|
|
// standard bitmap type
|
|
WORD bpp = FreeImage_GetBPP(_dib);
|
|
bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
|
|
} else {
|
|
// special bitmap type
|
|
bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
|
|
}
|
|
|
|
if(bCanSave) {
|
|
bSuccess = FreeImage_SaveU(fif, _dib, lpszPathName, flag);
|
|
return bSuccess;
|
|
}
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
BOOL fipImage::saveToHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flag) const {
|
|
BOOL bSuccess = FALSE;
|
|
|
|
if(fif != FIF_UNKNOWN ) {
|
|
// Check that the dib can be saved in this format
|
|
BOOL bCanSave;
|
|
|
|
FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
|
|
if(image_type == FIT_BITMAP) {
|
|
// standard bitmap type
|
|
WORD bpp = FreeImage_GetBPP(_dib);
|
|
bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
|
|
} else {
|
|
// special bitmap type
|
|
bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
|
|
}
|
|
|
|
if(bCanSave) {
|
|
bSuccess = FreeImage_SaveToHandle(fif, _dib, io, handle, flag);
|
|
return bSuccess;
|
|
}
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
BOOL fipImage::saveToMemory(FREE_IMAGE_FORMAT fif, fipMemoryIO& memIO, int flag) const {
|
|
BOOL bSuccess = FALSE;
|
|
|
|
if(fif != FIF_UNKNOWN ) {
|
|
// Check that the dib can be saved in this format
|
|
BOOL bCanSave;
|
|
|
|
FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
|
|
if(image_type == FIT_BITMAP) {
|
|
// standard bitmap type
|
|
WORD bpp = FreeImage_GetBPP(_dib);
|
|
bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
|
|
} else {
|
|
// special bitmap type
|
|
bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
|
|
}
|
|
|
|
if(bCanSave) {
|
|
bSuccess = memIO.save(fif, _dib, flag);
|
|
return bSuccess;
|
|
}
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Conversion routines
|
|
|
|
BOOL fipImage::convertToType(FREE_IMAGE_TYPE image_type, BOOL scale_linear) {
|
|
if(_dib) {
|
|
FIBITMAP *dib = FreeImage_ConvertToType(_dib, image_type, scale_linear);
|
|
return replace(dib);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::threshold(BYTE T) {
|
|
if(_dib) {
|
|
FIBITMAP *dib1 = FreeImage_Threshold(_dib, T);
|
|
return replace(dib1);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::convertTo4Bits() {
|
|
if(_dib) {
|
|
FIBITMAP *dib4 = FreeImage_ConvertTo4Bits(_dib);
|
|
return replace(dib4);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::convertTo8Bits() {
|
|
if(_dib) {
|
|
FIBITMAP *dib8 = FreeImage_ConvertTo8Bits(_dib);
|
|
return replace(dib8);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::convertTo16Bits555() {
|
|
if(_dib) {
|
|
FIBITMAP *dib16_555 = FreeImage_ConvertTo16Bits555(_dib);
|
|
return replace(dib16_555);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::convertTo16Bits565() {
|
|
if(_dib) {
|
|
FIBITMAP *dib16_565 = FreeImage_ConvertTo16Bits565(_dib);
|
|
return replace(dib16_565);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::convertTo24Bits() {
|
|
if(_dib) {
|
|
FIBITMAP *dibRGB = FreeImage_ConvertTo24Bits(_dib);
|
|
return replace(dibRGB);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::convertTo32Bits() {
|
|
if(_dib) {
|
|
FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(_dib);
|
|
return replace(dib32);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::convertToGrayscale() {
|
|
if(_dib) {
|
|
FIBITMAP *dib8 = FreeImage_ConvertToGreyscale(_dib);
|
|
return replace(dib8);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::colorQuantize(FREE_IMAGE_QUANTIZE algorithm) {
|
|
if(_dib) {
|
|
FIBITMAP *dib8 = FreeImage_ColorQuantize(_dib, algorithm);
|
|
return replace(dib8);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::dither(FREE_IMAGE_DITHER algorithm) {
|
|
if(_dib) {
|
|
FIBITMAP *dib = FreeImage_Dither(_dib, algorithm);
|
|
return replace(dib);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::convertToRGBF() {
|
|
if(_dib) {
|
|
FIBITMAP *dib = FreeImage_ConvertToRGBF(_dib);
|
|
return replace(dib);
|
|
}
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
BOOL fipImage::toneMapping(FREE_IMAGE_TMO tmo, double first_param, double second_param, double third_param, double fourth_param) {
|
|
if(_dib) {
|
|
FIBITMAP *dst = NULL;
|
|
// Apply a tone mapping algorithm and convert to 24-bit
|
|
switch(tmo) {
|
|
case FITMO_REINHARD05:
|
|
dst = FreeImage_TmoReinhard05Ex(_dib, first_param, second_param, third_param, fourth_param);
|
|
break;
|
|
default:
|
|
dst = FreeImage_ToneMapping(_dib, tmo, first_param, second_param);
|
|
break;
|
|
}
|
|
|
|
return replace(dst);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Transparency support: background colour and alpha channel
|
|
|
|
BOOL fipImage::isTransparent() const {
|
|
return FreeImage_IsTransparent(_dib);
|
|
}
|
|
|
|
unsigned fipImage::getTransparencyCount() const {
|
|
return FreeImage_GetTransparencyCount(_dib);
|
|
}
|
|
|
|
BYTE* fipImage::getTransparencyTable() const {
|
|
return FreeImage_GetTransparencyTable(_dib);
|
|
}
|
|
|
|
void fipImage::setTransparencyTable(BYTE *table, int count) {
|
|
FreeImage_SetTransparencyTable(_dib, table, count);
|
|
_bHasChanged = TRUE;
|
|
}
|
|
|
|
BOOL fipImage::hasFileBkColor() const {
|
|
return FreeImage_HasBackgroundColor(_dib);
|
|
}
|
|
|
|
BOOL fipImage::getFileBkColor(RGBQUAD *bkcolor) const {
|
|
return FreeImage_GetBackgroundColor(_dib, bkcolor);
|
|
}
|
|
|
|
BOOL fipImage::setFileBkColor(RGBQUAD *bkcolor) {
|
|
_bHasChanged = TRUE;
|
|
return FreeImage_SetBackgroundColor(_dib, bkcolor);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Channel processing support
|
|
|
|
BOOL fipImage::getChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel) const {
|
|
if(_dib) {
|
|
image = FreeImage_GetChannel(_dib, channel);
|
|
return image.isValid();
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::setChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel) {
|
|
if(_dib) {
|
|
_bHasChanged = TRUE;
|
|
return FreeImage_SetChannel(_dib, image._dib, channel);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::splitChannels(fipImage& RedChannel, fipImage& GreenChannel, fipImage& BlueChannel) {
|
|
if(_dib) {
|
|
RedChannel = FreeImage_GetChannel(_dib, FICC_RED);
|
|
GreenChannel = FreeImage_GetChannel(_dib, FICC_GREEN);
|
|
BlueChannel = FreeImage_GetChannel(_dib, FICC_BLUE);
|
|
|
|
return (RedChannel.isValid() && GreenChannel.isValid() && BlueChannel.isValid());
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::combineChannels(fipImage& red, fipImage& green, fipImage& blue) {
|
|
if(!_dib) {
|
|
int width = red.getWidth();
|
|
int height = red.getHeight();
|
|
_dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
|
|
}
|
|
|
|
if(_dib) {
|
|
BOOL bResult = TRUE;
|
|
bResult &= FreeImage_SetChannel(_dib, red._dib, FICC_RED);
|
|
bResult &= FreeImage_SetChannel(_dib, green._dib, FICC_GREEN);
|
|
bResult &= FreeImage_SetChannel(_dib, blue._dib, FICC_BLUE);
|
|
|
|
_bHasChanged = TRUE;
|
|
|
|
return bResult;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Rotation and flipping
|
|
|
|
BOOL fipImage::rotateEx(double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask) {
|
|
if(_dib) {
|
|
if(FreeImage_GetBPP(_dib) >= 8) {
|
|
FIBITMAP *rotated = FreeImage_RotateEx(_dib, angle, x_shift, y_shift, x_origin, y_origin, use_mask);
|
|
return replace(rotated);
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::rotate(double angle, const void *bkcolor) {
|
|
if(_dib) {
|
|
switch(FreeImage_GetImageType(_dib)) {
|
|
case FIT_BITMAP:
|
|
switch(FreeImage_GetBPP(_dib)) {
|
|
case 1:
|
|
case 8:
|
|
case 24:
|
|
case 32:
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case FIT_UINT16:
|
|
case FIT_RGB16:
|
|
case FIT_RGBA16:
|
|
case FIT_FLOAT:
|
|
case FIT_RGBF:
|
|
case FIT_RGBAF:
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
break;
|
|
}
|
|
|
|
FIBITMAP *rotated = FreeImage_Rotate(_dib, angle, bkcolor);
|
|
return replace(rotated);
|
|
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::flipVertical() {
|
|
if(_dib) {
|
|
_bHasChanged = TRUE;
|
|
|
|
return FreeImage_FlipVertical(_dib);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::flipHorizontal() {
|
|
if(_dib) {
|
|
_bHasChanged = TRUE;
|
|
|
|
return FreeImage_FlipHorizontal(_dib);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Color manipulation routines
|
|
|
|
BOOL fipImage::invert() {
|
|
if(_dib) {
|
|
_bHasChanged = TRUE;
|
|
|
|
return FreeImage_Invert(_dib);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::adjustCurve(BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel) {
|
|
if(_dib) {
|
|
_bHasChanged = TRUE;
|
|
|
|
return FreeImage_AdjustCurve(_dib, LUT, channel);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::adjustGamma(double gamma) {
|
|
if(_dib) {
|
|
_bHasChanged = TRUE;
|
|
|
|
return FreeImage_AdjustGamma(_dib, gamma);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::adjustBrightness(double percentage) {
|
|
if(_dib) {
|
|
_bHasChanged = TRUE;
|
|
|
|
return FreeImage_AdjustBrightness(_dib, percentage);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::adjustContrast(double percentage) {
|
|
if(_dib) {
|
|
_bHasChanged = TRUE;
|
|
|
|
return FreeImage_AdjustContrast(_dib, percentage);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::adjustBrightnessContrastGamma(double brightness, double contrast, double gamma) {
|
|
if(_dib) {
|
|
_bHasChanged = TRUE;
|
|
|
|
return FreeImage_AdjustColors(_dib, brightness, contrast, gamma, FALSE);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::getHistogram(DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel) const {
|
|
if(_dib) {
|
|
return FreeImage_GetHistogram(_dib, histo, channel);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Upsampling / downsampling routine
|
|
|
|
BOOL fipImage::rescale(unsigned new_width, unsigned new_height, FREE_IMAGE_FILTER filter) {
|
|
if(_dib) {
|
|
switch(FreeImage_GetImageType(_dib)) {
|
|
case FIT_BITMAP:
|
|
case FIT_UINT16:
|
|
case FIT_RGB16:
|
|
case FIT_RGBA16:
|
|
case FIT_FLOAT:
|
|
case FIT_RGBF:
|
|
case FIT_RGBAF:
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
break;
|
|
}
|
|
|
|
// Perform upsampling / downsampling
|
|
FIBITMAP *dst = FreeImage_Rescale(_dib, new_width, new_height, filter);
|
|
return replace(dst);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::makeThumbnail(unsigned max_size, BOOL convert) {
|
|
if(_dib) {
|
|
switch(FreeImage_GetImageType(_dib)) {
|
|
case FIT_BITMAP:
|
|
case FIT_UINT16:
|
|
case FIT_RGB16:
|
|
case FIT_RGBA16:
|
|
case FIT_FLOAT:
|
|
case FIT_RGBF:
|
|
case FIT_RGBAF:
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
break;
|
|
}
|
|
|
|
// Perform downsampling
|
|
FIBITMAP *dst = FreeImage_MakeThumbnail(_dib, max_size, convert);
|
|
return replace(dst);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Metadata
|
|
|
|
unsigned fipImage::getMetadataCount(FREE_IMAGE_MDMODEL model) const {
|
|
return FreeImage_GetMetadataCount(model, _dib);
|
|
}
|
|
|
|
BOOL fipImage::getMetadata(FREE_IMAGE_MDMODEL model, const char *key, fipTag& tag) const {
|
|
FITAG *searchedTag = NULL;
|
|
FreeImage_GetMetadata(model, _dib, key, &searchedTag);
|
|
if(searchedTag != NULL) {
|
|
tag = FreeImage_CloneTag(searchedTag);
|
|
return TRUE;
|
|
} else {
|
|
// clear the tag
|
|
tag = (FITAG*)NULL;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fipImage::setMetadata(FREE_IMAGE_MDMODEL model, const char *key, fipTag& tag) {
|
|
return FreeImage_SetMetadata(model, _dib, key, tag);
|
|
}
|
|
|