| // ========================================================== |
| // 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); |
| } |
| |
| unsigned fipImage::getImageSize() const { |
| return FreeImage_GetDIBSize(_dib); |
| } |
| |
| unsigned fipImage::getImageMemorySize() const { |
| return FreeImage_GetMemorySize(_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)); |
| } |
| |
| /////////////////////////////////////////////////////////////////// |
| // Thumbnail access |
| |
| BOOL fipImage::getThumbnail(fipImage& image) const { |
| image = FreeImage_Clone( FreeImage_GetThumbnail(_dib) ); |
| return image.isValid(); |
| } |
| |
| BOOL fipImage::setThumbnail(const fipImage& image) { |
| return FreeImage_SetThumbnail(_dib, (FIBITMAP*)image._dib); |
| } |
| |
| BOOL fipImage::hasThumbnail() const { |
| return (FreeImage_GetThumbnail(_dib) != NULL); |
| } |
| |
| BOOL fipImage::clearThumbnail() { |
| return FreeImage_SetThumbnail(_dib, NULL); |
| } |
| |
| |
| /////////////////////////////////////////////////////////////////// |
| // 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::convertToFloat() { |
| if(_dib) { |
| FIBITMAP *dib = FreeImage_ConvertToFloat(_dib); |
| return replace(dib); |
| } |
| return FALSE; |
| } |
| |
| BOOL fipImage::convertToRGBF() { |
| if(_dib) { |
| FIBITMAP *dib = FreeImage_ConvertToRGBF(_dib); |
| return replace(dib); |
| } |
| return FALSE; |
| } |
| |
| BOOL fipImage::convertToRGBAF() { |
| if(_dib) { |
| FIBITMAP *dib = FreeImage_ConvertToRGBAF(_dib); |
| return replace(dib); |
| } |
| return FALSE; |
| } |
| |
| BOOL fipImage::convertToUINT16() { |
| if(_dib) { |
| FIBITMAP *dib = FreeImage_ConvertToUINT16(_dib); |
| return replace(dib); |
| } |
| return FALSE; |
| } |
| |
| BOOL fipImage::convertToRGB16() { |
| if(_dib) { |
| FIBITMAP *dib = FreeImage_ConvertToRGB16(_dib); |
| return replace(dib); |
| } |
| return FALSE; |
| } |
| |
| BOOL fipImage::convertToRGBA16() { |
| if(_dib) { |
| FIBITMAP *dib = FreeImage_ConvertToRGBA16(_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); |
| } |
| |