1 #include "img_conv.h"
2 
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6 
7 #define map_RGB_gray ((Byte*)std256gray_palette)
8 
9 Byte     map_stdcolorref    [ 256];
10 Byte     div51              [ 256];
11 Byte     div51f             [ 256];
12 Byte     div17              [ 256];
13 Byte     mod51              [ 256];
14 int8_t   mod51f             [ 256];
15 Byte     mod17mul3          [ 256];
16 RGBColor cubic_palette      [ 256];
17 RGBColor cubic_palette8     [   8];
18 RGBColor cubic_palette16    [  16] =
19 {
20 	{0,0,0}, {0,128,128}, {128,0,128}, {0,0,255},
21 	{128,128,0}, {0,255,0}, {255,0,0}, {85,85,85},
22 	{170,170,170},{0,255,255},{255,0,255},{128,128,255},
23 	{255,255,0},{128,255,128},{255,128,128},{255,255,255}
24 };
25 RGBColor stdmono_palette    [   2] = {{ 0, 0, 0}, { 0xFF, 0xFF, 0xFF}};
26 RGBColor std16gray_palette  [  16];
27 RGBColor std256gray_palette [ 256];
28 Byte     map_halftone8x8_51 [  64] = {
29 	0, 38,  9, 47,  2, 40, 11, 50,
30 	25, 12, 35, 22, 27, 15, 37, 24,
31 	6, 44,  3, 41,  8, 47,  5, 43,
32 	31, 19, 28, 15, 34, 21, 31, 18,
33 	1, 39, 11, 49,  0, 39, 10, 48,
34 	27, 14, 36, 23, 26, 13, 35, 23,
35 	7, 46,  4, 43,  7, 45,  3, 42,
36 	33, 20, 30, 17, 32, 19, 29, 16
37 };
38 Byte     map_halftone8x8_64 [  64] = {
39 	0, 47, 12, 59,  3, 50, 15, 62,
40 	31, 16, 43, 28, 34, 19, 46, 31,
41 	8, 55,  4, 51, 11, 58,  7, 54,
42 	39, 24, 35, 20, 42, 27, 38, 23,
43 	2, 49, 14, 61,  1, 48, 13, 60,
44 	33, 18, 45, 30, 32, 17, 44, 29,
45 	10, 57,  6, 53,  9, 56,  5, 52,
46 	41, 26, 37, 22, 40, 25, 36, 21
47 };
48 
49 void
cm_init_colormap(void)50 cm_init_colormap( void)
51 {
52 	int i;
53 	for ( i = 0; i < 256; i++)
54 	{
55 		map_RGB_gray[ i * 3] = map_RGB_gray[ i * 3 + 1] = map_RGB_gray[ i * 3 + 2] = i;
56 		map_stdcolorref[ i] = i;
57 		div51f[ i] = (float) i / 51.0 + .5;
58 		mod51f[ i] = (i + 25) % 51 - 25;
59 		div51[ i] = i / 51;
60 		div17[ i] = i / 17;
61 		mod51[ i] = i % 51;
62 		mod17mul3[ i] = ( i % 17) * 3;
63 	}
64 	for ( i = 0; i < 16; i++)
65 		std16gray_palette[ i]. r = std16gray_palette[ i]. g = std16gray_palette[ i]. b = i * 17;
66 	{
67 		int b, g, r;
68 		for ( b = 0; b < 6; b++) for ( g = 0; g < 6; g++) for ( r = 0; r < 6; r++)
69 		{
70 /*       cubic_palette[ b + g * 6 + r * 36] =( RGBColor) { b * 51, g * 51, r *
71 *       51 }; */
72 			int idx = b + g * 6 + r * 36;
73 			cubic_palette[ idx]. b = b * 51;
74 			cubic_palette[ idx]. g = g * 51;
75 			cubic_palette[ idx]. r = r * 51;
76 		}
77 	}
78 	{
79 		int b, g, r;
80 		for ( b = 0; b < 2; b++) for ( g = 0; g < 2; g++) for ( r = 0; r < 2; r++)
81 		{
82 /*       cubic_palette8[ b + g * 2 + r * 4] = ( RGBColor) { b * 255, g * 255,
83 *       r * 255 }; */
84 			int idx = b + g * 2 + r * 4;
85 			cubic_palette8[ idx]. b = b * 255;
86 			cubic_palette8[ idx]. g = g * 255;
87 			cubic_palette8[ idx]. r = r * 255;
88 		}
89 	}
90 }
91 
92 void
cm_reverse_palette(PRGBColor source,PRGBColor dest,int colors)93 cm_reverse_palette( PRGBColor source, PRGBColor dest, int colors)
94 {
95 	while( colors--)
96 	{
97 		register Byte r = source[0].r;
98 		register Byte b = source[0].b;
99 		register Byte g = source[0].g;
100 		dest[0].r = b;
101 		dest[0].b = r;
102 		dest[0].g = g;
103 		source++;
104 		dest++;
105 	}
106 }
107 
108 void
cm_squeeze_palette(PRGBColor source,int srcColors,PRGBColor dest,int destColors)109 cm_squeeze_palette( PRGBColor source, int srcColors, PRGBColor dest, int destColors)
110 {
111 	if (( srcColors == 0) || ( destColors == 0)) return;
112 	if ( srcColors <= destColors)
113 		memcpy( dest, source, srcColors * sizeof( RGBColor));
114 	else
115 	{
116 		int tolerance = 0;
117 		int colors    = srcColors;
118 
119 		PRGBColor buf = allocn( RGBColor, srcColors);
120 		if (!buf) return;
121 		memcpy( buf, source, srcColors * sizeof( RGBColor));
122 		while (1)
123 		{
124 			int i;
125 			int tt2 = tolerance*tolerance;
126 
127 			for ( i = 0; i < colors - 1; i++)
128 			{
129 				register int r = buf[i]. r;
130 				register int g = buf[i]. g;
131 				register int b = buf[i]. b;
132 				int j;
133 				register PRGBColor next = buf + i + 1;
134 
135 				for ( j = i + 1; j < colors; j++)
136 				{
137 					if (( ( next-> r - r)*( next-> r - r) +
138 							( next-> g - g)*( next-> g - g) +
139 							( next-> b - b)*( next-> b - b)) <= tt2)
140 					{
141 						buf[ j] = buf[ --colors];
142 						if ( colors <= destColors) goto Enough;
143 					}
144 					next++;
145 				}
146 			}
147 			tolerance += 2;
148 		}
149 Enough:
150 		memcpy( dest, buf, destColors * sizeof( RGBColor));
151 		free( buf);
152 	}
153 }
154 
155 Byte
cm_nearest_color(RGBColor color,int palSize,PRGBColor palette)156 cm_nearest_color( RGBColor color, int palSize, PRGBColor palette)
157 {
158 	int diff = INT_MAX, cdiff = 0;
159 	Byte ret = 0;
160 	while( palSize--)
161 	{
162 		int dr=abs( (int)color. r - (int)palette[ palSize]. r),
163 			dg=abs( (int)color. g - (int)palette[ palSize]. g),
164 			db=abs( (int)color. b - (int)palette[ palSize]. b);
165 		cdiff=dr*dr+dg*dg+db*db;
166 		if ( cdiff < diff)
167 		{
168 			ret = palSize;
169 			diff = cdiff;
170 			if ( cdiff == 0) break;
171 		}
172 	}
173 	return ret;
174 }
175 
176 void
cm_fill_colorref(PRGBColor fromPalette,int fromColorCount,PRGBColor toPalette,int toColorCount,Byte * colorref)177 cm_fill_colorref( PRGBColor fromPalette, int fromColorCount, PRGBColor toPalette, int toColorCount, Byte * colorref)
178 {
179 
180 	while( fromColorCount--) {
181 		RGBColor x = fromPalette[fromColorCount]; /* don't optimize this away, register reading reads past the array bounds */
182 		colorref[ fromColorCount] =
183 			cm_nearest_color( x, toColorCount, toPalette);
184 	}
185 }
186 
187 /*
188 
189 cm_study_palette scans a RGB palette and builds a special structure that allows
190 quick mapping of a RGB triplet into palette index. The structure is organized
191 as a set of 64-cell tables (U16 array) following each other without any special
192 order except the 1st table:
193 
194 Table 0   Table 1
195 [U16 x 64][U16 x 64] ...
196 
197 so that it forms one chunk of memory.
198 
199 Each table can reference up to 64 colors, using a table-specific resolution.
200 In order to map a RGB value to a palette index, one splits 8-bit channel values
201 into 2-bit index, which makes for exactly 4*4*4=64 address space, and is
202 basically a color cube.
203 
204 Each U16 table entry is either a color
205 index (in which case it is less than 256 ), or a reference to another table, in
206 which case there's PAL_REF bit is set, and the table referenced by int value,
207 or PAL_FREE (unoccupied).
208 
209 For example, the tableset is formed like this:
210 
211 [ 50, PAL_REF | 1, 60, ... ]
212 [ 70, 100, ... ]
213 
214 and RGB=(0x00,0x00,0x00) is stripped to bit mask 0xC0 (bits 6 and 7), so that
215 index points in the table 1 to cell #0 (value 50). For RGB=(0x00,0x00,0x50) the
216 stripped bit mask (0x40>>6) points to the cell #1, which is PAL_REF|1.  That
217 means that one has to switch to table #1, and use bit mask 0x30 (bits 4 and 5),
218 and read cell #1 there (value 100).
219 
220 This process can go deep max 3 tables, where the last table uses bits 0 and 1.
221 However the procedure never allocates more than 256 color cells, because the
222 input palette is 256 colors max.
223 
224 At the end of the process there's no PAL_FREE entries, and each is made to hold
225 a color index to the closest color represented by the palette. This allows quick
226 mapping also for colors outside the palette, which is the whole point of this
227 function.
228 
229 */
230 U16 *
cm_study_palette(RGBColor * palette,int pal_size)231 cm_study_palette( RGBColor * palette, int pal_size)
232 {
233 	RGBColor * org_palette = palette;
234 	int i, pal2count = 1, pal2size = 64;
235 	int sz = CELL_SIZE * pal2size;
236 
237 	U16 * p = malloc( sz * sizeof( U16));
238 	if ( !p) return NULL;
239 	for ( i = 0; i < sz; i++) p[i] = PAL_FREE;
240 
241 	/* Scan for all palette entries. If the cell is empty, assign the color index to it;
242 		if there is already an index, promote the cell into PAL_REF and realloc the tableset.
243 		If there's alreay a PAL_REF, just go down and repeat the procesure on the next level */
244 	for ( i = 0; i < pal_size; i++, palette++) {
245 		int table = 0, index =
246 			((palette-> r >> 6) << 4) +
247 			((palette-> g >> 6) << 2) +
248 			(palette-> b >> 6);
249 		int shift = 4;
250 		while ( 1) {
251 			if ( p[table + index] & PAL_FREE) {
252 				/* PAL_FREE -> color index */
253 				p[table + index] = i;
254 				break;
255 			} else if ( p[table + index] & PAL_REF) {
256 				/* do down one level */
257 				table = (p[table + index] & ~PAL_REF) * CELL_SIZE;
258 				index =
259 					(((palette-> r >> shift) & 3) << 4) +
260 					(((palette-> g >> shift) & 3) << 2) +
261 					((palette-> b >> shift) & 3);
262 				shift -= 2;
263 			} else {
264 				/* color index -> PAL_REF */
265 				U16 old = p[table + index];
266 				int sub_index, old_sub_index, new_table;
267 
268 			REPEAT:
269 				/* realloc */
270 				if ( pal2count == pal2size) {
271 					int j, newsz;
272 					U16 * n;
273 					newsz = ( pal2size += 64 ) * CELL_SIZE;
274 					if ( !(n = malloc( newsz * sizeof( U16)))) {
275 						free( p);
276 						return NULL;
277 					}
278 					memcpy( n, p, sizeof(U16) * sz);
279 					for ( j = sz; j < newsz; j++) n[j] = PAL_FREE;
280 					free( p);
281 					p = n;
282 					sz = newsz;
283 				}
284 
285 				/* this color value */
286 				sub_index =
287 					(((palette-> r >> shift) & 3) << 4) +
288 					(((palette-> g >> shift) & 3) << 2) +
289 					((palette-> b >> shift) & 3);
290 				/* the value that was previously assigned - now both are moved
291 				to the subtable */
292 				old_sub_index =
293 					(((org_palette[old].r >> shift) & 3) << 4) +
294 					(((org_palette[old].g >> shift) & 3) << 2) +
295 					((org_palette[old].b >> shift) & 3);
296 				new_table = pal2count * CELL_SIZE;
297 				p[table + index] = (pal2count++) | PAL_REF;
298 				if ( sub_index != old_sub_index) {
299 					/* finally, assign color index */
300 					p[ new_table + sub_index]     = i;
301 					p[ new_table + old_sub_index] = old;
302 					break;
303 				} else {
304 					/* both values have the same 6-bit index on this level, go down to the next table */
305 					if ( shift > 1) {
306 						shift -= 2;
307 						table = new_table;
308 						index = sub_index;
309 						goto REPEAT;
310 					}
311 					/* just a duplicate */
312 					p[ table + index] = i;
313 					break;
314 				}
315 			}
316 		}
317 	}
318 
319 	/* do cm_nearest_color for each PAL_FREE cell */
320 	{
321 		struct {
322 			int i;
323 			int table;
324 			int r;
325 			int g;
326 			int b;
327 		} stack[4]; /* max depth - each channel is 8 bit, but each color cube uses 2 bits, so 8/2=4 levels max */
328 		int sp = 0;
329 		memset( stack, 0, sizeof(stack));
330 		for ( ; stack[sp].i < 64; stack[sp].i++) {
331 			if ( p[stack[sp].table + stack[sp].i] & PAL_FREE) {
332 				RGBColor cell;
333 				int shift = 6 - sp * 2, delta = 32 >> sp * 2;
334 				cell. r = stack[sp]. r + delta + ((( stack[sp].i >> 4) & 3) << shift);
335 				cell. g = stack[sp]. g + delta + ((( stack[sp].i >> 2) & 3) << shift);
336 				cell. b = stack[sp]. b + delta +  (( stack[sp].i & 3) << shift);
337 				p[stack[sp].table + stack[sp].i] = cm_nearest_color( cell, pal_size, org_palette);
338 			} else if ( p[stack[sp].table + stack[sp].i] & PAL_REF) {
339 				int shift = 6 - sp * 2;
340 				stack[sp + 1].r = stack[sp]. r + ((( stack[sp].i >> 4) & 3) << shift);
341 				stack[sp + 1].g = stack[sp]. g + ((( stack[sp].i >> 2) & 3) << shift);
342 				stack[sp + 1].b = stack[sp]. b + (( stack[sp].i & 3) << shift);
343 				stack[sp + 1].table = (p[stack[sp].table + stack[sp].i] & ~PAL_REF) * CELL_SIZE;
344 				stack[++sp].i = -1;
345 			}
346 			while ( stack[sp].i == 63 && sp > 0) sp--;
347 		}
348 	}
349 	return p;
350 }
351 
352 static int
sort_palette(const void * a,const void * b)353 sort_palette( const void * a, const void * b)
354 {
355 	register unsigned int A =
356 		((PRGBColor)a)->r +
357 		((PRGBColor)a)->g +
358 		((PRGBColor)a)->b
359 	;
360 	register unsigned int B =
361 		((PRGBColor)b)->r +
362 		((PRGBColor)b)->g +
363 		((PRGBColor)b)->b
364 	;
365 	if ( A < B)
366 		return -1;
367 	else if ( A > B)
368 		return 1;
369 	else
370 		return 0;
371 }
372 
373 void
cm_sort_palette(RGBColor * palette,int size)374 cm_sort_palette( RGBColor * palette, int size)
375 {
376 	qsort( palette, size, sizeof(RGBColor), sort_palette);
377 }
378 
379 void
cm_reduce_palette4(Byte * srcData,int srcLine,int width,int height,RGBColor * srcPalette,int srcPalSize,RGBColor * dstPalette,int * dstPalSize)380 cm_reduce_palette4( Byte * srcData, int srcLine, int width, int height, RGBColor * srcPalette, int srcPalSize, RGBColor * dstPalette, int * dstPalSize)
381 {
382 	Byte hist[16];
383 	int i, j, tail, w;
384 
385 	w = width / 2;
386 	tail = width % 2;
387 
388 	memset( hist, 0, sizeof( hist));
389 	*dstPalSize = 0;
390 	for ( i = 0; i < height; i++) {
391 		Byte * d = srcData;
392 		srcData += srcLine;
393 		for ( j = 0; j < w; j++, d++) {
394 			Byte c = *d >> 4;
395 			if ( hist[c] == 0) {
396 				hist[c] = 1;
397 				dstPalette[(*dstPalSize)++] = srcPalette[c];
398 				if ( *dstPalSize >= srcPalSize) return;
399 			}
400 			c = *d & 0x0f;
401 			if ( hist[c] == 0) {
402 				hist[c] = 1;
403 				dstPalette[(*dstPalSize)++] = srcPalette[c];
404 				if ( *dstPalSize >= srcPalSize) return;
405 			}
406 		}
407 		if (tail) {
408 			Byte c = *d >> 4;
409 			if ( hist[c] == 0) {
410 				hist[c] = 1;
411 				dstPalette[(*dstPalSize)++] = srcPalette[c];
412 				if ( *dstPalSize >= srcPalSize) return;
413 			}
414 		}
415 	}
416 }
417 
418 void
cm_reduce_palette8(Byte * srcData,int srcLine,int width,int height,RGBColor * srcPalette,int srcPalSize,RGBColor * dstPalette,int * dstPalSize)419 cm_reduce_palette8( Byte * srcData, int srcLine, int width, int height, RGBColor * srcPalette, int srcPalSize, RGBColor * dstPalette, int * dstPalSize)
420 {
421 	Byte hist[256];
422 	int i, j;
423 
424 	memset( hist, 0, sizeof( hist));
425 	*dstPalSize = 0;
426 	for ( i = 0; i < height; i++) {
427 		Byte * d = srcData;
428 		srcData += srcLine;
429 		for ( j = 0; j < width; j++, d++) {
430 			if ( hist[*d] == 0) {
431 				hist[*d] = 1;
432 				dstPalette[(*dstPalSize)++] = srcPalette[*d];
433 				if ( *dstPalSize >= srcPalSize) return;
434 			}
435 		}
436 	}
437 }
438 
439 /*
440 
441 cm_optimized_palette scans a RGB image and builds a palette that best represents colors found in the image.
442 
443 */
444 
445 #define MAP1_SIDE  32
446 #define MAP1_SHIFT  3
447 #define MAP1_SIDE3 (MAP1_SIDE*MAP1_SIDE*MAP1_SIDE)
448 #define MAP2_SIDE   8
449 #define MAP2_SHIFT  3
450 #define MAP2_MASK   7
451 #define MAP2_ITEM_SIZE  64
452 #define MAP2_ITEM_SHIFT 6
453 
454 Bool
cm_optimized_palette(Byte * data,int lineSize,int width,int height,RGBColor * palette,int * max_pal_size)455 cm_optimized_palette( Byte * data, int lineSize, int width, int height, RGBColor * palette, int * max_pal_size)
456 {
457 	int i, j, sz, count, side = MAP1_SIDE, shift = MAP1_SHIFT, force_squeeze = 0, map0index = 0;
458 	int countB, countL, map2scale = 0;
459 	Byte * map, * map2;
460 	RGBColor * big_pal;
461 
462 	if ( !( map = malloc( MAP1_SIDE3))) return false;
463 
464 REPEAT_CALC:
465 	count = 0;
466 	memset( map, 0, MAP1_SIDE3);
467 
468 	/* calculate colors with resolution 1 / 512 */
469 	for ( i = 0; i < height; i++) {
470 		RGBColor * p = ( RGBColor*)( data + i * lineSize );
471 		for ( j = 0; j < width; j++, p++) {
472 			int index = (p-> r >> shift) * side * side +
473 							(p-> g >> shift) * side +
474 							(p-> b >> shift);
475 			if ( map[index] == 0) {
476 				map[index] = 1;
477 				count++;
478 			}
479 		}
480 	}
481 
482 	j = 0;
483 	sz = side * side * side;
484 	/* if too many colors, extract only max_pal_size and return */
485 	if ( count > *max_pal_size) {
486 		if (( count > 512) && ( side > 8) && !force_squeeze) {
487 			side >>= 1;
488 			shift++;
489 			goto REPEAT_CALC;
490 		}
491 		NO_MEMORY:
492 		{
493 			int delta = (1 << shift) - 1;
494 			RGBColor * big_pal = malloc( count * sizeof(RGBColor));
495 			if ( !big_pal) {
496 				free( map);
497 				return false;
498 			}
499 			for ( i = 0; i < sz; i++)
500 				if ( map[i]) {
501 					big_pal[j]. r = (i / ( side * side)) << shift;
502 					big_pal[j]. g = ((i / side) % side ) << shift;
503 					big_pal[j]. b = (i % side) << shift;
504 					if ( big_pal[j]. r > 127) big_pal[j]. r += delta;
505 					if ( big_pal[j]. g > 127) big_pal[j]. g += delta;
506 					if ( big_pal[j]. b > 127) big_pal[j]. b += delta;
507 					j++;
508 				}
509 			cm_squeeze_palette( big_pal, j, palette, *max_pal_size);
510 			cm_sort_palette( palette, *max_pal_size);
511 			free( big_pal);
512 			free( map);
513 			return true;
514 		}
515 	}
516 
517 	/* scale was lowered due to many colors, but now it is too few colors... */
518 	if ( side != MAP1_SIDE) {
519 		force_squeeze = 1;
520 		side <<= 1;
521 		shift--;
522 		goto REPEAT_CALC;
523 	}
524 
525 
526 	/* stage 2 - full color calc */
527 	if (!( map2 = malloc( MAP2_ITEM_SIZE * count))) goto NO_MEMORY;
528 	memset( map2, 0, MAP2_ITEM_SIZE * count);
529 
530 	/* calculate colors with full resolution */
531 	sz = MAP1_SIDE * MAP1_SIDE * MAP1_SIDE;
532 	count = 0;
533 	for ( i = 0; i < sz; i++)
534 		if ( map[i]) {
535 			if ( count == 0) map0index = i;
536 			map[i] = count++;
537 		}
538 	count = 0;
539 
540 	for ( i = 0; i < height; i++) {
541 		RGBColor * p = ( RGBColor*)( data + i * lineSize );
542 		for ( j = 0; j < width; j++, p++) {
543 			int index1 = (p-> r >> MAP1_SHIFT) * MAP1_SIDE * MAP1_SIDE +
544 							(p-> g >> MAP1_SHIFT) * MAP1_SIDE +
545 							(p-> b >> MAP1_SHIFT);
546 			int index2 = (p-> r & MAP2_MASK) * MAP2_SIDE * MAP2_SIDE +
547 							(p-> g & MAP2_MASK) * MAP2_SIDE +
548 							(p-> b & MAP2_MASK);
549 			index1 = (map[index1] << MAP2_ITEM_SHIFT) + (index2 >> 3);
550 			if (( map2[index1] & (1 << (index2 & 7))) == 0) {
551 				map2[index1] |= (1 << (index2 & 7));
552 				count++;
553 			}
554 		}
555 	}
556 
557 	/* Too many colors - if indeed too many, resample with /8 and /64 scale.
558 		Even /64 scale though can result in up to 4K colors */
559 	countB = countL = 0;
560 	if ( count > *max_pal_size) {
561 		if ( count > *max_pal_size * 2) {
562 			for ( i = 0; i < sz; i++)
563 				if ( i == map0index || map[i] != 0) {
564 					Byte * k = map2 + map[i] * MAP2_ITEM_SIZE;
565 					U32 * l = ( U32 *) k;
566 					for ( j = 0; j < MAP2_ITEM_SIZE / 4; j+=2)
567 						if ( l[j] || l[j+1]) countL++;
568 					for ( j = 0; j < MAP2_ITEM_SIZE; j++)
569 						if ( k[j]) countB++;
570 				}
571 			if ( countB > *max_pal_size * 2) {
572 				count = countL;
573 				map2scale = 2;
574 			} else {
575 				count = countB;
576 				map2scale = 1;
577 			}
578 		}
579 	}
580 
581 	/* collect final palette */
582 	if ( count > *max_pal_size) {
583 		if ( !( big_pal = malloc( count * sizeof(RGBColor)))) {
584 			free( map);
585 			free( map2);
586 			return false;
587 		}
588 	} else
589 		big_pal = palette;
590 
591 	count = 0;
592 	for ( i = 0; i < sz; i++)
593 		if ( i == map0index || map[i] != 0) {
594 			int r = (i / ( MAP1_SIDE * MAP1_SIDE)) << MAP1_SHIFT;
595 			int g = ((i / MAP1_SIDE) % MAP1_SIDE ) << MAP1_SHIFT;
596 			int b = (i % MAP1_SIDE) << MAP1_SHIFT;
597 			Byte * k = map2 + map[i] * MAP2_ITEM_SIZE;
598 			switch ( map2scale) {
599 			case 0: /* 1/1  */
600 				for ( j = 0; j < 512; j++) {
601 					if ( k[j >> 3] & ( 1 << ( j & 7))) {
602 						big_pal[count]. r = r + j / ( MAP2_SIDE * MAP2_SIDE);
603 						big_pal[count]. g = g + (j / MAP2_SIDE) % MAP2_SIDE;
604 						big_pal[count]. b = b + j % MAP2_SIDE;
605 						count++;
606 					}
607 				}
608 				break;
609 			case 1: /* 1/8  */
610 				for ( j = 0; j < 64; j++) {
611 					if ( k[j]) {
612 						big_pal[count]. r = r + ((j / ( 4 * 4)) << 1);
613 						big_pal[count]. g = g + (((j / 4) % 4) << 1);
614 						big_pal[count]. b = b + ((j % 4) << 1);
615 						if ( big_pal[count]. r > 127) big_pal[count]. r ++;
616 						if ( big_pal[count]. g > 127) big_pal[count]. g ++;
617 						if ( big_pal[count]. b > 127) big_pal[count]. b ++;
618 						count++;
619 					}
620 				}
621 				break;
622 			case 2: /* 1/64  */
623 				for ( j = 0; j < 8; j++) {
624 					if ( *(( U32*) k) || *((( U32*) k) + 1)) {
625 						big_pal[count]. r = r + ((j / ( 2 * 2)) << 2);
626 						big_pal[count]. g = g + (((j / 2) % 2) << 2);
627 						big_pal[count]. b = b + ((j % 2) << 2);
628 						if ( big_pal[count]. r > 127) big_pal[count]. r += 3;
629 						if ( big_pal[count]. g > 127) big_pal[count]. g += 3;
630 						if ( big_pal[count]. b > 127) big_pal[count]. b += 3;
631 						count++;
632 					}
633 					k += 8;
634 				}
635 				break;
636 			}
637 		}
638 	if ( big_pal != palette) {
639 		cm_squeeze_palette( big_pal, count, palette, *max_pal_size);
640 		count = *max_pal_size;
641 		free( big_pal);
642 	}
643 	free( map);
644 	free( map2);
645 	*max_pal_size = count;
646 	cm_sort_palette( palette, count);
647 	return true;
648 }
649 
650 void
img_fill_dummy(PImage dummy,int w,int h,int type,Byte * data,RGBColor * palette)651 img_fill_dummy( PImage dummy, int w, int h, int type, Byte * data, RGBColor * palette)
652 {
653 	bzero( dummy, sizeof(Image));
654 	dummy-> self     = CImage;
655 	dummy-> w        = w;
656 	dummy-> h        = h;
657 	dummy-> type     = type;
658 	dummy-> data     = data;
659 	dummy-> lineSize = LINE_SIZE(w, type);
660 	dummy-> dataSize = dummy-> lineSize * h;
661 	dummy-> palette  = palette;
662 	dummy-> updateLock = true; /* just in case */
663 
664 	if ( type == imRGB ) {
665 		dummy-> palSize = 0;
666 	} else if ( type & ( imRealNumber|imComplexNumber|imTrigComplexNumber)) {
667 		dummy-> palSize = 256;
668 	} else {
669 		dummy-> palSize = type & imBPP;
670 	}
671 }
672 
673 #ifdef __cplusplus
674 }
675 #endif
676