source: trunk/JPGPROC/source/gbmsrc/gbmtrunc.c@ 4

Last change on this file since 4 was 2, checked in by stevenhl, 8 years ago

Import sources from cwmm-full.zip dated 2005-03-21

File size: 26.3 KB
Line 
1/*
2
3gbmtrunc.c - Truncate to lower bits per pixel
4
5*/
6
7/*...sincludes:0:*/
8#include <stdio.h>
9#include <stddef.h>
10#include <stdlib.h>
11#include <string.h>
12#include "gbm.h"
13
14/*...vgbm\46\h:0:*/
15/*...e*/
16/*...svars:0:*/
17static BOOLEAN inited = FALSE;
18
19/*
20For 6Rx6Gx6B, 7Rx8Gx4B palettes etc.
21*/
22
23static byte index4[0x100];
24static byte index6[0x100];
25static byte index7[0x100];
26static byte index8[0x100];
27static byte index16[0x100];
28static byte scale4[] = { 0, 85, 170, 255 };
29static byte scale6[] = { 0, 51, 102, 153, 204, 255 };
30static byte scale7[] = { 0, 43, 85, 128, 170, 213, 255 };
31static byte scale8[] = { 0, 36, 73, 109, 146, 182, 219, 255 };
32static byte scale16[] = { 0, 17, 34, 51, 68, 85, 102, 119, 136,
33 153, 170, 187, 204, 221, 238, 255 };
34/*...e*/
35/*...sinit:0:*/
36/*
37This function initialises this module.
38*/
39
40/*...snearest_inx:0:*/
41#ifndef abs
42#define abs(x) (((x)>=0)?(x):-(x))
43#endif
44
45static byte nearest_inx(byte value, const byte ab[], unsigned short cb)
46 {
47 byte b, inx, inx_min;
48 short diff, diff_min;
49
50 b = ab[0];
51 diff_min = abs((short) value - (short) b);
52 inx_min = 0;
53 for ( inx = 1; (unsigned short) inx < cb; inx++ )
54 {
55 b = ab[inx];
56 diff = abs((short) value - (short) b);
57 if ( diff < diff_min )
58 {
59 diff_min = diff;
60 inx_min = inx;
61 }
62 }
63 return inx_min;
64 }
65/*...e*/
66
67static void init(void)
68 {
69 int i;
70
71 if ( inited )
72 return;
73
74 /* For 7 Red x 8 Green x 4 Blue palettes etc. */
75
76 for ( i = 0; i < 0x100; i++ )
77 {
78 index4 [i] = nearest_inx((byte) i, scale4 , sizeof(scale4 ));
79 index6 [i] = nearest_inx((byte) i, scale6 , sizeof(scale6 ));
80 index7 [i] = nearest_inx((byte) i, scale7 , sizeof(scale7 ));
81 index8 [i] = nearest_inx((byte) i, scale8 , sizeof(scale8 ));
82 index16[i] = nearest_inx((byte) i, scale16, sizeof(scale16));
83 }
84
85 inited = TRUE;
86 }
87/*...e*/
88/*...strunc:0:*/
89static void trunc(
90 const GBM *gbm, const byte *src, byte *dest,
91 int dest_bpp,
92 void (*trunc_line)(const byte *src, byte *dest, int cx)
93 )
94 {
95 int stride_src = ((gbm->w * 3 + 3) & ~3);
96 int stride_dest = ((gbm->w * dest_bpp + 31) / 32) * 4;
97 int y;
98
99 for ( y = 0; y < gbm->h; y++ )
100 (*trunc_line)(src + y * stride_src, dest + y * stride_dest, gbm->w);
101 }
102/*...e*/
103/*...snearest_color:0:*/
104static byte nearest_color(byte r, byte g, byte b, GBMRGB *gbmrgb, int n_gbmrgb)
105 {
106 int i, i_min, dist_min = 0x30000;
107 for ( i = 0; i < n_gbmrgb; i++ )
108 {
109 int dr = (int) ( (unsigned)r - (unsigned)gbmrgb[i].r );
110 int dg = (int) ( (unsigned)g - (unsigned)gbmrgb[i].g );
111 int db = (int) ( (unsigned)b - (unsigned)gbmrgb[i].b );
112 int dist = dr*dr+dg*dg+db*db;
113 if ( dist < dist_min )
114 { dist_min = dist; i_min = i; }
115 }
116 return (byte) i_min;
117 }
118/*...e*/
119/*...sMAP:0:*/
120/* A map is a structure used to accelerate the conversion from r,g,b tuple
121 to palette index. A map divides RGB space into a cube. Each cube either
122 maps all its RGB space to a single index, or 0xffff is stored. */
123
124typedef struct
125 {
126 word inx[0x20][0x20][0x20]; /* 64KB */
127 } MAP;
128
129static void build_map(GBMRGB *gbmrgb, int n_gbmrgb, MAP *map)
130 {
131 int r, g, b;
132 for ( r = 0; r < 0x100; r += 8 )
133 for ( g = 0; g < 0x100; g += 8 )
134 for ( b = 0; b < 0x100; b += 8 )
135 {
136 byte i = nearest_color((byte) r , (byte) g , (byte) b , gbmrgb, n_gbmrgb);
137 if ( i == nearest_color((byte) r , (byte) g , (byte) (b+7), gbmrgb, n_gbmrgb) &&
138 i == nearest_color((byte) r , (byte) (g+7), (byte) b , gbmrgb, n_gbmrgb) &&
139 i == nearest_color((byte) r , (byte) (g+7), (byte) (b+7), gbmrgb, n_gbmrgb) &&
140 i == nearest_color((byte) (r+7), (byte) g , (byte) b , gbmrgb, n_gbmrgb) &&
141 i == nearest_color((byte) (r+7), (byte) g , (byte) (b+7), gbmrgb, n_gbmrgb) &&
142 i == nearest_color((byte) (r+7), (byte) (g+7), (byte) b , gbmrgb, n_gbmrgb) &&
143 i == nearest_color((byte) (r+7), (byte) (g+7), (byte) (b+7), gbmrgb, n_gbmrgb) )
144 map->inx[r/8][g/8][b/8] = i;
145 else
146 map->inx[r/8][g/8][b/8] = (word) 0xffff;
147 }
148 }
149
150static byte nearest_color_via_map(byte r, byte g, byte b, MAP *map, GBMRGB *gbmrgb, int n_gbmrgb)
151 {
152 word i = map->inx[r/8][g/8][b/8];
153 return ( i != (word) 0xffff )
154 ? (byte) i
155 : nearest_color(r, g, b, gbmrgb, n_gbmrgb);
156 }
157/*...e*/
158
159/*...sgbm_trunc_line_24 \45\ truncate to fewer bits per pixel one line:0:*/
160void gbm_trunc_line_24(const byte *src, byte *dest, int cx, byte rm, byte gm, byte bm)
161 {
162 int x;
163
164 for ( x = 0; x < cx; x++ )
165 {
166 *dest++ = (*src++ & bm);
167 *dest++ = (*src++ & gm);
168 *dest++ = (*src++ & rm);
169 }
170 }
171/*...e*/
172/*...sgbm_trunc_24 \45\ truncate to fewer bits per pixel:0:*/
173void gbm_trunc_24(const GBM *gbm, const byte *data24, byte *data8, byte rm, byte gm, byte bm)
174 {
175 int stride = ((gbm->w * 3 + 3) & ~3);
176 int y;
177
178 for ( y = 0; y < gbm->h; y++ )
179 gbm_trunc_line_24(data24 + y * stride, data8 + y * stride, gbm->w, rm, gm, bm);
180 }
181/*...e*/
182
183/*...sgbm_trunc_pal_6R6G6B \45\ return 6Rx6Gx6B palette:0:*/
184/*
185This function makes the palette for the 6 red x 6 green x 6 blue palette.
186216 palette entrys used. Remaining 40 left blank.
187*/
188
189void gbm_trunc_pal_6R6G6B(GBMRGB *gbmrgb)
190 {
191 byte volatile r; /* C-Set/2 optimiser fix */
192 byte volatile g;
193 byte volatile b;
194
195 init();
196 memset(gbmrgb, 0x80, 0x100 * sizeof(GBMRGB));
197 for ( r = 0; r < 6; r++ )
198 for ( g = 0; g < 6; g++ )
199 for ( b = 0; b < 6; b++ )
200 {
201 gbmrgb->r = scale6[r];
202 gbmrgb->g = scale6[g];
203 gbmrgb->b = scale6[b];
204 gbmrgb++;
205 }
206 }
207/*...e*/
208/*...sgbm_trunc_line_6R6G6B \45\ truncate to 6Rx6Gx6B one line:0:*/
209void gbm_trunc_line_6R6G6B(const byte *src, byte *dest, int cx)
210 {
211 int x;
212
213 init();
214
215 for ( x = 0; x < cx; x++ )
216 {
217 byte bi = index6[*src++];
218 byte gi = index6[*src++];
219 byte ri = index6[*src++];
220
221 *dest++ = (byte) (6 * (6 * ri + gi) + bi);
222 }
223 }
224/*...e*/
225/*...sgbm_trunc_6R6G6B \45\ truncate to 6Rx6Gx6B:0:*/
226void gbm_trunc_6R6G6B(const GBM *gbm, const byte *data24, byte *data8)
227 {
228 trunc(gbm, data24, data8, 8, gbm_trunc_line_6R6G6B);
229 }
230/*...e*/
231
232/*...sgbm_trunc_pal_7R8G4B \45\ return 7Rx8Gx4B palette:0:*/
233/*
234This function makes the palette for the 7 red x 8 green x 4 blue palette.
235224 palette entrys used. Remaining 32 left blank.
236Colours calculated to match those used by 8514/A PM driver.
237*/
238
239void gbm_trunc_pal_7R8G4B(GBMRGB *gbmrgb)
240 {
241 byte volatile r; /* C-Set/2 optimiser fix */
242 byte volatile g;
243 byte volatile b;
244
245 init();
246
247 memset(gbmrgb, 0x80, 0x100 * sizeof(GBMRGB));
248 for ( r = 0; r < 7; r++ )
249 for ( g = 0; g < 8; g++ )
250 for ( b = 0; b < 4; b++ )
251 {
252 gbmrgb->r = scale7[r];
253 gbmrgb->g = scale8[g];
254 gbmrgb->b = scale4[b];
255 gbmrgb++;
256 }
257 }
258/*...e*/
259/*...sgbm_trunc_line_7R8G4B \45\ truncate to 7Rx8Gx4B one line:0:*/
260void gbm_trunc_line_7R8G4B(const byte *src, byte *dest, int cx)
261 {
262 int x;
263
264 init();
265
266 for ( x = 0; x < cx; x++ )
267 {
268 byte bi = index4[*src++];
269 byte gi = index8[*src++];
270 byte ri = index7[*src++];
271
272 *dest++ = (byte) (4 * (8 * ri + gi) + bi);
273 }
274 }
275/*...e*/
276/*...sgbm_trunc_7R8G4B \45\ truncate to 7Rx8Gx4B:0:*/
277void gbm_trunc_7R8G4B(const GBM *gbm, const byte *data24, byte *data8)
278 {
279 trunc(gbm, data24, data8, 8, gbm_trunc_line_7R8G4B);
280 }
281/*...e*/
282
283/*...sgbm_trunc_pal_VGA \45\ return default VGA palette:0:*/
284/*
285This function makes the palette for the 16 colour VGA palette.
286*/
287
288static GBMRGB gbmrgb_vga[] =
289 {
290 0, 0, 0,
291 128, 0, 0,
292 0,128, 0,
293 128,128, 0,
294 0, 0,128,
295 128, 0,128,
296 0,128,128,
297 128,128,128,
298 204,204,204,
299 255, 0, 0,
300 0,255, 0,
301 255,255, 0,
302 0, 0,255,
303 255, 0,255,
304 0,255,255,
305 255,255,255,
306 };
307
308void gbm_trunc_pal_VGA(GBMRGB *gbmrgb)
309 {
310 init();
311 memcpy((char *) gbmrgb, (char *) gbmrgb_vga, sizeof(gbmrgb_vga));
312 }
313/*...e*/
314/*...sgbm_trunc_line_VGA \45\ truncate to default VGA palette:0:*/
315/*...scalc_nearest:0:*/
316/*
317This function, when given am RGB colour, finds the VGA palette entry closest
318to it. We deliberately bias away from the two grey palette entries.
319*/
320
321static byte calc_nearest(byte r, byte g, byte b)
322 {
323 long min_dist = 3L * 256L * 256L * 10L;
324 byte bi, bi_min;
325
326 for ( bi = 0; bi < 0x10; bi++ )
327 {
328 long b_dist = ((long) b - (long) gbmrgb_vga[bi].b);
329 long g_dist = ((long) g - (long) gbmrgb_vga[bi].g);
330 long r_dist = ((long) r - (long) gbmrgb_vga[bi].r);
331 long dist = r_dist * r_dist + g_dist * g_dist + b_dist * b_dist;
332
333 if ( dist < min_dist )
334 {
335 min_dist = dist;
336 bi_min = bi;
337 }
338 }
339 return bi_min;
340 }
341/*...e*/
342/*...snearest_colour:0:*/
343/*
344This function finds the closest VGA palette colour to a given RGB value.
345It uses a lookup table to avoid performing distance calculations to the
34616 palette entrys. The table is pre-calculated.
347*/
348
349/*...squick lookup table:0:*/
350/*...v_gbmtrun\46\c \45\ used to make quick_tab:0:*/
351
352static byte quick_tab[16][16][16] =
353 {
354 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
355 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
356 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
357 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
358 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
359 2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
360 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
361 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
362 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
363 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
364 2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
365 2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
366 10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
367 10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
368 10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
369 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
370 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
371 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
372 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
373 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
374 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
375 2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
376 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
377 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
378 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
379 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
380 2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
381 2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
382 10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
383 10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
384 10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
385 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
386 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
387 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
388 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
389 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
390 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
391 2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
392 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
393 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
394 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
395 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
396 2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
397 2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
398 10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
399 10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
400 10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
401 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
402 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
403 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
404 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
405 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
406 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
407 2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
408 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
409 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
410 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
411 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
412 2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
413 2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
414 10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
415 10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
416 10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
417 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
418 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
419 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
420 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
421 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
422 255,255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,
423 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,12,
424 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
425 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
426 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
427 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
428 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,14,
429 255,255,255,255,255,255,255,255,255,255,255,255,255,255,14,14,
430 255,255,255,255,255,255,255,255,255,255,255,255,255,14,14,14,
431 10,10,10,10,255,255,255,255,255,255,255,255,14,14,14,14,
432 10,10,10,10,10,255,255,255,255,255,255,14,14,14,14,14,
433 10,10,10,10,10,10,255,255,255,255,14,14,14,14,14,14,
434 1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
435 1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
436 1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
437 1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
438 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,12,
439 3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
440 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
441 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
442 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
443 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
444 3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
445 3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
446 3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,14,
447 255,255,255,255,255,7,7,7,7,7,7,255,255,255,14,14,
448 10,10,10,10,255,255,7,7,7,7,255,255,255,14,14,14,
449 10,10,10,10,10,255,255,7,7,255,255,255,14,14,14,14,
450 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
451 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
452 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
453 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
454 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
455 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
456 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
457 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
458 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
459 3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
460 3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
461 3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,255,
462 3,3,3,3,255,7,7,7,7,7,7,255,255,255,255,255,
463 3,3,3,3,255,7,7,7,7,7,255,255,255,255,255,255,
464 255,255,255,255,255,7,7,7,7,255,255,255,255,255,255,255,
465 10,10,10,10,255,255,7,7,255,255,255,255,255,255,255,255,
466 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
467 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
468 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
469 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
470 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
471 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
472 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
473 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
474 3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
475 3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
476 3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,8,
477 3,3,3,3,255,7,7,7,7,7,7,255,255,255,8,8,
478 3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
479 3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
480 3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
481 255,255,255,255,255,7,7,255,255,255,8,8,8,8,8,255,
482 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
483 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
484 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
485 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
486 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
487 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,7,
488 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
489 3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
490 3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
491 3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,8,
492 3,3,3,3,255,7,7,7,7,7,7,255,255,255,8,8,
493 3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
494 3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
495 3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
496 3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
497 255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
498 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
499 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
500 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
501 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
502 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
503 3,3,3,3,255,7,7,7,7,7,7,7,7,7,7,255,
504 3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
505 3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
506 3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,8,
507 3,3,3,3,255,7,7,7,7,7,7,255,255,255,8,8,
508 3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
509 3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
510 3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
511 3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
512 255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
513 11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
514 1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
515 1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
516 1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
517 1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
518 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,13,
519 3,3,3,3,255,7,7,7,7,7,7,7,7,7,255,255,
520 3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
521 3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,8,
522 3,3,3,3,255,7,7,7,7,7,7,255,255,255,8,8,
523 3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
524 3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
525 3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
526 3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
527 255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
528 11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
529 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
530 1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
531 1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
532 1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
533 1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
534 255,255,255,255,255,255,255,255,255,255,255,255,255,255,13,13,
535 3,3,3,3,255,7,7,7,7,7,7,7,7,255,255,255,
536 3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,255,
537 3,3,3,3,255,7,7,7,7,7,7,255,255,255,8,8,
538 3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
539 3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
540 3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
541 3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
542 255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
543 11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
544 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
545 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,255,
546 9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
547 9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
548 9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
549 9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
550 255,255,255,255,255,255,255,255,255,255,255,255,255,13,13,13,
551 3,3,3,3,255,7,7,7,7,7,7,7,255,255,255,13,
552 3,3,3,3,255,7,7,7,7,7,7,255,255,255,255,255,
553 3,3,3,3,255,7,7,7,7,7,255,255,255,8,8,8,
554 3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
555 3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
556 3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
557 255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
558 11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
559 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
560 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,255,
561 11,11,11,11,11,11,255,8,8,8,8,8,8,8,255,255,
562 9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
563 9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
564 9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
565 9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
566 9,9,9,9,255,255,255,255,255,255,255,255,13,13,13,13,
567 255,255,255,255,255,7,7,7,7,7,7,255,255,255,13,13,
568 3,3,3,3,255,7,7,7,7,7,255,255,255,255,255,255,
569 3,3,3,3,255,7,7,7,7,255,255,255,8,8,8,8,
570 3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
571 3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
572 255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
573 11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
574 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
575 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,255,
576 11,11,11,11,11,11,255,8,8,8,8,8,8,8,255,255,
577 11,11,11,11,11,11,255,8,8,8,8,8,8,255,255,255,
578 9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
579 9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
580 9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
581 9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
582 9,9,9,9,9,255,255,255,255,255,255,13,13,13,13,13,
583 9,9,9,9,255,255,7,7,7,7,255,255,255,13,13,13,
584 255,255,255,255,255,7,7,7,7,255,255,255,255,255,255,255,
585 3,3,3,3,255,7,7,7,255,255,255,8,8,8,8,8,
586 3,3,3,3,255,7,7,255,255,255,8,8,8,8,8,8,
587 255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
588 11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
589 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
590 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,255,
591 11,11,11,11,11,11,255,8,8,8,8,8,8,8,255,255,
592 11,11,11,11,11,11,255,8,8,8,8,8,8,255,255,255,
593 11,11,11,11,11,11,255,8,8,8,8,8,255,255,255,15,
594 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
595 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
596 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
597 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
598 9,9,9,9,9,9,255,255,255,255,13,13,13,13,13,13,
599 9,9,9,9,9,255,255,7,7,255,255,255,13,13,13,13,
600 9,9,9,9,255,255,7,7,255,255,255,255,255,255,255,255,
601 255,255,255,255,255,7,7,255,255,255,8,8,8,8,8,255,
602 255,255,255,255,255,7,255,255,255,8,8,8,8,8,8,8,
603 11,11,11,11,255,255,255,255,8,8,8,8,8,8,8,8,
604 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,8,
605 11,11,11,11,11,255,255,8,8,8,8,8,8,8,8,255,
606 11,11,11,11,11,11,255,8,8,8,8,8,8,8,255,255,
607 11,11,11,11,11,11,255,8,8,8,8,8,8,255,255,255,
608 11,11,11,11,11,11,255,8,8,8,8,8,255,255,255,15,
609 11,11,11,11,11,11,255,255,8,8,8,255,255,255,15,15,
610 };
611/*...e*/
612
613static byte nearest_colour(byte r, byte g, byte b)
614 {
615 byte i;
616
617 if ( (i = quick_tab[r >> 4][g >> 4][b >> 4]) != (byte) 0xff )
618 return i;
619
620 return calc_nearest(r, g, b);
621 }
622/*...e*/
623
624void gbm_trunc_line_VGA(const byte *src, byte *dest, int cx)
625 {
626 BOOLEAN left = TRUE;
627 int x;
628
629 init();
630
631 for ( x = 0; x < cx; x++ )
632 {
633 byte b = *src++;
634 byte g = *src++;
635 byte r = *src++;
636 byte inx = nearest_colour(r, g, b);
637
638 if ( left )
639 *dest = (byte) (inx << 4);
640 else
641 *dest++ |= inx;
642
643 left = !left;
644 }
645 }
646/*...e*/
647/*...sgbm_trunc_VGA \45\ truncate to default VGA palette:0:*/
648void gbm_trunc_VGA(const GBM *gbm, const byte *data24, byte *data4)
649 {
650 trunc(gbm, data24, data4, 4, gbm_trunc_line_VGA);
651 }
652/*...e*/
653
654/*...sgbm_trunc_pal_8 \45\ return default 8 colour palette:0:*/
655/*
656This function makes the palette for the 16 colour VGA palette.
657*/
658
659static GBMRGB gbmrgb_8[] =
660 {
661 0, 0, 0,
662 0, 0,255,
663 0,255, 0,
664 0,255,255,
665 255, 0, 0,
666 255, 0,255,
667 255,255, 0,
668 255,255,255,
669 0, 0, 0,
670 0, 0, 0,
671 0, 0, 0,
672 0, 0, 0,
673 0, 0, 0,
674 0, 0, 0,
675 0, 0, 0,
676 0, 0, 0,
677 };
678
679void gbm_trunc_pal_8(GBMRGB *gbmrgb)
680 {
681 init();
682 memcpy((char *) gbmrgb, (char *) gbmrgb_8, sizeof(gbmrgb_8));
683 }
684/*...e*/
685/*...sgbm_trunc_line_8 \45\ truncate to default 8 colour palette:0:*/
686void gbm_trunc_line_8(const byte *src, byte *dest, int cx)
687 {
688 BOOLEAN left = TRUE;
689 int x;
690
691 init();
692
693 for ( x = 0; x < cx; x++ )
694 {
695 byte b = ((*src++ & 0x80U) >> 7);
696 byte g = ((*src++ & 0x80U) >> 6);
697 byte r = ((*src++ & 0x80U) >> 5);
698 byte inx = r|g|b;
699
700 if ( left )
701 *dest = (byte) (inx << 4);
702 else
703 *dest++ |= inx;
704
705 left = !left;
706 }
707 }
708/*...e*/
709/*...sgbm_trunc_8 \45\ truncate to default 8 colour palette:0:*/
710void gbm_trunc_8(const GBM *gbm, const byte *data24, byte *data4)
711 {
712 trunc(gbm, data24, data4, 4, gbm_trunc_line_8);
713 }
714/*...e*/
715
716/*...sgbm_trunc_pal_4G \45\ return 4 bit greyscale palette:0:*/
717/*
718This function makes the palette for the 16 colour VGA palette.
719*/
720
721void gbm_trunc_pal_4G(GBMRGB *gbmrgb)
722 {
723 int i;
724
725 init();
726 for ( i = 0; i < 0x10; i++ )
727 {
728 gbmrgb[i].r = scale16[i];
729 gbmrgb[i].g = scale16[i];
730 gbmrgb[i].b = scale16[i];
731 }
732 }
733/*...e*/
734/*...sgbm_trunc_line_4G \45\ truncate to 4 bit greyscale palette:0:*/
735void gbm_trunc_line_4G(const byte *src, byte *dest, int cx)
736 {
737 BOOLEAN left = TRUE;
738 int x;
739
740 init();
741
742 for ( x = 0; x < cx; x++ )
743 {
744 byte b = *src++;
745 byte g = *src++;
746 byte r = *src++;
747 byte k = (byte) (((word) r * 77U + (word) g * 150U + (word) b * 29U) >> 8);
748 byte inx = index16[k];
749
750 if ( left )
751 *dest = (byte) (inx << 4);
752 else
753 *dest++ |= inx;
754
755 left = !left;
756 }
757 }
758/*...e*/
759/*...sgbm_trunc_4G \45\ truncate to 4 bit greyscale palette:0:*/
760void gbm_trunc_4G(const GBM *gbm, const byte *data24, byte *data4)
761 {
762 trunc(gbm, data24, data4, 4, gbm_trunc_line_4G);
763 }
764/*...e*/
765
766/*...sgbm_trunc_pal_BW \45\ return black and white palette:0:*/
767/*
768This function makes the black and white palette.
769(We consider the image to be black on white, hence the ordering).
770*/
771
772static GBMRGB gbmrgb_bw[] =
773 {
774 255,255,255,
775 0,0,0,
776 };
777
778void gbm_trunc_pal_BW(GBMRGB *gbmrgb)
779 {
780 init();
781 memcpy((char *) gbmrgb, (char *) gbmrgb_bw, sizeof(gbmrgb_bw));
782 }
783/*...e*/
784/*...sgbm_trunc_line_BW \45\ truncate to black and white:0:*/
785void gbm_trunc_line_BW(const byte *src, byte *dest, int cx)
786 {
787 int x, bit = 0;
788 byte v = 0xff;
789
790 init();
791
792 for ( x = 0; x < cx; x++ )
793 {
794 byte b = *src++;
795 byte g = *src++;
796 byte r = *src++;
797 word k = (word) ((word) r * 77 + (word) g * 150 + (word) b * 29);
798
799 if ( k >= 0x8000U )
800 v &= ~(0x80U >> bit);
801
802 if ( ++bit == 8 )
803 {
804 bit = 0;
805 *dest++ = v;
806 v = 0xff;
807 }
808 }
809 if ( bit )
810 *dest = v;
811 }
812/*...e*/
813/*...sgbm_trunc_BW \45\ truncate to black and white:0:*/
814void gbm_trunc_BW(const GBM *gbm, const byte *data24, byte *data1)
815 {
816 trunc(gbm, data24, data1, 1, gbm_trunc_line_BW);
817 }
818/*...e*/
819
820/*...sgbm_trunc_1bpp \45\ map to user specified 1bpp palette:0:*/
821void gbm_trunc_1bpp(
822 const GBM *gbm, const byte *data24, byte *data1,
823 GBMRGB *gbmrgb, int n_gbmrgb
824 )
825 {
826 int stride_src = ((gbm->w * 3 + 3) & ~3);
827 int step_src = stride_src - gbm->w * 3;
828 int stride_dest = ((gbm->w + 31) / 32) * 4;
829 int y;
830 MAP map;
831 build_map(gbmrgb, n_gbmrgb, &map);
832 memset(data1, 0, gbm->h * stride_dest);
833 for ( y = 0; y < gbm->h; y++ )
834 {
835 int x;
836 for ( x = 0; x < gbm->w; x++ )
837 {
838 byte b = *data24++;
839 byte g = *data24++;
840 byte r = *data24++;
841 byte i = nearest_color_via_map(r, g, b, &map, gbmrgb, n_gbmrgb);
842 if ( i )
843 data1[x>>3] |= ( 0x80 >> (x & 7) );
844 }
845 data24 += step_src;
846 data1 += stride_dest;
847 }
848 }
849/*...e*/
850/*...sgbm_trunc_4bpp \45\ map to user specified 4bpp palette:0:*/
851void gbm_trunc_4bpp(
852 const GBM *gbm, const byte *data24, byte *data4,
853 GBMRGB *gbmrgb, int n_gbmrgb
854 )
855 {
856 int stride_src = ((gbm->w * 3 + 3) & ~3);
857 int step_src = stride_src - gbm->w * 3;
858 int stride_dest = ((gbm->w * 4 + 31) / 32) * 4;
859 int step_dest = stride_dest - ((gbm->w * 4)+7)/8;
860 int y;
861 MAP map;
862 build_map(gbmrgb, n_gbmrgb, &map);
863 for ( y = 0; y < gbm->h; y++ )
864 {
865 int x;
866 for ( x = 0; x+1 < gbm->w; x += 2 )
867 {
868 byte b0 = *data24++;
869 byte g0 = *data24++;
870 byte r0 = *data24++;
871 byte i0 = nearest_color_via_map(r0, g0, b0, &map, gbmrgb, n_gbmrgb);
872 byte b1 = *data24++;
873 byte g1 = *data24++;
874 byte r1 = *data24++;
875 byte i1 = nearest_color_via_map(r1, g1, b1, &map, gbmrgb, n_gbmrgb);
876 *data4++ = ( ( i0 << 4 ) | i1 );
877 }
878 if ( gbm->w & 1 )
879 {
880 byte b0 = *data24++;
881 byte g0 = *data24++;
882 byte r0 = *data24++;
883 byte i0 = nearest_color_via_map(r0, g0, b0, &map, gbmrgb, n_gbmrgb);
884 *data4++ = ( i0 << 4 );
885 }
886 data24 += step_src;
887 data4 += step_dest;
888 }
889 }
890/*...e*/
891/*...sgbm_trunc_8bpp \45\ map to user specified 8bpp palette:0:*/
892void gbm_trunc_8bpp(
893 const GBM *gbm, const byte *data24, byte *data8,
894 GBMRGB *gbmrgb, int n_gbmrgb
895 )
896 {
897 int stride_src = ((gbm->w * 3 + 3) & ~3);
898 int step_src = stride_src - gbm->w * 3;
899 int stride_dest = ((gbm->w * 8 + 31) / 32) * 4;
900 int step_dest = stride_dest - gbm->w;
901 int y;
902 MAP map;
903 build_map(gbmrgb, n_gbmrgb, &map);
904 for ( y = 0; y < gbm->h; y++ )
905 {
906 int x;
907 for ( x = 0; x < gbm->w; x++ )
908 {
909 byte b = *data24++;
910 byte g = *data24++;
911 byte r = *data24++;
912 *data8++ = nearest_color_via_map(r, g, b, &map, gbmrgb, n_gbmrgb);
913 }
914 data24 += step_src;
915 data8 += step_dest;
916 }
917 }
918/*...e*/
Note: See TracBrowser for help on using the repository browser.