/src/freeimage-svn/FreeImage/trunk/Source/FreeImage/ConversionRGB16.cpp
Line | Count | Source |
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 RGB16 |
27 | | // ---------------------------------------------------------- |
28 | | |
29 | | FIBITMAP * DLL_CALLCONV |
30 | 0 | FreeImage_ConvertToRGB16(FIBITMAP *dib) { |
31 | 0 | FIBITMAP *src = NULL; |
32 | 0 | FIBITMAP *dst = NULL; |
33 | |
|
34 | 0 | if(!FreeImage_HasPixels(dib)) return NULL; |
35 | | |
36 | 0 | const FREE_IMAGE_TYPE src_type = FreeImage_GetImageType(dib); |
37 | | |
38 | | // check for allowed conversions |
39 | 0 | switch(src_type) { |
40 | 0 | case FIT_BITMAP: |
41 | 0 | { |
42 | | // convert to 24-bit if needed |
43 | 0 | if((FreeImage_GetBPP(dib) == 24) || (FreeImage_GetBPP(dib) == 32)) { |
44 | 0 | src = dib; |
45 | 0 | } else { |
46 | 0 | src = FreeImage_ConvertTo24Bits(dib); |
47 | 0 | if(!src) return NULL; |
48 | 0 | } |
49 | 0 | break; |
50 | 0 | } |
51 | 0 | case FIT_UINT16: |
52 | | // allow conversion from unsigned 16-bit |
53 | 0 | src = dib; |
54 | 0 | break; |
55 | 0 | case FIT_RGB16: |
56 | | // RGB16 type : clone the src |
57 | 0 | return FreeImage_Clone(dib); |
58 | 0 | break; |
59 | 0 | case FIT_RGBA16: |
60 | | // allow conversion from 64-bit RGBA (ignore the alpha channel) |
61 | 0 | src = dib; |
62 | 0 | break; |
63 | 0 | default: |
64 | 0 | return NULL; |
65 | 0 | } |
66 | | |
67 | | // allocate dst image |
68 | | |
69 | 0 | const unsigned width = FreeImage_GetWidth(src); |
70 | 0 | const unsigned height = FreeImage_GetHeight(src); |
71 | |
|
72 | 0 | dst = FreeImage_AllocateT(FIT_RGB16, width, height); |
73 | 0 | if(!dst) { |
74 | 0 | if(src != dib) { |
75 | 0 | FreeImage_Unload(src); |
76 | 0 | } |
77 | 0 | return NULL; |
78 | 0 | } |
79 | | |
80 | | // copy metadata from src to dst |
81 | 0 | FreeImage_CloneMetadata(dst, src); |
82 | | |
83 | | // convert from src type to RGB16 |
84 | |
|
85 | 0 | switch(src_type) { |
86 | 0 | case FIT_BITMAP: |
87 | 0 | { |
88 | | // Calculate the number of bytes per pixel (1 for 8-bit, 3 for 24-bit or 4 for 32-bit) |
89 | 0 | const unsigned bytespp = FreeImage_GetLine(src) / FreeImage_GetWidth(src); |
90 | |
|
91 | 0 | for(unsigned y = 0; y < height; y++) { |
92 | 0 | const BYTE *src_bits = (BYTE*)FreeImage_GetScanLine(src, y); |
93 | 0 | FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y); |
94 | 0 | for(unsigned x = 0; x < width; x++) { |
95 | 0 | dst_bits[x].red = src_bits[FI_RGBA_RED] << 8; |
96 | 0 | dst_bits[x].green = src_bits[FI_RGBA_GREEN] << 8; |
97 | 0 | dst_bits[x].blue = src_bits[FI_RGBA_BLUE] << 8; |
98 | 0 | src_bits += bytespp; |
99 | 0 | } |
100 | 0 | } |
101 | 0 | } |
102 | 0 | break; |
103 | | |
104 | 0 | case FIT_UINT16: |
105 | 0 | { |
106 | 0 | for(unsigned y = 0; y < height; y++) { |
107 | 0 | const WORD *src_bits = (WORD*)FreeImage_GetScanLine(src, y); |
108 | 0 | FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y); |
109 | 0 | for(unsigned x = 0; x < width; x++) { |
110 | | // convert by copying greyscale channel to each R, G, B channels |
111 | 0 | dst_bits[x].red = src_bits[x]; |
112 | 0 | dst_bits[x].green = src_bits[x]; |
113 | 0 | dst_bits[x].blue = src_bits[x]; |
114 | 0 | } |
115 | 0 | } |
116 | 0 | } |
117 | 0 | break; |
118 | | |
119 | 0 | case FIT_RGBA16: |
120 | 0 | { |
121 | 0 | for(unsigned y = 0; y < height; y++) { |
122 | 0 | const FIRGBA16 *src_bits = (FIRGBA16*)FreeImage_GetScanLine(src, y); |
123 | 0 | FIRGB16 *dst_bits = (FIRGB16*)FreeImage_GetScanLine(dst, y); |
124 | 0 | for(unsigned x = 0; x < width; x++) { |
125 | | // convert and skip alpha channel |
126 | 0 | dst_bits[x].red = src_bits[x].red; |
127 | 0 | dst_bits[x].green = src_bits[x].green; |
128 | 0 | dst_bits[x].blue = src_bits[x].blue; |
129 | 0 | } |
130 | 0 | } |
131 | 0 | } |
132 | 0 | break; |
133 | | |
134 | 0 | default: |
135 | 0 | break; |
136 | 0 | } |
137 | | |
138 | 0 | if(src != dib) { |
139 | 0 | FreeImage_Unload(src); |
140 | 0 | } |
141 | |
|
142 | 0 | return dst; |
143 | 0 | } |
144 | | |