source: trunk/JPGPROC/source/gbmsrc/gbmht.c@ 2

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

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

File size: 33.0 KB
Line 
1/*
2
3gbmht.c - Halftoner
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[0x400];
24static byte index6[0x400];
25static byte index7[0x400];
26static byte index8[0x400];
27static byte scale4[] = { 0, 85, 170, 255 };
28static byte scale6[] = { 0, 51, 102, 153, 204, 255 };
29static byte scale7[] = { 0, 43, 85, 128, 170, 213, 255 };
30static byte scale8[] = { 0, 36, 73, 109, 146, 182, 219, 255 };
31
32static byte map_to_012[0x900];
33 /* Returns 0 if index < 0x80 */
34 /* 1 if index >= 0x80 and index < 0xff */
35 /* 2 if index = 0xff */
36static byte map_to_inx[3][3][3];
37
38static GBMRGB gbmrgb_vga[] =
39 {
40 0, 0, 0,
41 128, 0, 0,
42 0,128, 0,
43 128,128, 0,
44 0, 0,128,
45 128, 0,128,
46 0,128,128,
47 128,128,128,
48 204,204,204,
49 255, 0, 0,
50 0,255, 0,
51 255,255, 0,
52 0, 0,255,
53 255, 0,255,
54 0,255,255,
55 255,255,255,
56 };
57
58static GBMRGB gbmrgb_8[] =
59 {
60 0, 0, 0,
61 0, 0,255,
62 0,255, 0,
63 0,255,255,
64 255, 0, 0,
65 255, 0,255,
66 255,255, 0,
67 255,255,255,
68 0, 0, 0,
69 0, 0, 0,
70 0, 0, 0,
71 0, 0, 0,
72 0, 0, 0,
73 0, 0, 0,
74 0, 0, 0,
75 0, 0, 0,
76 };
77/*...e*/
78/*...sdivt:0:*/
79/*
80This fold encompasses a way to get rapid division via lookup tables.
81*/
82
83static word divt9[9 * 0x100];
84static word divt7[9 * 0x100];
85static word divt6[9 * 0x100];
86static word divt5[9 * 0x100];
87static word divt3[9 * 0x100];
88
89/*...smake_divt:0:*/
90static void make_divt(word *divt, int size, int by)
91 {
92 int i;
93
94 for ( i = 0; i < size; i++ )
95 divt[i] = (word) (i / by);
96 }
97/*...e*/
98
99#define div9(w) divt9[w]
100#define div8(w) ((w)>>3)
101#define div7(w) divt7[w]
102#define div6(w) divt6[w]
103#define div5(w) divt5[w]
104#define div4(w) ((w)>>2)
105#define div3(w) divt3[w]
106#define div2(w) ((w)>>1)
107/*...e*/
108/*...sinit:0:*/
109/*
110This function initialises this module.
111*/
112
113/*...stakeout_inx:0:*/
114/*
115For the supplied value, find the index of the highest value in the scale
116less than or equal to the value.
117*/
118
119static byte takeout_inx(int value, const byte ab[], unsigned short cb)
120 {
121 byte inx = 0;
122 unsigned short i;
123
124 for ( i = 0; i < cb; i++ )
125 if ( (unsigned short) ab[i] <= (unsigned short) value )
126 inx = (byte) i;
127
128 return inx;
129 }
130/*...e*/
131/*...stakeout_inx_vga:0:*/
132/*
133The idea is to take as much of the r, g and b as possible by chosing a
134colour from the VGA palette that leaves as little left over as possible.
135Since there are 2 mid-greys, we discourage the use of one.
136The only justification for this is that the results seem to come out better!
137Also, I have tried allowing takefrom to return the closest index, allowing
138more to be taken than r,g and b. This gives less grey results, but the
139output is a lot dirtier and speckled.
140*/
141
142static byte takeout_inx_vga(word r, word g, word b)
143 {
144 byte inx;
145 byte inx_min = 0;
146 int e_min = (int) ( r + g + b );
147
148 for ( inx = 1; inx < 16; inx++ )
149 if ( inx != 8 )
150 {
151 int re = (int) ( r - (word) gbmrgb_vga[inx].r );
152 int ge = (int) ( g - (word) gbmrgb_vga[inx].g );
153 int be = (int) ( b - (word) gbmrgb_vga[inx].b );
154
155 if ( re >= 0 && ge >= 0 && be >= 0 )
156 {
157 int e = re + ge + be;
158
159 if ( e < e_min )
160 {
161 e_min = e;
162 inx_min = inx;
163 }
164 }
165 }
166 return inx_min;
167 }
168/*...e*/
169
170static void init(void)
171 {
172 static word val[] = { 0, 0x80, 0xff };
173 int i;
174 int volatile r; /* C-Set/2 optimiser fix */
175 int volatile g;
176 int volatile b;
177
178 if ( inited )
179 return;
180
181 /* For 7 Red x 8 Green x 4 Blue palettes etc. */
182
183 for ( i = 0; i < 0x400; i++ )
184 {
185 index4[i] = takeout_inx(i, scale4 , sizeof(scale4));
186 index6[i] = takeout_inx(i, scale6 , sizeof(scale6));
187 index7[i] = takeout_inx(i, scale7 , sizeof(scale7));
188 index8[i] = takeout_inx(i, scale8 , sizeof(scale8));
189 }
190
191 memset(map_to_012, 0, 0x80);
192 memset(map_to_012 + 0x80, 1, 0x7f);
193 memset(map_to_012 + 0xff, 2, 0x801);
194
195 for ( r = 0; r < 3; r++ )
196 for ( g = 0; g < 3; g++ )
197 for ( b = 0; b < 3; b++ )
198 map_to_inx[r][g][b] = takeout_inx_vga(val[r], val[g], val[b]);
199
200 make_divt(divt9, sizeof(divt9)/sizeof(word), 9);
201 make_divt(divt7, sizeof(divt7)/sizeof(word), 7);
202 make_divt(divt6, sizeof(divt6)/sizeof(word), 6);
203 make_divt(divt5, sizeof(divt5)/sizeof(word), 5);
204 make_divt(divt3, sizeof(divt3)/sizeof(word), 3);
205
206 inited = TRUE;
207 }
208/*...e*/
209/*...stakefrom:0:*/
210#define takefrom(r,g,b) ( map_to_inx[map_to_012[r]][map_to_012[g]][map_to_012[b]] )
211/*...e*/
212/*...ssplit_into:0:*/
213/* n is only ever 2, 3, 4, 6 or 9 */
214
215static void split_into(
216 word r, word g, word b,
217 int n, byte *inxs
218 )
219 {
220 byte inx;
221
222 if ( n >= 9 )
223 {
224 inx = takefrom(div9(r), div9(g), div9(b));
225 b -= gbmrgb_vga[inx].b;
226 g -= gbmrgb_vga[inx].g;
227 r -= gbmrgb_vga[inx].r;
228 *inxs++ = inx;
229
230 inx = takefrom(div8(r), div8(g), div8(b));
231 b -= gbmrgb_vga[inx].b;
232 g -= gbmrgb_vga[inx].g;
233 r -= gbmrgb_vga[inx].r;
234 *inxs++ = inx;
235
236 inx = takefrom(div7(r), div7(g), div7(b));
237 b -= gbmrgb_vga[inx].b;
238 g -= gbmrgb_vga[inx].g;
239 r -= gbmrgb_vga[inx].r;
240 *inxs++ = inx;
241 }
242
243 if ( n >= 6 )
244 {
245 inx = takefrom(div6(r), div6(g), div6(b));
246 b -= gbmrgb_vga[inx].b;
247 g -= gbmrgb_vga[inx].g;
248 r -= gbmrgb_vga[inx].r;
249 *inxs++ = inx;
250
251 inx = takefrom(div5(r), div5(g), div5(b));
252 b -= gbmrgb_vga[inx].b;
253 g -= gbmrgb_vga[inx].g;
254 r -= gbmrgb_vga[inx].r;
255 *inxs++ = inx;
256 }
257
258 if ( n >= 4 )
259 {
260 inx = takefrom(div4(r), div4(g), div4(b));
261 b -= gbmrgb_vga[inx].b;
262 g -= gbmrgb_vga[inx].g;
263 r -= gbmrgb_vga[inx].r;
264 *inxs++ = inx;
265 }
266
267 if ( n >= 3 )
268 {
269 inx = takefrom(div3(r), div3(g), div3(b));
270 b -= gbmrgb_vga[inx].b;
271 g -= gbmrgb_vga[inx].g;
272 r -= gbmrgb_vga[inx].r;
273 *inxs++ = inx;
274 }
275
276 inx = takefrom(div2(r), div2(g), div2(b));
277 b -= gbmrgb_vga[inx].b;
278 g -= gbmrgb_vga[inx].g;
279 r -= gbmrgb_vga[inx].r;
280 *inxs++ = inx;
281
282 *inxs = takefrom(r, g, b);
283 }
284/*...e*/
285/*...stakefrom8:0:*/
286/*
287Find the largest colour from the 8 colour palette.
288*/
289
290#define takefrom8(r,g,b) ( (((r)>=255)<<2) | (((g)>=255)<<1) | ((b)>=255) )
291/*...e*/
292/*...ssplit_into8:0:*/
293/* n is only ever 2, 3, 4, 6 or 9 */
294
295static void split_into8(
296 word r, word g, word b,
297 int n, byte *inxs
298 )
299 {
300 byte inx;
301
302 if ( n >= 9 )
303 {
304 inx = takefrom8(div9(r), div9(g), div9(b));
305 b -= gbmrgb_8[inx].b;
306 g -= gbmrgb_8[inx].g;
307 r -= gbmrgb_8[inx].r;
308 *inxs++ = inx;
309
310 inx = takefrom8(div8(r), div8(g), div8(b));
311 b -= gbmrgb_8[inx].b;
312 g -= gbmrgb_8[inx].g;
313 r -= gbmrgb_8[inx].r;
314 *inxs++ = inx;
315
316 inx = takefrom8(div7(r), div7(g), div7(b));
317 b -= gbmrgb_8[inx].b;
318 g -= gbmrgb_8[inx].g;
319 r -= gbmrgb_8[inx].r;
320 *inxs++ = inx;
321 }
322
323 if ( n >= 6 )
324 {
325 inx = takefrom8(div6(r), div6(g), div6(b));
326 b -= gbmrgb_8[inx].b;
327 g -= gbmrgb_8[inx].g;
328 r -= gbmrgb_8[inx].r;
329 *inxs++ = inx;
330
331 inx = takefrom8(div5(r), div5(g), div5(b));
332 b -= gbmrgb_8[inx].b;
333 g -= gbmrgb_8[inx].g;
334 r -= gbmrgb_8[inx].r;
335 *inxs++ = inx;
336 }
337
338 if ( n >= 4 )
339 {
340 inx = takefrom8(div4(r), div4(g), div4(b));
341 b -= gbmrgb_8[inx].b;
342 g -= gbmrgb_8[inx].g;
343 r -= gbmrgb_8[inx].r;
344 *inxs++ = inx;
345 }
346
347 if ( n >= 3 )
348 {
349 inx = takefrom8(div3(r), div3(g), div3(b));
350 b -= gbmrgb_8[inx].b;
351 g -= gbmrgb_8[inx].g;
352 r -= gbmrgb_8[inx].r;
353 *inxs++ = inx;
354 }
355
356 inx = takefrom8(div2(r), div2(g), div2(b));
357 b -= gbmrgb_8[inx].b;
358 g -= gbmrgb_8[inx].g;
359 r -= gbmrgb_8[inx].r;
360 *inxs++ = inx;
361
362 *inxs = takefrom8(r, g, b);
363 }
364/*...e*/
365
366/*...sgbm_ht_24_2x2 \45\ halftone by 2x2 to r\58\g\58\b bits:0:*/
367void gbm_ht_24_2x2(const GBM *gbm, const byte *src24, byte *dest24, byte rm, byte gm, byte bm)
368 {
369 int stride = ((gbm->w * 3 + 3) & ~3);
370 int x, y;
371
372 init();
373
374 src24 -= stride;
375 dest24 -= stride;
376
377 for ( y = 0; y < gbm->h - 1; y += 2 )
378 {
379 const byte *src24a = (src24 += stride);
380 const byte *src24b = (src24 += stride);
381 byte *dest24a = (dest24 += stride);
382 byte *dest24b = (dest24 += stride);
383
384 for ( x = 0; x < gbm->w - 1; x += 2 )
385/*...s2x2 case:24:*/
386{
387word r,g,b;
388byte ri,gi,bi;
389byte *tmp;
390
391b = *src24a++; g = *src24a++; r = *src24a++;
392b += *src24a++; g += *src24a++; r += *src24a++;
393b += *src24b++; g += *src24b++; r += *src24b++;
394b += *src24b++; g += *src24b++; r += *src24b++;
395
396bi = (div4(b) & bm); gi = (div4(g) & gm); ri = (div4(r) & rm);
397*dest24a++ = bi; *dest24a++ = gi; *dest24a++ = ri;
398b -= bi; g -= gi; r -= ri;
399
400if ( b > 255 * 3 ) b = 255 * 3;
401if ( g > 255 * 3 ) g = 255 * 3;
402if ( r > 255 * 3 ) r = 255 * 3;
403
404bi = (div3(b) & bm); gi = (div3(g) & gm); ri = (div3(r) & rm);
405*dest24a++ = bi; *dest24a++ = gi; *dest24a++ = ri;
406b -= bi; g -= gi; r -= ri;
407
408if ( b > 255 * 2 ) b = 255 * 2;
409if ( g > 255 * 2 ) g = 255 * 2;
410if ( r > 255 * 2 ) r = 255 * 2;
411
412bi = (div2(b) & bm); gi = (div2(g) & gm); ri = (div2(r) & rm);
413*dest24b++ = bi; *dest24b++ = gi; *dest24b++ = ri;
414b -= bi; g -= gi; r -= ri;
415
416if ( b > 255 ) b = 255;
417if ( g > 255 ) g = 255;
418if ( r > 255 ) r = 255;
419
420bi = (b & bm); gi = (g & gm); ri = (r & rm);
421*dest24b++ = bi; *dest24b++ = gi; *dest24b++ = ri;
422
423tmp = dest24a; dest24a = dest24b; dest24b = tmp;
424}
425/*...e*/
426 if ( x < gbm->w )
427/*...s1x2 case:24:*/
428{
429word r,g,b;
430byte ri, gi, bi;
431
432b = *src24a++; g = *src24a++; r = *src24a;
433b += *src24b++; g += *src24b++; r += *src24b;
434
435bi = (div2(b) & bm); gi = (div2(g) & gm); ri = (div2(r) & rm);
436*dest24a++ = bi; *dest24a++ = gi; *dest24a++ = ri;
437b -= bi; g -= gi; r -= ri;
438
439if ( b > 255 ) b = 255;
440if ( g > 255 ) g = 255;
441if ( r > 255 ) r = 255;
442
443bi = (b & bm); gi = (g & gm); ri = (r & rm);
444*dest24b++ = bi; *dest24b++ = gi; *dest24b = ri;
445}
446/*...e*/
447 }
448 if ( y < gbm->h )
449 {
450 const byte *src24a = src24 + stride;
451 byte *dest24a = dest24 + stride;
452
453 for ( x = 0; x < gbm->w - 1; x += 2 )
454/*...s2x1 case:24:*/
455{
456word r,g,b;
457byte ri, gi, bi;
458
459b = *src24a++; g = *src24a++; r = *src24a++;
460b += *src24a++; g += *src24a++; r += *src24a++;
461
462bi = (div2(b) & bm); gi = (div2(g) & gm); ri = (div2(r) & rm);
463*dest24a++ = bi; *dest24a++ = gi; *dest24a++ = ri;
464b -= bi; g -= gi; r -= ri;
465
466if ( b > 255 ) b = 255;
467if ( g > 255 ) g = 255;
468if ( r > 255 ) r = 255;
469
470bi = (b & bm); gi = (g & gm); ri = (r & rm);
471*dest24a++ = bi; *dest24a++ = gi; *dest24a++ = ri;
472}
473/*...e*/
474 if ( x < gbm->w )
475/*...s1x1 case:24:*/
476{
477byte ri, gi, bi;
478
479bi = ((*src24a++) & bm); gi = ((*src24a++) & gm); ri = ((*src24a) & rm);
480*dest24a++ = bi; *dest24a++ = gi; *dest24a = ri;
481}
482/*...e*/
483 }
484 }
485/*...e*/
486
487/*...sgbm_ht_pal_6R6G6B \45\ return 6Rx6Gx6B palette:0:*/
488/*
489This function makes the palette for the 6 red x 6 green x 6 blue palette.
490216 palette entrys used. Remaining 40 left blank.
491*/
492
493void gbm_ht_pal_6R6G6B(GBMRGB *gbmrgb)
494 {
495 byte volatile r; /* C-Set/2 optimiser fix */
496 byte volatile g;
497 byte volatile b;
498
499 init();
500 memset(gbmrgb, 0x80, 0x100 * sizeof(GBMRGB));
501 for ( r = 0; r < 6; r++ )
502 for ( g = 0; g < 6; g++ )
503 for ( b = 0; b < 6; b++ )
504 {
505 gbmrgb->r = scale6[r];
506 gbmrgb->g = scale6[g];
507 gbmrgb->b = scale6[b];
508 gbmrgb++;
509 }
510 }
511/*...e*/
512/*...sgbm_ht_6R6G6B_2x2 \45\ halftone by 2x2 to 6Rx6Gx6B palette:0:*/
513#define PIX666(ri,gi,bi) (byte) (6 * (6 * ri + gi) + bi)
514
515void gbm_ht_6R6G6B_2x2(const GBM *gbm, const byte *src24, byte *dest8)
516 {
517 int stride24 = ((gbm->w * 3 + 3) & ~3);
518 int stride8 = ((gbm->w + 3) & ~3);
519 int x, y;
520
521 init();
522
523 src24 -= stride24;
524 dest8 -= stride8;
525
526 for ( y = 0; y < gbm->h - 1; y += 2 )
527 {
528 const byte *src24a = (src24 += stride24);
529 const byte *src24b = (src24 += stride24);
530 byte *dest8a = (dest8 += stride8);
531 byte *dest8b = (dest8 += stride8);
532
533 for ( x = 0; x < gbm->w - 1; x += 2 )
534/*...s2x2 case:24:*/
535{
536word r,g,b;
537byte ri,gi,bi;
538byte *tmp;
539
540b = *src24a++; g = *src24a++; r = *src24a++;
541b += *src24a++; g += *src24a++; r += *src24a++;
542b += *src24b++; g += *src24b++; r += *src24b++;
543b += *src24b++; g += *src24b++; r += *src24b++;
544
545bi = index6[div4(b)]; gi = index6[div4(g)]; ri = index6[div4(r)];
546*dest8a++ = PIX666(ri,gi,bi);
547b -= scale6[bi]; g -= scale6[gi]; r -= scale6[ri];
548
549bi = index6[div3(b)]; gi = index6[div3(g)]; ri = index6[div3(r)];
550*dest8a++ = PIX666(ri,gi,bi);
551b -= scale6[bi]; g -= scale6[gi]; r -= scale6[ri];
552
553bi = index6[div2(b)]; gi = index6[div2(g)]; ri = index6[div2(r)];
554*dest8b++ = PIX666(ri,gi,bi);
555b -= scale6[bi]; g -= scale6[gi]; r -= scale6[ri];
556
557bi = index6[b ]; gi = index6[g ]; ri = index6[r ];
558*dest8b++ = PIX666(ri,gi,bi);
559
560tmp = dest8a; dest8a = dest8b; dest8b = tmp;
561}
562/*...e*/
563 if ( x < gbm->w )
564/*...s1x2 case:24:*/
565{
566word r,g,b;
567byte ri, gi, bi;
568
569b = *src24a++; g = *src24a++; r = *src24a;
570b += *src24b++; g += *src24b++; r += *src24b;
571
572bi = index6[div2(b)]; gi = index6[div2(g)]; ri = index6[div2(r)];
573*dest8a = PIX666(ri,gi,bi);
574b -= scale6[bi]; g -= scale6[gi]; r -= scale6[ri];
575
576bi = index6[b ]; gi = index6[g ]; ri = index6[r ];
577*dest8b = PIX666(ri,gi,bi);
578}
579/*...e*/
580 }
581 if ( y < gbm->h )
582 {
583 const byte *src24a = src24 + stride24;
584 byte *dest8a = dest8 + stride8;
585
586 for ( x = 0; x < gbm->w - 1; x += 2 )
587/*...s2x1 case:24:*/
588{
589word r,g,b;
590byte ri, gi, bi;
591
592b = *src24a++; g = *src24a++; r = *src24a++;
593b += *src24a++; g += *src24a++; r += *src24a++;
594
595bi = index6[div2(b)]; gi = index6[div2(g)]; ri = index6[div2(r)];
596*dest8a++ = PIX666(ri,gi,bi);
597b -= scale6[bi]; g -= scale6[gi]; r -= scale6[ri];
598
599bi = index6[b ]; gi = index6[g ]; ri = index6[r ];
600*dest8a++ = PIX666(ri,gi,bi);
601}
602/*...e*/
603 if ( x < gbm->w )
604/*...s1x1 case:24:*/
605{
606byte ri, gi, bi;
607
608bi = index6[*src24a++]; gi = index6[*src24a++]; ri = index6[*src24a];
609*dest8a = PIX666(ri,gi,bi);
610}
611/*...e*/
612 }
613 }
614/*...e*/
615
616/*...sgbm_ht_pal_7R8G4B \45\ return 7Rx8Gx4B palette:0:*/
617/*
618This function makes the palette for the 7 red x 8 green x 4 blue palette.
619224 palette entrys used. Remaining 32 left blank.
620Colours calculated to match those used by 8514/A PM driver.
621*/
622
623void gbm_ht_pal_7R8G4B(GBMRGB *gbmrgb)
624 {
625 byte volatile r; /* C-Set/2 optimiser fix */
626 byte volatile g;
627 byte volatile b;
628
629 init();
630
631 memset(gbmrgb, 0x80, 0x100 * sizeof(GBMRGB));
632 for ( r = 0; r < 7; r++ )
633 for ( g = 0; g < 8; g++ )
634 for ( b = 0; b < 4; b++ )
635 {
636 gbmrgb->r = scale7[r];
637 gbmrgb->g = scale8[g];
638 gbmrgb->b = scale4[b];
639 gbmrgb++;
640 }
641 }
642/*...e*/
643/*...sgbm_ht_7R8G4B_2x2 \45\ halftone by 2x2 to 7Rx8Gx4B palette:0:*/
644#define PIX784(ri,gi,bi) (byte) (((((ri)<<3)+(gi))<<2)+(bi))
645
646void gbm_ht_7R8G4B_2x2(const GBM *gbm, const byte *src24, byte *dest8)
647 {
648 int stride24 = ((gbm->w * 3 + 3) & ~3);
649 int stride8 = ((gbm->w + 3) & ~3);
650 int x, y;
651
652 init();
653
654 src24 -= stride24;
655 dest8 -= stride8;
656
657 for ( y = 0; y < gbm->h - 1; y += 2 )
658 {
659 const byte *src24a = (src24 += stride24);
660 const byte *src24b = (src24 += stride24);
661 byte *dest8a = (dest8 += stride8);
662 byte *dest8b = (dest8 += stride8);
663
664 for ( x = 0; x < gbm->w - 1; x += 2 )
665/*...s2x2 case:24:*/
666{
667word r,g,b;
668byte ri,gi,bi;
669byte *tmp;
670
671b = *src24a++; g = *src24a++; r = *src24a++;
672b += *src24a++; g += *src24a++; r += *src24a++;
673b += *src24b++; g += *src24b++; r += *src24b++;
674b += *src24b++; g += *src24b++; r += *src24b++;
675
676bi = index4[div4(b)]; gi = index8[div4(g)]; ri = index7[div4(r)];
677*dest8a++ = PIX784(ri,gi,bi);
678b -= scale4[bi]; g -= scale8[gi]; r -= scale7[ri];
679
680bi = index4[div3(b)]; gi = index8[div3(g)]; ri = index7[div3(r)];
681*dest8a++ = PIX784(ri,gi,bi);
682b -= scale4[bi]; g -= scale8[gi]; r -= scale7[ri];
683
684bi = index4[div2(b)]; gi = index8[div2(g)]; ri = index7[div2(r)];
685*dest8b++ = PIX784(ri,gi,bi);
686b -= scale4[bi]; g -= scale8[gi]; r -= scale7[ri];
687
688bi = index4[b ]; gi = index8[g ]; ri = index7[r ];
689*dest8b++ = PIX784(ri,gi,bi);
690
691tmp = dest8a; dest8a = dest8b; dest8b = tmp;
692}
693/*...e*/
694 if ( x < gbm->w )
695/*...s1x2 case:24:*/
696{
697word r,g,b;
698byte ri, gi, bi;
699
700b = *src24a++; g = *src24a++; r = *src24a;
701b += *src24b++; g += *src24b++; r += *src24b;
702
703bi = index4[div2(b)]; gi = index8[div2(g)]; ri = index7[div2(r)];
704*dest8a = PIX784(ri,gi,bi);
705b -= scale4[bi]; g -= scale8[gi]; r -= scale7[ri];
706
707bi = index4[b ]; gi = index8[g ]; ri = index7[r ];
708*dest8b = PIX784(ri,gi,bi);
709}
710/*...e*/
711 }
712 if ( y < gbm->h )
713 {
714 const byte *src24a = src24 + stride24;
715 byte *dest8a = dest8 + stride8;
716
717 for ( x = 0; x < gbm->w - 1; x += 2 )
718/*...s2x1 case:24:*/
719{
720word r,g,b;
721byte ri, gi, bi;
722
723b = *src24a++; g = *src24a++; r = *src24a++;
724b += *src24a++; g += *src24a++; r += *src24a++;
725
726bi = index4[div2(b)]; gi = index8[div2(g)]; ri = index7[div2(r)];
727*dest8a++ = PIX784(ri,gi,bi);
728b -= scale4[bi]; g -= scale8[gi]; r -= scale7[ri];
729
730bi = index4[b ]; gi = index8[g ]; ri = index7[r ];
731*dest8a++ = PIX784(ri,gi,bi);
732}
733/*...e*/
734 if ( x < gbm->w )
735/*...s1x1 case:24:*/
736{
737byte ri, gi, bi;
738
739bi = index4[*src24a++]; gi = index8[*src24a++]; ri = index7[*src24a];
740*dest8a = PIX784(ri,gi,bi);
741}
742/*...e*/
743 }
744 }
745/*...e*/
746
747/*...sgbm_ht_pal_VGA \45\ return default VGA palette:0:*/
748/*
749This function makes the palette for the 16 colour VGA palette.
750*/
751
752void gbm_ht_pal_VGA(GBMRGB *gbmrgb)
753 {
754 init();
755 memcpy((char *) gbmrgb, (char *) gbmrgb_vga, sizeof(gbmrgb_vga));
756 }
757/*...e*/
758/*...sgbm_ht_VGA_2x2 \45\ halftone by 2x2 to default VGA palette:0:*/
759void gbm_ht_VGA_2x2(const GBM *gbm, const byte *src24, byte *dest4)
760 {
761 int stride24 = ((gbm->w * 3 + 3) & ~3);
762 int stride4 = ((gbm->w * 4 + 31) / 32) * 4;
763 int x, y;
764
765 init();
766
767 src24 -= stride24;
768 dest4 -= stride4;
769
770 for ( y = 0; y < gbm->h - 1; y += 2 )
771 {
772 const byte *src24a = (src24 += stride24);
773 const byte *src24b = (src24 += stride24);
774 byte *dest4a = (dest4 += stride4);
775 byte *dest4b = (dest4 += stride4);
776
777 for ( x = 0; x < gbm->w - 1; x += 2 )
778/*...s2x2 case:24:*/
779{
780word r,g,b;
781byte inx;
782byte *tmp;
783
784b = *src24a++; g = *src24a++; r = *src24a++;
785b += *src24a++; g += *src24a++; r += *src24a++;
786b += *src24b++; g += *src24b++; r += *src24b++;
787b += *src24b++; g += *src24b++; r += *src24b++;
788
789inx = takefrom(div4(r), div4(g), div4(b)); *dest4a = (inx << 4);
790b -= gbmrgb_vga[inx].b; g -= gbmrgb_vga[inx].g; r -= gbmrgb_vga[inx].r;
791
792inx = takefrom(div3(r), div3(g), div3(b)); *dest4a++ |= inx;
793b -= gbmrgb_vga[inx].b; g -= gbmrgb_vga[inx].g; r -= gbmrgb_vga[inx].r;
794
795inx = takefrom(div2(r), div2(g), div2(b)); *dest4b = (inx << 4);
796b -= gbmrgb_vga[inx].b; g -= gbmrgb_vga[inx].g; r -= gbmrgb_vga[inx].r;
797
798inx = takefrom(r , g , b ); *dest4b++ |= inx;
799
800tmp = dest4a; dest4a = dest4b; dest4b = tmp;
801}
802/*...e*/
803 if ( x < gbm->w )
804/*...s1x2 case:24:*/
805{
806word r,g,b;
807byte inx;
808
809b = *src24a++; g = *src24a++; r = *src24a;
810b += *src24b++; g += *src24b++; r += *src24b;
811
812inx = takefrom(div2(r), div2(g), div2(b)); *dest4a = (inx << 4);
813b -= gbmrgb_vga[inx].b; g -= gbmrgb_vga[inx].g; r -= gbmrgb_vga[inx].r;
814
815inx = takefrom(r , g , b ); *dest4b = (inx << 4);
816}
817/*...e*/
818 }
819 if ( y < gbm->h )
820 {
821 const byte *src24a = src24 + stride24;
822 byte *dest4a = dest4 + stride4;
823
824 for ( x = 0; x < gbm->w - 1; x += 2 )
825/*...s2x1 case:24:*/
826{
827word r,g,b;
828byte inx;
829
830b = *src24a++; g = *src24a++; r = *src24a++;
831b += *src24a++; g += *src24a++; r += *src24a++;
832
833inx = takefrom(div2(r), div2(g), div2(b)); *dest4a = (inx << 4);
834b -= gbmrgb_vga[inx].b; g -= gbmrgb_vga[inx].g; r -= gbmrgb_vga[inx].r;
835
836inx = takefrom(r , g , b ); *dest4a++ |= inx;
837}
838/*...e*/
839 if ( x < gbm->w )
840/*...s1x1 case:24:*/
841{
842word r, g, b;
843byte inx;
844
845b = *src24a++; g = *src24a++; r = *src24a;
846inx = takefrom(r, g, b); *dest4a = (inx << 4);
847}
848/*...e*/
849 }
850 }
851/*...e*/
852/*...sgbm_ht_VGA_3x3 \45\ halftone by 3x3 to default VGA palette:0:*/
853void gbm_ht_VGA_3x3(const GBM *gbm, const byte *src24, byte *dest4)
854 {
855 int stride24 = ((gbm->w * 3 + 3) & ~3);
856 int stride4 = ((gbm->w * 4 + 31) / 32) * 4;
857 int x, y;
858
859 init();
860
861 src24 -= stride24;
862 dest4 -= stride4;
863
864 for ( y = 0; y < gbm->h - 2; y += 3 )
865 {
866 const byte *src24a = (src24 += stride24);
867 const byte *src24b = (src24 += stride24);
868 const byte *src24c = (src24 += stride24);
869 byte *dest4a = (dest4 += stride4);
870 byte *dest4b = (dest4 += stride4);
871 byte *dest4c = (dest4 += stride4);
872 BOOLEAN left = TRUE;
873
874 for ( x = 0; x < gbm->w - 2; x += 3, left = !left )
875/*...s3x3 case:24:*/
876{
877word r,g,b;
878byte inxs[9];
879byte *tmp;
880
881b = *src24a++; g = *src24a++; r = *src24a++;
882b += *src24a++; g += *src24a++; r += *src24a++;
883b += *src24a++; g += *src24a++; r += *src24a++;
884b += *src24b++; g += *src24b++; r += *src24b++;
885b += *src24b++; g += *src24b++; r += *src24b++;
886b += *src24b++; g += *src24b++; r += *src24b++;
887b += *src24c++; g += *src24c++; r += *src24c++;
888b += *src24c++; g += *src24c++; r += *src24c++;
889b += *src24c++; g += *src24c++; r += *src24c++;
890
891split_into(r, g, b, 9, inxs);
892
893if ( left )
894 {
895 *dest4a++ = ((inxs[0] << 4) | inxs[1]); *dest4a = (inxs[2] << 4);
896 *dest4b++ = ((inxs[3] << 4) | inxs[4]); *dest4b = (inxs[5] << 4);
897 *dest4c++ = ((inxs[6] << 4) | inxs[7]); *dest4c = (inxs[8] << 4);
898 }
899else
900 {
901 *dest4a++ |= inxs[0]; *dest4a++ = ((inxs[1] << 4) | inxs[2]);
902 *dest4b++ |= inxs[3]; *dest4b++ = ((inxs[4] << 4) | inxs[5]);
903 *dest4c++ |= inxs[6]; *dest4c++ = ((inxs[7] << 4) | inxs[8]);
904 }
905
906tmp = dest4a; dest4a = dest4b; dest4b = dest4c; dest4c = tmp;
907}
908/*...e*/
909 if ( x < gbm->w - 1 )
910/*...s2x3 case:24:*/
911{
912word r,g,b;
913byte inxs[6];
914
915b = *src24a++; g = *src24a++; r = *src24a++;
916b += *src24a++; g += *src24a++; r += *src24a++;
917b += *src24b++; g += *src24b++; r += *src24b++;
918b += *src24b++; g += *src24b++; r += *src24b++;
919b += *src24c++; g += *src24c++; r += *src24c++;
920b += *src24c++; g += *src24c++; r += *src24c++;
921
922split_into(r, g, b, 6, inxs);
923
924if ( left )
925 {
926 *dest4a = ((inxs[0] << 4) | inxs[1]);
927 *dest4b = ((inxs[2] << 4) | inxs[3]);
928 *dest4c = ((inxs[4] << 4) | inxs[5]);
929 }
930else
931 {
932 *dest4a++ |= inxs[0]; *dest4a = (inxs[1] << 4);
933 *dest4b++ |= inxs[2]; *dest4b = (inxs[3] << 4);
934 *dest4c++ |= inxs[4]; *dest4c = (inxs[5] << 4);
935 }
936}
937/*...e*/
938 else if ( x < gbm->w )
939/*...s1x3 case:24:*/
940{
941word r,g,b;
942byte inxs[3];
943
944b = *src24a++; g = *src24a++; r = *src24a++;
945b += *src24b++; g += *src24b++; r += *src24b++;
946b += *src24c++; g += *src24c++; r += *src24c++;
947
948split_into(r, g, b, 3, inxs);
949
950if ( left )
951 {
952 *dest4a = (inxs[0] << 4);
953 *dest4b = (inxs[1] << 4);
954 *dest4c = (inxs[2] << 4);
955 }
956else
957 {
958 *dest4a |= inxs[0];
959 *dest4b |= inxs[1];
960 *dest4c |= inxs[2];
961 }
962}
963/*...e*/
964 }
965 if ( y < gbm->h - 1 )
966 {
967 const byte *src24a = (src24 += stride24);
968 const byte *src24b = (src24 += stride24);
969 byte *dest4a = (dest4 += stride4);
970 byte *dest4b = (dest4 += stride4);
971 BOOLEAN left = TRUE;
972
973 for ( x = 0; x < gbm->w - 2; x += 3, left = !left )
974/*...s3x2 case:24:*/
975{
976word r,g,b;
977byte inxs[6];
978byte *tmp;
979
980b = *src24a++; g = *src24a++; r = *src24a++;
981b += *src24a++; g += *src24a++; r += *src24a++;
982b += *src24a++; g += *src24a++; r += *src24a++;
983b += *src24b++; g += *src24b++; r += *src24b++;
984b += *src24b++; g += *src24b++; r += *src24b++;
985b += *src24b++; g += *src24b++; r += *src24b++;
986
987split_into(r, g, b, 6, inxs);
988
989if ( left )
990 {
991 *dest4a++ = (inxs[0] << 4) | inxs[1]; *dest4a = (inxs[2] << 4);
992 *dest4b++ = (inxs[3] << 4) | inxs[4]; *dest4b = (inxs[5] << 4);
993 }
994else
995 {
996 *dest4a++ |= inxs[0]; *dest4a++ = ((inxs[1] << 4) | inxs[2]);
997 *dest4b++ |= inxs[3]; *dest4b++ = ((inxs[4] << 4) | inxs[5]);
998 }
999
1000tmp = dest4a; dest4a = dest4b; dest4b = tmp;
1001}
1002/*...e*/
1003 if ( x < gbm->w - 1 )
1004/*...s2x2 case:24:*/
1005{
1006word r,g,b;
1007byte inxs[4];
1008
1009b = *src24a++; g = *src24a++; r = *src24a++;
1010b += *src24a++; g += *src24a++; r += *src24a++;
1011b += *src24b++; g += *src24b++; r += *src24b++;
1012b += *src24b++; g += *src24b++; r += *src24b++;
1013
1014split_into(r, g, b, 4, inxs);
1015
1016if ( left )
1017 {
1018 *dest4a = ((inxs[0] << 4) | inxs[1]);
1019 *dest4b = ((inxs[2] << 4) | inxs[3]);
1020 }
1021else
1022 {
1023 *dest4a++ |= inxs[0]; *dest4a = (inxs[1] << 4);
1024 *dest4b++ |= inxs[2]; *dest4b = (inxs[3] << 4);
1025 }
1026}
1027/*...e*/
1028 else if ( x < gbm->w )
1029/*...s1x2 case:24:*/
1030{
1031word r,g,b;
1032byte inxs[2];
1033
1034b = *src24a++; g = *src24a++; r = *src24a++;
1035b += *src24b++; g += *src24b++; r += *src24b++;
1036
1037split_into(r, g, b, 2, inxs);
1038
1039if ( left )
1040 {
1041 *dest4a = (inxs[0] << 4);
1042 *dest4b = (inxs[1] << 4);
1043 }
1044else
1045 {
1046 *dest4a |= inxs[0];
1047 *dest4b |= inxs[1];
1048 }
1049}
1050/*...e*/
1051 }
1052 else if ( y < gbm->h )
1053 {
1054 const byte *src24a = (src24 += stride24);
1055 byte *dest4a = (dest4 += stride4);
1056 BOOLEAN left = TRUE;
1057
1058 for ( x = 0; x < gbm->w - 2; x += 3, left = !left )
1059/*...s3x1 case:24:*/
1060{
1061word r,g,b;
1062byte inxs[3];
1063
1064b = *src24a++; g = *src24a++; r = *src24a++;
1065b += *src24a++; g += *src24a++; r += *src24a++;
1066b += *src24a++; g += *src24a++; r += *src24a++;
1067
1068split_into(r, g, b, 3, inxs);
1069
1070if ( left )
1071 {
1072 *dest4a++ = ((inxs[0] << 4) | inxs[1]); *dest4a = (inxs[2] << 4);
1073 }
1074else
1075 {
1076 *dest4a++ |= inxs[0]; *dest4a++ = ((inxs[1] << 4) | inxs[2]);
1077 }
1078}
1079/*...e*/
1080 if ( x < gbm->w - 1 )
1081/*...s2x1 case:24:*/
1082{
1083word r,g,b;
1084byte inxs[2];
1085
1086b = *src24a++; g = *src24a++; r = *src24a++;
1087b += *src24a++; g += *src24a++; r += *src24a++;
1088
1089split_into(r, g, b, 4, inxs);
1090
1091if ( left )
1092 *dest4a = ((inxs[0] << 4) | inxs[1]);
1093else
1094 {
1095 *dest4a++ |= inxs[0]; *dest4a = (inxs[1] << 4);
1096 }
1097}
1098/*...e*/
1099 else if ( x < gbm->w )
1100/*...s1x1 case:24:*/
1101{
1102word r,g,b;
1103byte inx;
1104
1105b = *src24a++; g = *src24a++; r = *src24a++;
1106
1107inx = takefrom(r, g, b);
1108
1109if ( left )
1110 *dest4a = (inx << 4);
1111else
1112 *dest4a |= inx;
1113}
1114/*...e*/
1115 }
1116 }
1117/*...e*/
1118
1119/*...sgbm_ht_pal_8 \45\ return default 8 colour palette:0:*/
1120/*
1121This function makes the palette for the 8 colour palette.
1122*/
1123
1124void gbm_ht_pal_8(GBMRGB *gbmrgb)
1125 {
1126 init();
1127 memcpy((char *) gbmrgb, (char *) gbmrgb_8, sizeof(gbmrgb_8));
1128 }
1129/*...e*/
1130/*...sgbm_ht_8_2x2 \45\ halftone by 2x2 to default 8 colour palette:0:*/
1131void gbm_ht_8_2x2(const GBM *gbm, const byte *src24, byte *dest4)
1132 {
1133 int stride24 = ((gbm->w * 3 + 3) & ~3);
1134 int stride4 = ((gbm->w * 4 + 31) / 32) * 4;
1135 int x, y;
1136
1137 init();
1138
1139 src24 -= stride24;
1140 dest4 -= stride4;
1141
1142 for ( y = 0; y < gbm->h - 1; y += 2 )
1143 {
1144 const byte *src24a = (src24 += stride24);
1145 const byte *src24b = (src24 += stride24);
1146 byte *dest4a = (dest4 += stride4);
1147 byte *dest4b = (dest4 += stride4);
1148
1149 for ( x = 0; x < gbm->w - 1; x += 2 )
1150/*...s2x2 case:24:*/
1151{
1152word r,g,b;
1153byte inx;
1154byte *tmp;
1155
1156b = *src24a++; g = *src24a++; r = *src24a++;
1157b += *src24a++; g += *src24a++; r += *src24a++;
1158b += *src24b++; g += *src24b++; r += *src24b++;
1159b += *src24b++; g += *src24b++; r += *src24b++;
1160
1161inx = takefrom8(r >> 2, g >> 2, b >> 2); *dest4a = (inx << 4);
1162b -= gbmrgb_8[inx].b; g -= gbmrgb_8[inx].g; r -= gbmrgb_8[inx].r;
1163
1164inx = takefrom8(r / 3, g / 3, b / 3); *dest4a++ |= inx;
1165b -= gbmrgb_8[inx].b; g -= gbmrgb_8[inx].g; r -= gbmrgb_8[inx].r;
1166
1167inx = takefrom8(r >> 1, g >> 1, b >> 1); *dest4b = (inx << 4);
1168b -= gbmrgb_8[inx].b; g -= gbmrgb_8[inx].g; r -= gbmrgb_8[inx].r;
1169
1170inx = takefrom8(r , g , b ); *dest4b++ |= inx;
1171
1172tmp = dest4a; dest4a = dest4b; dest4b = tmp;
1173}
1174/*...e*/
1175 if ( x < gbm->w )
1176/*...s1x2 case:24:*/
1177{
1178word r,g,b;
1179byte inx;
1180
1181b = *src24a++; g = *src24a++; r = *src24a;
1182b += *src24b++; g += *src24b++; r += *src24b;
1183
1184inx = takefrom8(r >> 1, g >> 1, b >> 1); *dest4a = (inx << 4);
1185b -= gbmrgb_8[inx].b; g -= gbmrgb_8[inx].g; r -= gbmrgb_8[inx].r;
1186
1187inx = takefrom8(r , g , b ); *dest4b = (inx << 4);
1188}
1189/*...e*/
1190 }
1191 if ( y < gbm->h )
1192 {
1193 const byte *src24a = src24 + stride24;
1194 byte *dest4a = dest4 + stride4;
1195
1196 for ( x = 0; x < gbm->w - 1; x += 2 )
1197/*...s2x1 case:24:*/
1198{
1199word r,g,b;
1200byte inx;
1201
1202b = *src24a++; g = *src24a++; r = *src24a++;
1203b += *src24a++; g += *src24a++; r += *src24a++;
1204
1205inx = takefrom8(r >> 1, g >> 1, b >> 1); *dest4a = (inx << 4);
1206b -= gbmrgb_8[inx].b; g -= gbmrgb_8[inx].g; r -= gbmrgb_8[inx].r;
1207
1208inx = takefrom8(r , g , b ); *dest4a++ |= inx;
1209}
1210/*...e*/
1211 if ( x < gbm->w )
1212/*...s1x1 case:24:*/
1213{
1214word r, g, b;
1215byte inx;
1216
1217b = *src24a++; g = *src24a++; r = *src24a;
1218inx = takefrom8(r, g, b); *dest4a = (inx << 4);
1219}
1220/*...e*/
1221 }
1222 }
1223/*...e*/
1224/*...sgbm_ht_8_3x3 \45\ halftone by 3x3 to default 8 colour palette:0:*/
1225void gbm_ht_8_3x3(const GBM *gbm, const byte *src24, byte *dest4)
1226 {
1227 int stride24 = ((gbm->w * 3 + 3) & ~3);
1228 int stride4 = ((gbm->w * 4 + 31) / 32) * 4;
1229 int x, y;
1230
1231 init();
1232
1233 src24 -= stride24;
1234 dest4 -= stride4;
1235
1236 for ( y = 0; y < gbm->h - 2; y += 3 )
1237 {
1238 const byte *src24a = (src24 += stride24);
1239 const byte *src24b = (src24 += stride24);
1240 const byte *src24c = (src24 += stride24);
1241 byte *dest4a = (dest4 += stride4);
1242 byte *dest4b = (dest4 += stride4);
1243 byte *dest4c = (dest4 += stride4);
1244 BOOLEAN left = TRUE;
1245
1246 for ( x = 0; x < gbm->w - 2; x += 3, left = !left )
1247/*...s3x3 case:24:*/
1248{
1249word r,g,b;
1250byte inxs[9];
1251byte *tmp;
1252
1253b = *src24a++; g = *src24a++; r = *src24a++;
1254b += *src24a++; g += *src24a++; r += *src24a++;
1255b += *src24a++; g += *src24a++; r += *src24a++;
1256b += *src24b++; g += *src24b++; r += *src24b++;
1257b += *src24b++; g += *src24b++; r += *src24b++;
1258b += *src24b++; g += *src24b++; r += *src24b++;
1259b += *src24c++; g += *src24c++; r += *src24c++;
1260b += *src24c++; g += *src24c++; r += *src24c++;
1261b += *src24c++; g += *src24c++; r += *src24c++;
1262
1263split_into8(r, g, b, 9, inxs);
1264
1265if ( left )
1266 {
1267 *dest4a++ = ((inxs[0] << 4) | inxs[1]); *dest4a = (inxs[2] << 4);
1268 *dest4b++ = ((inxs[3] << 4) | inxs[4]); *dest4b = (inxs[5] << 4);
1269 *dest4c++ = ((inxs[6] << 4) | inxs[7]); *dest4c = (inxs[8] << 4);
1270 }
1271else
1272 {
1273 *dest4a++ |= inxs[0]; *dest4a++ = ((inxs[1] << 4) | inxs[2]);
1274 *dest4b++ |= inxs[3]; *dest4b++ = ((inxs[4] << 4) | inxs[5]);
1275 *dest4c++ |= inxs[6]; *dest4c++ = ((inxs[7] << 4) | inxs[8]);
1276 }
1277
1278tmp = dest4a; dest4a = dest4b; dest4b = dest4c; dest4c = tmp;
1279}
1280/*...e*/
1281 if ( x < gbm->w - 1 )
1282/*...s2x3 case:24:*/
1283{
1284word r,g,b;
1285byte inxs[6];
1286
1287b = *src24a++; g = *src24a++; r = *src24a++;
1288b += *src24a++; g += *src24a++; r += *src24a++;
1289b += *src24b++; g += *src24b++; r += *src24b++;
1290b += *src24b++; g += *src24b++; r += *src24b++;
1291b += *src24c++; g += *src24c++; r += *src24c++;
1292b += *src24c++; g += *src24c++; r += *src24c++;
1293
1294split_into8(r, g, b, 6, inxs);
1295
1296if ( left )
1297 {
1298 *dest4a = ((inxs[0] << 4) | inxs[1]);
1299 *dest4b = ((inxs[2] << 4) | inxs[3]);
1300 *dest4c = ((inxs[4] << 4) | inxs[5]);
1301 }
1302else
1303 {
1304 *dest4a++ |= inxs[0]; *dest4a = (inxs[1] << 4);
1305 *dest4b++ |= inxs[2]; *dest4b = (inxs[3] << 4);
1306 *dest4c++ |= inxs[4]; *dest4c = (inxs[5] << 4);
1307 }
1308}
1309/*...e*/
1310 else if ( x < gbm->w )
1311/*...s1x3 case:24:*/
1312{
1313word r,g,b;
1314byte inxs[3];
1315
1316b = *src24a++; g = *src24a++; r = *src24a++;
1317b += *src24b++; g += *src24b++; r += *src24b++;
1318b += *src24c++; g += *src24c++; r += *src24c++;
1319
1320split_into8(r, g, b, 3, inxs);
1321
1322if ( left )
1323 {
1324 *dest4a = (inxs[0] << 4);
1325 *dest4b = (inxs[1] << 4);
1326 *dest4c = (inxs[2] << 4);
1327 }
1328else
1329 {
1330 *dest4a |= inxs[0];
1331 *dest4b |= inxs[1];
1332 *dest4c |= inxs[2];
1333 }
1334}
1335/*...e*/
1336 }
1337 if ( y < gbm->h - 1 )
1338 {
1339 const byte *src24a = (src24 += stride24);
1340 const byte *src24b = (src24 += stride24);
1341 byte *dest4a = (dest4 += stride4);
1342 byte *dest4b = (dest4 += stride4);
1343 BOOLEAN left = TRUE;
1344
1345 for ( x = 0; x < gbm->w - 2; x += 3, left = !left )
1346/*...s3x2 case:24:*/
1347{
1348word r,g,b;
1349byte inxs[6];
1350byte *tmp;
1351
1352b = *src24a++; g = *src24a++; r = *src24a++;
1353b += *src24a++; g += *src24a++; r += *src24a++;
1354b += *src24a++; g += *src24a++; r += *src24a++;
1355b += *src24b++; g += *src24b++; r += *src24b++;
1356b += *src24b++; g += *src24b++; r += *src24b++;
1357b += *src24b++; g += *src24b++; r += *src24b++;
1358
1359split_into8(r, g, b, 6, inxs);
1360
1361if ( left )
1362 {
1363 *dest4a++ = (inxs[0] << 4) | inxs[1]; *dest4a = (inxs[2] << 4);
1364 *dest4b++ = (inxs[3] << 4) | inxs[4]; *dest4b = (inxs[5] << 4);
1365 }
1366else
1367 {
1368 *dest4a++ |= inxs[0]; *dest4a++ = ((inxs[1] << 4) | inxs[2]);
1369 *dest4b++ |= inxs[3]; *dest4b++ = ((inxs[4] << 4) | inxs[5]);
1370 }
1371
1372tmp = dest4a; dest4a = dest4b; dest4b = tmp;
1373}
1374/*...e*/
1375 if ( x < gbm->w - 1 )
1376/*...s2x2 case:24:*/
1377{
1378word r,g,b;
1379byte inxs[4];
1380
1381b = *src24a++; g = *src24a++; r = *src24a++;
1382b += *src24a++; g += *src24a++; r += *src24a++;
1383b += *src24b++; g += *src24b++; r += *src24b++;
1384b += *src24b++; g += *src24b++; r += *src24b++;
1385
1386split_into8(r, g, b, 4, inxs);
1387
1388if ( left )
1389 {
1390 *dest4a = ((inxs[0] << 4) | inxs[1]);
1391 *dest4b = ((inxs[2] << 4) | inxs[3]);
1392 }
1393else
1394 {
1395 *dest4a++ |= inxs[0]; *dest4a = (inxs[1] << 4);
1396 *dest4b++ |= inxs[2]; *dest4b = (inxs[3] << 4);
1397 }
1398}
1399/*...e*/
1400 else if ( x < gbm->w )
1401/*...s1x2 case:24:*/
1402{
1403word r,g,b;
1404byte inxs[2];
1405
1406b = *src24a++; g = *src24a++; r = *src24a++;
1407b += *src24b++; g += *src24b++; r += *src24b++;
1408
1409split_into8(r, g, b, 2, inxs);
1410
1411if ( left )
1412 {
1413 *dest4a = (inxs[0] << 4);
1414 *dest4b = (inxs[1] << 4);
1415 }
1416else
1417 {
1418 *dest4a |= inxs[0];
1419 *dest4b |= inxs[1];
1420 }
1421}
1422/*...e*/
1423 }
1424 else if ( y < gbm->h )
1425 {
1426 const byte *src24a = (src24 += stride24);
1427 byte *dest4a = (dest4 += stride4);
1428 BOOLEAN left = TRUE;
1429
1430 for ( x = 0; x < gbm->w - 2; x += 3, left = !left )
1431/*...s3x1 case:24:*/
1432{
1433word r,g,b;
1434byte inxs[3];
1435
1436b = *src24a++; g = *src24a++; r = *src24a++;
1437b += *src24a++; g += *src24a++; r += *src24a++;
1438b += *src24a++; g += *src24a++; r += *src24a++;
1439
1440split_into8(r, g, b, 3, inxs);
1441
1442if ( left )
1443 {
1444 *dest4a++ = ((inxs[0] << 4) | inxs[1]); *dest4a = (inxs[2] << 4);
1445 }
1446else
1447 {
1448 *dest4a++ |= inxs[0]; *dest4a++ = ((inxs[1] << 4) | inxs[2]);
1449 }
1450}
1451/*...e*/
1452 if ( x < gbm->w - 1 )
1453/*...s2x1 case:24:*/
1454{
1455word r,g,b;
1456byte inxs[2];
1457
1458b = *src24a++; g = *src24a++; r = *src24a++;
1459b += *src24a++; g += *src24a++; r += *src24a++;
1460
1461split_into8(r, g, b, 4, inxs);
1462
1463if ( left )
1464 *dest4a = ((inxs[0] << 4) | inxs[1]);
1465else
1466 {
1467 *dest4a++ |= inxs[0]; *dest4a = (inxs[1] << 4);
1468 }
1469}
1470/*...e*/
1471 else if ( x < gbm->w )
1472/*...s1x1 case:24:*/
1473{
1474word r,g,b;
1475byte inx;
1476
1477b = *src24a++; g = *src24a++; r = *src24a++;
1478
1479inx = takefrom8(r, g, b);
1480
1481if ( left )
1482 *dest4a = (inx << 4);
1483else
1484 *dest4a |= inx;
1485}
1486/*...e*/
1487 }
1488 }
1489/*...e*/
Note: See TracBrowser for help on using the repository browser.