1 #include "img_conv.h"
2 
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6 
7 #define EDIFF_OP_RGB \
8 if ( b > 255) { eb -= ( b - 255); b = 255; } else { eb = 0; } \
9 if ( g > 255) { eg -= ( g - 255); g = 255; } else { eg = 0; } \
10 if ( r > 255) { er -= ( r - 255); r = 255; } else { er = 0; }
11 
12 #define dEDIFF_ARGS \
13 	int er, eg, eb, nextR, nextG, nextB, *perr = err_buf;\
14 	register int r, g, b
15 
16 #define EDIFF_INIT \
17 	nextR = perr[0], nextG = perr[1], nextB = perr[2];\
18 	perr[0] = perr[1] = perr[2] = er = eg = eb = 0
19 
20 #define EDIFF_BEGIN_PIXEL(red,gre,blu) \
21 		b = (blu) + eb + nextB;\
22 		g = (gre) + eg + nextG;\
23 		r = (red) + er + nextR;\
24 		nextR = perr[3];\
25 		nextG = perr[4];\
26 		nextB = perr[5];\
27 		if ( r > 255) r = 255; else if ( r < 0) r = 0;\
28 		if ( g > 255) g = 255; else if ( g < 0) g = 0;\
29 		if ( b > 255) b = 255; else if ( b < 0) b = 0;\
30 		er = eb = eg = 0
31 
32 #define EDIFF_END_PIXEL_EX(red_err,gre_err,blu_err) \
33 		perr[0] += er = (perr[3] = (red_err) / 5) * 2;\
34 		perr[1] += eg = (perr[4] = (gre_err) / 5) * 2;\
35 		perr[2] += eb = (perr[5] = (blu_err) / 5) * 2;\
36 		perr += 3
37 
38 #define EDIFF_END_PIXEL(red_err,gre_err,blu_err) \
39 		EDIFF_END_PIXEL_EX(r-(red_err),g-(gre_err),b-(blu_err))
40 
41 /* Bitstroke convertors */
42 /* Mono */
43 /* 1-> 16 */
44 void
bc_mono_nibble(register Byte * source,register Byte * dest,register int count)45 bc_mono_nibble( register Byte * source, register Byte * dest, register int count)
46 {
47 	register Byte tailsize = count & 7;
48 	dest    += (count - 1) >> 1;
49 	count    = count >> 3;
50 	source  += count;
51 
52 	if ( tailsize)
53 	{
54 		register Byte tail = (*source) >> ( 8 - tailsize);
55 		if ( tailsize & 1)
56 		{
57 			tailsize++;
58 			tail <<= 1;
59 		}
60 		while( tailsize)
61 		{
62 			*dest-- = ( tail & 1) | (( tail & 2) << 3);
63 			tail >>= 2;
64 			tailsize -= 2;
65 		}
66 	}
67 	source--;
68 	while( count--)
69 	{
70 		register Byte c = *source--;
71 		*dest-- = ( c & 1) | (( c & 2) << 3);  c >>= 2;
72 		*dest-- = ( c & 1) | (( c & 2) << 3);  c >>= 2;
73 		*dest-- = ( c & 1) | (( c & 2) << 3);  c >>= 2;
74 		*dest-- = ( c & 1) | (( c & 2) << 3);
75 	}
76 }
77 
78 /* 1-> mapped 16 */
79 void
bc_mono_nibble_cr(register Byte * source,register Byte * dest,register int count,register Byte * colorref)80 bc_mono_nibble_cr( register Byte * source, register Byte * dest, register int count, register Byte * colorref)
81 {
82 	register Byte tailsize = count & 7;
83 	dest    += (count - 1) >> 1;
84 	count    = count >> 3;
85 	source  += count;
86 
87 	if ( tailsize)
88 	{
89 		register Byte tail = (*source) >> ( 8 - tailsize);
90 		if ( tailsize & 1)
91 		{
92 			tailsize++;
93 			tail <<= 1;
94 		}
95 		while( tailsize)
96 		{
97 			*dest-- = colorref[ tail & 1] | ( colorref[( tail & 2) >> 1] << 4);
98 			tail >>= 2;
99 			tailsize -= 2;
100 		}
101 	}
102 	source--;
103 	while( count--)
104 	{
105 		register Byte c = *source--;
106 		*dest-- = colorref[ c & 1] | ( colorref[( c & 2) >> 1] << 4); c >>= 2;
107 		*dest-- = colorref[ c & 1] | ( colorref[( c & 2) >> 1] << 4); c >>= 2;
108 		*dest-- = colorref[ c & 1] | ( colorref[( c & 2) >> 1] << 4); c >>= 2;
109 		*dest-- = colorref[ c & 1] | ( colorref[( c & 2) >> 1] << 4);
110 	}
111 }
112 
113 /*  1 -> 256 */
114 void
bc_mono_byte(register Byte * source,register Byte * dest,register int count)115 bc_mono_byte( register Byte * source, register Byte * dest, register int count)
116 {
117 	register Byte tailsize = count & 7;
118 	dest    += count - 1;
119 	count    = count >> 3;
120 	source  += count;
121 	if ( tailsize)
122 	{
123 		register Byte tail = (*source) >> ( 8 - tailsize);
124 		while( tailsize--)
125 		{
126 			*dest-- = tail & 1;
127 			tail >>= 1;
128 		}
129 	}
130 	source--;
131 	while( count--)
132 	{
133 		register Byte c = *source--;
134 		*dest-- = c & 1;      c >>= 1;
135 		*dest-- = c & 1;      c >>= 1;
136 		*dest-- = c & 1;      c >>= 1;
137 		*dest-- = c & 1;      c >>= 1;
138 		*dest-- = c & 1;      c >>= 1;
139 		*dest-- = c & 1;      c >>= 1;
140 		*dest-- = c & 1;
141 		*dest-- = c >> 1;
142 	}
143 }
144 
145 /*  1 -> mapped 256 */
146 void
bc_mono_byte_cr(register Byte * source,register Byte * dest,register int count,register Byte * colorref)147 bc_mono_byte_cr( register Byte * source, register Byte * dest, register int count, register Byte * colorref)
148 {
149 	register Byte tailsize = count & 7;
150 	dest    += count - 1;
151 	count    = count >> 3;
152 	source  += count;
153 	if ( tailsize)
154 	{
155 		register Byte tail = (*source) >> ( 8 - tailsize);
156 		while( tailsize--)
157 		{
158 			*dest-- = colorref[ tail & 1];
159 			tail >>= 1;
160 		}
161 	}
162 	source--;
163 	while( count--)
164 	{
165 		register Byte c = *source--;
166 		*dest-- = colorref[ c & 1];      c >>= 1;
167 		*dest-- = colorref[ c & 1];      c >>= 1;
168 		*dest-- = colorref[ c & 1];      c >>= 1;
169 		*dest-- = colorref[ c & 1];      c >>= 1;
170 		*dest-- = colorref[ c & 1];      c >>= 1;
171 		*dest-- = colorref[ c & 1];      c >>= 1;
172 		*dest-- = colorref[ c & 1];
173 		*dest-- = colorref[ c >> 1];
174 	}
175 }
176 
177 
178 /*  1 -> gray */
179 void
bc_mono_graybyte(register Byte * source,register Byte * dest,register int count,register PRGBColor palette)180 bc_mono_graybyte( register Byte * source, register Byte * dest, register int count, register PRGBColor palette)
181 {
182 	register Byte tailsize = count & 7;
183 	dest    += count - 1;
184 	count    = count >> 3;
185 	source  += count;
186 	if ( tailsize)
187 	{
188 		register Byte tail = (*source) >> ( 8 - tailsize);
189 		while( tailsize--)
190 		{
191 			register RGBColor r = palette[ tail & 1];
192 			*dest-- = map_RGB_gray[ r.r + r.g + r.b];
193 			tail >>= 1;
194 		}
195 	}
196 	source--;
197 	while( count--)
198 	{
199 		register Byte c = *source--;
200 		register RGBColor r;
201 		r = palette[ c & 1]; *dest-- = map_RGB_gray[ r.r + r.g + r.b]; c >>= 1;
202 		r = palette[ c & 1]; *dest-- = map_RGB_gray[ r.r + r.g + r.b]; c >>= 1;
203 		r = palette[ c & 1]; *dest-- = map_RGB_gray[ r.r + r.g + r.b]; c >>= 1;
204 		r = palette[ c & 1]; *dest-- = map_RGB_gray[ r.r + r.g + r.b]; c >>= 1;
205 		r = palette[ c & 1]; *dest-- = map_RGB_gray[ r.r + r.g + r.b]; c >>= 1;
206 		r = palette[ c & 1]; *dest-- = map_RGB_gray[ r.r + r.g + r.b]; c >>= 1;
207 		r = palette[ c & 1]; *dest-- = map_RGB_gray[ r.r + r.g + r.b]; c >>= 1;
208 		r = palette[ c];     *dest-- = map_RGB_gray[ r.r + r.g + r.b];
209 	}
210 }
211 
212 
213 /*  1 -> rgb */
214 void
bc_mono_rgb(register Byte * source,Byte * dest,register int count,register PRGBColor palette)215 bc_mono_rgb( register Byte * source, Byte * dest, register int count, register PRGBColor palette)
216 {
217 	register Byte tailsize   = count & 7;
218 	register PRGBColor rdest = ( PRGBColor) dest;
219 	rdest   += count - 1;
220 	count    = count >> 3;
221 	source  += count;
222 	if ( tailsize)
223 	{
224 		register Byte tail = (*source) >> ( 8 - tailsize);
225 		while( tailsize--)
226 		{
227 			*rdest-- = palette[ tail & 1];
228 			tail >>= 1;
229 		}
230 	}
231 	source--;
232 	while( count--)
233 	{
234 		register Byte c = *source--;
235 		*rdest-- = palette[ c & 1];      c >>= 1;
236 		*rdest-- = palette[ c & 1];      c >>= 1;
237 		*rdest-- = palette[ c & 1];      c >>= 1;
238 		*rdest-- = palette[ c & 1];      c >>= 1;
239 		*rdest-- = palette[ c & 1];      c >>= 1;
240 		*rdest-- = palette[ c & 1];      c >>= 1;
241 		*rdest-- = palette[ c & 1];
242 		*rdest-- = palette[ c >> 1];
243 	}
244 }
245 
246 
247 /*  Nibble */
248 /* 16-> 1 */
249 void
bc_nibble_mono_cr(register Byte * source,register Byte * dest,register int count,register Byte * colorref)250 bc_nibble_mono_cr( register Byte * source, register Byte * dest, register int count, register Byte * colorref)
251 {
252 	register int count8 = count >> 3;
253 	while ( count8--)
254 	{
255 		register Byte c;
256 		register Byte d;
257 		c = *source++;  d  = ( colorref[ c & 0xF] << 6) | ( colorref[ c >> 4] << 7);
258 		c = *source++;  d |= ( colorref[ c & 0xF] << 4) | ( colorref[ c >> 4] << 5);
259 		c = *source++;  d |= ( colorref[ c & 0xF] << 2) | ( colorref[ c >> 4] << 3);
260 		c = *source++;  *dest++ = d | colorref[ c & 0xF] |( colorref[ c >> 4] << 1);
261 	}
262 	count &= 7;
263 	if ( count)
264 	{
265 		register Byte d = 0;
266 		register Byte s = 7;
267 		count = ( count >> 1) + ( count & 1);
268 		while ( count--)
269 		{
270 			register Byte c = *source++;
271 			d |= colorref[ c >> 4 ] << s--;
272 			d |= colorref[ c & 0xF] << s--;
273 		}
274 		*dest = d;
275 	}
276 }
277 
278 /* 16-> 1, halftone */
279 void
bc_nibble_mono_ht(register Byte * source,register Byte * dest,register int count,register PRGBColor palette,int lineSeqNo)280 bc_nibble_mono_ht( register Byte * source, register Byte * dest, register int count, register PRGBColor palette, int lineSeqNo)
281 {
282 #define n64cmp1 (( r = palette[ c >> 4], (( map_RGB_gray[r.r+r.g+r.b] >> 2) > map_halftone8x8_64[ index++]))?1:0)
283 #define n64cmp2 (( r = palette[ c & 15], (( map_RGB_gray[r.r+r.g+r.b] >> 2) > map_halftone8x8_64[ index++]))?1:0)
284 	register int count8 = count >> 3;
285 	lineSeqNo = ( lineSeqNo & 7) << 3;
286 	while ( count8--)
287 	{
288 		register Byte  index = lineSeqNo;
289 		register Byte  c;
290 		register Byte  dst;
291 		register RGBColor r;
292 		c = *source++; dst   = n64cmp1 << 7; dst |= n64cmp2 << 6;
293 		c = *source++; dst  |= n64cmp1 << 5; dst |= n64cmp2 << 4;
294 		c = *source++; dst  |= n64cmp1 << 3; dst |= n64cmp2 << 2;
295 		c = *source++; dst  |= n64cmp1 << 1; *dest++ = dst | n64cmp2;
296 	}
297 	count &= 7;
298 	if ( count)
299 	{
300 		Byte index = lineSeqNo;
301 		register Byte d = 0;
302 		register Byte s = 7;
303 		count = ( count >> 1) + ( count & 1);
304 		while ( count--)
305 		{
306 			register Byte c = *source++;
307 			register RGBColor r;
308 			d |= n64cmp1 << s--;
309 			d |= n64cmp2 << s--;
310 		}
311 		*dest = d;
312 	}
313 }
314 
315 /* 16-> 1, error diffusion */
316 void
bc_nibble_mono_ed(Byte * source,Byte * dest,int count,PRGBColor palette,int * err_buf)317 bc_nibble_mono_ed( Byte * source, Byte * dest, int count, PRGBColor palette, int * err_buf)
318 {
319 	dEDIFF_ARGS;
320 	int count8 = count >> 3;
321 	EDIFF_INIT;
322 
323 	while ( count8--) {
324 		Byte c, dst = 0, i, shift = 8;
325 		for ( i = 0; i < 4; i++) {
326 			c = (*source) >> 4;
327 			c = map_RGB_gray[ palette[c].r + palette[c].g + palette[c].b];
328 			EDIFF_BEGIN_PIXEL(c,c,c);
329 			dst |= (( r + g + b ) > 383) << (--shift);
330 			EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
331 			c = *(source++) & 0xf;
332 			c = map_RGB_gray[ palette[c].r + palette[c].g + palette[c].b];
333 			EDIFF_BEGIN_PIXEL(c,c,c);
334 			dst |= (( r + g + b ) > 383) << (--shift);
335 			EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
336 		}
337 		*(dest++) = dst;
338 	}
339 	count &= 7;
340 	if ( count) {
341 		Byte c, dst = 0, shift = 8;
342 		count = ( count >> 1) + ( count & 1);
343 		while ( count--) {
344 			c = *source >> 4;
345 			c = map_RGB_gray[ palette[c].r + palette[c].g + palette[c].b];
346 			EDIFF_BEGIN_PIXEL(c,c,c);
347 			dst |= (( r + g + b ) > 383) << (--shift);
348 			EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
349 			c = *(source++) & 0xf;
350 			c = map_RGB_gray[ palette[c].r + palette[c].g + palette[c].b];
351 			EDIFF_BEGIN_PIXEL(c,c,c);
352 			dst |= (( r + g + b ) > 383) << (--shift);
353 			EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
354 		}
355 		*(dest++) = dst;
356 	}
357 }
358 
359 /* map 16 */
360 void
bc_nibble_cr(register Byte * source,register Byte * dest,register int count,register Byte * colorref)361 bc_nibble_cr( register Byte * source, register Byte * dest, register int count, register Byte * colorref)
362 {
363 	count  =  ( count >> 1) + ( count & 1);
364 	source += count - 1;
365 	dest   += count - 1;
366 	while ( count--)
367 	{
368 		register Byte c = *source--;
369 		*dest-- = colorref[ c & 0xF] | ( colorref[ c >> 4] << 4);
370 	}
371 }
372 
373 /* 16-> 16 cubic halftoned */
374 void
bc_nibble_nibble_ht(register Byte * source,Byte * dest,register int count,register PRGBColor palette,int lineSeqNo)375 bc_nibble_nibble_ht( register Byte * source, Byte * dest, register int count, register PRGBColor palette, int lineSeqNo)
376 {
377 #define b8cmp (                                      \
378 					(((r. b >> 2) > cmp))      +  \
379 					(((r. g >> 2) > cmp) << 1) +  \
380 					(((r. r >> 2) > cmp) << 2)    \
381 					)
382 	Byte tail = count & 1;
383 	lineSeqNo = ( lineSeqNo & 7) << 3;
384 	count = count >> 1;
385 	while ( count--)
386 	{
387 		register Byte index = lineSeqNo + (( count & 3) << 1);
388 		register Byte dst;
389 		register RGBColor r;
390 		register Byte cmp;
391 
392 		r = palette[ *source >> 4 ];
393 		cmp = map_halftone8x8_64[ index++];
394 		dst = b8cmp << 4;
395 		r = palette[ *source++ & 0x0F];
396 		cmp = map_halftone8x8_64[ index];
397 		*dest++ = dst + b8cmp;
398 	}
399 	if ( tail)
400 	{
401 		register RGBColor r = palette[ *source >> 4];
402 		register Byte cmp   = map_halftone8x8_64[ lineSeqNo + 1];
403 		*dest = b8cmp << 4;
404 	}
405 #undef b8cmp
406 }
407 
408 /* 16-> 16 cubic, error diffusion */
409 void
bc_nibble_nibble_ed(Byte * source,Byte * dest,int count,PRGBColor palette,int * err_buf)410 bc_nibble_nibble_ed( Byte * source, Byte * dest, int count, PRGBColor palette, int * err_buf)
411 {
412 	dEDIFF_ARGS;
413 	Byte tail = count & 1;
414 	count = count >> 1;
415 	EDIFF_INIT;
416 	while ( count--)
417 	{
418 		Byte dst, c;
419 		c = *source >> 4;
420 		EDIFF_BEGIN_PIXEL(palette[c].r, palette[c].g, palette[c].b);
421 		dst = (( r > 127) * 4 + (g > 127) * 2 + (b > 127)) << 4;
422 		EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
423 		c = *source++ & 0x0f;
424 		EDIFF_BEGIN_PIXEL(palette[c].r, palette[c].g, palette[c].b);
425 		*dest++ = dst | (( r > 127) * 4 + (g > 127) * 2 + (b > 127));
426 		EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
427 	}
428 	if ( tail)
429 	{
430 		Byte c = *source >> 4;
431 		EDIFF_BEGIN_PIXEL(palette[c].r, palette[c].g, palette[c].b);
432 		*dest = (( r > 127) * 4 + (g > 127) * 2 + (b > 127)) << 4;
433 		EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
434 	}
435 }
436 
437 /*  16 -> 256 */
438 void
bc_nibble_byte(register Byte * source,register Byte * dest,register int count)439 bc_nibble_byte( register Byte * source, register Byte * dest, register int count)
440 {
441 	register Byte tail = count & 1;
442 	dest   += count - 1;
443 	count  =  count >> 1;
444 	source += count;
445 
446 	if ( tail) *dest-- = (*source) >> 4;
447 	source--;
448 	while( count--)
449 	{
450 		register Byte c = *source--;
451 		*dest-- = c & 0xF;
452 		*dest-- = c >> 4;
453 	}
454 }
455 
456 /*  16 -> gray */
457 void
bc_nibble_graybyte(register Byte * source,register Byte * dest,register int count,register PRGBColor palette)458 bc_nibble_graybyte( register Byte * source, register Byte * dest, register int count, register PRGBColor palette)
459 {
460 	register Byte tail = count & 1;
461 	dest   += count - 1;
462 	count  =  count >> 1;
463 	source += count;
464 
465 	if ( tail)
466 	{
467 		register RGBColor r = palette[ (*source) >> 4];
468 		*dest-- = map_RGB_gray[ r.r + r.g + r.b];
469 	}
470 	source--;
471 	while( count--)
472 	{
473 		register Byte c = *source--;
474 		register RGBColor r = palette[ c & 0xF];
475 		*dest-- = map_RGB_gray[ r.r + r.g + r.b];
476 		r = palette[ c >> 4];
477 		*dest-- = map_RGB_gray[ r.r + r.g + r.b];
478 	}
479 }
480 
481 
482 /* 16 -> mapped 256 */
483 void
bc_nibble_byte_cr(register Byte * source,register Byte * dest,register int count,register Byte * colorref)484 bc_nibble_byte_cr( register Byte * source, register Byte * dest, register int count, register Byte * colorref)
485 {
486 	register Byte tail = count & 1;
487 	dest   += count - 1;
488 	count  =  count >> 1;
489 	source += count;
490 
491 	if ( tail) *dest-- = colorref[ (*source) >> 4];
492 	source--;
493 	while( count--)
494 	{
495 		register Byte c = *source--;
496 		*dest-- = colorref[ c & 0xF];
497 		*dest-- = colorref[ c >> 4];
498 	}
499 }
500 
501 
502 /* 16-> rgb */
503 void
bc_nibble_rgb(register Byte * source,Byte * dest,register int count,register PRGBColor palette)504 bc_nibble_rgb( register Byte * source, Byte * dest, register int count, register PRGBColor palette)
505 {
506 	register Byte tail = count & 1;
507 	register PRGBColor rdest = ( PRGBColor) dest;
508 	rdest  += count - 1;
509 	count  =  count >> 1;
510 	source += count;
511 
512 	if ( tail) *rdest-- = palette[ (*source) >> 4];
513 	source--;
514 	while( count--)
515 	{
516 		register Byte c = *source--;
517 		*rdest-- = palette[ c & 0xF];
518 		*rdest-- = palette[ c >> 4];
519 	}
520 }
521 
522 /* Byte */
523 /* 256-> 1 */
524 void
bc_byte_mono_cr(register Byte * source,Byte * dest,register int count,register Byte * colorref)525 bc_byte_mono_cr( register Byte * source, Byte * dest, register int count, register Byte * colorref)
526 {
527 	register int count8 = count >> 3;
528 	while ( count8--)
529 	{
530 		register Byte c = colorref[ *source++] << 7;
531 		c |= colorref[ *source++] << 6;
532 		c |= colorref[ *source++] << 5;
533 		c |= colorref[ *source++] << 4;
534 		c |= colorref[ *source++] << 3;
535 		c |= colorref[ *source++] << 2;
536 		c |= colorref[ *source++] << 1;
537 		*dest++ = c | colorref[ *source++];
538 	}
539 	count &= 7;
540 	if ( count)
541 	{
542 		register Byte c = 0;
543 		register Byte s = 7;
544 		while ( count--) c |= colorref[ *source++] << s--;
545 		*dest = c;
546 	}
547 }
548 
549 /* byte-> mono, halftoned */
550 void
bc_byte_mono_ht(register Byte * source,register Byte * dest,register int count,PRGBColor palette,int lineSeqNo)551 bc_byte_mono_ht( register Byte * source, register Byte * dest, register int count, PRGBColor palette, int lineSeqNo)
552 {
553 #define b64cmp  (( r = palette[ *source++], (( map_RGB_gray[r.r+r.g+r.b] >> 2) > map_halftone8x8_64[ index++]))?1:0)
554 	int count8 = count & 7;
555 	lineSeqNo = ( lineSeqNo & 7) << 3;
556 	count >>= 3;
557 	while ( count--)
558 	{
559 		register Byte  index = lineSeqNo;
560 		register Byte  dst;
561 		register RGBColor r;
562 		dst  = b64cmp << 7;
563 		dst |= b64cmp << 6;
564 		dst |= b64cmp << 5;
565 		dst |= b64cmp << 4;
566 		dst |= b64cmp << 3;
567 		dst |= b64cmp << 2;
568 		dst |= b64cmp << 1;
569 		*dest++ = dst | b64cmp;
570 	}
571 	if ( count8)
572 	{
573 		register Byte     index = lineSeqNo;
574 		register Byte     dst = 0;
575 		register Byte     i = 7;
576 		register RGBColor r;
577 		count = count8;
578 		while( count--) dst |= b64cmp << i--;
579 		*dest = dst;
580 	}
581 }
582 
583 /* byte-> mono, halftoned */
584 void
bc_byte_mono_ed(Byte * source,Byte * dest,int count,PRGBColor palette,int * err_buf)585 bc_byte_mono_ed( Byte * source, Byte * dest, int count, PRGBColor palette, int * err_buf)
586 {
587 	dEDIFF_ARGS;
588 	int count8 = count & 7;
589 	EDIFF_INIT;
590 	count >>= 3;
591 	while ( count--)
592 	{
593 		Byte dst = 0, c, i = 8;
594 		while ( i--) {
595 			c = *source++;
596 			c = map_RGB_gray[ palette[c].r + palette[c].g + palette[c].b];
597 			EDIFF_BEGIN_PIXEL(c,c,c);
598 			dst |= (( r + g + b ) > 383) << i;
599 			EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
600 		}
601 		*dest++ = dst;
602 	}
603 	if ( count8) {
604 		Byte dst = 0, c, i = 8;
605 		while ( count8--) {
606 			c = *source++;
607 			c = map_RGB_gray[ palette[c].r + palette[c].g + palette[c].b];
608 			EDIFF_BEGIN_PIXEL(c,c,c);
609 			dst |= (( r + g + b ) > 383) << --i;
610 			EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
611 		}
612 		*dest = dst;
613 	}
614 }
615 
616 /* 256-> 16 */
617 void
bc_byte_nibble_cr(register Byte * source,Byte * dest,register int count,register Byte * colorref)618 bc_byte_nibble_cr( register Byte * source, Byte * dest, register int count, register Byte * colorref)
619 {
620 	Byte tail = count & 1;
621 	count = count >> 1;
622 	while ( count--)
623 	{
624 		register Byte c = colorref[ *source++] << 4;
625 		*dest++     = c | colorref[ *source++];
626 	}
627 	if ( tail) *dest = colorref[ *source] << 4;
628 }
629 
630 /* 256-> 16 cubic halftoned */
631 void
bc_byte_nibble_ht(register Byte * source,Byte * dest,register int count,register PRGBColor palette,int lineSeqNo)632 bc_byte_nibble_ht( register Byte * source, Byte * dest, register int count, register PRGBColor palette, int lineSeqNo)
633 {
634 #define b8cmp (                                      \
635 					(((r. b >> 2) > cmp))      +  \
636 					(((r. g >> 2) > cmp) << 1) +  \
637 					(((r. r >> 2) > cmp) << 2)    \
638 					)
639 	Byte tail = count & 1;
640 	lineSeqNo = ( lineSeqNo & 7) << 3;
641 	count = count >> 1;
642 	while ( count--)
643 	{
644 		register Byte index = lineSeqNo + (( count & 3) << 1);
645 		register Byte dst;
646 		register RGBColor r;
647 		register Byte cmp;
648 
649 		r = palette[ *source++];
650 		cmp = map_halftone8x8_64[ index++];
651 		dst = b8cmp << 4;
652 		r = palette[ *source++];
653 		cmp = map_halftone8x8_64[ index];
654 		*dest++ = dst + b8cmp;
655 	}
656 	if ( tail)
657 	{
658 		register RGBColor r = palette[ *source];
659 		register Byte cmp   = map_halftone8x8_64[ lineSeqNo + 1];
660 		*dest = b8cmp << 4;
661 	}
662 #undef b8cmp
663 }
664 
665 /* 256-> 16 cubic, error diffusion */
666 void
bc_byte_nibble_ed(Byte * source,Byte * dest,int count,PRGBColor palette,int * err_buf)667 bc_byte_nibble_ed( Byte * source, Byte * dest, int count, PRGBColor palette, int * err_buf)
668 {
669 	dEDIFF_ARGS;
670 	Byte tail = count & 1;
671 	count = count >> 1;
672 	EDIFF_INIT;
673 	while ( count--)
674 	{
675 		Byte dst, c;
676 		c = *source++;
677 		EDIFF_BEGIN_PIXEL(palette[c].r, palette[c].g, palette[c].b);
678 		dst = (( r > 127) * 4 + (g > 127) * 2 + (b > 127)) << 4;
679 		EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
680 		c = *source++;
681 		EDIFF_BEGIN_PIXEL(palette[c].r, palette[c].g, palette[c].b);
682 		*dest++ = dst | (( r > 127) * 4 + (g > 127) * 2 + (b > 127));
683 		EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
684 	}
685 	if ( tail)
686 	{
687 		Byte c = *source++;
688 		EDIFF_BEGIN_PIXEL(palette[c].r, palette[c].g, palette[c].b);
689 		*dest = (( r > 127) * 4 + (g > 127) * 2 + (b > 127)) << 4;
690 		EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
691 	}
692 }
693 
694 /* 256-> 256 cubic halftoned */
695 void
bc_byte_byte_ht(register Byte * source,Byte * dest,register int count,register PRGBColor palette,int lineSeqNo)696 bc_byte_byte_ht( register Byte * source, Byte * dest, register int count, register PRGBColor palette, int lineSeqNo)
697 {
698 	lineSeqNo = ( lineSeqNo & 7) << 3;
699 	while ( count--)
700 	{
701 		register Byte cmp = map_halftone8x8_51[( count & 7) + lineSeqNo];
702 		register RGBColor r;
703 
704 		r = palette[ *source++];
705 #define COL(x) (div51[x] + (mod51[x] > cmp))
706 		*dest++ = COL(r.b) + COL(r.g)*6 + COL(r.r)*36;
707 #undef COL
708 	}
709 }
710 
711 /* 256-> 256 cubic, error diffusion */
712 void
bc_byte_byte_ed(Byte * source,Byte * dest,int count,PRGBColor palette,int * err_buf)713 bc_byte_byte_ed( Byte * source, Byte * dest, int count, PRGBColor palette, int * err_buf)
714 {
715 	dEDIFF_ARGS;
716 	EDIFF_INIT;
717 	while ( count--)
718 	{
719 		Byte c;
720 		c = *source++;
721 		EDIFF_BEGIN_PIXEL(palette[c].r, palette[c].g, palette[c].b);
722 		*(dest++) = div51f[r] * 36 + div51f[g] * 6 + div51f[b];
723 		EDIFF_END_PIXEL_EX( mod51f[r], mod51f[g], mod51f[b]);
724 	}
725 }
726 
727 /* map 256 */
728 void
bc_byte_cr(register Byte * source,register Byte * dest,register int count,register Byte * colorref)729 bc_byte_cr( register Byte * source, register Byte * dest, register int count, register Byte * colorref)
730 {
731 	dest   += count - 1;
732 	source += count - 1;
733 	while ( count--) *dest-- = colorref[ *source--];
734 }
735 
736 /* 256, remap one palette to another */
737 void
bc_byte_op(Byte * source,Byte * dest,int count,U16 * tree,PRGBColor src_palette,PRGBColor dst_palette,int * err_buf)738 bc_byte_op( Byte * source, Byte * dest, int count, U16 * tree,
739 				PRGBColor src_palette, PRGBColor dst_palette, int * err_buf)
740 {
741 	dEDIFF_ARGS;
742 	EDIFF_INIT;
743 	while ( count--) {
744 		int table = 0, shift = 6, index;
745 		PRGBColor src_pal = src_palette + *(source++);
746 		EDIFF_BEGIN_PIXEL(src_pal->r,src_pal->g,src_pal->b);
747 		while ( 1) {
748 			index = (((r >> shift) & 3) << 4) +
749 				(((g >> shift) & 3) << 2) +
750 				((b >> shift) & 3);
751 			if ( tree[ table + index] & PAL_REF) {
752 				table = (tree[ table + index] & ~PAL_REF) * CELL_SIZE;
753 				shift -= 2;
754 			} else {
755 				PRGBColor dst_pal = dst_palette + (*(dest++) = tree[ table + index]);
756 				EDIFF_END_PIXEL( dst_pal->r, dst_pal->g, dst_pal->b);
757 				break;
758 			}
759 		}
760 	}
761 }
762 
763 /* 256, remap one palette to another, not dithered */
764 void
bc_byte_nop(Byte * source,Byte * dest,int count,U16 * tree,PRGBColor src_palette,PRGBColor dst_palette)765 bc_byte_nop( Byte * source, Byte * dest, int count, U16 * tree, PRGBColor src_palette, PRGBColor dst_palette)
766 {
767 	while ( count--) {
768 		int table = 0, shift = 6, index;
769 		PRGBColor src_pal = src_palette + *(source++);
770 		while ( 1) {
771 			index = (((src_pal->r >> shift) & 3) << 4) +
772 				(((src_pal->g >> shift) & 3) << 2) +
773 				((src_pal->b >> shift) & 3);
774 			if ( tree[ table + index] & PAL_REF) {
775 				table = (tree[ table + index] & ~PAL_REF) * CELL_SIZE;
776 				shift -= 2;
777 			} else {
778 				*(dest++) = tree[ table + index];
779 				break;
780 			}
781 		}
782 	}
783 }
784 
785 /* 256-> gray */
786 void
bc_byte_graybyte(register Byte * source,register Byte * dest,register int count,register PRGBColor palette)787 bc_byte_graybyte( register Byte * source, register Byte * dest, register int count, register PRGBColor palette)
788 {
789 	while ( count--)
790 	{
791 		register RGBColor r = palette[ *source++];
792 		*dest++ = map_RGB_gray[ r .r + r. g + r. b];
793 	}
794 }
795 
796 /* 256-> rgb */
797 void
bc_byte_rgb(register Byte * source,Byte * dest,register int count,register PRGBColor palette)798 bc_byte_rgb( register Byte * source, Byte * dest, register int count, register PRGBColor palette)
799 {
800 	register PRGBColor rdest = ( PRGBColor) dest;
801 	rdest  += count - 1;
802 	source += count - 1;
803 	while ( count--) *rdest-- = palette[ *source--];
804 }
805 
806 /* Gray Byte */
807 /* gray-> mono, halftoned */
808 void
bc_graybyte_mono_ht(register Byte * source,register Byte * dest,register int count,int lineSeqNo)809 bc_graybyte_mono_ht( register Byte * source, register Byte * dest, register int count, int lineSeqNo)
810 {
811 #define gb64cmp  ((*source++ >> 2) > map_halftone8x8_64[ index++])
812 	int count8 = count & 7;
813 	lineSeqNo = ( lineSeqNo & 7) << 3;
814 	count >>= 3;
815 	while ( count--)
816 	{
817 		register Byte  index = lineSeqNo;
818 		register Byte  dst;
819 		dst  = gb64cmp << 7;
820 		dst |= gb64cmp << 6;
821 		dst |= gb64cmp << 5;
822 		dst |= gb64cmp << 4;
823 		dst |= gb64cmp << 3;
824 		dst |= gb64cmp << 2;
825 		dst |= gb64cmp << 1;
826 		*dest++ = dst | gb64cmp;
827 	}
828 	if ( count8)
829 	{
830 		register Byte  index = lineSeqNo;
831 		register Byte  dst = 0;
832 		register Byte  i = 7;
833 		count = count8;
834 		while( count--) dst |= gb64cmp << i--;
835 		*dest = dst;
836 	}
837 }
838 
839 /* gray -> 16 gray */
840 void
bc_graybyte_nibble_ht(register Byte * source,Byte * dest,register int count,int lineSeqNo)841 bc_graybyte_nibble_ht( register Byte * source, Byte * dest, register int count, int lineSeqNo)
842 {
843 #define gb16cmp ( div17[c] + (( mod17mul3[c]) > cmp))
844 	Byte tail = count & 1;
845 	lineSeqNo = ( lineSeqNo & 7) << 3;
846 	count = count >> 1;
847 	while ( count--)
848 	{
849 		register short c;
850 		register Byte index = lineSeqNo + (( count & 3) << 1);
851 		register Byte dst;
852 		register Byte cmp;
853 		c = *source++;
854 		cmp = map_halftone8x8_51[ index++];
855 		dst = gb16cmp << 4;
856 		c = *source++;
857 		cmp = map_halftone8x8_51[ index];
858 		*dest++ = dst + gb16cmp;
859 	}
860 	if ( tail)
861 	{
862 		register short c = *source;
863 		register Byte cmp = map_halftone8x8_51[ lineSeqNo + 1];
864 		*dest = gb16cmp << 4;
865 	}
866 }
867 
868 /* gray -> 16 gray, error diffusion */
869 void
bc_graybyte_nibble_ed(Byte * source,Byte * dest,int count,int * err_buf)870 bc_graybyte_nibble_ed( Byte * source, Byte * dest, int count, int * err_buf)
871 {
872 	dEDIFF_ARGS;
873 	Byte tail = count & 1;
874 	count = count >> 1;
875 	EDIFF_INIT;
876 	while ( count--)
877 	{
878 		Byte dst, c;
879 		int rm;
880 		c = *source++;
881 		EDIFF_BEGIN_PIXEL(c,c,c);
882 		rm = (r & 0x0f) - (r >> 4);
883 		dst = r & 0xf0;
884 		EDIFF_END_PIXEL_EX(rm,rm,rm);
885 		c = *source++;
886 		EDIFF_BEGIN_PIXEL(c,c,c);
887 		rm = (r & 0x0f) - (r >> 4);
888 		*dest++ = dst | (r >> 4);
889 		EDIFF_END_PIXEL_EX(rm,rm,rm);
890 	}
891 	if ( tail)
892 	{
893 		Byte c = *source++;
894 		int rm;
895 		EDIFF_BEGIN_PIXEL(c,c,c);
896 		rm = (r & 0x0f) - (r >> 4);
897 		*dest = r & 0xf0;
898 		EDIFF_END_PIXEL_EX(rm,rm,rm);
899 	}
900 }
901 
902 /* gray-> rgb */
903 void
bc_graybyte_rgb(register Byte * source,Byte * dest,register int count)904 bc_graybyte_rgb( register Byte * source, Byte * dest, register int count)
905 {
906 	register PRGBColor rdest = ( PRGBColor) dest;
907 	rdest  += count - 1;
908 	source += count - 1;
909 	while ( count--)
910 	{
911 		register Byte  c = *source--;
912 		register RGBColor r;
913 		r. r = c;
914 		r. b = c;
915 		r. g = c;
916 		*rdest-- = r;
917 	}
918 }
919 
920 /* RGB */
921 
922 /* rgb -> gray */
923 void
bc_rgb_graybyte(Byte * source,register Byte * dest,register int count)924 bc_rgb_graybyte( Byte * source, register Byte * dest, register int count)
925 {
926 	register PRGBColor rsource = ( PRGBColor) source;
927 	while ( count--)
928 	{
929 		register RGBColor r = *rsource++;
930 		*dest++ = map_RGB_gray[ r .r + r. g + r. b];
931 	}
932 }
933 
934 /* rgb-> mono, halftoned */
935 void
bc_rgb_mono_ht(register Byte * source,register Byte * dest,register int count,int lineSeqNo)936 bc_rgb_mono_ht( register Byte * source, register Byte * dest, register int count, int lineSeqNo)
937 {
938 #define tc64cmp  (( source+=3, ( map_RGB_gray[ source[-1] + source[-2] + source[-3]] >> 2) > map_halftone8x8_64[ index++])?1:0)
939 	int count8 = count & 7;
940 	lineSeqNo = ( lineSeqNo & 7) << 3;
941 	count >>= 3;
942 	while ( count--)
943 	{
944 		register Byte  index = lineSeqNo;
945 		register Byte  dst;
946 		dst  = tc64cmp << 7;
947 		dst |= tc64cmp << 6;
948 		dst |= tc64cmp << 5;
949 		dst |= tc64cmp << 4;
950 		dst |= tc64cmp << 3;
951 		dst |= tc64cmp << 2;
952 		dst |= tc64cmp << 1;
953 		*dest++  = dst | tc64cmp;
954 	}
955 	if ( count8)
956 	{
957 		register Byte  index = lineSeqNo;
958 		register Byte  dst = 0;
959 		register Byte  i = 7;
960 		count = count8;
961 		while( count--) dst |=  tc64cmp << i--;
962 		*dest = dst;
963 	}
964 }
965 
966 /* rgb-> mono, error diffusion */
967 void
bc_rgb_mono_ed(Byte * source,Byte * dest,int count,int * err_buf)968 bc_rgb_mono_ed( Byte * source, Byte * dest, int count, int * err_buf)
969 {
970 	int count8 = count & 7;
971 	dEDIFF_ARGS;
972 	EDIFF_INIT;
973 	count >>= 3;
974 	while ( count--) {
975 		Byte i = 8, dst = 0;
976 		while(i--) {
977 			int c = map_RGB_gray[source[0]+source[1]+source[2]];
978 			source += 3;
979 			EDIFF_BEGIN_PIXEL(c,c,c);
980 			dst |= (( r + g + b) > 383) << i;
981 			EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
982 		}
983 		*dest++ = dst;
984 	}
985 	if ( count8) {
986 		Byte i = 8, dst = 0;
987 		while ( count8--) {
988 			int c = map_RGB_gray[source[0]+source[1]+source[2]];
989 			source += 3;
990 			EDIFF_BEGIN_PIXEL(c,c,c);
991 			dst |= (((r + g + b) > 383) << --i);
992 			EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
993 		}
994 		*dest = dst;
995 	}
996 }
997 
998 /* rgb -> nibble, no halftoning */
999 Byte
rgb_color_to_16(register Byte b,register Byte g,register Byte r)1000 rgb_color_to_16( register Byte b, register Byte g, register Byte r)
1001 {
1002 	/* 1 == 255 */
1003 	/* 2/3 == 170 */
1004 	/* 1/2 == 128 */
1005 	/* 1/3 == 85 */
1006 	/* 0 == 0 */
1007 	int rg, dist = 384;
1008 	Byte code = 0;
1009 	Byte mask = 8;
1010 
1011 	rg = r+g;
1012 	if ( rg-b > 128 ) code |= 1;
1013 	if ((int)r - (int)g + (int)b > 128 ) code |= 2;
1014 	if ((int)g + (int)b - (int)r > 128 ) code |= 4;
1015 	if ( code == 0)
1016 	{
1017 		dist = 128;
1018 		mask = 7;
1019 	}
1020 	else if ( code == 7)
1021 	{
1022 		code = 8;
1023 		dist = 640;
1024 		mask = 7;
1025 	}
1026 	if ( rg+b > dist) code |= mask;
1027 	return code;
1028 }
1029 
1030 void
bc_rgb_nibble(register Byte * source,Byte * dest,int count)1031 bc_rgb_nibble( register Byte *source, Byte *dest, int count)
1032 {
1033 	Byte tail = count & 1;
1034 	register Byte *stop = source + (count >> 1)*6;
1035 	while ( source != stop)
1036 	{
1037 		*dest++ = (rgb_color_to_16(source[0],source[1],source[2]) << 4) |
1038 					rgb_color_to_16(source[3],source[4],source[5]);
1039 		source += 6;
1040 	}
1041 	if ( tail)
1042 		*dest = rgb_color_to_16(source[0],source[1],source[2]) << 4;
1043 }
1044 
1045 /* rgb-> 8 halftoned */
1046 void
bc_rgb_nibble_ht(register Byte * source,Byte * dest,register int count,int lineSeqNo)1047 bc_rgb_nibble_ht( register Byte * source, Byte * dest, register int count, int lineSeqNo)
1048 {
1049 #define tc8cmp  ( source+=3,                          \
1050 					(((source[-3]>>2) > cmp))      +  \
1051 					(((source[-2]>>2) > cmp) << 1) +  \
1052 					(((source[-1]>>2) > cmp) << 2)    \
1053 					)
1054 	Byte tail = count & 1;
1055 	lineSeqNo = ( lineSeqNo & 7) << 3;
1056 	count = count >> 1;
1057 	while ( count--)
1058 	{
1059 		register Byte index = lineSeqNo + (( count & 3) << 1);
1060 		register Byte dst;
1061 		register Byte cmp;
1062 		cmp = map_halftone8x8_64[ index++];
1063 		dst = tc8cmp << 4;
1064 		cmp = map_halftone8x8_64[ index];
1065 		*dest++ = dst + tc8cmp;
1066 	}
1067 	if ( tail)
1068 	{
1069 		register Byte cmp  = map_halftone8x8_64[ lineSeqNo + 1];
1070 		*dest = tc8cmp << 4;
1071 	}
1072 }
1073 
1074 /* rgb-> 8 cubic, error diffusion */
1075 void
bc_rgb_nibble_ed(Byte * source,Byte * dest,int count,int * err_buf)1076 bc_rgb_nibble_ed( Byte * source, Byte * dest, int count, int * err_buf)
1077 {
1078 	dEDIFF_ARGS;
1079 	Byte tail = count & 1;
1080 	count = count >> 1;
1081 	EDIFF_INIT;
1082 	while ( count--) {
1083 		Byte dst;
1084 		EDIFF_BEGIN_PIXEL(*(source++), *(source++), *(source++));
1085 		dst = (( r > 127) * 4 + (g > 127) * 2 + (b > 127)) << 4;
1086 		EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
1087 		EDIFF_BEGIN_PIXEL(*(source++), *(source++), *(source++));
1088 		*dest++ = dst + (( r > 127) * 4 + (g > 127) * 2 + (b > 127));
1089 		EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
1090 	}
1091 	if ( tail) {
1092 		EDIFF_BEGIN_PIXEL(*(source++), *(source++), *(source++));
1093 		*dest++ = (( r > 127) * 4 + (g > 127) * 2 + (b > 127)) << 4;
1094 		EDIFF_END_PIXEL(( r > 127) ? 255 : 0, ( g > 127) ? 255 : 0, ( b > 127) ? 255 : 0);
1095 	}
1096 }
1097 
1098 /* rgb-> 256 cubic */
1099 void
bc_rgb_byte(Byte * source,register Byte * dest,register int count)1100 bc_rgb_byte( Byte * source, register Byte * dest, register int count)
1101 {
1102 	while ( count--)
1103 	{
1104 		register Byte dst = ( div51f[ *source++]);
1105 		dst += ( div51f[ *source++]) * 6;
1106 		*dest++ = dst + div51f[ *source++] * 36;
1107 	}
1108 }
1109 
1110 /* rgb-> 256 cubic, halftoned */
1111 void
bc_rgb_byte_ht(Byte * source,register Byte * dest,register int count,int lineSeqNo)1112 bc_rgb_byte_ht( Byte * source, register Byte * dest, register int count, int lineSeqNo)
1113 {
1114 	lineSeqNo = ( lineSeqNo & 7) << 3;
1115 	while ( count--)
1116 	{
1117 		register Byte cmp = map_halftone8x8_51[( count & 7) + lineSeqNo];
1118 		register Byte src;
1119 		register Byte dst;
1120 		src = *source++;
1121 		dst =  ( div51[ src] + ( mod51[ src] > cmp));
1122 		src = *source++;
1123 		dst += ( div51[ src] + ( mod51[ src] > cmp)) * 6;
1124 		src = *source++;
1125 		dst += ( div51[ src] + ( mod51[ src] > cmp)) * 36;
1126 		*dest++ = dst;
1127 	}
1128 }
1129 
1130 /* rgb-> 256 cubic, error diffusion */
1131 void
bc_rgb_byte_ed(Byte * source,Byte * dest,int count,int * err_buf)1132 bc_rgb_byte_ed( Byte * source, Byte * dest, int count, int * err_buf)
1133 {
1134 	dEDIFF_ARGS;
1135 	EDIFF_INIT;
1136 	while ( count--) {
1137 		EDIFF_BEGIN_PIXEL(*(source++), *(source++), *(source++));
1138 		*(dest++) = div51f[r] * 36 + div51f[g] * 6 + div51f[b];
1139 		EDIFF_END_PIXEL_EX( mod51f[r], mod51f[g], mod51f[b]);
1140 	}
1141 }
1142 
1143 /* rgb -> 8bit optimized */
1144 void
bc_rgb_byte_op(RGBColor * src,Byte * dest,int count,U16 * tree,RGBColor * palette,int * err_buf)1145 bc_rgb_byte_op( RGBColor * src, Byte * dest, int count, U16 * tree, RGBColor * palette, int * err_buf)
1146 {
1147 	dEDIFF_ARGS;
1148 	EDIFF_INIT;
1149 	while ( count--) {
1150 		int table = 0, shift = 6, index;
1151 		EDIFF_BEGIN_PIXEL(src->r,src->g,src->b);
1152 		src++;
1153 		while ( 1) {
1154 			index = (((r >> shift) & 3) << 4) +
1155 				(((g >> shift) & 3) << 2) +
1156 				 ((b >> shift) & 3);
1157 			if ( tree[ table + index] & PAL_REF) {
1158 				table = (tree[ table + index] & ~PAL_REF) * CELL_SIZE;
1159 				shift -= 2;
1160 			} else {
1161 				*dest = tree[ table + index];
1162 				EDIFF_END_PIXEL( palette[*dest].r, palette[*dest].g, palette[*dest].b);
1163 				dest++;
1164 				break;
1165 			}
1166 		}
1167 	}
1168 }
1169 
1170 /* rgb -> 8bit optimized not dithered */
1171 void
bc_rgb_byte_nop(RGBColor * src,Byte * dest,int count,U16 * tree,RGBColor * palette)1172 bc_rgb_byte_nop( RGBColor * src, Byte * dest, int count, U16 * tree, RGBColor * palette)
1173 {
1174 	while ( count--) {
1175 		int table = 0, shift = 6, index;
1176 		while ( 1) {
1177 			index = (((src->r >> shift) & 3) << 4) +
1178 				(((src->g >> shift) & 3) << 2) +
1179 				 ((src->b >> shift) & 3);
1180 			if ( tree[ table + index] & PAL_REF) {
1181 				table = (tree[ table + index] & ~PAL_REF) * CELL_SIZE;
1182 				shift -= 2;
1183 			} else {
1184 				*(dest++) = tree[ table + index];
1185 				break;
1186 			}
1187 		}
1188 		src++;
1189 	}
1190 }
1191 
1192 /* bitstroke copiers */
1193 void
bc_nibble_copy(Byte * source,Byte * dest,unsigned int from,unsigned int width)1194 bc_nibble_copy( Byte * source, Byte * dest, unsigned int from, unsigned int width)
1195 {
1196 	if ( from & 1) {
1197 		register Byte a;
1198 		register int byteLim = (( width - 1) >> 1) + (( width - 1) & 1);
1199 		source += from >> 1;
1200 		a = *source++;
1201 		while ( byteLim--) {
1202 			register Byte b = *source++;
1203 			*dest++ = ( a << 4) | ( b >> 4);
1204 			a = b;
1205 		}
1206 		if ( width & 1) *dest++ = a << 4;
1207 	} else
1208 		memcpy( dest, source + ( from >> 1), ( width >> 1) + ( width & 1));
1209 }
1210 
1211 void
bc_mono_copy(Byte * source,Byte * dest,unsigned int from,unsigned int width)1212 bc_mono_copy( Byte * source, Byte * dest, unsigned int from, unsigned int width)
1213 {
1214 	if (( from & 7) != 0) {
1215 		register Byte a;
1216 		short    lShift = from & 7;
1217 		short    rShift = 8 - lShift;
1218 		register int toLim  = ( width >> 3) + ((( width & 7) > 0) ? 1 : 0);
1219 		Byte * froLim = source + (( from + width) >> 3) + (((( from + width) & 7) > 0) ? 1 : 0);
1220 		source += from >> 3;
1221 		a = *source++;
1222 		while( toLim--) {
1223 			register Byte b = ( source == froLim) ? 0 : *source++;
1224 			*dest++ = ( a << lShift) | ( b >> rShift);
1225 			a = b;
1226 		}
1227 	} else
1228 		memcpy( dest, source + ( from >> 3), ( width >> 3) + (( width & 7) > 0 ? 1 : 0));
1229 }
1230 
1231 #ifdef __cplusplus
1232 }
1233 #endif
1234