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