/src/freeimage-svn/FreeImage/trunk/Source/FreeImage/Conversion16_555.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // ========================================================== |
2 | | // Bitmap conversion routines |
3 | | // |
4 | | // Design and implementation by |
5 | | // - Floris van den Berg (flvdberg@wxs.nl) |
6 | | // - Hervé Drolon (drolon@infonie.fr) |
7 | | // - Jani Kajala (janik@remedy.fi) |
8 | | // |
9 | | // This file is part of FreeImage 3 |
10 | | // |
11 | | // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY |
12 | | // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES |
13 | | // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE |
14 | | // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED |
15 | | // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT |
16 | | // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY |
17 | | // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL |
18 | | // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER |
19 | | // THIS DISCLAIMER. |
20 | | // |
21 | | // Use at your own risk! |
22 | | // ========================================================== |
23 | | |
24 | | #include "FreeImage.h" |
25 | | #include "Utilities.h" |
26 | | |
27 | | // ---------------------------------------------------------- |
28 | | |
29 | 0 | #define RGB555(b, g, r) ((((b) >> 3) << FI16_555_BLUE_SHIFT) | (((g) >> 3) << FI16_555_GREEN_SHIFT) | (((r) >> 3) << FI16_555_RED_SHIFT)) |
30 | | |
31 | | // ---------------------------------------------------------- |
32 | | // internal conversions X to 16 bits (555) |
33 | | // ---------------------------------------------------------- |
34 | | |
35 | | void DLL_CALLCONV |
36 | 0 | FreeImage_ConvertLine1To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) { |
37 | 0 | WORD *new_bits = (WORD *)target; |
38 | |
|
39 | 0 | for (int cols = 0; cols < width_in_pixels; cols++) { |
40 | 0 | int index = (source[cols >> 3] & (0x80 >> (cols & 0x07))) != 0 ? 1 : 0; |
41 | |
|
42 | 0 | new_bits[cols] = RGB555(palette[index].rgbBlue, palette[index].rgbGreen, palette[index].rgbRed); |
43 | 0 | } |
44 | 0 | } |
45 | | |
46 | | void DLL_CALLCONV |
47 | 0 | FreeImage_ConvertLine4To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) { |
48 | 0 | WORD *new_bits = (WORD *)target; |
49 | 0 | BOOL lonibble = FALSE; |
50 | 0 | int x = 0; |
51 | |
|
52 | 0 | for (int cols = 0; cols < width_in_pixels; cols++) { |
53 | 0 | RGBQUAD *grab_palette; |
54 | |
|
55 | 0 | if (lonibble) { |
56 | 0 | grab_palette = palette + LOWNIBBLE(source[x++]); |
57 | 0 | } else { |
58 | 0 | grab_palette = palette + (HINIBBLE(source[x]) >> 4); |
59 | 0 | } |
60 | |
|
61 | 0 | new_bits[cols] = RGB555(grab_palette->rgbBlue, grab_palette->rgbGreen, grab_palette->rgbRed); |
62 | |
|
63 | 0 | lonibble = !lonibble; |
64 | 0 | } |
65 | 0 | } |
66 | | |
67 | | void DLL_CALLCONV |
68 | 0 | FreeImage_ConvertLine8To16_555(BYTE *target, BYTE *source, int width_in_pixels, RGBQUAD *palette) { |
69 | 0 | WORD *new_bits = (WORD *)target; |
70 | |
|
71 | 0 | for (int cols = 0; cols < width_in_pixels; cols++) { |
72 | 0 | RGBQUAD *grab_palette = palette + source[cols]; |
73 | |
|
74 | 0 | new_bits[cols] = RGB555(grab_palette->rgbBlue, grab_palette->rgbGreen, grab_palette->rgbRed); |
75 | 0 | } |
76 | 0 | } |
77 | | |
78 | | void DLL_CALLCONV |
79 | 0 | FreeImage_ConvertLine16_565_To16_555(BYTE *target, BYTE *source, int width_in_pixels) { |
80 | 0 | WORD *src_bits = (WORD *)source; |
81 | 0 | WORD *new_bits = (WORD *)target; |
82 | |
|
83 | 0 | for (int cols = 0; cols < width_in_pixels; cols++) { |
84 | 0 | new_bits[cols] = RGB555((((src_bits[cols] & FI16_565_BLUE_MASK) >> FI16_565_BLUE_SHIFT) * 0xFF) / 0x1F, |
85 | 0 | (((src_bits[cols] & FI16_565_GREEN_MASK) >> FI16_565_GREEN_SHIFT) * 0xFF) / 0x3F, |
86 | 0 | (((src_bits[cols] & FI16_565_RED_MASK) >> FI16_565_RED_SHIFT) * 0xFF) / 0x1F); |
87 | 0 | } |
88 | 0 | } |
89 | | |
90 | | void DLL_CALLCONV |
91 | 0 | FreeImage_ConvertLine24To16_555(BYTE *target, BYTE *source, int width_in_pixels) { |
92 | 0 | WORD *new_bits = (WORD *)target; |
93 | |
|
94 | 0 | for (int cols = 0; cols < width_in_pixels; cols++) { |
95 | 0 | new_bits[cols] = RGB555(source[FI_RGBA_BLUE], source[FI_RGBA_GREEN], source[FI_RGBA_RED]); |
96 | |
|
97 | 0 | source += 3; |
98 | 0 | } |
99 | 0 | } |
100 | | |
101 | | void DLL_CALLCONV |
102 | 0 | FreeImage_ConvertLine32To16_555(BYTE *target, BYTE *source, int width_in_pixels) { |
103 | 0 | WORD *new_bits = (WORD *)target; |
104 | |
|
105 | 0 | for (int cols = 0; cols < width_in_pixels; cols++) { |
106 | 0 | new_bits[cols] = RGB555(source[FI_RGBA_BLUE], source[FI_RGBA_GREEN], source[FI_RGBA_RED]); |
107 | |
|
108 | 0 | source += 4; |
109 | 0 | } |
110 | 0 | } |
111 | | |
112 | | // ---------------------------------------------------------- |
113 | | // smart convert X to 16 bits |
114 | | // ---------------------------------------------------------- |
115 | | |
116 | | FIBITMAP * DLL_CALLCONV |
117 | 0 | FreeImage_ConvertTo16Bits555(FIBITMAP *dib) { |
118 | 0 | if(!FreeImage_HasPixels(dib) || (FreeImage_GetImageType(dib) != FIT_BITMAP)) return NULL; |
119 | | |
120 | 0 | const int width = FreeImage_GetWidth(dib); |
121 | 0 | const int height = FreeImage_GetHeight(dib); |
122 | 0 | const int bpp = FreeImage_GetBPP(dib); |
123 | |
|
124 | 0 | if(bpp == 16) { |
125 | 0 | if ((FreeImage_GetRedMask(dib) == FI16_565_RED_MASK) && (FreeImage_GetGreenMask(dib) == FI16_565_GREEN_MASK) && (FreeImage_GetBlueMask(dib) == FI16_565_BLUE_MASK)) { |
126 | | // RGB 565 |
127 | 0 | FIBITMAP *new_dib = FreeImage_Allocate(width, height, 16, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK); |
128 | 0 | if(new_dib == NULL) { |
129 | 0 | return NULL; |
130 | 0 | } |
131 | 0 | for (int rows = 0; rows < height; rows++) { |
132 | 0 | FreeImage_ConvertLine16_565_To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width); |
133 | 0 | } |
134 | | |
135 | | // copy metadata from src to dst |
136 | 0 | FreeImage_CloneMetadata(new_dib, dib); |
137 | |
|
138 | 0 | return new_dib; |
139 | 0 | } else { |
140 | | // RGB 555 |
141 | 0 | return FreeImage_Clone(dib); |
142 | 0 | } |
143 | 0 | } |
144 | 0 | else { |
145 | | // other bpp cases => convert to RGB 555 |
146 | 0 | FIBITMAP *new_dib = FreeImage_Allocate(width, height, 16, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK); |
147 | 0 | if(new_dib == NULL) { |
148 | 0 | return NULL; |
149 | 0 | } |
150 | | |
151 | | // copy metadata from src to dst |
152 | 0 | FreeImage_CloneMetadata(new_dib, dib); |
153 | |
|
154 | 0 | switch (bpp) { |
155 | 0 | case 1 : |
156 | 0 | { |
157 | 0 | for (int rows = 0; rows < height; rows++) { |
158 | 0 | FreeImage_ConvertLine1To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib)); |
159 | 0 | } |
160 | |
|
161 | 0 | return new_dib; |
162 | 0 | } |
163 | | |
164 | 0 | case 4 : |
165 | 0 | { |
166 | 0 | for (int rows = 0; rows < height; rows++) { |
167 | 0 | FreeImage_ConvertLine4To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib)); |
168 | 0 | } |
169 | |
|
170 | 0 | return new_dib; |
171 | 0 | } |
172 | | |
173 | 0 | case 8 : |
174 | 0 | { |
175 | 0 | for (int rows = 0; rows < height; rows++) { |
176 | 0 | FreeImage_ConvertLine8To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width, FreeImage_GetPalette(dib)); |
177 | 0 | } |
178 | |
|
179 | 0 | return new_dib; |
180 | 0 | } |
181 | | |
182 | 0 | case 24 : |
183 | 0 | { |
184 | 0 | for (int rows = 0; rows < height; rows++) { |
185 | 0 | FreeImage_ConvertLine24To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width); |
186 | 0 | } |
187 | |
|
188 | 0 | return new_dib; |
189 | 0 | } |
190 | | |
191 | 0 | case 32 : |
192 | 0 | { |
193 | 0 | for (int rows = 0; rows < height; rows++) { |
194 | 0 | FreeImage_ConvertLine32To16_555(FreeImage_GetScanLine(new_dib, rows), FreeImage_GetScanLine(dib, rows), width); |
195 | 0 | } |
196 | |
|
197 | 0 | return new_dib; |
198 | 0 | } |
199 | | |
200 | 0 | default : |
201 | | // unreachable code ... |
202 | 0 | FreeImage_Unload(new_dib); |
203 | 0 | break; |
204 | |
|
205 | 0 | } |
206 | 0 | } |
207 | | |
208 | 0 | return NULL; |
209 | 0 | } |