/src/freeimage-svn/FreeImage/trunk/Source/FreeImage/PluginKOALA.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // ========================================================== |
2 | | // KOALA Loader |
3 | | // |
4 | | // Design and implementation by |
5 | | // - Floris van den Berg (flvdberg@wxs.nl) |
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 | | // Constants + headers |
27 | | // ---------------------------------------------------------- |
28 | | |
29 | | #ifdef _WIN32 |
30 | | #pragma pack(push, 1) |
31 | | #else |
32 | | #pragma pack(1) |
33 | | #endif |
34 | | |
35 | | typedef struct tagKOALA { |
36 | | BYTE image[8000]; // pixmap image |
37 | | BYTE colour1[1000]; // first colourmap (colour 1 and 2) |
38 | | BYTE colour2[1000]; // second colourmap (colour 3) |
39 | | BYTE background; // background colour |
40 | | } koala_t; |
41 | | |
42 | | struct colour_t { |
43 | | int r; |
44 | | int g; |
45 | | int b; |
46 | | }; |
47 | | |
48 | | #ifdef _WIN32 |
49 | | #pragma pack(pop) |
50 | | #else |
51 | | #pragma pack() |
52 | | #endif |
53 | | |
54 | | // ---------------------------------------------------------- |
55 | | |
56 | 0 | #define CBM_WIDTH 320 |
57 | 0 | #define CBM_HEIGHT 200 |
58 | | |
59 | | // ---------------------------------------------------------- |
60 | | |
61 | | const colour_t c64colours[16] = { |
62 | | { 0, 0, 0 }, // Black |
63 | | { 255, 255, 255 }, // White |
64 | | { 170, 17, 17 }, // Red |
65 | | { 12, 204, 204 }, // Cyan |
66 | | { 221, 51, 221 }, // Purple |
67 | | { 0, 187, 0 }, // Green |
68 | | { 0, 0, 204 }, // Blue |
69 | | { 255, 255, 140 }, // Yellow |
70 | | { 204, 119, 34 }, // Orange |
71 | | { 136, 68, 0 }, // Brown |
72 | | { 255, 153, 136 }, // Light red |
73 | | { 92, 92, 92 }, // Gray 1 |
74 | | { 170, 170, 170 }, // Gray 2 |
75 | | { 140, 255, 178 }, // Light green |
76 | | { 39, 148, 255 }, // Light blue |
77 | | { 196, 196, 196 } // Gray 3 |
78 | | }; |
79 | | |
80 | | // ========================================================== |
81 | | // Plugin Interface |
82 | | // ========================================================== |
83 | | |
84 | | static int s_format_id; |
85 | | |
86 | | // ========================================================== |
87 | | // Plugin Implementation |
88 | | // ========================================================== |
89 | | |
90 | | const char * DLL_CALLCONV |
91 | 2 | Format() { |
92 | 2 | return "KOALA"; |
93 | 2 | } |
94 | | |
95 | | const char * DLL_CALLCONV |
96 | 0 | Description() { |
97 | 0 | return "C64 Koala Graphics"; |
98 | 0 | } |
99 | | |
100 | | const char * DLL_CALLCONV |
101 | 0 | Extension() { |
102 | 0 | return "koa"; |
103 | 0 | } |
104 | | |
105 | | const char * DLL_CALLCONV |
106 | 0 | RegExpr() { |
107 | 0 | return NULL; |
108 | 0 | } |
109 | | |
110 | | static const char * DLL_CALLCONV |
111 | 0 | MimeType() { |
112 | 0 | return "image/x-koala"; |
113 | 0 | } |
114 | | |
115 | | static BOOL DLL_CALLCONV |
116 | 24.3k | Validate(FreeImageIO *io, fi_handle handle) { |
117 | 24.3k | BYTE koala_signature[] = { 0x00, 0x60 }; |
118 | 24.3k | BYTE signature[2] = { 0, 0 }; |
119 | | |
120 | 24.3k | io->read_proc(signature, 1, sizeof(koala_signature), handle); |
121 | | |
122 | 24.3k | return (memcmp(koala_signature, signature, sizeof(koala_signature)) == 0); |
123 | 24.3k | } |
124 | | |
125 | | static BOOL DLL_CALLCONV |
126 | 0 | SupportsExportDepth(int depth) { |
127 | 0 | return FALSE; |
128 | 0 | } |
129 | | |
130 | | static BOOL DLL_CALLCONV |
131 | 0 | SupportsExportType(FREE_IMAGE_TYPE type) { |
132 | 0 | return FALSE; |
133 | 0 | } |
134 | | |
135 | | // ---------------------------------------------------------- |
136 | | |
137 | | FIBITMAP * DLL_CALLCONV |
138 | 0 | Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { |
139 | 0 | if (handle) { |
140 | 0 | koala_t image; |
141 | | |
142 | | // read the load address |
143 | |
|
144 | 0 | unsigned char load_address[2]; // highbit, lowbit |
145 | |
|
146 | 0 | io->read_proc(&load_address, 1, 2, handle); |
147 | | |
148 | | // if the load address is correct, skip it. otherwise ignore the load address |
149 | |
|
150 | 0 | if ((load_address[0] != 0x00) || (load_address[1] != 0x60)) { |
151 | 0 | ((BYTE *)&image)[0] = load_address[0]; |
152 | 0 | ((BYTE *)&image)[1] = load_address[1]; |
153 | |
|
154 | 0 | io->read_proc((BYTE *)&image + 2, 1, 10001 - 2, handle); |
155 | 0 | } else { |
156 | 0 | io->read_proc(&image, 1, 10001, handle); |
157 | 0 | } |
158 | | |
159 | | // build DIB in memory |
160 | |
|
161 | 0 | FIBITMAP *dib = FreeImage_Allocate(CBM_WIDTH, CBM_HEIGHT, 4); |
162 | |
|
163 | 0 | if (dib) { |
164 | | // write out the commodore 64 color palette |
165 | |
|
166 | 0 | RGBQUAD *palette = FreeImage_GetPalette(dib); |
167 | |
|
168 | 0 | for (int i = 0; i < 16; i++) { |
169 | 0 | palette[i].rgbBlue = (BYTE)c64colours[i].b; |
170 | 0 | palette[i].rgbGreen = (BYTE)c64colours[i].g; |
171 | 0 | palette[i].rgbRed = (BYTE)c64colours[i].r; |
172 | 0 | } |
173 | | |
174 | | // write out bitmap data |
175 | |
|
176 | 0 | BYTE pixel_mask[4] = { 0xc0, 0x30, 0x0c, 0x03 }; |
177 | 0 | BYTE pixel_displacement[4] = { 6, 4, 2, 0 }; |
178 | 0 | int pixel, index, colourindex; |
179 | 0 | unsigned char found_color = 0; |
180 | |
|
181 | 0 | for (int y = 0; y < 200; y++) { |
182 | 0 | for (int x = 0; x < 160; x++) { |
183 | | // Get value of pixel at (x,y) |
184 | |
|
185 | 0 | index = (x / 4) * 8 + (y % 8) + (y / 8) * CBM_WIDTH; |
186 | 0 | colourindex = (x / 4) + (y / 8) * 40; |
187 | 0 | pixel = (image.image[index] & pixel_mask[x % 4]) >> pixel_displacement[x % 4]; |
188 | | |
189 | | // Retrieve RGB values |
190 | |
|
191 | 0 | switch (pixel) { |
192 | 0 | case 0: // Background |
193 | 0 | found_color = image.background; |
194 | 0 | break; |
195 | | |
196 | 0 | case 1: // Colour 1 |
197 | 0 | found_color = image.colour1[colourindex] >> 4; |
198 | 0 | break; |
199 | | |
200 | 0 | case 2: // Colour 2 |
201 | 0 | found_color = image.colour1[colourindex] & 0xf; |
202 | 0 | break; |
203 | | |
204 | 0 | case 3: // Colour 3 |
205 | 0 | found_color = image.colour2[colourindex] & 0xf; |
206 | 0 | break; |
207 | 0 | }; |
208 | |
|
209 | 0 | *(FreeImage_GetScanLine(dib, CBM_HEIGHT - y - 1) + x) = (found_color << 4) | found_color; |
210 | 0 | } |
211 | 0 | } |
212 | | |
213 | 0 | return dib; |
214 | 0 | } |
215 | 0 | } |
216 | | |
217 | 0 | return NULL; |
218 | 0 | } |
219 | | |
220 | | // ========================================================== |
221 | | // Init |
222 | | // ========================================================== |
223 | | |
224 | | void DLL_CALLCONV |
225 | 2 | InitKOALA(Plugin *plugin, int format_id) { |
226 | 2 | s_format_id = format_id; |
227 | | |
228 | 2 | plugin->format_proc = Format; |
229 | 2 | plugin->description_proc = Description; |
230 | 2 | plugin->extension_proc = Extension; |
231 | 2 | plugin->regexpr_proc = RegExpr; |
232 | 2 | plugin->open_proc = NULL; |
233 | 2 | plugin->close_proc = NULL; |
234 | 2 | plugin->pagecount_proc = NULL; |
235 | 2 | plugin->pagecapability_proc = NULL; |
236 | 2 | plugin->load_proc = Load; |
237 | 2 | plugin->save_proc = NULL; |
238 | 2 | plugin->validate_proc = Validate; |
239 | 2 | plugin->mime_proc = MimeType; |
240 | 2 | plugin->supports_export_bpp_proc = SupportsExportDepth; |
241 | 2 | plugin->supports_export_type_proc = SupportsExportType; |
242 | 2 | plugin->supports_icc_profiles_proc = NULL; |
243 | 2 | } |