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