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