1 // ==========================================================
2 // Bitmap conversion routines
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 "FreeImage.h"
23 #include "Utilities.h"
24
25 // ----------------------------------------------------------
26 // smart convert X to UINT16
27 // ----------------------------------------------------------
28
29 FIBITMAP * DLL_CALLCONV
FreeImage_ConvertToUINT16(FIBITMAP * dib)30 FreeImage_ConvertToUINT16(FIBITMAP *dib) {
31 FIBITMAP *src = NULL;
32 FIBITMAP *dst = NULL;
33
34 if(!FreeImage_HasPixels(dib)) return NULL;
35
36 const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib);
37
38 // check for allowed conversions
39 switch(src_type) {
40 case FIT_BITMAP:
41 {
42 // convert to greyscale if needed
43 if((FreeImage_GetBPP(dib) == 8) && (FreeImage_GetColorType(dib) == FIC_MINISBLACK)) {
44 src = dib;
45 } else {
46 src = FreeImage_ConvertToGreyscale(dib);
47 if(!src) return NULL;
48 }
49 break;
50 }
51 case FIT_UINT16:
52 // UINT16 type : clone the src
53 return FreeImage_Clone(dib);
54 break;
55 case FIT_RGB16:
56 // allow conversion from 48-bit RGB
57 src = dib;
58 break;
59 case FIT_RGBA16:
60 // allow conversion from 64-bit RGBA (ignore the alpha channel)
61 src = dib;
62 break;
63 default:
64 return NULL;
65 }
66
67 // allocate dst image
68
69 const unsigned width = FreeImage_GetWidth(src);
70 const unsigned height = FreeImage_GetHeight(src);
71
72 dst = FreeImage_AllocateT(FIT_UINT16, width, height);
73 if(!dst) {
74 if(src != dib) {
75 FreeImage_Unload(src);
76 }
77 return NULL;
78 }
79
80 // copy metadata from src to dst
81 FreeImage_CloneMetadata(dst, src);
82
83 // convert from src type to UINT16
84
85 switch(src_type) {
86 case FIT_BITMAP:
87 {
88 for(unsigned y = 0; y < height; y++) {
89 const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y);
90 WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
91 for(unsigned x = 0; x < width; x++) {
92 dst_bits[x] = src_bits[x] << 8;
93 }
94 }
95 }
96 break;
97
98 case FIT_RGB16:
99 {
100 for(unsigned y = 0; y < height; y++) {
101 const FIRGB16 *src_bits = (FIRGB16*)FreeImage_GetScanLine(src, y);
102 WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
103 for(unsigned x = 0; x < width; x++) {
104 // convert to grey
105 dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue);
106 }
107 }
108 }
109 break;
110
111 case FIT_RGBA16:
112 {
113 for(unsigned y = 0; y < height; y++) {
114 const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y);
115 WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dst, y);
116 for(unsigned x = 0; x < width; x++) {
117 // convert to grey
118 dst_bits[x] = (WORD)LUMA_REC709(src_bits[x].red, src_bits[x].green, src_bits[x].blue);
119 }
120 }
121 }
122 break;
123
124 default:
125 break;
126 }
127
128 if(src != dib) {
129 FreeImage_Unload(src);
130 }
131
132 return dst;
133 }
134
135