1 /*
2 * dither.c: Various dithering routines
3 *
4 * Adapted by: Ullrich Hafner
5 *
6 * This file is part of FIASCO (Fractal Image And Sequence COdec)
7 * Copyright (C) 1994-2000 Ullrich Hafner
8 */
9
10 /*
11 * Copyright (c) 1995 Erik Corry
12 * All rights reserved.
13 *
14 * Permission to use, copy, modify, and distribute this software and its
15 * documentation for any purpose, without fee, and without written agreement is
16 * hereby granted, provided that the above copyright notice and the following
17 * two paragraphs appear in all copies of this software.
18 *
19 * IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
20 * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
21 * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED
22 * OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26 * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
27 * BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
28 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
29 */
30
31 /*
32 * $Date: 2000/11/27 20:22:51 $
33 * $Author: hafner $
34 * $Revision: 5.3 $
35 * $State: Exp $
36 */
37
38 #include "pm_config.h"
39 #include "config.h"
40
41 #include <string.h>
42 #include <stdlib.h>
43
44 #include "types.h"
45 #include "macros.h"
46 #include "error.h"
47
48 #include "fiasco.h"
49 #include "image.h"
50 #include "misc.h"
51 #include "dither.h"
52
53 /*****************************************************************************
54
55 prototypes
56
57 *****************************************************************************/
58
59 static int
60 display_16_bit (const struct fiasco_renderer *this, unsigned char *ximage,
61 const fiasco_image_t *fiasco_image);
62
63 static int
64 display_24_bit_bgr (const struct fiasco_renderer *this, unsigned char *ximage,
65 const fiasco_image_t *fiasco_image);
66
67 static int
68 display_24_bit_rgb (const struct fiasco_renderer *this, unsigned char *ximage,
69 const fiasco_image_t *fiasco_image);
70
71 static int
72 display_32_bit (const struct fiasco_renderer *this, unsigned char *ximage,
73 const fiasco_image_t *fiasco_image);
74
75 static int
76 free_bits_at_bottom (unsigned long a);
77
78 static int
79 number_of_bits_set (unsigned long a);
80
81 /*****************************************************************************
82
83 public code
84
85 *****************************************************************************/
86
87 fiasco_renderer_t *
fiasco_renderer_new(unsigned long red_mask,unsigned long green_mask,unsigned long blue_mask,unsigned bpp,int double_resolution)88 fiasco_renderer_new (unsigned long red_mask, unsigned long green_mask,
89 unsigned long blue_mask, unsigned bpp,
90 int double_resolution)
91 /*
92 * FIASCO renderer constructor.
93 * Allocate memory for the FIASCO renderer structure and
94 * initialize values.
95 * `red_mask', `green_mask', and `blue_mask' are the corresponding masks
96 * of the X11R6 XImage structure.
97 * `bpp' gives the depth of the image in bits per pixel (16, 24, or 32).
98 * If `double_resolution' is not 0 the the image width and height is doubled.
99 * (fast pixel doubling, no interpolation!)
100 *
101 * Return value:
102 * pointer to the new structure or NULL on error
103 */
104 {
105 if (bpp != 16 && bpp != 24 && bpp !=32)
106 {
107 set_error (_("Rendering depth of XImage must be 16, 24, or 32 bpp."));
108 return NULL;
109 }
110 else
111 {
112 fiasco_renderer_t *render = calloc (1, sizeof (fiasco_renderer_t));
113 renderer_private_t *private = calloc (1, sizeof (renderer_private_t));
114 bool_t twopixels = (bpp == 16 && double_resolution);
115 int crval, cbval, i; /* counter */
116
117 if (!render || !private)
118 {
119 set_error (_("Out of memory."));
120 return NULL;
121 }
122 switch (bpp)
123 {
124 case 16:
125 render->render = display_16_bit;
126 break;
127 case 24:
128 if (red_mask > green_mask)
129 render->render = display_24_bit_rgb;
130 else
131 render->render = display_24_bit_bgr;
132 break;
133 case 32:
134 render->render = display_32_bit;
135 break;
136 default:
137 break; /* does not happen */
138 }
139 render->private = private;
140 render->delete = fiasco_renderer_delete;
141
142 private->double_resolution = double_resolution;
143 private->Cr_r_tab = calloc (256 + 2 * 1024, sizeof (int));
144 private->Cr_g_tab = calloc (256 + 2 * 1024, sizeof (int));
145 private->Cb_g_tab = calloc (256 + 2 * 1024, sizeof (int));
146 private->Cb_b_tab = calloc (256 + 2 * 1024, sizeof (int));
147
148 if (!private->Cr_r_tab || !private->Cr_g_tab
149 || !private->Cb_b_tab || !private->Cb_g_tab)
150 {
151 set_error (_("Out of memory."));
152 return NULL;
153 }
154
155 for (i = 1024; i < 1024 + 256; i++)
156 {
157 cbval = crval = i - 128 - 1024;
158
159 private->Cr_r_tab [i] = 1.4022 * crval + 0.5;
160 private->Cr_g_tab [i] = -0.7145 * crval + 0.5;
161 private->Cb_g_tab [i] = -0.3456 * cbval + 0.5;
162 private->Cb_b_tab [i] = 1.7710 * cbval + 0.5;
163 }
164 for (i = 0; i < 1024; i++)
165 {
166 private->Cr_r_tab [i] = private->Cr_r_tab [1024];
167 private->Cr_g_tab [i] = private->Cr_g_tab [1024];
168 private->Cb_g_tab [i] = private->Cb_g_tab [1024];
169 private->Cb_b_tab [i] = private->Cb_b_tab [1024];
170 }
171 for (i = 1024 + 256; i < 2048 + 256; i++)
172 {
173 private->Cr_r_tab [i] = private->Cr_r_tab [1024 + 255];
174 private->Cr_g_tab [i] = private->Cr_g_tab [1024 + 255];
175 private->Cb_g_tab [i] = private->Cb_g_tab [1024 + 255];
176 private->Cb_b_tab [i] = private->Cb_b_tab [1024 + 255];
177 }
178
179 private->Cr_r_tab += 1024 + 128;
180 private->Cr_g_tab += 1024 + 128;
181 private->Cb_g_tab += 1024 + 128;
182 private->Cb_b_tab += 1024 + 128;
183
184 /*
185 * Set up entries 0-255 in rgb-to-pixel value tables.
186 */
187 private->r_table = calloc (256 + 2 * 1024, sizeof (unsigned int));
188 private->g_table = calloc (256 + 2 * 1024, sizeof (unsigned int));
189 private->b_table = calloc (256 + 2 * 1024, sizeof (unsigned int));
190 private->y_table = calloc (256 + 2 * 1024, sizeof (unsigned int));
191
192 if (!private->r_table || !private->g_table
193 || !private->b_table || !private->y_table)
194 {
195 set_error (_("Out of memory."));
196 return NULL;
197 }
198
199 for (i = 0; i < 256; i++)
200 {
201 private->r_table [i + 1024]
202 = i >> (8 - number_of_bits_set(red_mask));
203 private->r_table [i + 1024]
204 <<= free_bits_at_bottom (red_mask);
205 private->g_table [i + 1024]
206 = i >> (8 - number_of_bits_set (green_mask));
207 private->g_table [i + 1024]
208 <<= free_bits_at_bottom (green_mask);
209 private->b_table [i + 1024]
210 <<= free_bits_at_bottom (blue_mask);
211 private->b_table [i + 1024]
212 = i >> (8 - number_of_bits_set (blue_mask));
213 if (twopixels)
214 {
215 private->r_table [i + 1024] = ((private->r_table [i + 1024] << 16)
216 | private->r_table [i + 1024]);
217 private->g_table [i + 1024] = ((private->g_table [i + 1024] << 16)
218 | private->g_table [i + 1024]);
219 private->b_table [i + 1024] = ((private->b_table [i + 1024] << 16)
220 | private->b_table [i + 1024]);
221 }
222 private->y_table [i + 1024] = (private->r_table [i + 1024]
223 | private->g_table [i + 1024]
224 | private->b_table [i + 1024]);
225 }
226
227 /*
228 * Spread out the values we have to the rest of the array so that
229 * we do not need to check for overflow.
230 */
231 for (i = 0; i < 1024; i++)
232 {
233 private->r_table [i] = private->r_table [1024];
234 private->r_table [i + 1024 + 256] = private->r_table [1024 + 255];
235 private->g_table [i] = private->g_table [1024];
236 private->g_table [i + 1024 + 256] = private->g_table [1024 + 255];
237 private->b_table [i] = private->b_table [1024];
238 private->b_table [i + 1024 + 256] = private->b_table [1024 + 255];
239 private->y_table [i] = private->y_table [1024];
240 private->y_table [i + 1024 + 256] = private->y_table [1024 + 255];
241 }
242
243 private->r_table += 1024;
244 private->g_table += 1024;
245 private->b_table += 1024;
246 private->y_table += 1024 + 128;
247
248 return render;
249 }
250
251 }
252
253 void
fiasco_renderer_delete(fiasco_renderer_t * renderer)254 fiasco_renderer_delete (fiasco_renderer_t *renderer)
255 /*
256 * FIASCO renderer destructor:
257 * Free memory of 'renderer' structure.
258 *
259 * No return value.
260 *
261 * Side effects:
262 * structure 'renderer' is discarded.
263 */
264 {
265 if (!renderer)
266 return;
267 else
268 {
269 renderer_private_t *private = (renderer_private_t *) renderer->private;
270
271 Free (private->Cr_g_tab - (1024 + 128));
272 Free (private->Cr_r_tab - (1024 + 128));
273 Free (private->Cb_g_tab - (1024 + 128));
274 Free (private->Cb_b_tab - (1024 + 128));
275 Free (private->r_table - 1024);
276 Free (private->g_table - 1024);
277 Free (private->b_table - 1024);
278 Free (private->y_table - (1024 + 128));
279
280 Free (private);
281 Free (renderer);
282 }
283 }
284
285 int
fiasco_renderer_render(const fiasco_renderer_t * renderer,unsigned char * ximage,const fiasco_image_t * fiasco_image)286 fiasco_renderer_render (const fiasco_renderer_t *renderer,
287 unsigned char *ximage,
288 const fiasco_image_t *fiasco_image)
289 {
290 if (!renderer)
291 {
292 set_error (_("Parameter `%s' not defined (NULL)."), "renderer");
293 return 0;
294 }
295 else
296 return renderer->render (renderer, ximage, fiasco_image);
297 }
298
299 /*****************************************************************************
300
301 private code
302
303 *****************************************************************************/
304
305 /*
306 * Erik Corry's multi-byte dither routines.
307 *
308 * The basic idea is that the Init generates all the necessary
309 * tables. The tables incorporate the information about the layout
310 * of pixels in the XImage, so that it should be able to cope with
311 * 16-bit 24-bit (non-packed) and 32-bit (10-11 bits per
312 * color!) screens. At present it cannot cope with 24-bit packed
313 * mode, since this involves getting down to byte level again. It is
314 * assumed that the bits for each color are contiguous in the
315 * longword.
316 *
317 * Writing to memory is done in shorts or ints. (Unfortunately, short
318 * is not very fast on Alpha, so there is room for improvement
319 * here). There is no dither time check for overflow - instead the
320 * tables have slack at each end. This is likely to be faster than an
321 * 'if' test as many modern architectures are really bad at
322 * ifs. Potentially, each '&&' causes a pipeline flush!
323 *
324 * There is no shifting and fixed point arithmetic, as I really doubt
325 * you can see the difference, and it costs. This may be just my
326 * bias, since I heard that Intel is really bad at shifting.
327 */
328
329 static int
number_of_bits_set(unsigned long a)330 number_of_bits_set (unsigned long a)
331 /*
332 * How many 1 bits are there in the longword.
333 * Low performance, do not call often.
334 */
335 {
336 if (!a)
337 return 0;
338 if (a & 1)
339 return 1 + number_of_bits_set (a >> 1);
340 else
341 return (number_of_bits_set (a >> 1));
342 }
343
344 static int
free_bits_at_bottom(unsigned long a)345 free_bits_at_bottom (unsigned long a)
346 /*
347 * How many 0 bits are there at least significant end of longword.
348 * Low performance, do not call often.
349 */
350 {
351 /* assume char is 8 bits */
352 if (!a)
353 return sizeof (unsigned long) * 8;
354 else if(((long) a) & 1l)
355 return 0;
356 else
357 return 1 + free_bits_at_bottom ( a >> 1);
358 }
359
360 static int
display_16_bit(const struct fiasco_renderer * this,unsigned char * ximage,const fiasco_image_t * fiasco_image)361 display_16_bit (const struct fiasco_renderer *this, unsigned char *ximage,
362 const fiasco_image_t *fiasco_image)
363 /*
364 * Convert 'image' to 16 bit color bitmap.
365 * If 'double_resolution' is true then double image size in both directions.
366 *
367 * No return value.
368 *
369 * Side effects:
370 * 'out[]' is filled with dithered image
371 */
372 {
373 const image_t *image;
374 renderer_private_t *private;
375 byte_t *out;
376
377 if (!this)
378 {
379 set_error (_("Parameter `%s' not defined (NULL)."), "this");
380 return 0;
381 }
382 if (!ximage)
383 {
384 set_error (_("Parameter `%s' not defined (NULL)."), "ximage");
385 return 0;
386 }
387 if (!fiasco_image)
388 {
389 set_error (_("Parameter `%s' not defined (NULL)."), "fiasco_image");
390 return 0;
391 }
392
393 out = (byte_t *) ximage;
394 image = cast_image ((fiasco_image_t *) fiasco_image);
395 if (!image)
396 return 0;
397 private = (renderer_private_t *) this->private;
398
399 if (image->color)
400 {
401 word_t *cbptr, *crptr; /* pointer to chroma bands */
402 word_t *yptr; /* pointers to lumincance band */
403 int yval, crval, cbval; /* pixel value in YCbCr color space */
404 int R, G, B; /* pixel value in RGB color space */
405 int n; /* pixel counter */
406 int x, y; /* pixel coordinates */
407 int *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
408 unsigned int *r_table, *g_table, *b_table;
409
410 Cr_g_tab = private->Cr_g_tab;
411 Cr_r_tab = private->Cr_r_tab;
412 Cb_b_tab = private->Cb_b_tab;
413 Cb_g_tab = private->Cb_g_tab;
414 r_table = private->r_table;
415 g_table = private->g_table;
416 b_table = private->b_table;
417 yptr = image->pixels [Y];
418 cbptr = image->pixels [Cb];
419 crptr = image->pixels [Cr];
420
421 if (image->format == FORMAT_4_2_0)
422 {
423 u_word_t *dst, *dst2; /* pointers to dithered pixels */
424 word_t *yptr2; /* pointers to lumincance band */
425
426 if (private->double_resolution)
427 {
428 yptr2 = yptr + image->width;
429 dst = (u_word_t *) out;
430 dst2 = dst + 4 * image->width;
431 for (y = image->height / 2; y; y--)
432 {
433 for (x = image->width / 2; x; x--)
434 {
435 #ifdef HAVE_SIGNED_SHIFT
436 crval = *crptr++ >> 4;
437 cbval = *cbptr++ >> 4;
438 yval = (*yptr++ >> 4) + 128;
439 #else /* not HAVE_SIGNED_SHIFT */
440 crval = *crptr++ / 16;
441 cbval = *cbptr++ / 16;
442 yval = *yptr++ / 16 + 128;
443 #endif /* not HAVE_SIGNED_SHIFT */
444 R = yval + Cr_r_tab [crval];
445 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
446 B = yval + Cb_b_tab [cbval];
447 *dst++ = r_table [R] | g_table [G] | b_table [B];
448 *dst++ = r_table [R] | g_table [G] | b_table [B];
449
450 #ifdef HAVE_SIGNED_SHIFT
451 yval = (*yptr++ >> 4) + 128;
452 #else /* not HAVE_SIGNED_SHIFT */
453 yval = *yptr++ / 16 + 128;
454 #endif /* not HAVE_SIGNED_SHIFT */
455 R = yval + Cr_r_tab [crval];
456 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
457 B = yval + Cb_b_tab [cbval];
458 *dst++ = r_table [R] | g_table [G] | b_table [B];
459 *dst++ = r_table [R] | g_table [G] | b_table [B];
460
461 #ifdef HAVE_SIGNED_SHIFT
462 yval = (*yptr2++ >> 4) + 128;
463 #else /* not HAVE_SIGNED_SHIFT */
464 yval = *yptr2++ / 16 + 128;
465 #endif /* not HAVE_SIGNED_SHIFT */
466 R = yval + Cr_r_tab [crval];
467 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
468 B = yval + Cb_b_tab [cbval];
469 *dst2++ = r_table [R] | g_table [G] | b_table [B];
470 *dst2++ = r_table [R] | g_table [G] | b_table [B];
471
472 #ifdef HAVE_SIGNED_SHIFT
473 yval = (*yptr2++ >> 4) + 128;
474 #else /* not HAVE_SIGNED_SHIFT */
475 yval = *yptr2++ / 16 + 128;
476 #endif /* not HAVE_SIGNED_SHIFT */
477 R = yval + Cr_r_tab [crval];
478 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
479 B = yval + Cb_b_tab [cbval];
480 *dst2++ = r_table [R] | g_table [G] | b_table [B];
481 *dst2++ = r_table [R] | g_table [G] | b_table [B];
482 }
483 memcpy (dst, dst - 2 * image->width,
484 2 * image->width * sizeof (u_word_t));
485 memcpy (dst2, dst2 - 2 * image->width,
486 2 * image->width * sizeof (u_word_t));
487 yptr += image->width;
488 yptr2 += image->width;
489 dst += 3 * image->width * 2;
490 dst2 += 3 * image->width * 2;
491 }
492 }
493 else
494 {
495 yptr2 = yptr + image->width;
496 dst = (u_word_t *) out;
497 dst2 = dst + image->width;
498
499 for (y = image->height / 2; y; y--)
500 {
501 for (x = image->width / 2; x; x--)
502 {
503 #ifdef HAVE_SIGNED_SHIFT
504 crval = *crptr++ >> 4;
505 cbval = *cbptr++ >> 4;
506 yval = (*yptr++ >> 4) + 128;
507 #else /* not HAVE_SIGNED_SHIFT */
508 crval = *crptr++ / 16;
509 cbval = *cbptr++ / 16;
510 yval = *yptr++ / 16 + 128;
511 #endif /* not HAVE_SIGNED_SHIFT */
512 R = yval + Cr_r_tab [crval];
513 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
514 B = yval + Cb_b_tab [cbval];
515 *dst++ = r_table [R] | g_table [G] | b_table [B];
516
517 #ifdef HAVE_SIGNED_SHIFT
518 yval = (*yptr++ >> 4) + 128;
519 #else /* not HAVE_SIGNED_SHIFT */
520 yval = *yptr++ / 16 + 128;
521 #endif /* not HAVE_SIGNED_SHIFT */
522 R = yval + Cr_r_tab [crval];
523 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
524 B = yval + Cb_b_tab [cbval];
525 *dst++ = r_table [R] | g_table [G] | b_table [B];
526
527 #ifdef HAVE_SIGNED_SHIFT
528 yval = (*yptr2++ >> 4) + 128;
529 #else /* not HAVE_SIGNED_SHIFT */
530 yval = *yptr2++ / 16 + 128;
531 #endif /* not HAVE_SIGNED_SHIFT */
532 R = yval + Cr_r_tab [crval];
533 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
534 B = yval + Cb_b_tab [cbval];
535 *dst2++ = r_table [R] | g_table [G] | b_table [B];
536
537 #ifdef HAVE_SIGNED_SHIFT
538 yval = (*yptr2++ >> 4) + 128;
539 #else /* not HAVE_SIGNED_SHIFT */
540 yval = *yptr2++ / 16 + 128;
541 #endif /* not HAVE_SIGNED_SHIFT */
542 R = yval + Cr_r_tab [crval];
543 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
544 B = yval + Cb_b_tab [cbval];
545 *dst2++ = r_table [R] | g_table [G] | b_table [B];
546 }
547 yptr += image->width;
548 yptr2 += image->width;
549 dst += image->width;
550 dst2 += image->width;
551 }
552 }
553 }
554 else /* 4:4:4 format */
555 {
556 if (private->double_resolution)
557 {
558 unsigned int *dst; /* pointer to dithered pixels */
559
560 dst = (unsigned int *) out;
561
562 for (y = image->height; y; y--)
563 {
564 for (x = image->width; x; x--)
565 {
566 #ifdef HAVE_SIGNED_SHIFT
567 crval = *crptr++ >> 4;
568 cbval = *cbptr++ >> 4;
569 yval = (*yptr++ >> 4) + 128;
570 #else /* not HAVE_SIGNED_SHIFT */
571 crval = *crptr++ / 16;
572 cbval = *cbptr++ / 16;
573 yval = *yptr++ / 16 + 128;
574 #endif /* not HAVE_SIGNED_SHIFT */
575 R = yval + Cr_r_tab [crval];
576 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
577 B = yval + Cb_b_tab [cbval];
578
579 *dst++ = r_table [R] | g_table [G] | b_table [B];
580 }
581 memcpy (dst, dst - image->width,
582 image->width * sizeof (unsigned int));
583 dst += image->width;
584 }
585 }
586 else
587 {
588 u_word_t *dst; /* pointer to dithered pixels */
589
590 dst = (u_word_t *) out;
591
592 for (n = image->width * image->height; n; n--)
593 {
594 #ifdef HAVE_SIGNED_SHIFT
595 crval = *crptr++ >> 4;
596 cbval = *cbptr++ >> 4;
597 yval = (*yptr++ >> 4) + 128;
598 #else /* not HAVE_SIGNED_SHIFT */
599 crval = *crptr++ / 16;
600 cbval = *cbptr++ / 16;
601 yval = *yptr++ / 16 + 128;
602 #endif /* not HAVE_SIGNED_SHIFT */
603 R = yval + Cr_r_tab [crval];
604 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
605 B = yval + Cb_b_tab [cbval];
606
607 *dst++ = r_table [R] | g_table [G] | b_table [B];
608 }
609 }
610 }
611 }
612 else
613 {
614 unsigned int *dst; /* pointer to dithered pixels */
615 word_t *src; /* current pixel of frame */
616 unsigned int *y_table;
617
618 y_table = private->y_table;
619 dst = (unsigned int *) out;
620 src = image->pixels [GRAY];
621
622 if (private->double_resolution)
623 {
624 int x, y; /* pixel coordinates */
625
626 for (y = image->height; y; y--)
627 {
628 for (x = image->width; x; x--)
629 {
630 int value;
631
632 #ifdef HAVE_SIGNED_SHIFT
633 value = y_table [*src++ >> 4];
634 #else /* not HAVE_SIGNED_SHIFT */
635 value = y_table [*src++ / 16];
636 #endif /* not HAVE_SIGNED_SHIFT */
637 *dst++ = (value << 16) | value;
638 }
639
640 memcpy (dst, dst - image->width,
641 image->width * sizeof (unsigned int));
642 dst += image->width;
643 }
644 }
645 else
646 {
647 int n; /* pixel counter */
648
649 for (n = image->width * image->height / 2; n; n--, src += 2)
650 #ifdef HAVE_SIGNED_SHIFT
651 # if BYTE_ORDER == LITTLE_ENDIAN
652 *dst++ = (y_table [src [1] >> 4] << 16) | y_table [src [0] >> 4];
653 # else
654 *dst++ = (y_table [src [0] >> 4] << 16) | y_table [src [1] >> 4];
655 # endif
656 #else /* not HAVE_SIGNED_SHIFT */
657 # if BYTE_ORDER == LITTLE_ENDIAN
658 *dst++ = (y_table [src [1] / 16] << 16) | y_table [src [0] / 16];
659 # else
660 *dst++ = (y_table [src [0] / 16] << 16) | y_table [src [1] / 16];
661 # endif
662 #endif /* not HAVE_SIGNED_SHIFT */
663 }
664 }
665
666 return 1;
667 }
668
669 static int
display_24_bit_bgr(const struct fiasco_renderer * this,unsigned char * ximage,const fiasco_image_t * fiasco_image)670 display_24_bit_bgr (const struct fiasco_renderer *this, unsigned char *ximage,
671 const fiasco_image_t *fiasco_image)
672 /*
673 * Convert 'image' to 16 bit color bitmap.
674 * If 'double_resolution' is true then double image size in both directions.
675 *
676 * No return value.
677 *
678 * Side effects:
679 * 'out[]' is filled with dithered image
680 */
681 {
682 unsigned *gray_clip = init_clipping ();
683 const image_t *image;
684 renderer_private_t *private;
685 byte_t *out;
686
687 if (!gray_clip)
688 return 0;
689 if (!this)
690 {
691 set_error (_("Parameter `%s' not defined (NULL)."), "this");
692 return 0;
693 }
694 if (!ximage)
695 {
696 set_error (_("Parameter `%s' not defined (NULL)."), "ximage");
697 return 0;
698 }
699 if (!fiasco_image)
700 {
701 set_error (_("Parameter `%s' not defined (NULL)."), "fiasco_image");
702 return 0;
703 }
704
705 out = (byte_t *) ximage;
706 image = cast_image ((fiasco_image_t *) fiasco_image);
707 if (!image)
708 return 0;
709 private = (renderer_private_t *) this->private;
710
711 if (image->color)
712 {
713 word_t *cbptr, *crptr; /* pointer to chroma bands */
714 word_t *yptr; /* pointers to lumincance band */
715 int *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
716
717 Cr_g_tab = private->Cr_g_tab;
718 Cr_r_tab = private->Cr_r_tab;
719 Cb_b_tab = private->Cb_b_tab;
720 Cb_g_tab = private->Cb_g_tab;
721 yptr = image->pixels [Y];
722 cbptr = image->pixels [Cb];
723 crptr = image->pixels [Cr];
724
725 if (image->format == FORMAT_4_2_0)
726 {
727 if (private->double_resolution)
728 {
729 int yval1; /* lumincance pixel */
730 int crval1, cbval1; /* chroma pixels */
731 int yval2; /* pixel in YCbCr color space */
732 unsigned int R1, G1, B1; /* pixel in RGB color space */
733 unsigned int R2, G2, B2; /* pixel in RGB color space */
734 int x, y; /* pixel counter */
735 unsigned int *dst; /* pointer to dithered pixels */
736 unsigned int *dst2; /* pointers to dithered pixels */
737 word_t *yptr2; /* pointers to lumincance band */
738
739 dst = (unsigned int *) out;
740 dst2 = dst + (image->width >> 1) * 3 * 2;
741 yptr2 = yptr + image->width;
742
743 for (y = image->height >> 1; y; y--)
744 {
745 for (x = image->width >> 1; x; x--)
746 {
747 #ifdef HAVE_SIGNED_SHIFT
748 yval1 = (*yptr++ >> 4) + 128;
749 yval2 = (*yptr++ >> 4) + 128;
750 crval1 = *crptr++ >> 4;
751 cbval1 = *cbptr++ >> 4;
752 #else /* not HAVE_SIGNED_SHIFT */
753 yval1 = *yptr++ / 16 + 128;
754 yval2 = *yptr++ / 16 + 128;
755 crval1 = *crptr++ / 16;
756 cbval1 = *cbptr++ / 16;
757 #endif /* not HAVE_SIGNED_SHIFT */
758
759 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
760 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
761 + Cb_g_tab [cbval1]];
762 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
763 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
764 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
765 + Cb_g_tab [cbval1]];
766 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
767
768 *dst++ = B1 | (G1 << 8) | (R1 << 16) | (B1 << 24);
769 *dst++ = G1 | (R1 << 8) | (B2 << 16) | (G2 << 24);
770 *dst++ = R2 | (B2 << 8) | (G2 << 16) | (R2 << 24);
771
772 #ifdef HAVE_SIGNED_SHIFT
773 yval1 = (*yptr2++ >> 4) + 128;
774 yval2 = (*yptr2++ >> 4) + 128;
775 #else /* not HAVE_SIGNED_SHIFT */
776 yval1 = *yptr2++ / 16 + 128;
777 yval2 = *yptr2++ / 16 + 128;
778 #endif /* not HAVE_SIGNED_SHIFT */
779
780 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
781 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
782 + Cb_g_tab [cbval1]];
783 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
784 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
785 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
786 + Cb_g_tab [cbval1]];
787 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
788
789 *dst2++ = B1 | (G1 << 8) | (R1 << 16) | (B1 << 24);
790 *dst2++ = G1 | (R1 << 8) | (B2 << 16) | (G2 << 24);
791 *dst2++ = R2 | (B2 << 8) | (G2 << 16) | (R2 << 24);
792 }
793 memcpy (dst, dst - (image->width >> 1) * 3,
794 (image->width >> 1) * 3 * sizeof (unsigned int));
795 memcpy (dst2, dst2 - (image->width >> 1) * 3,
796 (image->width >> 1) * 3 * sizeof (unsigned int));
797 dst += (image->width >> 1) * 3 * 3;
798 dst2 += (image->width >> 1) * 3 * 3;
799 yptr += image->width;
800 yptr2 += image->width;
801 }
802 }
803 else
804 {
805 int yval1; /* lumincance pixel */
806 int crval1, cbval1; /* chroma pixels */
807 int yval2; /* pixel in YCbCr color space */
808 unsigned int R1, G1, B1; /* pixel in RGB color space */
809 unsigned int R2, G2, B2; /* pixel in RGB color space */
810 int x, y; /* pixel counter */
811 unsigned int *dst; /* pointer to dithered pixels */
812 unsigned int *dst2; /* pointers to dithered pixels */
813 word_t *yptr2; /* pointers to lumincance band */
814
815 dst = (unsigned int *) out;
816 dst2 = dst + (image->width >> 2) * 3;
817 yptr2 = yptr + image->width;
818
819 for (y = image->height >> 1; y; y--)
820 {
821 for (x = image->width >> 2; x; x--)
822 {
823 #ifdef HAVE_SIGNED_SHIFT
824 yval1 = (*yptr++ >> 4) + 128;
825 yval2 = (*yptr++ >> 4) + 128;
826 crval1 = *crptr++ >> 4;
827 cbval1 = *cbptr++ >> 4;
828 #else /* not HAVE_SIGNED_SHIFT */
829 yval1 = *yptr++ / 16 + 128;
830 yval2 = *yptr++ / 16 + 128;
831 crval1 = *crptr++ / 16;
832 cbval1 = *cbptr++ / 16;
833 #endif /* not HAVE_SIGNED_SHIFT */
834
835 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
836 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
837 + Cb_g_tab [cbval1]];
838 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
839 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
840 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
841 + Cb_g_tab [cbval1]];
842 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
843
844 *dst++ = B1 | (G1 << 8) | (R1 << 16) | (B2 << 24);
845 *dst = G2 | (R2 << 8);
846
847 #ifdef HAVE_SIGNED_SHIFT
848 yval1 = (*yptr2++ >> 4) + 128;
849 yval2 = (*yptr2++ >> 4) + 128;
850 #else /* not HAVE_SIGNED_SHIFT */
851 yval1 = *yptr2++ / 16 + 128;
852 yval2 = *yptr2++ / 16 + 128;
853 #endif /* not HAVE_SIGNED_SHIFT */
854
855 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
856 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
857 + Cb_g_tab [cbval1]];
858 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
859 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
860 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
861 + Cb_g_tab [cbval1]];
862 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
863
864 *dst2++ = B1 | (G1 << 8) | (R1 << 16) | (B2 << 24);
865 *dst2 = G2 | (R2 << 8);
866
867 #ifdef HAVE_SIGNED_SHIFT
868 yval1 = (*yptr++ >> 4) + 128;
869 yval2 = (*yptr++ >> 4) + 128;
870 crval1 = *crptr++ >> 4;
871 cbval1 = *cbptr++ >> 4;
872 #else /* not HAVE_SIGNED_SHIFT */
873 yval1 = *yptr++ / 16 + 128;
874 yval2 = *yptr++ / 16 + 128;
875 crval1 = *crptr++ / 16;
876 crval2 = *crptr++ / 16;
877 cbval1 = *cbptr++ / 16;
878 cbval2 = *cbptr++ / 16;
879 #endif /* not HAVE_SIGNED_SHIFT */
880
881 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
882 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
883 + Cb_g_tab [cbval1]];
884 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
885 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
886 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
887 + Cb_g_tab [cbval1]];
888 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
889
890 *dst++ |= (B1 << 16) | (G1 << 24);
891 *dst++ = R1 | (B2 << 8) | (G2 << 16) | (R2 << 24);
892
893 #ifdef HAVE_SIGNED_SHIFT
894 yval1 = (*yptr2++ >> 4) + 128;
895 yval2 = (*yptr2++ >> 4) + 128;
896 #else /* not HAVE_SIGNED_SHIFT */
897 yval1 = *yptr2++ / 16 + 128;
898 yval2 = *yptr2++ / 16 + 128;
899 #endif /* not HAVE_SIGNED_SHIFT */
900
901 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
902 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
903 + Cb_g_tab [cbval1]];
904 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
905 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
906 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
907 + Cb_g_tab [cbval1]];
908 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
909
910 *dst2++ |= (B1 << 16) | (G1 << 24);
911 *dst2++ = R1 | (B2 << 8) | (G2 << 16) | (R2 << 24);
912 }
913 dst += (image->width >> 2) * 3;
914 dst2 += (image->width >> 2) * 3;
915 yptr += image->width;
916 yptr2 += image->width;
917 }
918 }
919 }
920 else /* 4:4:4 format */
921 {
922 if (private->double_resolution)
923 {
924 unsigned int R1, G1, B1; /* pixel1 in RGB color space */
925 unsigned int R2, G2, B2; /* pixel2 in RGB color space */
926 int yval1, crval1, cbval1; /* pixel1 in YCbCr space */
927 int yval2, crval2, cbval2; /* pixel2 in YCbCr space */
928 int x, y; /* pixel counter */
929 unsigned int *dst; /* dithered pixel pointer */
930
931 dst = (unsigned int *) out;
932
933 for (y = image->height; y; y--)
934 {
935 for (x = image->width >> 1; x; x--)
936 {
937 #ifdef HAVE_SIGNED_SHIFT
938 yval1 = (*yptr++ >> 4) + 128;
939 yval2 = (*yptr++ >> 4) + 128;
940 crval1 = *crptr++ >> 4;
941 crval2 = *crptr++ >> 4;
942 cbval1 = *cbptr++ >> 4;
943 cbval2 = *cbptr++ >> 4;
944 #else /* not HAVE_SIGNED_SHIFT */
945 yval1 = *yptr++ / 16 + 128;
946 yval2 = *yptr++ / 16 + 128;
947 crval1 = *crptr++ / 16;
948 crval2 = *crptr++ / 16;
949 cbval1 = *cbptr++ / 16;
950 cbval2 = *cbptr++ / 16;
951 #endif /* not HAVE_SIGNED_SHIFT */
952
953 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
954 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
955 + Cb_g_tab [cbval1]];
956 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
957 R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
958 G2 = gray_clip [yval2 + Cr_g_tab [crval2]
959 + Cb_g_tab [cbval2]];
960 B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
961
962 *dst++ = B1 | (G1 << 8) | (R1 << 16) | (B1 << 24);
963 *dst++ = G1 | (R1 << 8) | (B2 << 16) | (G2 << 24);
964 *dst++ = R2 | (B2 << 8) | (G2 << 16) | (R2 << 24);
965 }
966 memcpy (dst, dst - 3 * (image->width >> 1),
967 3 * (image->width >> 1) * sizeof (unsigned int));
968 dst += 3 * (image->width >> 1);
969 }
970 }
971 else
972 {
973 unsigned int R1, G1, B1; /* pixel in RGB color space */
974 unsigned int R2, G2, B2; /* pixel in RGB color space */
975 int yval1, crval1, cbval1; /* pixel1 in YCbCr space */
976 int yval2, crval2, cbval2; /* pixel2 in YCbCr space */
977 int n; /* pixel counter */
978 unsigned int *dst; /* dithered pixel pointer */
979
980 dst = (unsigned int *) out;
981
982 for (n = (image->width * image->height) >> 2; n; n--)
983 {
984 #ifdef HAVE_SIGNED_SHIFT
985 yval1 = (*yptr++ >> 4) + 128;
986 yval2 = (*yptr++ >> 4) + 128;
987 crval1 = *crptr++ >> 4;
988 crval2 = *crptr++ >> 4;
989 cbval1 = *cbptr++ >> 4;
990 cbval2 = *cbptr++ >> 4;
991 #else /* not HAVE_SIGNED_SHIFT */
992 yval1 = *yptr++ / 16 + 128;
993 yval2 = *yptr++ / 16 + 128;
994 crval1 = *crptr++ / 16;
995 crval2 = *crptr++ / 16;
996 cbval1 = *cbptr++ / 16;
997 cbval2 = *cbptr++ / 16;
998 #endif /* not HAVE_SIGNED_SHIFT */
999
1000 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1001 G1 = gray_clip [yval1 + Cr_g_tab [crval1] + Cb_g_tab [cbval1]];
1002 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1003 R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
1004 G2 = gray_clip [yval2 + Cr_g_tab [crval2] + Cb_g_tab [cbval2]];
1005 B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
1006
1007 *dst++ = B1 | (G1 << 8) | (R1 << 16) | (B2 << 24);
1008 *dst = G2 | (R2 << 8);
1009
1010 #ifdef HAVE_SIGNED_SHIFT
1011 yval1 = (*yptr++ >> 4) + 128;
1012 yval2 = (*yptr++ >> 4) + 128;
1013 crval1 = *crptr++ >> 4;
1014 crval2 = *crptr++ >> 4;
1015 cbval1 = *cbptr++ >> 4;
1016 cbval2 = *cbptr++ >> 4;
1017 #else /* not HAVE_SIGNED_SHIFT */
1018 yval1 = *yptr++ / 16 + 128;
1019 yval2 = *yptr++ / 16 + 128;
1020 crval1 = *crptr++ / 16;
1021 crval2 = *crptr++ / 16;
1022 cbval1 = *cbptr++ / 16;
1023 cbval2 = *cbptr++ / 16;
1024 #endif /* not HAVE_SIGNED_SHIFT */
1025
1026 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1027 G1 = gray_clip [yval1 + Cr_g_tab [crval1] + Cb_g_tab [cbval1]];
1028 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1029 R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
1030 G2 = gray_clip [yval2 + Cr_g_tab [crval2] + Cb_g_tab [cbval2]];
1031 B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
1032
1033 *dst++ |= (B1 << 16) | (G1 << 24);
1034 *dst++ = R1 | (B2 << 8) | (G2 << 16) | (R2 << 24);
1035 }
1036 }
1037 }
1038 }
1039 else
1040 {
1041 unsigned int *dst; /* pointer to dithered pixels */
1042 word_t *src; /* current pixel of frame */
1043
1044 dst = (unsigned int *) out;
1045 src = image->pixels [GRAY];
1046
1047 if (private->double_resolution)
1048 {
1049 int x, y; /* pixel counter */
1050 unsigned *shift_clipping = gray_clip + 128;
1051
1052 for (y = image->height; y; y--)
1053 {
1054 for (x = image->width >> 1; x; x--)
1055 {
1056 unsigned int val1, val2;
1057 #ifdef HAVE_SIGNED_SHIFT
1058 val1 = shift_clipping [*src++ >> 4];
1059 val2 = shift_clipping [*src++ >> 4];
1060 #else /* not HAVE_SIGNED_SHIFT */
1061 val1 = shift_clipping [*src++ / 16];
1062 val2 = shift_clipping [*src++ / 16];
1063 #endif /* not HAVE_SIGNED_SHIFT */
1064
1065 *dst++ = val1 | (val1 << 8) | (val1 << 16) | (val1 << 24);
1066 *dst++ = val1 | (val1 << 8) | (val2 << 16) | (val2 << 24);
1067 *dst++ = val2 | (val2 << 8) | (val2 << 16) | (val2 << 24);
1068 }
1069
1070 memcpy (dst, dst - 3 * (image->width >> 1),
1071 3 * (image->width >> 1) * sizeof (unsigned int));
1072 dst += 3 * (image->width >> 1);
1073 }
1074 }
1075 else
1076 {
1077 int n; /* pixel counter */
1078 unsigned *shift_clipping = gray_clip + 128;
1079
1080 for (n = (image->width * image->height) >> 2; n; n--)
1081 {
1082 unsigned int val1, val2;
1083
1084 #ifdef HAVE_SIGNED_SHIFT
1085 val1 = shift_clipping [*src++ >> 4];
1086 val2 = shift_clipping [*src++ >> 4];
1087 #else /* not HAVE_SIGNED_SHIFT */
1088 val1 = shift_clipping [*src++ / 16];
1089 val2 = shift_clipping [*src++ / 16];
1090 #endif /* not HAVE_SIGNED_SHIFT */
1091
1092 *dst++ = val1 | (val1 << 8)
1093 | (val1 << 16) | (val2 << 24); /* RGBR */
1094 *dst = val2 | (val2 << 8); /* GB-- */
1095
1096 #ifdef HAVE_SIGNED_SHIFT
1097 val1 = shift_clipping [*src++ >> 4];
1098 val2 = shift_clipping [*src++ >> 4];
1099 #else /* not HAVE_SIGNED_SHIFT */
1100 val1 = shift_clipping [*src++ / 16];
1101 val2 = shift_clipping [*src++ / 16];
1102 #endif /* not HAVE_SIGNED_SHIFT */
1103
1104 *dst++ |= (val1 << 16) | (val1 << 24); /* --RG */
1105 *dst++ = val1 | (val2 << 8)
1106 | (val2 << 16) | (val2 << 24); /* BRGB */
1107 }
1108 }
1109 }
1110
1111 return 1;
1112 }
1113
1114 static int
display_24_bit_rgb(const struct fiasco_renderer * this,unsigned char * ximage,const fiasco_image_t * fiasco_image)1115 display_24_bit_rgb (const struct fiasco_renderer *this, unsigned char *ximage,
1116 const fiasco_image_t *fiasco_image)
1117 /*
1118 * Convert 'image' to 16 bit color bitmap.
1119 * If 'double_resolution' is true then double image size in both directions.
1120 *
1121 * No return value.
1122 *
1123 * Side effects:
1124 * 'out[]' is filled with dithered image
1125 */
1126 {
1127 unsigned *gray_clip = init_clipping ();
1128 const image_t *image;
1129 renderer_private_t *private;
1130 byte_t *out;
1131
1132 if (!gray_clip)
1133 return 0;
1134 if (!this)
1135 {
1136 set_error (_("Parameter `%s' not defined (NULL)."), "this");
1137 return 0;
1138 }
1139 if (!ximage)
1140 {
1141 set_error (_("Parameter `%s' not defined (NULL)."), "ximage");
1142 return 0;
1143 }
1144 if (!fiasco_image)
1145 {
1146 set_error (_("Parameter `%s' not defined (NULL)."), "fiasco_image");
1147 return 0;
1148 }
1149
1150 out = (byte_t *) ximage;
1151 image = cast_image ((fiasco_image_t *) fiasco_image);
1152 if (!image)
1153 return 0;
1154 private = (renderer_private_t *) this->private;
1155
1156 if (image->color)
1157 {
1158 word_t *cbptr, *crptr; /* pointer to chroma bands */
1159 word_t *yptr; /* pointers to lumincance band */
1160 int *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
1161
1162 Cr_g_tab = private->Cr_g_tab;
1163 Cr_r_tab = private->Cr_r_tab;
1164 Cb_b_tab = private->Cb_b_tab;
1165 Cb_g_tab = private->Cb_g_tab;
1166 yptr = image->pixels [Y];
1167 cbptr = image->pixels [Cb];
1168 crptr = image->pixels [Cr];
1169
1170 if (image->format == FORMAT_4_2_0)
1171 {
1172 if (private->double_resolution)
1173 {
1174 int yval1; /* lumincance pixel */
1175 int crval1, cbval1; /* chroma pixels */
1176 int yval2; /* pixel in YCbCr color space */
1177 unsigned int R1, G1, B1; /* pixel in RGB color space */
1178 unsigned int R2, G2, B2; /* pixel in RGB color space */
1179 int x, y; /* pixel counter */
1180 unsigned int *dst; /* pointer to dithered pixels */
1181 unsigned int *dst2; /* pointers to dithered pixels */
1182 word_t *yptr2; /* pointers to lumincance band */
1183
1184 dst = (unsigned int *) out;
1185 dst2 = dst + (image->width >> 1) * 3 * 2;
1186 yptr2 = yptr + image->width;
1187
1188 for (y = image->height >> 1; y; y--)
1189 {
1190 for (x = image->width >> 1; x; x--)
1191 {
1192 #ifdef HAVE_SIGNED_SHIFT
1193 yval1 = (*yptr++ >> 4) + 128;
1194 yval2 = (*yptr++ >> 4) + 128;
1195 crval1 = *crptr++ >> 4;
1196 cbval1 = *cbptr++ >> 4;
1197 #else /* not HAVE_SIGNED_SHIFT */
1198 yval1 = *yptr++ / 16 + 128;
1199 yval2 = *yptr++ / 16 + 128;
1200 crval1 = *crptr++ / 16;
1201 cbval1 = *cbptr++ / 16;
1202 #endif /* not HAVE_SIGNED_SHIFT */
1203
1204 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1205 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
1206 + Cb_g_tab [cbval1]];
1207 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1208 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
1209 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
1210 + Cb_g_tab [cbval1]];
1211 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
1212
1213 *dst++ = R1 | (G1 << 8) | (B1 << 16) | (R1 << 24);
1214 *dst++ = G1 | (B1 << 8) | (R2 << 16) | (G2 << 24);
1215 *dst++ = B2 | (R2 << 8) | (G2 << 16) | (B2 << 24);
1216
1217 #ifdef HAVE_SIGNED_SHIFT
1218 yval1 = (*yptr2++ >> 4) + 128;
1219 yval2 = (*yptr2++ >> 4) + 128;
1220 #else /* not HAVE_SIGNED_SHIFT */
1221 yval1 = *yptr2++ / 16 + 128;
1222 yval2 = *yptr2++ / 16 + 128;
1223 #endif /* not HAVE_SIGNED_SHIFT */
1224
1225 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1226 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
1227 + Cb_g_tab [cbval1]];
1228 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1229 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
1230 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
1231 + Cb_g_tab [cbval1]];
1232 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
1233
1234 *dst2++ = R1 | (G1 << 8) | (B1 << 16) | (R1 << 24);
1235 *dst2++ = G1 | (B1 << 8) | (R2 << 16) | (G2 << 24);
1236 *dst2++ = B2 | (R2 << 8) | (G2 << 16) | (B2 << 24);
1237 }
1238 memcpy (dst, dst - (image->width >> 1) * 3,
1239 (image->width >> 1) * 3 * sizeof (unsigned int));
1240 memcpy (dst2, dst2 - (image->width >> 1) * 3,
1241 (image->width >> 1) * 3 * sizeof (unsigned int));
1242 dst += (image->width >> 1) * 3 * 3;
1243 dst2 += (image->width >> 1) * 3 * 3;
1244 yptr += image->width;
1245 yptr2 += image->width;
1246 }
1247 }
1248 else
1249 {
1250 int yval1; /* lumincance pixel */
1251 int crval1, cbval1; /* chroma pixels */
1252 int yval2; /* pixel in YCbCr color space */
1253 unsigned int R1, G1, B1; /* pixel in RGB color space */
1254 unsigned int R2, G2, B2; /* pixel in RGB color space */
1255 int x, y; /* pixel counter */
1256 unsigned int *dst; /* pointer to dithered pixels */
1257 unsigned int *dst2; /* pointers to dithered pixels */
1258 word_t *yptr2; /* pointers to lumincance band */
1259
1260 dst = (unsigned int *) out;
1261 dst2 = dst + (image->width >> 2) * 3;
1262 yptr2 = yptr + image->width;
1263
1264 for (y = image->height >> 1; y; y--)
1265 {
1266 for (x = image->width >> 2; x; x--)
1267 {
1268 #ifdef HAVE_SIGNED_SHIFT
1269 yval1 = (*yptr++ >> 4) + 128;
1270 yval2 = (*yptr++ >> 4) + 128;
1271 crval1 = *crptr++ >> 4;
1272 cbval1 = *cbptr++ >> 4;
1273 #else /* not HAVE_SIGNED_SHIFT */
1274 yval1 = *yptr++ / 16 + 128;
1275 yval2 = *yptr++ / 16 + 128;
1276 crval1 = *crptr++ / 16;
1277 cbval1 = *cbptr++ / 16;
1278 #endif /* not HAVE_SIGNED_SHIFT */
1279
1280 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1281 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
1282 + Cb_g_tab [cbval1]];
1283 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1284 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
1285 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
1286 + Cb_g_tab [cbval1]];
1287 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
1288
1289 *dst++ = R1 | (G1 << 8) | (B1 << 16) | (R2 << 24);
1290 *dst = G2 | (B2 << 8);
1291
1292 #ifdef HAVE_SIGNED_SHIFT
1293 yval1 = (*yptr2++ >> 4) + 128;
1294 yval2 = (*yptr2++ >> 4) + 128;
1295 #else /* not HAVE_SIGNED_SHIFT */
1296 yval1 = *yptr2++ / 16 + 128;
1297 yval2 = *yptr2++ / 16 + 128;
1298 #endif /* not HAVE_SIGNED_SHIFT */
1299
1300 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1301 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
1302 + Cb_g_tab [cbval1]];
1303 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1304 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
1305 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
1306 + Cb_g_tab [cbval1]];
1307 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
1308
1309 *dst2++ = R1 | (G1 << 8) | (B1 << 16) | (R2 << 24);
1310 *dst2 = G2 | (B2 << 8);
1311
1312 #ifdef HAVE_SIGNED_SHIFT
1313 yval1 = (*yptr++ >> 4) + 128;
1314 yval2 = (*yptr++ >> 4) + 128;
1315 crval1 = *crptr++ >> 4;
1316 cbval1 = *cbptr++ >> 4;
1317 #else /* not HAVE_SIGNED_SHIFT */
1318 yval1 = *yptr++ / 16 + 128;
1319 yval2 = *yptr++ / 16 + 128;
1320 crval1 = *crptr++ / 16;
1321 crval2 = *crptr++ / 16;
1322 cbval1 = *cbptr++ / 16;
1323 cbval2 = *cbptr++ / 16;
1324 #endif /* not HAVE_SIGNED_SHIFT */
1325
1326 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1327 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
1328 + Cb_g_tab [cbval1]];
1329 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1330 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
1331 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
1332 + Cb_g_tab [cbval1]];
1333 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
1334
1335 *dst++ |= (R1 << 16) | (G1 << 24);
1336 *dst++ = B1 | (R2 << 8) | (G2 << 16) | (B2 << 24);
1337
1338 #ifdef HAVE_SIGNED_SHIFT
1339 yval1 = (*yptr2++ >> 4) + 128;
1340 yval2 = (*yptr2++ >> 4) + 128;
1341 #else /* not HAVE_SIGNED_SHIFT */
1342 yval1 = *yptr2++ / 16 + 128;
1343 yval2 = *yptr2++ / 16 + 128;
1344 #endif /* not HAVE_SIGNED_SHIFT */
1345
1346 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1347 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
1348 + Cb_g_tab [cbval1]];
1349 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1350 R2 = gray_clip [yval2 + Cr_r_tab [crval1]];
1351 G2 = gray_clip [yval2 + Cr_g_tab [crval1]
1352 + Cb_g_tab [cbval1]];
1353 B2 = gray_clip [yval2 + Cb_b_tab [cbval1]];
1354
1355 *dst2++ |= (R1 << 16) | (G1 << 24);
1356 *dst2++ = B1 | (R2 << 8) | (G2 << 16) | (B2 << 24);
1357 }
1358 dst += (image->width >> 2) * 3;
1359 dst2 += (image->width >> 2) * 3;
1360 yptr += image->width;
1361 yptr2 += image->width;
1362 }
1363 }
1364 }
1365 else /* 4:4:4 format */
1366 {
1367 if (private->double_resolution)
1368 {
1369 unsigned int R1, G1, B1; /* pixel1 in RGB color space */
1370 unsigned int R2, G2, B2; /* pixel2 in RGB color space */
1371 int yval1, crval1, cbval1; /* pixel1 in YCbCr space */
1372 int yval2, crval2, cbval2; /* pixel2 in YCbCr space */
1373 int x, y; /* pixel counter */
1374 unsigned int *dst; /* dithered pixel pointer */
1375
1376 dst = (unsigned int *) out;
1377
1378 for (y = image->height; y; y--)
1379 {
1380 for (x = image->width >> 1; x; x--)
1381 {
1382 #ifdef HAVE_SIGNED_SHIFT
1383 yval1 = (*yptr++ >> 4) + 128;
1384 yval2 = (*yptr++ >> 4) + 128;
1385 crval1 = *crptr++ >> 4;
1386 crval2 = *crptr++ >> 4;
1387 cbval1 = *cbptr++ >> 4;
1388 cbval2 = *cbptr++ >> 4;
1389 #else /* not HAVE_SIGNED_SHIFT */
1390 yval1 = *yptr++ / 16 + 128;
1391 yval2 = *yptr++ / 16 + 128;
1392 crval1 = *crptr++ / 16;
1393 crval2 = *crptr++ / 16;
1394 cbval1 = *cbptr++ / 16;
1395 cbval2 = *cbptr++ / 16;
1396 #endif /* not HAVE_SIGNED_SHIFT */
1397
1398 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1399 G1 = gray_clip [yval1 + Cr_g_tab [crval1]
1400 + Cb_g_tab [cbval1]];
1401 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1402 R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
1403 G2 = gray_clip [yval2 + Cr_g_tab [crval2]
1404 + Cb_g_tab [cbval2]];
1405 B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
1406
1407 *dst++ = R1 | (G1 << 8) | (B1 << 16) | (R1 << 24);
1408 *dst++ = G1 | (B1 << 8) | (R2 << 16) | (G2 << 24);
1409 *dst++ = B2 | (R2 << 8) | (G2 << 16) | (B2 << 24);
1410 }
1411 memcpy (dst, dst - 3 * (image->width >> 1),
1412 3 * (image->width >> 1) * sizeof (unsigned int));
1413 dst += 3 * (image->width >> 1);
1414 }
1415 }
1416 else
1417 {
1418 unsigned int R1, G1, B1; /* pixel in RGB color space */
1419 unsigned int R2, G2, B2; /* pixel in RGB color space */
1420 int yval1, crval1, cbval1; /* pixel1 in YCbCr space */
1421 int yval2, crval2, cbval2; /* pixel2 in YCbCr space */
1422 int n; /* pixel counter */
1423 unsigned int *dst; /* dithered pixel pointer */
1424
1425 dst = (unsigned int *) out;
1426
1427 for (n = (image->width * image->height) >> 2; n; n--)
1428 {
1429 #ifdef HAVE_SIGNED_SHIFT
1430 yval1 = (*yptr++ >> 4) + 128;
1431 yval2 = (*yptr++ >> 4) + 128;
1432 crval1 = *crptr++ >> 4;
1433 crval2 = *crptr++ >> 4;
1434 cbval1 = *cbptr++ >> 4;
1435 cbval2 = *cbptr++ >> 4;
1436 #else /* not HAVE_SIGNED_SHIFT */
1437 yval1 = *yptr++ / 16 + 128;
1438 yval2 = *yptr++ / 16 + 128;
1439 crval1 = *crptr++ / 16;
1440 crval2 = *crptr++ / 16;
1441 cbval1 = *cbptr++ / 16;
1442 cbval2 = *cbptr++ / 16;
1443 #endif /* not HAVE_SIGNED_SHIFT */
1444
1445 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1446 G1 = gray_clip [yval1 + Cr_g_tab [crval1] + Cb_g_tab [cbval1]];
1447 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1448 R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
1449 G2 = gray_clip [yval2 + Cr_g_tab [crval2] + Cb_g_tab [cbval2]];
1450 B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
1451
1452 *dst++ = R1 | (G1 << 8) | (B1 << 16) | (R2 << 24);
1453 *dst = G2 | (B2 << 8);
1454
1455 #ifdef HAVE_SIGNED_SHIFT
1456 yval1 = (*yptr++ >> 4) + 128;
1457 yval2 = (*yptr++ >> 4) + 128;
1458 crval1 = *crptr++ >> 4;
1459 crval2 = *crptr++ >> 4;
1460 cbval1 = *cbptr++ >> 4;
1461 cbval2 = *cbptr++ >> 4;
1462 #else /* not HAVE_SIGNED_SHIFT */
1463 yval1 = *yptr++ / 16 + 128;
1464 yval2 = *yptr++ / 16 + 128;
1465 crval1 = *crptr++ / 16;
1466 crval2 = *crptr++ / 16;
1467 cbval1 = *cbptr++ / 16;
1468 cbval2 = *cbptr++ / 16;
1469 #endif /* not HAVE_SIGNED_SHIFT */
1470
1471 R1 = gray_clip [yval1 + Cr_r_tab [crval1]];
1472 G1 = gray_clip [yval1 + Cr_g_tab [crval1] + Cb_g_tab [cbval1]];
1473 B1 = gray_clip [yval1 + Cb_b_tab [cbval1]];
1474 R2 = gray_clip [yval2 + Cr_r_tab [crval2]];
1475 G2 = gray_clip [yval2 + Cr_g_tab [crval2] + Cb_g_tab [cbval2]];
1476 B2 = gray_clip [yval2 + Cb_b_tab [cbval2]];
1477
1478 *dst++ |= (R1 << 16) | (G1 << 24);
1479 *dst++ = B1 | (R2 << 8) | (G2 << 16) | (B2 << 24);
1480 }
1481 }
1482 }
1483 }
1484 else
1485 {
1486 unsigned int *dst; /* pointer to dithered pixels */
1487 word_t *src; /* current pixel of frame */
1488
1489 dst = (unsigned int *) out;
1490 src = image->pixels [GRAY];
1491
1492 if (private->double_resolution)
1493 {
1494 int x, y; /* pixel counter */
1495 unsigned *shift_clipping = gray_clip + 128;
1496
1497 for (y = image->height; y; y--)
1498 {
1499 for (x = image->width >> 1; x; x--)
1500 {
1501 unsigned int val1, val2;
1502 #ifdef HAVE_SIGNED_SHIFT
1503 val1 = shift_clipping [*src++ >> 4];
1504 val2 = shift_clipping [*src++ >> 4];
1505 #else /* not HAVE_SIGNED_SHIFT */
1506 val1 = shift_clipping [*src++ / 16];
1507 val2 = shift_clipping [*src++ / 16];
1508 #endif /* not HAVE_SIGNED_SHIFT */
1509
1510 *dst++ = val1 | (val1 << 8) | (val1 << 16) | (val1 << 24);
1511 *dst++ = val1 | (val1 << 8) | (val2 << 16) | (val2 << 24);
1512 *dst++ = val2 | (val2 << 8) | (val2 << 16) | (val2 << 24);
1513 }
1514
1515 memcpy (dst, dst - 3 * (image->width >> 1),
1516 3 * (image->width >> 1) * sizeof (unsigned int));
1517 dst += 3 * (image->width >> 1);
1518 }
1519 }
1520 else
1521 {
1522 int n; /* pixel counter */
1523 unsigned *shift_clipping = gray_clip + 128;
1524
1525 for (n = (image->width * image->height) >> 2; n; n--)
1526 {
1527 unsigned int val1, val2;
1528
1529 #ifdef HAVE_SIGNED_SHIFT
1530 val1 = shift_clipping [*src++ >> 4];
1531 val2 = shift_clipping [*src++ >> 4];
1532 #else /* not HAVE_SIGNED_SHIFT */
1533 val1 = shift_clipping [*src++ / 16];
1534 val2 = shift_clipping [*src++ / 16];
1535 #endif /* not HAVE_SIGNED_SHIFT */
1536
1537 *dst++ = val1 | (val1 << 8)
1538 | (val1 << 16) | (val2 << 24); /* RGBR */
1539 *dst = val2 | (val2 << 8); /* GB-- */
1540
1541 #ifdef HAVE_SIGNED_SHIFT
1542 val1 = shift_clipping [*src++ >> 4];
1543 val2 = shift_clipping [*src++ >> 4];
1544 #else /* not HAVE_SIGNED_SHIFT */
1545 val1 = shift_clipping [*src++ / 16];
1546 val2 = shift_clipping [*src++ / 16];
1547 #endif /* not HAVE_SIGNED_SHIFT */
1548
1549 *dst++ |= (val1 << 16) | (val1 << 24); /* --RG */
1550 *dst++ = val1 | (val2 << 8)
1551 | (val2 << 16) | (val2 << 24); /* BRGB */
1552 }
1553 }
1554 }
1555
1556 return 1;
1557 }
1558
1559 static int
display_32_bit(const struct fiasco_renderer * this,unsigned char * ximage,const fiasco_image_t * fiasco_image)1560 display_32_bit (const struct fiasco_renderer *this, unsigned char *ximage,
1561 const fiasco_image_t *fiasco_image)
1562 /*
1563 * Convert 'image' to 16 bit color bitmap.
1564 * If 'double_resolution' is true then double image size in both directions.
1565 *
1566 * No return value.
1567 *
1568 * Side effects:
1569 * 'out[]' is filled with dithered image
1570 */
1571 {
1572 const image_t *image;
1573 renderer_private_t *private;
1574 byte_t *out;
1575
1576 if (!this)
1577 {
1578 set_error (_("Parameter `%s' not defined (NULL)."), "this");
1579 return 0;
1580 }
1581 if (!ximage)
1582 {
1583 set_error (_("Parameter `%s' not defined (NULL)."), "ximage");
1584 return 0;
1585 }
1586 if (!fiasco_image)
1587 {
1588 set_error (_("Parameter `%s' not defined (NULL)."), "fiasco_image");
1589 return 0;
1590 }
1591
1592 out = (byte_t *) ximage;
1593 private = (renderer_private_t *) this->private;
1594 image = cast_image ((fiasco_image_t *) fiasco_image);
1595 if (!image)
1596 return 0;
1597
1598 if (image->color)
1599 {
1600 word_t *cbptr, *crptr; /* pointer to chroma bands */
1601 word_t *yptr; /* pointers to lumincance band */
1602 int yval, crval, cbval; /* pixel value in YCbCr color space */
1603 int R, G, B; /* pixel value in RGB color space */
1604 int n; /* pixel counter */
1605 int x, y; /* pixel coordinates */
1606 int *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
1607 unsigned int *r_table, *g_table, *b_table;
1608
1609 Cr_g_tab = private->Cr_g_tab;
1610 Cr_r_tab = private->Cr_r_tab;
1611 Cb_b_tab = private->Cb_b_tab;
1612 Cb_g_tab = private->Cb_g_tab;
1613 r_table = private->r_table;
1614 g_table = private->g_table;
1615 b_table = private->b_table;
1616 yptr = image->pixels [Y];
1617 cbptr = image->pixels [Cb];
1618 crptr = image->pixels [Cr];
1619
1620 if (image->format == FORMAT_4_2_0)
1621 {
1622 unsigned int *dst, *dst2; /* pointers to dithered pixels */
1623 word_t *yptr2; /* pointers to lumincance band */
1624
1625 if (private->double_resolution)
1626 {
1627 yptr2 = yptr + image->width;
1628 dst = (unsigned int *) out;
1629 dst2 = dst + 4 * image->width;
1630 for (y = image->height / 2; y; y--)
1631 {
1632 for (x = image->width / 2; x; x--)
1633 {
1634 #ifdef HAVE_SIGNED_SHIFT
1635 crval = *crptr++ >> 4;
1636 cbval = *cbptr++ >> 4;
1637 yval = (*yptr++ >> 4) + 128;
1638 #else /* not HAVE_SIGNED_SHIFT */
1639 crval = *crptr++ / 16;
1640 cbval = *cbptr++ / 16;
1641 yval = *yptr++ / 16 + 128;
1642 #endif /* not HAVE_SIGNED_SHIFT */
1643 R = yval + Cr_r_tab [crval];
1644 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
1645 B = yval + Cb_b_tab [cbval];
1646 *dst++ = r_table [R] | g_table [G] | b_table [B];
1647 *dst++ = r_table [R] | g_table [G] | b_table [B];
1648
1649 #ifdef HAVE_SIGNED_SHIFT
1650 yval = (*yptr++ >> 4) + 128;
1651 #else /* not HAVE_SIGNED_SHIFT */
1652 yval = *yptr++ / 16 + 128;
1653 #endif /* not HAVE_SIGNED_SHIFT */
1654 R = yval + Cr_r_tab [crval];
1655 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
1656 B = yval + Cb_b_tab [cbval];
1657 *dst++ = r_table [R] | g_table [G] | b_table [B];
1658 *dst++ = r_table [R] | g_table [G] | b_table [B];
1659
1660 #ifdef HAVE_SIGNED_SHIFT
1661 yval = (*yptr2++ >> 4) + 128;
1662 #else /* not HAVE_SIGNED_SHIFT */
1663 yval = *yptr2++ / 16 + 128;
1664 #endif /* not HAVE_SIGNED_SHIFT */
1665 R = yval + Cr_r_tab [crval];
1666 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
1667 B = yval + Cb_b_tab [cbval];
1668 *dst2++ = r_table [R] | g_table [G] | b_table [B];
1669 *dst2++ = r_table [R] | g_table [G] | b_table [B];
1670
1671 #ifdef HAVE_SIGNED_SHIFT
1672 yval = (*yptr2++ >> 4) + 128;
1673 #else /* not HAVE_SIGNED_SHIFT */
1674 yval = *yptr2++ / 16 + 128;
1675 #endif /* not HAVE_SIGNED_SHIFT */
1676 R = yval + Cr_r_tab [crval];
1677 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
1678 B = yval + Cb_b_tab [cbval];
1679 *dst2++ = r_table [R] | g_table [G] | b_table [B];
1680 *dst2++ = r_table [R] | g_table [G] | b_table [B];
1681 }
1682 memcpy (dst, dst - 2 * image->width,
1683 2 * image->width * sizeof (unsigned int));
1684 memcpy (dst2, dst2 - 2 * image->width,
1685 2 * image->width * sizeof (unsigned int));
1686 yptr += image->width;
1687 yptr2 += image->width;
1688 dst += 3 * image->width * 2;
1689 dst2 += 3 * image->width * 2;
1690 }
1691 }
1692 else
1693 {
1694 yptr2 = yptr + image->width;
1695 dst = (unsigned int *) out;
1696 dst2 = dst + image->width;
1697
1698 for (y = image->height / 2; y; y--)
1699 {
1700 for (x = image->width / 2; x; x--)
1701 {
1702 #ifdef HAVE_SIGNED_SHIFT
1703 crval = *crptr++ >> 4;
1704 cbval = *cbptr++ >> 4;
1705 yval = (*yptr++ >> 4) + 128;
1706 #else /* not HAVE_SIGNED_SHIFT */
1707 crval = *crptr++ / 16;
1708 cbval = *cbptr++ / 16;
1709 yval = *yptr++ / 16 + 128;
1710 #endif /* not HAVE_SIGNED_SHIFT */
1711 R = yval + Cr_r_tab [crval];
1712 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
1713 B = yval + Cb_b_tab [cbval];
1714 *dst++ = r_table [R] | g_table [G] | b_table [B];
1715
1716 #ifdef HAVE_SIGNED_SHIFT
1717 yval = (*yptr++ >> 4) + 128;
1718 #else /* not HAVE_SIGNED_SHIFT */
1719 yval = *yptr++ / 16 + 128;
1720 #endif /* not HAVE_SIGNED_SHIFT */
1721 R = yval + Cr_r_tab [crval];
1722 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
1723 B = yval + Cb_b_tab [cbval];
1724 *dst++ = r_table [R] | g_table [G] | b_table [B];
1725
1726 #ifdef HAVE_SIGNED_SHIFT
1727 yval = (*yptr2++ >> 4) + 128;
1728 #else /* not HAVE_SIGNED_SHIFT */
1729 yval = *yptr2++ / 16 + 128;
1730 #endif /* not HAVE_SIGNED_SHIFT */
1731 R = yval + Cr_r_tab [crval];
1732 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
1733 B = yval + Cb_b_tab [cbval];
1734 *dst2++ = r_table [R] | g_table [G] | b_table [B];
1735
1736 #ifdef HAVE_SIGNED_SHIFT
1737 yval = (*yptr2++ >> 4) + 128;
1738 #else /* not HAVE_SIGNED_SHIFT */
1739 yval = *yptr2++ / 16 + 128;
1740 #endif /* not HAVE_SIGNED_SHIFT */
1741 R = yval + Cr_r_tab [crval];
1742 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
1743 B = yval + Cb_b_tab [cbval];
1744 *dst2++ = r_table [R] | g_table [G] | b_table [B];
1745 }
1746 yptr += image->width;
1747 yptr2 += image->width;
1748 dst += image->width;
1749 dst2 += image->width;
1750 }
1751 }
1752 }
1753 else /* 4:4:4 format */
1754 {
1755 if (private->double_resolution)
1756 {
1757 unsigned int *dst; /* pointer to dithered pixels */
1758
1759 dst = (unsigned int *) out;
1760
1761 for (y = image->height; y; y--)
1762 {
1763 for (x = image->width; x; x--)
1764 {
1765 #ifdef HAVE_SIGNED_SHIFT
1766 crval = *crptr++ >> 4;
1767 cbval = *cbptr++ >> 4;
1768 yval = (*yptr++ >> 4) + 128;
1769 #else /* not HAVE_SIGNED_SHIFT */
1770 crval = *crptr++ / 16;
1771 cbval = *cbptr++ / 16;
1772 yval = *yptr++ / 16 + 128;
1773 #endif /* not HAVE_SIGNED_SHIFT */
1774 R = yval + Cr_r_tab [crval];
1775 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
1776 B = yval + Cb_b_tab [cbval];
1777
1778 *dst++ = r_table [R] | g_table [G] | b_table [B];
1779 *dst++ = r_table [R] | g_table [G] | b_table [B];
1780 }
1781 memcpy (dst, dst - 2 * image->width,
1782 2 * image->width * sizeof (unsigned int));
1783 dst += image->width * 2;
1784 }
1785 }
1786 else
1787 {
1788 unsigned int *dst; /* pointer to dithered pixels */
1789
1790 dst = (unsigned int *) out;
1791
1792 for (n = image->width * image->height; n; n--)
1793 {
1794 #ifdef HAVE_SIGNED_SHIFT
1795 crval = *crptr++ >> 4;
1796 cbval = *cbptr++ >> 4;
1797 yval = (*yptr++ >> 4) + 128;
1798 #else /* not HAVE_SIGNED_SHIFT */
1799 crval = *crptr++ / 16;
1800 cbval = *cbptr++ / 16;
1801 yval = *yptr++ / 16 + 128;
1802 #endif /* not HAVE_SIGNED_SHIFT */
1803 R = yval + Cr_r_tab [crval];
1804 G = yval + Cr_g_tab [crval] + Cb_g_tab [cbval];
1805 B = yval + Cb_b_tab [cbval];
1806
1807 *dst++ = r_table [R] | g_table [G] | b_table [B];
1808 }
1809 }
1810 }
1811 }
1812 else
1813 {
1814 unsigned int *dst; /* pointer to dithered pixels */
1815 word_t *src; /* current pixel of frame */
1816 unsigned int *y_table;
1817
1818 y_table = private->y_table;
1819 dst = (unsigned int *) out;
1820 src = image->pixels [GRAY];
1821
1822 if (private->double_resolution)
1823 {
1824 int x, y; /* pixel coordinates */
1825
1826 for (y = image->height; y; y--)
1827 {
1828 for (x = image->width; x; x--)
1829 {
1830 int value;
1831
1832 #ifdef HAVE_SIGNED_SHIFT
1833 value = y_table [*src++ >> 4];
1834 #else /* not HAVE_SIGNED_SHIFT */
1835 value = y_table [*src++ / 16];
1836 #endif /* not HAVE_SIGNED_SHIFT */
1837 *dst++ = value;
1838 *dst++ = value;
1839 }
1840
1841 memcpy (dst, dst - 2 * image->width,
1842 2 * image->width * sizeof (unsigned int));
1843 dst += 2 * image->width;
1844 }
1845 }
1846 else
1847 {
1848 int n; /* pixel counter */
1849
1850 for (n = image->width * image->height; n; n--)
1851 #ifdef HAVE_SIGNED_SHIFT
1852 *dst++ = y_table [*src++ >> 4];
1853 #else /* not HAVE_SIGNED_SHIFT */
1854 *dst++ = y_table [*src++ / 16];
1855 #endif /* not HAVE_SIGNED_SHIFT */
1856 }
1857 }
1858
1859 return 1;
1860 }
1861
1862
1863
1864