1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <errno.h>
7 #include <fnmatch.h>
8 #include <netinet/in.h>
9 #include <gdk/gdk.h>
10 
11 #include "macres.h"
12 #include "cicn.h"
13 
14 static RGBColor rgb_8[256] = {
15 	{ 0xff00, 0xff00, 0xff00 },
16 	{ 0xff00, 0xfe00, 0xcb00 },
17 	{ 0xff00, 0xfe00, 0x9a00 },
18 	{ 0xff00, 0xfe00, 0x6600 },
19 	{ 0xff00, 0xfe00, 0x3300 },
20 	{ 0xfe00, 0xfe00, 0x0000 },
21 	{ 0xff00, 0xcb00, 0xfe00 },
22 	{ 0xff00, 0xcb00, 0xcb00 },
23 	{ 0xff00, 0xcc00, 0x9a00 },
24 	{ 0xff00, 0xcc00, 0x6600 },
25 	{ 0xff00, 0xcc00, 0x3300 },
26 	{ 0xfe00, 0xcb00, 0x0000 },
27 	{ 0xff00, 0x9a00, 0xfe00 },
28 	{ 0xff00, 0x9a00, 0xcc00 },
29 	{ 0xff00, 0x9a00, 0x9a00 },
30 	{ 0xff00, 0x9900, 0x6600 },
31 	{ 0xff00, 0x9900, 0x3300 },
32 	{ 0xfe00, 0x9800, 0x0000 },
33 	{ 0xff00, 0x6600, 0xfe00 },
34 	{ 0xff00, 0x6600, 0xcc00 },
35 	{ 0xff00, 0x6600, 0x9900 },
36 	{ 0xff00, 0x6600, 0x6600 },
37 	{ 0xff00, 0x6600, 0x3300 },
38 	{ 0xfe00, 0x6500, 0x0000 },
39 	{ 0xff00, 0x3300, 0xfe00 },
40 	{ 0xff00, 0x3300, 0xcc00 },
41 	{ 0xff00, 0x3300, 0x9900 },
42 	{ 0xff00, 0x3300, 0x6600 },
43 	{ 0xff00, 0x3300, 0x3300 },
44 	{ 0xfe00, 0x3200, 0x0000 },
45 	{ 0xfe00, 0x0000, 0xfe00 },
46 	{ 0xfe00, 0x0000, 0xcb00 },
47 	{ 0xfe00, 0x0000, 0x9800 },
48 	{ 0xfe00, 0x0000, 0x6500 },
49 	{ 0xfe00, 0x0000, 0x3200 },
50 	{ 0xfe00, 0x0000, 0x0000 },
51 	{ 0xcb00, 0xff00, 0xff00 },
52 	{ 0xcb00, 0xff00, 0xcb00 },
53 	{ 0xcc00, 0xff00, 0x9a00 },
54 	{ 0xcc00, 0xff00, 0x6600 },
55 	{ 0xcc00, 0xff00, 0x3300 },
56 	{ 0xcb00, 0xfe00, 0x0000 },
57 	{ 0xcb00, 0xcb00, 0xff00 },
58 	{ 0xcc00, 0xcc00, 0xcc00 },
59 	{ 0xcc00, 0xcc00, 0x9900 },
60 	{ 0xcc00, 0xcc00, 0x6600 },
61 	{ 0xcb00, 0xcb00, 0x3200 },
62 	{ 0xcd00, 0xcd00, 0x0000 },
63 	{ 0xcc00, 0x9a00, 0xff00 },
64 	{ 0xcc00, 0x9900, 0xcc00 },
65 	{ 0xcc00, 0x9900, 0x9900 },
66 	{ 0xcc00, 0x9900, 0x6600 },
67 	{ 0xcb00, 0x9800, 0x3200 },
68 	{ 0xcd00, 0x9a00, 0x0000 },
69 	{ 0xcc00, 0x6600, 0xff00 },
70 	{ 0xcc00, 0x6600, 0xcc00 },
71 	{ 0xcc00, 0x6600, 0x9900 },
72 	{ 0xcc00, 0x6600, 0x6600 },
73 	{ 0xcb00, 0x6500, 0x3200 },
74 	{ 0xcd00, 0x6600, 0x0000 },
75 	{ 0xcc00, 0x3300, 0xff00 },
76 	{ 0xcb00, 0x3200, 0xcb00 },
77 	{ 0xcb00, 0x3200, 0x9800 },
78 	{ 0xcb00, 0x3200, 0x6500 },
79 	{ 0xcb00, 0x3200, 0x3200 },
80 	{ 0xcd00, 0x3300, 0x0000 },
81 	{ 0xcb00, 0x0000, 0xfe00 },
82 	{ 0xcd00, 0x0000, 0xcd00 },
83 	{ 0xcd00, 0x0000, 0x9a00 },
84 	{ 0xcd00, 0x0000, 0x6600 },
85 	{ 0xcd00, 0x0000, 0x3300 },
86 	{ 0xcd00, 0x0000, 0x0000 },
87 	{ 0x9a00, 0xff00, 0xff00 },
88 	{ 0x9a00, 0xff00, 0xcc00 },
89 	{ 0x9a00, 0xff00, 0x9a00 },
90 	{ 0x9900, 0xff00, 0x6600 },
91 	{ 0x9900, 0xff00, 0x3300 },
92 	{ 0x9900, 0xfe00, 0x0000 },
93 	{ 0x9a00, 0xcc00, 0xff00 },
94 	{ 0x9900, 0xcc00, 0xcc00 },
95 	{ 0x0000, 0x9800, 0x6500 },
96 	{ 0x9900, 0xcc00, 0x6600 },
97 	{ 0x9900, 0xcb00, 0x3200 },
98 	{ 0x9a00, 0xcd00, 0x0000 },
99 	{ 0x9a00, 0x9a00, 0xff00 },
100 	{ 0x9900, 0x9900, 0xcc00 },
101 	{ 0x9900, 0x9900, 0x9900 },
102 	{ 0x9800, 0x9800, 0x6500 },
103 	{ 0x9a00, 0x9a00, 0x3300 },
104 	{ 0x9800, 0x9800, 0x0000 },
105 	{ 0x9900, 0x6600, 0xff00 },
106 	{ 0x9900, 0x6600, 0xcc00 },
107 	{ 0x9800, 0x6500, 0x9800 },
108 	{ 0x9800, 0x6500, 0x6500 },
109 	{ 0x9a00, 0x6600, 0x3300 },
110 	{ 0x9800, 0x6500, 0x0000 },
111 	{ 0x9900, 0x3300, 0xff00 },
112 	{ 0x9800, 0x3200, 0xcb00 },
113 	{ 0x9a00, 0x3300, 0x9a00 },
114 	{ 0x9a00, 0x3300, 0x6600 },
115 	{ 0x9a00, 0x3300, 0x3300 },
116 	{ 0x9800, 0x3200, 0x0000 },
117 	{ 0x9800, 0x0000, 0xfe00 },
118 	{ 0x9a00, 0x0000, 0xcd00 },
119 	{ 0x9800, 0x0000, 0x9800 },
120 	{ 0x9800, 0x0000, 0x6500 },
121 	{ 0x9800, 0x0000, 0x3200 },
122 	{ 0x9800, 0x0000, 0x0000 },
123 	{ 0x6600, 0xff00, 0xff00 },
124 	{ 0x6600, 0xff00, 0xcc00 },
125 	{ 0x6600, 0xff00, 0x9900 },
126 	{ 0x6600, 0xff00, 0x6600 },
127 	{ 0x6600, 0xff00, 0x3300 },
128 	{ 0x6600, 0xfe00, 0x0000 },
129 	{ 0x6600, 0xcc00, 0xff00 },
130 	{ 0x6600, 0xcc00, 0xcc00 },
131 	{ 0x6600, 0xcc00, 0x9900 },
132 	{ 0x6600, 0xcc00, 0x6600 },
133 	{ 0x6600, 0xcb00, 0x3200 },
134 	{ 0x6600, 0xcd00, 0x0000 },
135 	{ 0x6600, 0x9900, 0xff00 },
136 	{ 0x6600, 0x9900, 0xcc00 },
137 	{ 0x6500, 0x9800, 0x9800 },
138 	{ 0x6500, 0x9800, 0x6500 },
139 	{ 0x6600, 0x9a00, 0x3300 },
140 	{ 0x6500, 0x9800, 0x0000 },
141 	{ 0x6600, 0x6600, 0xff00 },
142 	{ 0x6600, 0x6600, 0xcc00 },
143 	{ 0x6500, 0x6500, 0x9800 },
144 	{ 0x6600, 0x6600, 0x6600 },
145 	{ 0x6500, 0x6500, 0x3200 },
146 	{ 0x6600, 0x6600, 0x0000 },
147 	{ 0x6600, 0x3300, 0xff00 },
148 	{ 0x6500, 0x3200, 0xcb00 },
149 	{ 0x6600, 0x3300, 0x9a00 },
150 	{ 0x6500, 0x3200, 0x6500 },
151 	{ 0x6500, 0x3200, 0x3200 },
152 	{ 0x6600, 0x3300, 0x0000 },
153 	{ 0x6500, 0x0000, 0xfe00 },
154 	{ 0x6600, 0x0000, 0xcd00 },
155 	{ 0x6500, 0x0000, 0x9800 },
156 	{ 0x6600, 0x0000, 0x6600 },
157 	{ 0x6600, 0x0000, 0x3300 },
158 	{ 0x6600, 0x0000, 0x0000 },
159 	{ 0x3300, 0xff00, 0xff00 },
160 	{ 0x3300, 0xff00, 0xcc00 },
161 	{ 0x3300, 0xff00, 0x9900 },
162 	{ 0x3300, 0xff00, 0x6600 },
163 	{ 0x3300, 0xff00, 0x3300 },
164 	{ 0x3300, 0xfe00, 0x0000 },
165 	{ 0x3300, 0xcc00, 0xff00 },
166 	{ 0x3200, 0xcb00, 0xcb00 },
167 	{ 0x3200, 0xcb00, 0x9800 },
168 	{ 0x3200, 0xcb00, 0x6500 },
169 	{ 0x3300, 0xcb00, 0x3200 },
170 	{ 0x3300, 0xcd00, 0x0000 },
171 	{ 0x3300, 0x9900, 0xff00 },
172 	{ 0x3200, 0x9900, 0xcb00 },
173 	{ 0x3300, 0x9a00, 0x9a00 },
174 	{ 0x3300, 0x9a00, 0x6600 },
175 	{ 0x3300, 0x9a00, 0x3300 },
176 	{ 0x3200, 0x9800, 0x0000 },
177 	{ 0x3300, 0x6600, 0xff00 },
178 	{ 0x3200, 0x6600, 0xcb00 },
179 	{ 0x3300, 0x6600, 0x9a00 },
180 	{ 0x3200, 0x6500, 0x6500 },
181 	{ 0x3200, 0x6500, 0x3200 },
182 	{ 0x3300, 0x6600, 0x0000 },
183 	{ 0x3300, 0x3300, 0xff00 },
184 	{ 0x3200, 0x3300, 0xcb00 },
185 	{ 0x3300, 0x3300, 0x9a00 },
186 	{ 0x3200, 0x3200, 0x6500 },
187 	{ 0x3300, 0x3300, 0x3300 },
188 	{ 0x3300, 0x3300, 0x0000 },
189 	{ 0x3200, 0x0000, 0xfe00 },
190 	{ 0x3300, 0x0000, 0xcd00 },
191 	{ 0x3200, 0x0000, 0x9800 },
192 	{ 0x3300, 0x0000, 0x6600 },
193 	{ 0x3300, 0x0000, 0x3300 },
194 	{ 0x3300, 0x0000, 0x0000 },
195 	{ 0x0000, 0xfe00, 0xfe00 },
196 	{ 0x0000, 0xfe00, 0xcb00 },
197 	{ 0x0000, 0xfe00, 0x9800 },
198 	{ 0x0000, 0xfe00, 0x6500 },
199 	{ 0x0000, 0xfe00, 0x3200 },
200 	{ 0x0000, 0xfe00, 0x0000 },
201 	{ 0x0000, 0xcb00, 0xfe00 },
202 	{ 0x0000, 0xcd00, 0xcd00 },
203 	{ 0x0000, 0xcd00, 0x9a00 },
204 	{ 0x0000, 0xcd00, 0x6600 },
205 	{ 0x0000, 0xcd00, 0x3300 },
206 	{ 0x0000, 0xcd00, 0x0000 },
207 	{ 0x0000, 0x9800, 0xfe00 },
208 	{ 0x0000, 0x9a00, 0xcd00 },
209 	{ 0x0000, 0x9800, 0x9800 },
210 	{ 0x0000, 0x9800, 0x6500 },
211 	{ 0x0000, 0x9800, 0x3200 },
212 	{ 0x0000, 0x9800, 0x0000 },
213 	{ 0x0000, 0x6600, 0xfe00 },
214 	{ 0x0000, 0x6600, 0xcd00 },
215 	{ 0x0000, 0x6500, 0x9800 },
216 	{ 0x0000, 0x6600, 0x6600 },
217 	{ 0x0000, 0x6600, 0x3300 },
218 	{ 0x0000, 0x6600, 0x0000 },
219 	{ 0x0000, 0x3300, 0xfe00 },
220 	{ 0x0000, 0x3300, 0xcd00 },
221 	{ 0x0000, 0x3200, 0x9800 },
222 	{ 0x0000, 0x3300, 0x6600 },
223 	{ 0x0000, 0x3300, 0x3300 },
224 	{ 0x0000, 0x3300, 0x0000 },
225 	{ 0x0000, 0x0000, 0xfe00 },
226 	{ 0x0000, 0x0000, 0xcd00 },
227 	{ 0x0000, 0x0000, 0x9800 },
228 	{ 0x0000, 0x0000, 0x6600 },
229 	{ 0x0000, 0x0000, 0x3300 },
230 	{ 0xef00, 0x0000, 0x0000 },
231 	{ 0xdc00, 0x0000, 0x0000 },
232 	{ 0xba00, 0x0000, 0x0000 },
233 	{ 0xab00, 0x0000, 0x0000 },
234 	{ 0x8900, 0x0000, 0x0000 },
235 	{ 0x7700, 0x0000, 0x0000 },
236 	{ 0x5500, 0x0000, 0x0000 },
237 	{ 0x4400, 0x0000, 0x0000 },
238 	{ 0x2200, 0x0000, 0x0000 },
239 	{ 0x1100, 0x0000, 0x0000 },
240 	{ 0x0000, 0xef00, 0x0000 },
241 	{ 0x0000, 0xdc00, 0x0000 },
242 	{ 0x0000, 0xba00, 0x0000 },
243 	{ 0x0000, 0xab00, 0x0000 },
244 	{ 0x0000, 0x8900, 0x0000 },
245 	{ 0x0000, 0x7700, 0x0000 },
246 	{ 0x0000, 0x5500, 0x0000 },
247 	{ 0x0000, 0x4400, 0x0000 },
248 	{ 0x0000, 0x2200, 0x0000 },
249 	{ 0x0000, 0x1100, 0x0000 },
250 	{ 0x0000, 0x0000, 0xef00 },
251 	{ 0x0000, 0x0000, 0xdc00 },
252 	{ 0x0000, 0x0000, 0xba00 },
253 	{ 0x0000, 0x0000, 0xab00 },
254 	{ 0x0000, 0x0000, 0x8900 },
255 	{ 0x0000, 0x0000, 0x7700 },
256 	{ 0x0000, 0x0000, 0x5500 },
257 	{ 0x0000, 0x0000, 0x4400 },
258 	{ 0x0000, 0x0000, 0x2200 },
259 	{ 0x0000, 0x0000, 0x1100 },
260 	{ 0xee00, 0xee00, 0xee00 },
261 	{ 0xdd00, 0xdd00, 0xdd00 },
262 	{ 0xbb00, 0xbb00, 0xbb00 },
263 	{ 0xaa00, 0xaa00, 0xaa00 },
264 	{ 0x8800, 0x8800, 0x8800 },
265 	{ 0x7700, 0x7700, 0x7700 },
266 	{ 0x5500, 0x5500, 0x5500 },
267 	{ 0x4400, 0x4400, 0x4400 },
268 	{ 0x2200, 0x2200, 0x2200 },
269 	{ 0x1100, 0x1100, 0x1100 },
270 	{ 0x0000, 0x0000, 0x0000 }
271 };
272 
273 static RGBColor rgb_4[16] = {
274 	{ 0xffff, 0xffff, 0xffff },
275 	{ 0xffff, 0xffff, 0x0000 },
276 	{ 0xffff, 0xa0a0, 0x7a7a },
277 	{ 0xffff, 0x0000, 0x0000 },
278 	{ 0xffff, 0x1414, 0x9393 },
279 	{ 0x8a8a, 0x2b2b, 0xe2e2 },
280 	{ 0x0000, 0x0000, 0x8080 },
281 	{ 0x6464, 0x9595, 0xeded },
282 	{ 0x2222, 0x8b8b, 0x2222 },
283 	{ 0x0000, 0x6464, 0x0000 },
284 	{ 0x8b8b, 0x4545, 0x1313 },
285 	{ 0xd2d2, 0xb4b4, 0x8c8c },
286 	{ 0xd3d3, 0xd3d3, 0xd3d3 },
287 	{ 0xbebe, 0xbebe, 0xbebe },
288 	{ 0x6969, 0x6969, 0x6969 },
289 	{ 0x0000, 0x0000, 0x0000 }
290 };
291 
292 static RGBColor rgb_2[4] = {
293 	{ 0xffff, 0xffff, 0xffff },
294 	{ 0xffff, 0xffff, 0x0000 },
295 	{ 0x0000, 0xffff, 0xffff },
296 	{ 0x0000, 0x0000, 0x0000 }
297 };
298 
299 static RGBColor rgb_1[2] = {
300 	{ 0xffff, 0xffff, 0xffff },
301 	{ 0x0000, 0x0000, 0x0000 }
302 };
303 
304 void
palette_get_rgb_8(unsigned int * palette)305 palette_get_rgb_8 (unsigned int *palette)
306 {
307 	unsigned int i;
308 
309 	for (i = 0; i < 256; i++) {
310 		palette[i] = ((rgb_8[i].blue >> 8) << 16)
311 			   | ((rgb_8[i].green >> 8) << 8)
312 			   | ((rgb_8[i].red >> 8) << 0)
313 			   | 0xff000000;
314 	}
315 }
316 
317 static unsigned int cmap_8[256], cmap_4[16], cmap_2[4], cmap_1[2];
318 #if WHITE_CLEAR
319 static unsigned int white = 0;
320 #endif
321 
322 static unsigned int
rgb_to_pixel(GdkColormap * colormap,RGBColor * rgb)323 rgb_to_pixel (GdkColormap *colormap, RGBColor *rgb)
324 {
325 	GdkColor col;
326 
327 	col.pixel = 0;
328 	/* col.red = rgb->red;
329 	   col.green = rgb->green;
330 	   col.blue = rgb->blue; */
331 	col.red = (rgb->red & 0xff) | ((rgb->red & 0xff) << 8);
332 	col.green = (rgb->green & 0xff) | ((rgb->green & 0xff) << 8);
333 	col.blue = (rgb->blue & 0xff) | ((rgb->blue & 0xff) << 8);
334 
335 	if (!gdk_colormap_alloc_color(colormap, &col, 0, 1))
336 		fprintf(stderr, "rgb_to_pixel: can't allocate %u/%u/%u\n",
337 			rgb->red, rgb->green, rgb->blue);
338 
339 	return col.pixel;
340 }
341 
342 GdkImage *
cicn_to_gdkimage(GdkColormap * colormap,GdkVisual * visual,void * cicn_rsrc,unsigned int len,GdkImage ** maskimp)343 cicn_to_gdkimage (GdkColormap *colormap, GdkVisual *visual,
344 		  void *cicn_rsrc, unsigned int len, GdkImage **maskimp)
345 {
346 	GdkImage *gim;
347 	GdkImage *mim;
348 	PixMap *pm = (PixMap *)((unsigned char *)cicn_rsrc);
349 	BitMap *mbm = (BitMap *)((unsigned char *)cicn_rsrc + 50);
350 	BitMap *bm = (BitMap *)((unsigned char *)cicn_rsrc + 64);
351 	unsigned int height = ntohs(pm->bounds.bottom) - ntohs(pm->bounds.top);
352 	unsigned int width = ntohs(pm->bounds.right) - ntohs(pm->bounds.left);
353 	unsigned int bpp = ntohs(pm->pixelSize);
354 	ColorTable *ct = (ColorTable *)
355 			((unsigned char *)cicn_rsrc
356 			+ 50 + 14 + 14 + 4
357 			+ (ntohs(mbm->rowBytes) * (ntohs(mbm->bounds.bottom) - ntohs(mbm->bounds.top)))
358 			+ (ntohs(bm->rowBytes) * (ntohs(bm->bounds.bottom) - ntohs(bm->bounds.top))));
359 	unsigned int i, x, y, rowBytes, ctsize;
360 	unsigned int idlen;
361 	unsigned char *base_id, *id;
362 	unsigned char maski, maskp, *maskfb;
363 	unsigned int maskfb_size;
364 
365 #if WHITE_CLEAR
366 	if (!white)
367 		white = rgb_to_pixel(colormap, &rgb_8[0]);
368 #endif
369 
370 	rowBytes = ntohs(pm->rowBytes) & 0x7fff;
371 	idlen = height * rowBytes;
372 	switch (bpp) {
373 		case 8:
374 			for (i = 0; i < 256; i++) cmap_8[i] = 257;
375 			break;
376 		case 4:
377 			for (i = 0; i < 16; i++) cmap_4[i] = 17;
378 			break;
379 		case 2:
380 			for (i = 0; i < 4; i++) cmap_2[i] = 5;
381 			break;
382 		case 1:
383 			for (i = 0; i < 2; i++) cmap_1[i] = 2;
384 			break;
385 		default:
386 			return 0;
387 	}
388 	base_id = (((unsigned char *)cicn_rsrc + len) - idlen);
389 
390 	if (mbm->bounds.right == 0 || mbm->bounds.bottom == 0) {
391 		maskfb = 0;
392 	} else {
393 		unsigned char *md = ((unsigned char *)cicn_rsrc) + 82;
394 		unsigned int mrb = ntohs(mbm->rowBytes);
395 		unsigned int w3 = (width >> 3) + ((width % 8) ? 1 : 0);
396 
397 		maskfb_size = ((((w3<<3) * height) / 8) + 1);
398 		maskfb = malloc(maskfb_size);
399 		if (!maskfb)
400 			return 0;
401 		for (y = 0; y < height; y++) {
402 			id = md + mrb * y;
403 			for (x = 0; x < w3; x++) {
404 				maskfb[y * w3 + x] = ~(*id);
405 				id++;
406 			}
407 		}
408 	}
409 
410 	gim = gdk_image_new(GDK_IMAGE_FASTEST, visual, width, height);
411 	if (!gim)
412 		return 0;
413 
414 	ctsize = ntohs(ct->ctSize) + 1;
415 	for (i = 0; i < ctsize; i++) {
416 		unsigned int v = ntohs(ct->ctTable[i].value);
417 		if (bpp == 8)
418 			cmap_8[v&0xff] = rgb_to_pixel(colormap, &ct->ctTable[i].rgb);
419 		else if (bpp == 4)
420 			cmap_4[v&0xf] = rgb_to_pixel(colormap, &ct->ctTable[i].rgb);
421 		else if (bpp == 2)
422 			cmap_2[v&0x3] = rgb_to_pixel(colormap, &ct->ctTable[i].rgb);
423 		else if (bpp == 1)
424 			cmap_1[v&0x1] = rgb_to_pixel(colormap, &ct->ctTable[i].rgb);
425 	}
426 
427 	if (bpp == 1) {
428 		for (y = 0; y < height; y++) {
429 			id = base_id + rowBytes * y;
430 			for (x = 0; x < width; x++) {
431 				unsigned int i, j, k, l, m, n, o, p;
432 				i = *id >> 7;
433 				j = (*id & 0x40) >> 6;
434 				k = (*id & 0x20) >> 5;
435 				l = (*id & 0x10) >> 4;
436 				m = (*id & 0x8) >> 3;
437 				n = (*id & 0x4) >> 2;
438 				o = (*id & 0x2) >> 1;
439 				p = *id & 0x1;
440 				if (cmap_1[i] == 2)
441 					cmap_1[i] = rgb_to_pixel(colormap, &rgb_1[i]);
442 				if (cmap_1[j] == 2)
443 					cmap_1[j] = rgb_to_pixel(colormap, &rgb_1[j]);
444 				if (cmap_1[k] == 2)
445 					cmap_1[k] = rgb_to_pixel(colormap, &rgb_1[k]);
446 				if (cmap_1[l] == 2)
447 					cmap_1[l] = rgb_to_pixel(colormap, &rgb_1[l]);
448 				if (cmap_1[m] == 2)
449 					cmap_1[m] = rgb_to_pixel(colormap, &rgb_1[m]);
450 				if (cmap_1[n] == 2)
451 					cmap_1[n] = rgb_to_pixel(colormap, &rgb_1[n]);
452 				if (cmap_1[o] == 2)
453 					cmap_1[o] = rgb_to_pixel(colormap, &rgb_1[o]);
454 				if (cmap_1[p] == 2)
455 					cmap_1[p] = rgb_to_pixel(colormap, &rgb_1[p]);
456 				gdk_image_put_pixel(gim, x++, y, cmap_1[i]);
457 				gdk_image_put_pixel(gim, x++, y, cmap_1[j]);
458 				gdk_image_put_pixel(gim, x++, y, cmap_1[k]);
459 				gdk_image_put_pixel(gim, x++, y, cmap_1[l]);
460 				gdk_image_put_pixel(gim, x++, y, cmap_1[m]);
461 				gdk_image_put_pixel(gim, x++, y, cmap_1[n]);
462 				gdk_image_put_pixel(gim, x++, y, cmap_1[o]);
463 				gdk_image_put_pixel(gim, x, y, cmap_1[p]);
464 #if WHITE_CLEAR
465 				if (maskfb) {
466 					maskp = ((cmap_1[i]!=white)?0:1<<7)
467 						| ((cmap_1[j]!=white)?0:1<<6)
468 						| ((cmap_1[k]!=white)?0:1<<5)
469 						| ((cmap_1[l]!=white)?0:1<<4)
470 						| ((cmap_1[m]!=white)?0:1<<3)
471 						| ((cmap_1[n]!=white)?0:1<<2)
472 						| ((cmap_1[o]!=white)?0:1<<1)
473 						| ((cmap_1[p]!=white)?0:1);
474 					maskfb[y * (width>>3) + (x>>3)] |= maskp;
475 				}
476 #endif
477 				id++;
478 			}
479 		}
480 	} else if (bpp == 2) {
481 		for (y = 0; y < height; y++) {
482 			id = base_id + rowBytes * y;
483 			maski = 7;
484 			maskp = 0;
485 			for (x = 0; x < width; x++) {
486 				unsigned int i = *id >> 6;
487 				unsigned int j = (*id & 0x30) >> 4;
488 				unsigned int k = (*id & 0xc) >> 2;
489 				unsigned int l = *id & 0x3;
490 				if (cmap_2[i] == 5)
491 					cmap_2[i] = rgb_to_pixel(colormap, &rgb_2[i]);
492 				if (cmap_2[j] == 5)
493 					cmap_2[j] = rgb_to_pixel(colormap, &rgb_2[j]);
494 				if (cmap_2[k] == 5)
495 					cmap_2[k] = rgb_to_pixel(colormap, &rgb_2[k]);
496 				if (cmap_2[l] == 5)
497 					cmap_2[l] = rgb_to_pixel(colormap, &rgb_2[l]);
498 				gdk_image_put_pixel(gim, x++, y, cmap_2[i]);
499 				gdk_image_put_pixel(gim, x++, y, cmap_2[j]);
500 				gdk_image_put_pixel(gim, x++, y, cmap_2[k]);
501 				gdk_image_put_pixel(gim, x, y, cmap_2[l]);
502 #if WHITE_CLEAR
503 				if (maskfb) {
504 					maskp |= ((cmap_2[i]!=white)?0:1<<maski)
505 						| ((cmap_2[j]!=white)?0:1<<(maski-1))
506 						| ((cmap_2[k]!=white)?0:1<<(maski-2))
507 						| ((cmap_2[l]!=white)?0:1<<(maski-3));
508 					if (maski == 3) {
509 						maskfb[y * (width>>3) + (x>>3)] |= maskp;
510 						maski = 7;
511 						maskp = 0;
512 					} else {
513 						maski = 3;
514 					}
515 				}
516 #endif
517 				id++;
518 			}
519 		}
520 	} else if (bpp == 4) {
521 		for (y = 0; y < height; y++) {
522 			id = base_id + rowBytes * y;
523 			maski = 7;
524 			maskp = 0;
525 			for (x = 0; x < width; x++) {
526 				unsigned int i = *id >> 4;
527 				unsigned int j = *id & 0xf;
528 				if (cmap_4[i] == 17)
529 					cmap_4[i] = rgb_to_pixel(colormap, &rgb_4[i]);
530 				if (cmap_4[j] == 17)
531 					cmap_4[j] = rgb_to_pixel(colormap, &rgb_4[j]);
532 				gdk_image_put_pixel(gim, x++, y, cmap_4[i]);
533 				gdk_image_put_pixel(gim, x, y, cmap_4[j]);
534 #if WHITE_CLEAR
535 				if (maskfb) {
536 					maskp |= ((cmap_4[i]!=white)?0:1<<maski)
537 						| ((cmap_4[j]!=white)?0:1<<(maski-1));
538 					if (maski == 1) {
539 						maskfb[y * (width>>3) + (x>>3)] |= maskp;
540 						maski = 7;
541 						maskp = 0;
542 					} else {
543 						maski -= 2;
544 					}
545 				}
546 #endif
547 				id++;
548 			}
549 		}
550 	} else if (bpp == 8) {
551 		for (y = 0; y < height; y++) {
552 			id = base_id + rowBytes * y;
553 			maski = 7;
554 			maskp = 0;
555 			for (x = 0; x < width; x++) {
556 				unsigned int i = *id++;
557 				if (cmap_8[i] == 257)
558 					cmap_8[i] = rgb_to_pixel(colormap, &rgb_8[i]);
559 				gdk_image_put_pixel(gim, x, y, cmap_8[i]);
560 #if WHITE_CLEAR
561 				if (maskfb) {
562 					maskp |= ((cmap_8[i]!=white)?0:1<<maski);
563 					if (!maski) {
564 						maskfb[y * (width>>3) + (x>>3)] |= maskp;
565 						maski = 7;
566 						maskp = 0;
567 					} else {
568 						maski--;
569 					}
570 				}
571 #endif
572 			}
573 		}
574 	}
575 
576 	if (maskimp) {
577 		if (!maskfb)
578 			mim = 0;
579 		else
580 			mim = gdk_image_new_bitmap(visual, maskfb, width, height);
581 		*maskimp = mim;
582 	}
583 
584 	return gim;
585 }
586