1 // ==========================================================
2 // fipImage class implementation
3 //
4 // Design and implementation by
5 // - Herv� Drolon (drolon@infonie.fr)
6 //
7 // This file is part of FreeImage 3
8 //
9 // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
10 // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
11 // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
12 // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
13 // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
14 // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
15 // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
16 // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
17 // THIS DISCLAIMER.
18 //
19 // Use at your own risk!
20 // ==========================================================
21
22 #include "FreeImagePlus.h"
23
24 ///////////////////////////////////////////////////////////////////
25 // Protected functions
26
replace(FIBITMAP * new_dib)27 BOOL fipImage::replace(FIBITMAP *new_dib) {
28 if (new_dib == NULL) {
29 return FALSE;
30 }
31 if (_dib) {
32 FreeImage_Unload(_dib);
33 }
34 _dib = new_dib;
35 _bHasChanged = TRUE;
36 return TRUE;
37 }
38
39 ///////////////////////////////////////////////////////////////////
40 // Creation & Destruction
41
fipImage(FREE_IMAGE_TYPE image_type,unsigned width,unsigned height,unsigned bpp)42 fipImage::fipImage(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp) {
43 _dib = NULL;
44 _fif = FIF_UNKNOWN;
45 _bHasChanged = FALSE;
46 if(width && height && bpp) {
47 setSize(image_type, width, height, bpp);
48 }
49 }
50
~fipImage()51 fipImage::~fipImage() {
52 if(_dib) {
53 FreeImage_Unload(_dib);
54 _dib = NULL;
55 }
56 }
57
setSize(FREE_IMAGE_TYPE image_type,unsigned width,unsigned height,unsigned bpp,unsigned red_mask,unsigned green_mask,unsigned blue_mask)58 BOOL fipImage::setSize(FREE_IMAGE_TYPE image_type, unsigned width, unsigned height, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask) {
59 if(_dib) {
60 FreeImage_Unload(_dib);
61 }
62 if((_dib = FreeImage_AllocateT(image_type, width, height, bpp, red_mask, green_mask, blue_mask)) == NULL) {
63 return FALSE;
64 }
65
66 if(image_type == FIT_BITMAP) {
67 // Create palette if needed
68 switch(bpp) {
69 case 1:
70 case 4:
71 case 8:
72 RGBQUAD *pal = FreeImage_GetPalette(_dib);
73 for(unsigned i = 0; i < FreeImage_GetColorsUsed(_dib); i++) {
74 pal[i].rgbRed = i;
75 pal[i].rgbGreen = i;
76 pal[i].rgbBlue = i;
77 }
78 break;
79 }
80 }
81
82 _bHasChanged = TRUE;
83
84 return TRUE;
85 }
86
clear()87 void fipImage::clear() {
88 if(_dib) {
89 FreeImage_Unload(_dib);
90 _dib = NULL;
91 }
92 _bHasChanged = TRUE;
93 }
94
95 ///////////////////////////////////////////////////////////////////
96 // Copying
97
fipImage(const fipImage & Image)98 fipImage::fipImage(const fipImage& Image) {
99 _dib = NULL;
100 FIBITMAP *clone = FreeImage_Clone((FIBITMAP*)Image._dib);
101 replace(clone);
102 _fif = Image._fif;
103 }
104
operator =(const fipImage & Image)105 fipImage& fipImage::operator=(const fipImage& Image) {
106 if(this != &Image) {
107 FIBITMAP *clone = FreeImage_Clone((FIBITMAP*)Image._dib);
108 replace(clone);
109 _fif = Image._fif;
110 }
111 return *this;
112 }
113
operator =(FIBITMAP * dib)114 fipImage& fipImage::operator=(FIBITMAP *dib) {
115 if(_dib != dib) {
116 replace(dib);
117 _fif = FIF_UNKNOWN;
118 }
119 return *this;
120 }
121
copySubImage(fipImage & dst,int left,int top,int right,int bottom) const122 BOOL fipImage::copySubImage(fipImage& dst, int left, int top, int right, int bottom) const {
123 if(_dib) {
124 dst = FreeImage_Copy(_dib, left, top, right, bottom);
125 return dst.isValid();
126 }
127 return FALSE;
128 }
129
pasteSubImage(fipImage & src,int left,int top,int alpha)130 BOOL fipImage::pasteSubImage(fipImage& src, int left, int top, int alpha) {
131 if(_dib) {
132 BOOL bResult = FreeImage_Paste(_dib, src._dib, left, top, alpha);
133 _bHasChanged = TRUE;
134 return bResult;
135 }
136 return FALSE;
137 }
138
crop(int left,int top,int right,int bottom)139 BOOL fipImage::crop(int left, int top, int right, int bottom) {
140 if(_dib) {
141 FIBITMAP *dst = FreeImage_Copy(_dib, left, top, right, bottom);
142 return replace(dst);
143 }
144 return FALSE;
145 }
146
createView(fipImage & dynamicView,unsigned left,unsigned top,unsigned right,unsigned bottom)147 BOOL fipImage::createView(fipImage& dynamicView, unsigned left, unsigned top, unsigned right, unsigned bottom) {
148 dynamicView = FreeImage_CreateView(_dib, left, top, right, bottom);
149 return dynamicView.isValid();
150 }
151
152 ///////////////////////////////////////////////////////////////////
153 // Information functions
154
getImageType() const155 FREE_IMAGE_TYPE fipImage::getImageType() const {
156 return FreeImage_GetImageType(_dib);
157 }
158
getFIF() const159 FREE_IMAGE_FORMAT fipImage::getFIF() const {
160 return _fif;
161 }
162
getWidth() const163 unsigned fipImage::getWidth() const {
164 return FreeImage_GetWidth(_dib);
165 }
166
getHeight() const167 unsigned fipImage::getHeight() const {
168 return FreeImage_GetHeight(_dib);
169 }
170
getScanWidth() const171 unsigned fipImage::getScanWidth() const {
172 return FreeImage_GetPitch(_dib);
173 }
174
isValid() const175 BOOL fipImage::isValid() const {
176 return (_dib != NULL) ? TRUE:FALSE;
177 }
178
getInfo() const179 const BITMAPINFO* fipImage::getInfo() const {
180 return FreeImage_GetInfo(_dib);
181 }
182
getInfoHeader() const183 const BITMAPINFOHEADER* fipImage::getInfoHeader() const {
184 return FreeImage_GetInfoHeader(_dib);
185 }
186
getImageSize() const187 unsigned fipImage::getImageSize() const {
188 return FreeImage_GetDIBSize(_dib);
189 }
190
getImageMemorySize() const191 unsigned fipImage::getImageMemorySize() const {
192 return FreeImage_GetMemorySize(_dib);
193 }
194
getBitsPerPixel() const195 unsigned fipImage::getBitsPerPixel() const {
196 return FreeImage_GetBPP(_dib);
197 }
198
getLine() const199 unsigned fipImage::getLine() const {
200 return FreeImage_GetLine(_dib);
201 }
202
getHorizontalResolution() const203 double fipImage::getHorizontalResolution() const {
204 return (FreeImage_GetDotsPerMeterX(_dib) / (double)100);
205 }
206
getVerticalResolution() const207 double fipImage::getVerticalResolution() const {
208 return (FreeImage_GetDotsPerMeterY(_dib) / (double)100);
209 }
210
setHorizontalResolution(double value)211 void fipImage::setHorizontalResolution(double value) {
212 FreeImage_SetDotsPerMeterX(_dib, (unsigned)(value * 100 + 0.5));
213 }
214
setVerticalResolution(double value)215 void fipImage::setVerticalResolution(double value) {
216 FreeImage_SetDotsPerMeterY(_dib, (unsigned)(value * 100 + 0.5));
217 }
218
219
220 ///////////////////////////////////////////////////////////////////
221 // Palette operations
222
getPalette() const223 RGBQUAD* fipImage::getPalette() const {
224 return FreeImage_GetPalette(_dib);
225 }
226
getPaletteSize() const227 unsigned fipImage::getPaletteSize() const {
228 return FreeImage_GetColorsUsed(_dib) * sizeof(RGBQUAD);
229 }
230
getColorsUsed() const231 unsigned fipImage::getColorsUsed() const {
232 return FreeImage_GetColorsUsed(_dib);
233 }
234
getColorType() const235 FREE_IMAGE_COLOR_TYPE fipImage::getColorType() const {
236 return FreeImage_GetColorType(_dib);
237 }
238
isGrayscale() const239 BOOL fipImage::isGrayscale() const {
240 return ((FreeImage_GetBPP(_dib) == 8) && (FreeImage_GetColorType(_dib) != FIC_PALETTE));
241 }
242
243 ///////////////////////////////////////////////////////////////////
244 // Thumbnail access
245
getThumbnail(fipImage & image) const246 BOOL fipImage::getThumbnail(fipImage& image) const {
247 image = FreeImage_Clone( FreeImage_GetThumbnail(_dib) );
248 return image.isValid();
249 }
250
setThumbnail(const fipImage & image)251 BOOL fipImage::setThumbnail(const fipImage& image) {
252 return FreeImage_SetThumbnail(_dib, (FIBITMAP*)image._dib);
253 }
254
hasThumbnail() const255 BOOL fipImage::hasThumbnail() const {
256 return (FreeImage_GetThumbnail(_dib) != NULL);
257 }
258
clearThumbnail()259 BOOL fipImage::clearThumbnail() {
260 return FreeImage_SetThumbnail(_dib, NULL);
261 }
262
263
264 ///////////////////////////////////////////////////////////////////
265 // Pixel access
266
accessPixels() const267 BYTE* fipImage::accessPixels() const {
268 return FreeImage_GetBits(_dib);
269 }
270
getScanLine(unsigned scanline) const271 BYTE* fipImage::getScanLine(unsigned scanline) const {
272 if(scanline < FreeImage_GetHeight(_dib)) {
273 return FreeImage_GetScanLine(_dib, scanline);
274 }
275 return NULL;
276 }
277
getPixelIndex(unsigned x,unsigned y,BYTE * value) const278 BOOL fipImage::getPixelIndex(unsigned x, unsigned y, BYTE *value) const {
279 return FreeImage_GetPixelIndex(_dib, x, y, value);
280 }
281
getPixelColor(unsigned x,unsigned y,RGBQUAD * value) const282 BOOL fipImage::getPixelColor(unsigned x, unsigned y, RGBQUAD *value) const {
283 return FreeImage_GetPixelColor(_dib, x, y, value);
284 }
285
setPixelIndex(unsigned x,unsigned y,BYTE * value)286 BOOL fipImage::setPixelIndex(unsigned x, unsigned y, BYTE *value) {
287 _bHasChanged = TRUE;
288 return FreeImage_SetPixelIndex(_dib, x, y, value);
289 }
290
setPixelColor(unsigned x,unsigned y,RGBQUAD * value)291 BOOL fipImage::setPixelColor(unsigned x, unsigned y, RGBQUAD *value) {
292 _bHasChanged = TRUE;
293 return FreeImage_SetPixelColor(_dib, x, y, value);
294 }
295
296 ///////////////////////////////////////////////////////////////////
297 // File type identification
298
identifyFIF(const char * lpszPathName)299 FREE_IMAGE_FORMAT fipImage::identifyFIF(const char* lpszPathName) {
300 FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
301
302 // check the file signature and get its format
303 // (the second argument is currently not used by FreeImage)
304 fif = FreeImage_GetFileType(lpszPathName, 0);
305 if(fif == FIF_UNKNOWN) {
306 // no signature ?
307 // try to guess the file format from the file extension
308 fif = FreeImage_GetFIFFromFilename(lpszPathName);
309 }
310
311 return fif;
312 }
313
identifyFIFU(const wchar_t * lpszPathName)314 FREE_IMAGE_FORMAT fipImage::identifyFIFU(const wchar_t* lpszPathName) {
315 FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
316
317 // check the file signature and get its format
318 // (the second argument is currently not used by FreeImage)
319 fif = FreeImage_GetFileTypeU(lpszPathName, 0);
320 if(fif == FIF_UNKNOWN) {
321 // no signature ?
322 // try to guess the file format from the file extension
323 fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
324 }
325
326 return fif;
327 }
328
identifyFIFFromHandle(FreeImageIO * io,fi_handle handle)329 FREE_IMAGE_FORMAT fipImage::identifyFIFFromHandle(FreeImageIO *io, fi_handle handle) {
330 if(io && handle) {
331 // check the file signature and get its format
332 return FreeImage_GetFileTypeFromHandle(io, handle);
333 }
334 return FIF_UNKNOWN;
335 }
336
identifyFIFFromMemory(FIMEMORY * hmem)337 FREE_IMAGE_FORMAT fipImage::identifyFIFFromMemory(FIMEMORY *hmem) {
338 if(hmem != NULL) {
339 return FreeImage_GetFileTypeFromMemory(hmem, 0);
340 }
341 return FIF_UNKNOWN;
342 }
343
344
345 ///////////////////////////////////////////////////////////////////
346 // Loading & Saving
347
load(FREE_IMAGE_FORMAT fif,const char * lpszPathName,int flag)348 BOOL fipImage::load(FREE_IMAGE_FORMAT fif, const char* lpszPathName, int flag) {
349 // free the previous dib
350 if (_dib) {
351 FreeImage_Unload(_dib);
352 }
353 // load the file
354 _dib = FreeImage_Load(fif, lpszPathName, flag);
355 _fif = fif;
356 _bHasChanged = TRUE;
357
358 return (_dib == NULL) ? FALSE : TRUE;
359 }
360
load(const char * lpszPathName,int flag)361 BOOL fipImage::load(const char* lpszPathName, int flag) {
362 FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
363
364 // check the file signature and get its format
365 // (the second argument is currently not used by FreeImage)
366 fif = FreeImage_GetFileType(lpszPathName, 0);
367 if(fif == FIF_UNKNOWN) {
368 // no signature ?
369 // try to guess the file format from the file extension
370 fif = FreeImage_GetFIFFromFilename(lpszPathName);
371 }
372 // check that the plugin has reading capabilities ...
373 if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
374 return load(fif, lpszPathName, flag);
375 }
376
377 return FALSE;
378 }
379
loadU(FREE_IMAGE_FORMAT fif,const wchar_t * lpszPathName,int flag)380 BOOL fipImage::loadU(FREE_IMAGE_FORMAT fif, const wchar_t* lpszPathName, int flag) {
381 // free the previous dib
382 if (_dib) {
383 FreeImage_Unload(_dib);
384 }
385 // load the file
386 _dib = FreeImage_LoadU(fif, lpszPathName, flag);
387 _fif = fif;
388 _bHasChanged = TRUE;
389
390 return (_dib == NULL) ? FALSE : TRUE;
391 }
392
loadU(const wchar_t * lpszPathName,int flag)393 BOOL fipImage::loadU(const wchar_t* lpszPathName, int flag) {
394 FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
395
396 // check the file signature and get its format
397 // (the second argument is currently not used by FreeImage)
398 fif = FreeImage_GetFileTypeU(lpszPathName, 0);
399 if(fif == FIF_UNKNOWN) {
400 // no signature ?
401 // try to guess the file format from the file extension
402 fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
403 }
404 // check that the plugin has reading capabilities ...
405 if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
406 return loadU(fif, lpszPathName, flag);
407 }
408
409 return FALSE;
410 }
411
loadFromHandle(FreeImageIO * io,fi_handle handle,int flag)412 BOOL fipImage::loadFromHandle(FreeImageIO *io, fi_handle handle, int flag) {
413 FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
414
415 // check the file signature and get its format
416 fif = FreeImage_GetFileTypeFromHandle(io, handle);
417 if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
418 // Free the previous dib
419 if(_dib) {
420 FreeImage_Unload(_dib);
421 }
422 // Load the file
423 _dib = FreeImage_LoadFromHandle(fif, io, handle, flag);
424 _fif = fif;
425 _bHasChanged = TRUE;
426
427 return (_dib == NULL) ? FALSE : TRUE;
428 }
429 return FALSE;
430 }
431
loadFromMemory(fipMemoryIO & memIO,int flag)432 BOOL fipImage::loadFromMemory(fipMemoryIO& memIO, int flag) {
433 FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
434
435 // check the file signature and get its format
436 fif = memIO.getFileType();
437 if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
438 // Free the previous dib
439 if(_dib) {
440 FreeImage_Unload(_dib);
441 }
442 // Load the file
443 _dib = memIO.load(fif, flag);
444 _fif = fif;
445 _bHasChanged = TRUE;
446
447 return (_dib == NULL) ? FALSE : TRUE;
448 }
449 return FALSE;
450 }
451
loadFromMemory(FREE_IMAGE_FORMAT fif,fipMemoryIO & memIO,int flag)452 BOOL fipImage::loadFromMemory(FREE_IMAGE_FORMAT fif, fipMemoryIO& memIO, int flag) {
453 if (fif != FIF_UNKNOWN) {
454 // Free the previous dib
455 if (_dib) {
456 FreeImage_Unload(_dib);
457 }
458 // Load the file
459 _dib = memIO.load(fif, flag);
460 _fif = fif;
461 _bHasChanged = TRUE;
462
463 return (_dib == NULL) ? FALSE : TRUE;
464 }
465 return FALSE;
466 }
467
save(FREE_IMAGE_FORMAT fif,const char * lpszPathName,int flag)468 BOOL fipImage::save(FREE_IMAGE_FORMAT fif, const char* lpszPathName, int flag) {
469 BOOL bSuccess = FreeImage_Save(fif, _dib, lpszPathName, flag);
470 _fif = fif;
471 return bSuccess;
472 }
473
save(const char * lpszPathName,int flag)474 BOOL fipImage::save(const char* lpszPathName, int flag) {
475 FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
476 BOOL bSuccess = FALSE;
477
478 // Try to guess the file format from the file extension
479 fif = FreeImage_GetFIFFromFilename(lpszPathName);
480 if(fif != FIF_UNKNOWN ) {
481 // Check that the dib can be saved in this format
482 BOOL bCanSave;
483
484 FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
485 if(image_type == FIT_BITMAP) {
486 // standard bitmap type
487 WORD bpp = FreeImage_GetBPP(_dib);
488 bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
489 } else {
490 // special bitmap type
491 bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
492 }
493
494 if(bCanSave) {
495 bSuccess = FreeImage_Save(fif, _dib, lpszPathName, flag);
496 _fif = fif;
497 return bSuccess;
498 }
499 }
500 return bSuccess;
501 }
502
saveU(FREE_IMAGE_FORMAT fif,const wchar_t * lpszPathName,int flag)503 BOOL fipImage::saveU(FREE_IMAGE_FORMAT fif, const wchar_t* lpszPathName, int flag) {
504 BOOL bSuccess = FreeImage_SaveU(fif, _dib, lpszPathName, flag);
505 _fif = fif;
506 return bSuccess;
507 }
508
saveU(const wchar_t * lpszPathName,int flag)509 BOOL fipImage::saveU(const wchar_t* lpszPathName, int flag) {
510 FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
511 BOOL bSuccess = FALSE;
512
513 // Try to guess the file format from the file extension
514 fif = FreeImage_GetFIFFromFilenameU(lpszPathName);
515 if(fif != FIF_UNKNOWN ) {
516 // Check that the dib can be saved in this format
517 BOOL bCanSave;
518
519 FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
520 if(image_type == FIT_BITMAP) {
521 // standard bitmap type
522 WORD bpp = FreeImage_GetBPP(_dib);
523 bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
524 } else {
525 // special bitmap type
526 bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
527 }
528
529 if(bCanSave) {
530 bSuccess = FreeImage_SaveU(fif, _dib, lpszPathName, flag);
531 _fif = fif;
532 return bSuccess;
533 }
534 }
535 return bSuccess;
536 }
537
saveToHandle(FREE_IMAGE_FORMAT fif,FreeImageIO * io,fi_handle handle,int flag)538 BOOL fipImage::saveToHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_handle handle, int flag) {
539 BOOL bSuccess = FALSE;
540
541 if(fif != FIF_UNKNOWN ) {
542 // Check that the dib can be saved in this format
543 BOOL bCanSave;
544
545 FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
546 if(image_type == FIT_BITMAP) {
547 // standard bitmap type
548 WORD bpp = FreeImage_GetBPP(_dib);
549 bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
550 } else {
551 // special bitmap type
552 bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
553 }
554
555 if(bCanSave) {
556 bSuccess = FreeImage_SaveToHandle(fif, _dib, io, handle, flag);
557 _fif = fif;
558 return bSuccess;
559 }
560 }
561 return bSuccess;
562 }
563
saveToMemory(FREE_IMAGE_FORMAT fif,fipMemoryIO & memIO,int flag)564 BOOL fipImage::saveToMemory(FREE_IMAGE_FORMAT fif, fipMemoryIO& memIO, int flag) {
565 BOOL bSuccess = FALSE;
566
567 if(fif != FIF_UNKNOWN ) {
568 // Check that the dib can be saved in this format
569 BOOL bCanSave;
570
571 FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(_dib);
572 if(image_type == FIT_BITMAP) {
573 // standard bitmap type
574 WORD bpp = FreeImage_GetBPP(_dib);
575 bCanSave = (FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp));
576 } else {
577 // special bitmap type
578 bCanSave = FreeImage_FIFSupportsExportType(fif, image_type);
579 }
580
581 if(bCanSave) {
582 bSuccess = memIO.save(fif, _dib, flag);
583 _fif = fif;
584 return bSuccess;
585 }
586 }
587 return bSuccess;
588 }
589
590 ///////////////////////////////////////////////////////////////////
591 // Conversion routines
592
convertToType(FREE_IMAGE_TYPE image_type,BOOL scale_linear)593 BOOL fipImage::convertToType(FREE_IMAGE_TYPE image_type, BOOL scale_linear) {
594 if(_dib) {
595 FIBITMAP *dib = FreeImage_ConvertToType(_dib, image_type, scale_linear);
596 return replace(dib);
597 }
598 return FALSE;
599 }
600
threshold(BYTE T)601 BOOL fipImage::threshold(BYTE T) {
602 if(_dib) {
603 FIBITMAP *dib1 = FreeImage_Threshold(_dib, T);
604 return replace(dib1);
605 }
606 return FALSE;
607 }
608
convertTo4Bits()609 BOOL fipImage::convertTo4Bits() {
610 if(_dib) {
611 FIBITMAP *dib4 = FreeImage_ConvertTo4Bits(_dib);
612 return replace(dib4);
613 }
614 return FALSE;
615 }
616
convertTo8Bits()617 BOOL fipImage::convertTo8Bits() {
618 if(_dib) {
619 FIBITMAP *dib8 = FreeImage_ConvertTo8Bits(_dib);
620 return replace(dib8);
621 }
622 return FALSE;
623 }
624
convertTo16Bits555()625 BOOL fipImage::convertTo16Bits555() {
626 if(_dib) {
627 FIBITMAP *dib16_555 = FreeImage_ConvertTo16Bits555(_dib);
628 return replace(dib16_555);
629 }
630 return FALSE;
631 }
632
convertTo16Bits565()633 BOOL fipImage::convertTo16Bits565() {
634 if(_dib) {
635 FIBITMAP *dib16_565 = FreeImage_ConvertTo16Bits565(_dib);
636 return replace(dib16_565);
637 }
638 return FALSE;
639 }
640
convertTo24Bits()641 BOOL fipImage::convertTo24Bits() {
642 if(_dib) {
643 FIBITMAP *dibRGB = FreeImage_ConvertTo24Bits(_dib);
644 return replace(dibRGB);
645 }
646 return FALSE;
647 }
648
convertTo32Bits()649 BOOL fipImage::convertTo32Bits() {
650 if(_dib) {
651 FIBITMAP *dib32 = FreeImage_ConvertTo32Bits(_dib);
652 return replace(dib32);
653 }
654 return FALSE;
655 }
656
convertToGrayscale()657 BOOL fipImage::convertToGrayscale() {
658 if(_dib) {
659 FIBITMAP *dib8 = FreeImage_ConvertToGreyscale(_dib);
660 return replace(dib8);
661 }
662 return FALSE;
663 }
664
colorQuantize(FREE_IMAGE_QUANTIZE algorithm)665 BOOL fipImage::colorQuantize(FREE_IMAGE_QUANTIZE algorithm) {
666 if(_dib) {
667 FIBITMAP *dib8 = FreeImage_ColorQuantize(_dib, algorithm);
668 return replace(dib8);
669 }
670 return FALSE;
671 }
672
dither(FREE_IMAGE_DITHER algorithm)673 BOOL fipImage::dither(FREE_IMAGE_DITHER algorithm) {
674 if(_dib) {
675 FIBITMAP *dib = FreeImage_Dither(_dib, algorithm);
676 return replace(dib);
677 }
678 return FALSE;
679 }
680
convertToFloat()681 BOOL fipImage::convertToFloat() {
682 if(_dib) {
683 FIBITMAP *dib = FreeImage_ConvertToFloat(_dib);
684 return replace(dib);
685 }
686 return FALSE;
687 }
688
convertToRGBF()689 BOOL fipImage::convertToRGBF() {
690 if(_dib) {
691 FIBITMAP *dib = FreeImage_ConvertToRGBF(_dib);
692 return replace(dib);
693 }
694 return FALSE;
695 }
696
convertToRGBAF()697 BOOL fipImage::convertToRGBAF() {
698 if(_dib) {
699 FIBITMAP *dib = FreeImage_ConvertToRGBAF(_dib);
700 return replace(dib);
701 }
702 return FALSE;
703 }
704
convertToUINT16()705 BOOL fipImage::convertToUINT16() {
706 if(_dib) {
707 FIBITMAP *dib = FreeImage_ConvertToUINT16(_dib);
708 return replace(dib);
709 }
710 return FALSE;
711 }
712
convertToRGB16()713 BOOL fipImage::convertToRGB16() {
714 if(_dib) {
715 FIBITMAP *dib = FreeImage_ConvertToRGB16(_dib);
716 return replace(dib);
717 }
718 return FALSE;
719 }
720
convertToRGBA16()721 BOOL fipImage::convertToRGBA16() {
722 if(_dib) {
723 FIBITMAP *dib = FreeImage_ConvertToRGBA16(_dib);
724 return replace(dib);
725 }
726 return FALSE;
727 }
728
toneMapping(FREE_IMAGE_TMO tmo,double first_param,double second_param,double third_param,double fourth_param)729 BOOL fipImage::toneMapping(FREE_IMAGE_TMO tmo, double first_param, double second_param, double third_param, double fourth_param) {
730 if(_dib) {
731 FIBITMAP *dst = NULL;
732 // Apply a tone mapping algorithm and convert to 24-bit
733 switch(tmo) {
734 case FITMO_REINHARD05:
735 dst = FreeImage_TmoReinhard05Ex(_dib, first_param, second_param, third_param, fourth_param);
736 break;
737 default:
738 dst = FreeImage_ToneMapping(_dib, tmo, first_param, second_param);
739 break;
740 }
741
742 return replace(dst);
743 }
744 return FALSE;
745 }
746
747 ///////////////////////////////////////////////////////////////////
748 // Transparency support: background colour and alpha channel
749
isTransparent() const750 BOOL fipImage::isTransparent() const {
751 return FreeImage_IsTransparent(_dib);
752 }
753
getTransparencyCount() const754 unsigned fipImage::getTransparencyCount() const {
755 return FreeImage_GetTransparencyCount(_dib);
756 }
757
getTransparencyTable() const758 BYTE* fipImage::getTransparencyTable() const {
759 return FreeImage_GetTransparencyTable(_dib);
760 }
761
setTransparencyTable(BYTE * table,int count)762 void fipImage::setTransparencyTable(BYTE *table, int count) {
763 FreeImage_SetTransparencyTable(_dib, table, count);
764 _bHasChanged = TRUE;
765 }
766
hasFileBkColor() const767 BOOL fipImage::hasFileBkColor() const {
768 return FreeImage_HasBackgroundColor(_dib);
769 }
770
getFileBkColor(RGBQUAD * bkcolor) const771 BOOL fipImage::getFileBkColor(RGBQUAD *bkcolor) const {
772 return FreeImage_GetBackgroundColor(_dib, bkcolor);
773 }
774
setFileBkColor(RGBQUAD * bkcolor)775 BOOL fipImage::setFileBkColor(RGBQUAD *bkcolor) {
776 _bHasChanged = TRUE;
777 return FreeImage_SetBackgroundColor(_dib, bkcolor);
778 }
779
780 ///////////////////////////////////////////////////////////////////
781 // Channel processing support
782
getChannel(fipImage & image,FREE_IMAGE_COLOR_CHANNEL channel) const783 BOOL fipImage::getChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel) const {
784 if(_dib) {
785 image = FreeImage_GetChannel(_dib, channel);
786 return image.isValid();
787 }
788 return FALSE;
789 }
790
setChannel(fipImage & image,FREE_IMAGE_COLOR_CHANNEL channel)791 BOOL fipImage::setChannel(fipImage& image, FREE_IMAGE_COLOR_CHANNEL channel) {
792 if(_dib) {
793 _bHasChanged = TRUE;
794 return FreeImage_SetChannel(_dib, image._dib, channel);
795 }
796 return FALSE;
797 }
798
splitChannels(fipImage & RedChannel,fipImage & GreenChannel,fipImage & BlueChannel)799 BOOL fipImage::splitChannels(fipImage& RedChannel, fipImage& GreenChannel, fipImage& BlueChannel) {
800 if(_dib) {
801 RedChannel = FreeImage_GetChannel(_dib, FICC_RED);
802 GreenChannel = FreeImage_GetChannel(_dib, FICC_GREEN);
803 BlueChannel = FreeImage_GetChannel(_dib, FICC_BLUE);
804
805 return (RedChannel.isValid() && GreenChannel.isValid() && BlueChannel.isValid());
806 }
807 return FALSE;
808 }
809
combineChannels(fipImage & red,fipImage & green,fipImage & blue)810 BOOL fipImage::combineChannels(fipImage& red, fipImage& green, fipImage& blue) {
811 if(!_dib) {
812 int width = red.getWidth();
813 int height = red.getHeight();
814 _dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
815 }
816
817 if(_dib) {
818 BOOL bResult = TRUE;
819 bResult &= FreeImage_SetChannel(_dib, red._dib, FICC_RED);
820 bResult &= FreeImage_SetChannel(_dib, green._dib, FICC_GREEN);
821 bResult &= FreeImage_SetChannel(_dib, blue._dib, FICC_BLUE);
822
823 _bHasChanged = TRUE;
824
825 return bResult;
826 }
827 return FALSE;
828 }
829
830 ///////////////////////////////////////////////////////////////////
831 // Rotation and flipping
832
rotateEx(double angle,double x_shift,double y_shift,double x_origin,double y_origin,BOOL use_mask)833 BOOL fipImage::rotateEx(double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask) {
834 if(_dib) {
835 if(FreeImage_GetBPP(_dib) >= 8) {
836 FIBITMAP *rotated = FreeImage_RotateEx(_dib, angle, x_shift, y_shift, x_origin, y_origin, use_mask);
837 return replace(rotated);
838 }
839 }
840 return FALSE;
841 }
842
rotate(double angle,const void * bkcolor)843 BOOL fipImage::rotate(double angle, const void *bkcolor) {
844 if(_dib) {
845 switch(FreeImage_GetImageType(_dib)) {
846 case FIT_BITMAP:
847 switch(FreeImage_GetBPP(_dib)) {
848 case 1:
849 case 8:
850 case 24:
851 case 32:
852 break;
853 default:
854 return FALSE;
855 }
856 break;
857
858 case FIT_UINT16:
859 case FIT_RGB16:
860 case FIT_RGBA16:
861 case FIT_FLOAT:
862 case FIT_RGBF:
863 case FIT_RGBAF:
864 break;
865 default:
866 return FALSE;
867 break;
868 }
869
870 FIBITMAP *rotated = FreeImage_Rotate(_dib, angle, bkcolor);
871 return replace(rotated);
872
873 }
874 return FALSE;
875 }
876
flipVertical()877 BOOL fipImage::flipVertical() {
878 if(_dib) {
879 _bHasChanged = TRUE;
880
881 return FreeImage_FlipVertical(_dib);
882 }
883 return FALSE;
884 }
885
flipHorizontal()886 BOOL fipImage::flipHorizontal() {
887 if(_dib) {
888 _bHasChanged = TRUE;
889
890 return FreeImage_FlipHorizontal(_dib);
891 }
892 return FALSE;
893 }
894
895 ///////////////////////////////////////////////////////////////////
896 // Color manipulation routines
897
invert()898 BOOL fipImage::invert() {
899 if(_dib) {
900 _bHasChanged = TRUE;
901
902 return FreeImage_Invert(_dib);
903 }
904 return FALSE;
905 }
906
adjustCurve(BYTE * LUT,FREE_IMAGE_COLOR_CHANNEL channel)907 BOOL fipImage::adjustCurve(BYTE *LUT, FREE_IMAGE_COLOR_CHANNEL channel) {
908 if(_dib) {
909 _bHasChanged = TRUE;
910
911 return FreeImage_AdjustCurve(_dib, LUT, channel);
912 }
913 return FALSE;
914 }
915
adjustGamma(double gamma)916 BOOL fipImage::adjustGamma(double gamma) {
917 if(_dib) {
918 _bHasChanged = TRUE;
919
920 return FreeImage_AdjustGamma(_dib, gamma);
921 }
922 return FALSE;
923 }
924
adjustBrightness(double percentage)925 BOOL fipImage::adjustBrightness(double percentage) {
926 if(_dib) {
927 _bHasChanged = TRUE;
928
929 return FreeImage_AdjustBrightness(_dib, percentage);
930 }
931 return FALSE;
932 }
933
adjustContrast(double percentage)934 BOOL fipImage::adjustContrast(double percentage) {
935 if(_dib) {
936 _bHasChanged = TRUE;
937
938 return FreeImage_AdjustContrast(_dib, percentage);
939 }
940 return FALSE;
941 }
942
adjustBrightnessContrastGamma(double brightness,double contrast,double gamma)943 BOOL fipImage::adjustBrightnessContrastGamma(double brightness, double contrast, double gamma) {
944 if(_dib) {
945 _bHasChanged = TRUE;
946
947 return FreeImage_AdjustColors(_dib, brightness, contrast, gamma, FALSE);
948 }
949 return FALSE;
950 }
951
getHistogram(DWORD * histo,FREE_IMAGE_COLOR_CHANNEL channel) const952 BOOL fipImage::getHistogram(DWORD *histo, FREE_IMAGE_COLOR_CHANNEL channel) const {
953 if(_dib) {
954 return FreeImage_GetHistogram(_dib, histo, channel);
955 }
956 return FALSE;
957 }
958
959 ///////////////////////////////////////////////////////////////////
960 // Upsampling / downsampling routine
961
rescale(unsigned new_width,unsigned new_height,FREE_IMAGE_FILTER filter)962 BOOL fipImage::rescale(unsigned new_width, unsigned new_height, FREE_IMAGE_FILTER filter) {
963 if(_dib) {
964 switch(FreeImage_GetImageType(_dib)) {
965 case FIT_BITMAP:
966 case FIT_UINT16:
967 case FIT_RGB16:
968 case FIT_RGBA16:
969 case FIT_FLOAT:
970 case FIT_RGBF:
971 case FIT_RGBAF:
972 break;
973 default:
974 return FALSE;
975 break;
976 }
977
978 // Perform upsampling / downsampling
979 FIBITMAP *dst = FreeImage_Rescale(_dib, new_width, new_height, filter);
980 return replace(dst);
981 }
982 return FALSE;
983 }
984
makeThumbnail(unsigned max_size,BOOL convert)985 BOOL fipImage::makeThumbnail(unsigned max_size, BOOL convert) {
986 if(_dib) {
987 switch(FreeImage_GetImageType(_dib)) {
988 case FIT_BITMAP:
989 case FIT_UINT16:
990 case FIT_RGB16:
991 case FIT_RGBA16:
992 case FIT_FLOAT:
993 case FIT_RGBF:
994 case FIT_RGBAF:
995 break;
996 default:
997 return FALSE;
998 break;
999 }
1000
1001 // Perform downsampling
1002 FIBITMAP *dst = FreeImage_MakeThumbnail(_dib, max_size, convert);
1003 return replace(dst);
1004 }
1005 return FALSE;
1006 }
1007
1008 ///////////////////////////////////////////////////////////////////
1009 // Metadata
1010
getMetadataCount(FREE_IMAGE_MDMODEL model) const1011 unsigned fipImage::getMetadataCount(FREE_IMAGE_MDMODEL model) const {
1012 return FreeImage_GetMetadataCount(model, _dib);
1013 }
1014
getMetadata(FREE_IMAGE_MDMODEL model,const char * key,fipTag & tag) const1015 BOOL fipImage::getMetadata(FREE_IMAGE_MDMODEL model, const char *key, fipTag& tag) const {
1016 FITAG *searchedTag = NULL;
1017 FreeImage_GetMetadata(model, _dib, key, &searchedTag);
1018 if(searchedTag != NULL) {
1019 tag = FreeImage_CloneTag(searchedTag);
1020 return TRUE;
1021 } else {
1022 // clear the tag
1023 tag = (FITAG*)NULL;
1024 }
1025 return FALSE;
1026 }
1027
setMetadata(FREE_IMAGE_MDMODEL model,const char * key,fipTag & tag)1028 BOOL fipImage::setMetadata(FREE_IMAGE_MDMODEL model, const char *key, fipTag& tag) {
1029 return FreeImage_SetMetadata(model, _dib, key, tag);
1030 }
1031
clearMetadata()1032 void fipImage::clearMetadata() {
1033 // clear all metadata attached to the dib
1034 FreeImage_SetMetadata(FIMD_COMMENTS, _dib, NULL, NULL); // single comment or keywords
1035 FreeImage_SetMetadata(FIMD_EXIF_MAIN, _dib, NULL, NULL); // Exif-TIFF metadata
1036 FreeImage_SetMetadata(FIMD_EXIF_EXIF, _dib, NULL, NULL); // Exif-specific metadata
1037 FreeImage_SetMetadata(FIMD_EXIF_GPS, _dib, NULL, NULL); // Exif GPS metadata
1038 FreeImage_SetMetadata(FIMD_EXIF_MAKERNOTE, _dib, NULL, NULL); // Exif maker note metadata
1039 FreeImage_SetMetadata(FIMD_EXIF_INTEROP, _dib, NULL, NULL); // Exif interoperability metadata
1040 FreeImage_SetMetadata(FIMD_IPTC, _dib, NULL, NULL); // IPTC/NAA metadata
1041 FreeImage_SetMetadata(FIMD_XMP, _dib, NULL, NULL); // Abobe XMP metadata
1042 FreeImage_SetMetadata(FIMD_GEOTIFF, _dib, NULL, NULL); // GeoTIFF metadata
1043 FreeImage_SetMetadata(FIMD_ANIMATION, _dib, NULL, NULL); // Animation metadata
1044 FreeImage_SetMetadata(FIMD_CUSTOM, _dib, NULL, NULL); // Used to attach other metadata types to a dib
1045 FreeImage_SetMetadata(FIMD_EXIF_RAW, _dib, NULL, NULL); // Exif metadata as a raw buffer
1046 }
1047
1048