]> git.sesse.net Git - vlc/blob - src/video_output/video_yuv.c
Toujours du nettoyage.
[vlc] / src / video_output / video_yuv.c
1 /*******************************************************************************
2  * video_yuv.c: YUV transformation functions
3  * (c)1999 VideoLAN
4  *******************************************************************************
5  * Provides functions to perform the YUV conversion. The functions provided here
6  * are a complete and portable C implementation, and may be replaced in certain
7  * case by optimized functions.
8  *******************************************************************************/
9
10 /*******************************************************************************
11  * Preamble
12  *******************************************************************************/
13 #include <errno.h>
14 #include <math.h>
15 #include <string.h>
16 #include <stdlib.h>
17
18 #ifdef VIDEO_X11
19 #include <X11/Xlib.h>                           /* for video_sys.h in X11 mode */
20 #endif
21
22 #include "common.h"
23 #include "config.h"
24 #include "mtime.h"
25 #include "vlc_thread.h"
26 #include "video.h"
27 #include "video_output.h"
28 #include "video_yuv.h"
29 #include "intf_msg.h"
30
31 /*******************************************************************************
32  * Constants
33  *******************************************************************************/
34
35 /* RGB/YUV inversion matrix (ISO/IEC 13818-2 section 6.3.6, table 6.9) */
36 const int MATRIX_COEFFICIENTS_TABLE[8][4] =
37 {
38   {117504, 138453, 13954, 34903},       /* no sequence_display_extension */
39   {117504, 138453, 13954, 34903},       /* ITU-R Rec. 709 (1990) */
40   {104597, 132201, 25675, 53279},       /* unspecified */
41   {104597, 132201, 25675, 53279},       /* reserved */
42   {104448, 132798, 24759, 53109},       /* FCC */
43   {104597, 132201, 25675, 53279},       /* ITU-R Rec. 624-4 System B, G */
44   {104597, 132201, 25675, 53279},       /* SMPTE 170M */
45   {117579, 136230, 16907, 35559}        /* SMPTE 240M (1987) */
46 };
47
48 /*******************************************************************************
49  * Local prototypes
50  *******************************************************************************/
51 static int      BinaryLog         ( u32 i );
52 static void     MaskToShift       ( int *pi_right, int *pi_left, u32 i_mask );
53 static void     SetTables         ( vout_thread_t *p_vout );
54
55 static void     ConvertY4Gray16   ( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
56                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
57 static void     ConvertY4Gray24   ( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
58                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
59 static void     ConvertY4Gray32   ( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
60                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
61 static void     ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
62                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
63 static void     ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
64                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
65 static void     ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
66                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
67 static void     ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
68                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
69 static void     ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
70                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
71 static void     ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
72                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
73 static void     ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
74                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
75 static void     ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
76                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
77 static void     ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
78                                     int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
79 static void     Scale16           ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
80                                     int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
81 static void     Scale24           ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
82                                     int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
83 static void     Scale32           ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
84                                     int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
85
86 /*******************************************************************************
87  * CLIP_BYTE macro: boundary detection
88  *******************************************************************************
89  * Return parameter if between 0 and 255, else return nearest boundary (0 or 
90  * 255). This macro is used to build translations tables.
91  *******************************************************************************/
92 #define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
93
94 /*******************************************************************************
95  * LINE_COPY macro: memcopy using 16 pixels blocks
96  *******************************************************************************
97  * Variables:
98  *      p_pic                   destination pointer
99  *      p_pic_src               source pointer
100  *      i_width                 width
101  *      i_x                     index
102  *******************************************************************************/
103 #define LINE_COPY                                                       \
104 for( i_x = 0; i_x < i_width; i_x+=16 )                                  \
105 {                                                                       \
106     *p_pic++ = *p_pic_src++;                                            \
107     *p_pic++ = *p_pic_src++;                                            \
108     *p_pic++ = *p_pic_src++;                                            \
109     *p_pic++ = *p_pic_src++;                                            \
110     *p_pic++ = *p_pic_src++;                                            \
111     *p_pic++ = *p_pic_src++;                                            \
112     *p_pic++ = *p_pic_src++;                                            \
113     *p_pic++ = *p_pic_src++;                                            \
114     *p_pic++ = *p_pic_src++;                                            \
115     *p_pic++ = *p_pic_src++;                                            \
116     *p_pic++ = *p_pic_src++;                                            \
117     *p_pic++ = *p_pic_src++;                                            \
118     *p_pic++ = *p_pic_src++;                                            \
119     *p_pic++ = *p_pic_src++;                                            \
120     *p_pic++ = *p_pic_src++;                                            \
121     *p_pic++ = *p_pic_src++;                                            \
122 }
123
124 /*******************************************************************************
125  * CONVERT_YUV_GRAY macro: grayscale YUV convertion
126  *******************************************************************************
127  * Variables:
128  *      ...see vout_convert_t
129  *      i_x, i_y                coordinates
130  *      i_pic_copy              same type as p_pic
131  *      p_gray                  gray translation table
132  *******************************************************************************/
133 #define CONVERT_YUV_GRAY                                                \
134 for (i_y = 0; i_y < i_height ; i_y++)                                   \
135 {                                                                       \
136     for (i_x = 0; i_x < i_width; i_x += 16)                             \
137     {                                                                   \
138         /* Convert 16 pixels (width is always multiple of 16 */         \
139         *p_pic++ = p_gray[ *p_y++ ];                                    \
140         *p_pic++ = p_gray[ *p_y++ ];                                    \
141         *p_pic++ = p_gray[ *p_y++ ];                                    \
142         *p_pic++ = p_gray[ *p_y++ ];                                    \
143         *p_pic++ = p_gray[ *p_y++ ];                                    \
144         *p_pic++ = p_gray[ *p_y++ ];                                    \
145         *p_pic++ = p_gray[ *p_y++ ];                                    \
146         *p_pic++ = p_gray[ *p_y++ ];                                    \
147         *p_pic++ = p_gray[ *p_y++ ];                                    \
148         *p_pic++ = p_gray[ *p_y++ ];                                    \
149         *p_pic++ = p_gray[ *p_y++ ];                                    \
150         *p_pic++ = p_gray[ *p_y++ ];                                    \
151         *p_pic++ = p_gray[ *p_y++ ];                                    \
152         *p_pic++ = p_gray[ *p_y++ ];                                    \
153         *p_pic++ = p_gray[ *p_y++ ];                                    \
154         *p_pic++ = p_gray[ *p_y++ ];                                    \
155     }                                                                   \
156                                                                         \
157     /* Handle scale factor */                                           \
158     if( i_scale && ! (i_y % i_scale) )                                  \
159     {                                                                   \
160         if( i_scale < 0 )                                               \
161         {                                                               \
162             /* Copy previous line */                                    \
163             p_pic_src = p_pic - i_width;                                \
164             p_pic += i_pic_eol;                                         \
165             LINE_COPY                                                   \
166         }                                                               \
167         else                                                            \
168         {                                                               \
169             /* Ignore next line */                                      \
170             p_y += i_eol + i_width;                                     \
171             i_y++;                                                      \
172         }                                                               \
173     }                                                                   \
174                                                                         \
175     /* Skip until beginning of next line */                             \
176     p_pic += i_pic_eol;                                                 \
177     p_y   += i_eol;                                                     \
178 }
179
180 /*******************************************************************************
181  * CONVERT_YUV_RGB: color YUV convertion
182  *******************************************************************************
183  * Parameters
184  *      CHROMA                          420, 422 or 444
185  * Variables:
186  *      ...see vout_convert_t
187  *      i_x, i_y                        coordinates
188  *      i_uval, i_yval, i_vval          samples
189  *      p_pic_src                       same type as p_pic
190  *      i_chroma_width                  chroma width
191  *      i_chroma_eol                    chroma eol
192  *      p_red                           red translation table
193  *      p_green                         green translation table
194  *      p_blue                          blue translation table
195  *      i_crv, i_cgu, i_cgv, i_cbu      matrix coefficients
196  *******************************************************************************/
197 #define CONVERT_YUV_RGB( CHROMA )                                       \
198 for (i_y = 0; i_y < i_height ; i_y++)                                   \
199 {                                                                       \
200     for (i_x = 0; i_x < i_width; i_x += 2 )                             \
201     {                                                                   \
202         /* First sample (complete) */                                   \
203         i_yval = 76309 * *p_y++ - 1188177;                              \
204         i_uval = *p_u++ - 128;                                          \
205         i_vval = *p_v++ - 128;                                          \
206         *p_pic++ =                                                      \
207             p_red  [(i_yval+i_crv*i_vval)                >>16] |        \
208             p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval)   >>16] |        \
209             p_blue [(i_yval+i_cbu*i_uval)                >>16];         \
210         i_yval = 76309 * *p_y++ - 1188177;                              \
211         /* Second sample (partial) */                                   \
212         if( CHROMA == 444 )                                             \
213         {                                                               \
214             i_uval = *p_u++ - 128;                                      \
215             i_vval = *p_v++ - 128;                                      \
216         }                                                               \
217         *p_pic++ =                                                      \
218             p_red  [(i_yval+i_crv*i_vval)                >>16] |        \
219             p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval)   >>16] |        \
220             p_blue [(i_yval+i_cbu*i_uval)                >>16];         \
221     }                                                                   \
222                                                                         \
223     /* Handle scale factor and rewind in 4:2:0 */                       \
224     if( i_scale && ! (i_y % i_scale) )                                  \
225     {                                                                   \
226         if( i_scale < 0 )                                               \
227         {                                                               \
228             /* Copy previous line, rewind if required */                \
229             p_pic_src = p_pic - i_width;                                \
230             p_pic += i_pic_eol;                                         \
231             LINE_COPY                                                   \
232             if( (CHROMA == 420) && !(i_y & 0x1) )                       \
233             {                                                           \
234                 p_u -= i_chroma_width;                                  \
235                 p_v -= i_chroma_width;                                  \
236             }                                                           \
237             else                                                        \
238             {                                                           \
239                 p_u += i_chroma_eol;                                    \
240                 p_v += i_chroma_eol;                                    \
241             }                                                           \
242         }                                                               \
243         else                                                            \
244         {                                                               \
245             /* Ignore next line */                                      \
246             p_y += i_eol + i_width;                                     \
247             p_u += i_chroma_eol;                                        \
248             p_v += i_chroma_eol;                                        \
249             i_y++;                                                      \
250         }                                                               \
251     }                                                                   \
252     else if( (CHROMA == 420) && !(i_y & 0x1) )                          \
253     {                                                                   \
254         p_u -= i_chroma_width;                                          \
255         p_v -= i_chroma_width;                                          \
256     }                                                                   \
257     else                                                                \
258     {                                                                   \
259         p_u += i_chroma_eol;                                            \
260         p_v += i_chroma_eol;                                            \
261     }                                                                   \
262                                                                         \
263     /* Skip until beginning of next line */                             \
264     p_pic += i_pic_eol;                                                 \
265     p_y   += i_eol;                                                     \
266 }
267
268
269 /*******************************************************************************
270  * vout_InitTables: allocate and initialize translations tables
271  *******************************************************************************
272  * This function will allocate memory to store translation tables, depending
273  * of the screen depth.
274  *******************************************************************************/
275 int vout_InitTables( vout_thread_t *p_vout )
276 {
277     size_t      tables_size;                          /* tables size, in bytes */
278     
279     /* Computes tables size */
280     switch( p_vout->i_screen_depth )
281     {
282     case 15:
283     case 16:
284         tables_size = sizeof( u16 ) * 1024 * (p_vout->b_grayscale ? 1 : 3);
285         break;        
286     case 24:        
287     case 32:
288 #ifndef DEBUG
289     default:        
290 #endif
291         tables_size = sizeof( u32 ) * 1024 * (p_vout->b_grayscale ? 1 : 3);        
292         break;        
293 #ifdef DEBUG
294     default:
295         intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
296         tables_size = 0;
297         break;        
298 #endif      
299     }
300     
301     /* Allocate memory */
302     p_vout->tables.p_base = malloc( tables_size );
303     if( p_vout->tables.p_base == NULL )
304     {
305         intf_ErrMsg("error: %s\n", strerror(ENOMEM));
306         return( 1 );                
307     }
308
309     /* Initialize tables */
310     SetTables( p_vout );    
311     return( 0 );    
312 }
313
314 /*******************************************************************************
315  * vout_ResetTables: re-initialize translations tables
316  *******************************************************************************
317  * This function will initialize the tables allocated by vout_CreateTables and
318  * set functions pointers.
319  *******************************************************************************/
320 int vout_ResetTables( vout_thread_t *p_vout )
321 {
322     // ?? realloc if b_grayscale or i_screen_depth changed
323     SetTables( p_vout );
324     return( 0 );    
325 }
326
327 /*******************************************************************************
328  * vout_EndTables: destroy translations tables
329  *******************************************************************************
330  * Free memory allocated by vout_CreateTables.
331  *******************************************************************************/
332 void vout_EndTables( vout_thread_t *p_vout )
333 {
334     free( p_vout->tables.p_base );
335 }
336
337 /* following functions are local */
338
339 /*******************************************************************************
340  * BinaryLog: computes the base 2 log of a binary value
341  *******************************************************************************
342  * This functions is used by MaskToShift during tables initialisation, to
343  * get a bit index from a binary value.
344  *******************************************************************************/
345 static int BinaryLog(u32 i)
346 {
347     int i_log;
348
349     i_log = 0;
350     if (i & 0xffff0000) 
351     {        
352         i_log = 16;
353     }    
354     if (i & 0xff00ff00) 
355     {        
356         i_log += 8;
357     }    
358     if (i & 0xf0f0f0f0) 
359     {        
360         i_log += 4;
361     }    
362     if (i & 0xcccccccc) 
363     {        
364         i_log += 2;
365     }    
366     if (i & 0xaaaaaaaa) 
367     {        
368         i_log++;
369     }    
370     if (i != ((u32)1 << i_log))
371     {        
372         intf_ErrMsg("internal error: binary log overflow\n");        
373     }    
374
375     return( i_log );
376 }
377
378 /*******************************************************************************
379  * MaskToShift: Transform a color mask into right and left shifts
380  *******************************************************************************
381  * This function is used during table initialisation. It can return a value
382  *******************************************************************************/
383 static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
384 {
385     u32 i_low, i_high;                   /* lower hand higher bits of the mask */
386
387     /* Get bits */
388     i_low =  i_mask & (- i_mask);                     /* lower bit of the mask */
389     i_high = i_mask + i_low;                         /* higher bit of the mask */
390
391     /* Transform bits into an index */
392     i_low =  BinaryLog (i_low);
393     i_high = BinaryLog (i_high);
394
395     /* Update pointers and return */
396     *pi_left =   i_low;
397     *pi_right = (8 - i_high + i_low);
398 }
399
400 /*******************************************************************************
401  * SetTables: compute tables and set function pointers
402  *******************************************************************************/
403 static void SetTables( vout_thread_t *p_vout )
404 {
405     u8          i_gamma[256];                                   /* gamma table */    
406     int         i_index;                                    /* index in tables */
407     int         i_red_right, i_red_left;                         /* red shifts */
408     int         i_green_right, i_green_left;                   /* green shifts */
409     int         i_blue_right, i_blue_left;                      /* blue shifts */
410
411     /*
412      * Build gamma table 
413      */     
414     for( i_index = 0; i_index < 256; i_index++ )
415     {
416         i_gamma[i_index] = 255. * exp( (double)i_index * p_vout->f_gamma / 255. );        
417     }
418
419     /*          
420      * Set color masks and shifts
421      */
422     switch( p_vout->i_screen_depth )
423     {
424     case 15:
425         MaskToShift( &i_red_right,   &i_red_left,   0xf800 );
426         MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
427         MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );        
428         break;        
429     case 16:
430         MaskToShift( &i_red_right,   &i_red_left,   0xf800 );
431         MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
432         MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );
433         break;        
434     case 24:
435     case 32:        
436         MaskToShift( &i_red_right,   &i_red_left,   0x00ff0000 );
437         MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
438         MaskToShift( &i_blue_right,  &i_blue_left,  0x000000ff );
439         break;
440 #ifdef DEBUG
441     default:
442         intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
443         break;        
444 #endif      
445     }
446
447     /*
448      * Set pointers and build YUV tables
449      */        
450     if( p_vout->b_grayscale )
451     {
452         /* Grayscale: build gray table */
453         switch( p_vout->i_screen_depth )
454         {
455         case 15:
456         case 16:         
457             p_vout->tables.yuv.gray16.p_gray =  (u16 *)p_vout->tables.p_base + 384;
458             for( i_index = -384; i_index < 640; i_index++) 
459             {
460                 p_vout->tables.yuv.gray16.p_gray[ i_index ] = 
461                     ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right)   << i_red_left)   |
462                     ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
463                     ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right)  << i_blue_left);                
464             }
465             break;        
466         case 24:
467         case 32:        
468             p_vout->tables.yuv.gray32.p_gray =  (u32 *)p_vout->tables.p_base + 384;
469             for( i_index = -384; i_index < 640; i_index++) 
470             {
471                 p_vout->tables.yuv.gray32.p_gray[ i_index ] = 
472                     ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right)   << i_red_left)   |
473                     ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
474                     ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right)  << i_blue_left);                
475             }        
476             break;        
477         }
478     }
479     else
480     {
481         /* Color: build red, green and blue tables */
482         switch( p_vout->i_screen_depth )
483         {
484         case 15:
485         case 16:            
486             p_vout->tables.yuv.rgb16.p_red =    (u16 *)p_vout->tables.p_base +          384;
487             p_vout->tables.yuv.rgb16.p_green =  (u16 *)p_vout->tables.p_base +   1024 + 384;
488             p_vout->tables.yuv.rgb16.p_blue =   (u16 *)p_vout->tables.p_base + 2*1024 + 384;
489             for( i_index = -384; i_index < 640; i_index++) 
490             {
491                 p_vout->tables.yuv.rgb16.p_red[i_index] =   (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
492                 p_vout->tables.yuv.rgb16.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
493                 p_vout->tables.yuv.rgb16.p_blue[i_index] =  (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
494             }
495             break;        
496         case 24:
497         case 32:
498             p_vout->tables.yuv.rgb32.p_red =    (u32 *)p_vout->tables.p_base +          384;
499             p_vout->tables.yuv.rgb32.p_green =  (u32 *)p_vout->tables.p_base +   1024 + 384;
500             p_vout->tables.yuv.rgb32.p_blue =   (u32 *)p_vout->tables.p_base + 2*1024 + 384;
501             for( i_index = -384; i_index < 640; i_index++) 
502             {
503                 p_vout->tables.yuv.rgb32.p_red[i_index] =   (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
504                 p_vout->tables.yuv.rgb32.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
505                 p_vout->tables.yuv.rgb32.p_blue[i_index] =  (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
506             }
507             break;        
508         }
509     }    
510     
511     /*
512      * Set functions pointers
513      */
514     if( p_vout->b_grayscale )
515     {
516         /* Grayscale */
517         switch( p_vout->i_screen_depth )
518         {
519         case 15:
520         case 16:  
521             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;        
522             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;        
523             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;        
524             p_vout->p_Scale =           (vout_scale_t *) Scale16;                    
525             break;        
526         case 24:
527             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;        
528             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;        
529             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;        
530             p_vout->p_Scale =           (vout_scale_t *) Scale24;
531             break;        
532         case 32:        
533             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;        
534             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;        
535             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;        
536             p_vout->p_Scale =           (vout_scale_t *) Scale32;                    
537             break;        
538         }        
539     }
540     else
541     {
542         /* Color */
543         switch( p_vout->i_screen_depth )
544         {
545         case 15:
546         case 16:  
547             p_vout->p_ConvertYUV420 =   (vout_convert_t *) ConvertYUV420RGB16;        
548             p_vout->p_ConvertYUV422 =   (vout_convert_t *) ConvertYUV422RGB16;        
549             p_vout->p_ConvertYUV444 =   (vout_convert_t *) ConvertYUV444RGB16;        
550             p_vout->p_Scale =           (vout_scale_t *)   Scale16;                    
551             break;        
552         case 24:
553             p_vout->p_ConvertYUV420 =   (vout_convert_t *) ConvertYUV420RGB24;        
554             p_vout->p_ConvertYUV422 =   (vout_convert_t *) ConvertYUV422RGB24;        
555             p_vout->p_ConvertYUV444 =   (vout_convert_t *) ConvertYUV444RGB24;        
556             p_vout->p_Scale =           (vout_scale_t *)   Scale24;                    
557             break;        
558         case 32:        
559             p_vout->p_ConvertYUV420 =   (vout_convert_t *) ConvertYUV420RGB32;        
560             p_vout->p_ConvertYUV422 =   (vout_convert_t *) ConvertYUV422RGB32;        
561             p_vout->p_ConvertYUV444 =   (vout_convert_t *) ConvertYUV444RGB32;        
562             p_vout->p_Scale =           (vout_scale_t *)   Scale32;                    
563             break;        
564         }
565     }        
566 }
567
568 /*******************************************************************************
569  * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
570  *******************************************************************************/
571 static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic,
572                              yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
573                              int i_width, int i_height, int i_eol, int i_pic_eol,
574                              int i_scale, int i_matrix_coefficients )
575 {
576     u16 *       p_pic_src;                   /* source pointer in case of copy */
577     u16 *       p_gray;                                          /* gray table */    
578     int         i_x, i_y;                               /* picture coordinates */
579     
580     p_gray = p_vout->tables.yuv.gray16.p_gray;
581     CONVERT_YUV_GRAY
582 }
583
584 /*******************************************************************************
585  * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
586  *******************************************************************************/
587 static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic,
588                              yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
589                              int i_width, int i_height, int i_eol, int i_pic_eol,
590                              int i_scale, int i_matrix_coefficients )
591 {
592     //??
593 }
594
595 /*******************************************************************************
596  * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
597  *******************************************************************************/
598 static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic,
599                              yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
600                              int i_width, int i_height, int i_eol, int i_pic_eol,
601                              int i_scale, int i_matrix_coefficients )
602 {
603     u32 *       p_pic_src;                   /* source pointer in case of copy */
604     u32 *       p_gray;                                          /* gray table */    
605     int         i_x, i_y;                               /* picture coordinates */
606     
607     p_gray = p_vout->tables.yuv.gray32.p_gray;
608     CONVERT_YUV_GRAY
609 }
610
611 /*******************************************************************************
612  * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
613  *******************************************************************************/
614 static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic,
615                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
616                                 int i_width, int i_height, int i_eol, int i_pic_eol,
617                                 int i_scale, int i_matrix_coefficients )
618 {
619 #ifdef HAVE_MMX
620     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
621
622     i_chroma_width =    i_width / 2;
623     i_chroma_eol =      i_eol / 2;
624     ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height, 
625                            (i_width + i_eol) * sizeof( yuv_data_t ), 
626                            (i_chroma_width + i_chroma_eol) * sizeof( yuv_data_t),
627                            i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
628                            p_vout->i_screen_depth == 15 );    
629 #else
630     u16 *       p_pic_src;                   /* source pointer in case of copy */
631     u16 *       p_red;                                            /* red table */
632     u16 *       p_green;                                        /* green table */
633     u16 *       p_blue;                                          /* blue table */
634     int         i_uval, i_yval, i_vval;                             /* samples */   
635     int         i_x, i_y;                               /* picture coordinates */
636     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
637     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
638
639     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
640     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
641     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
642     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
643     p_red   = p_vout->tables.yuv.rgb16.p_red;
644     p_green = p_vout->tables.yuv.rgb16.p_green;
645     p_blue  = p_vout->tables.yuv.rgb16.p_blue;
646     i_chroma_width =    i_width / 2;
647     i_chroma_eol =      i_eol / 2;
648     CONVERT_YUV_RGB( 420 )
649 #endif
650 }
651
652 /*******************************************************************************
653  * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
654  *******************************************************************************/
655 static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic,
656                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
657                                 int i_width, int i_height, int i_eol, int i_pic_eol,
658                                 int i_scale, int i_matrix_coefficients )
659 {
660     u16 *       p_pic_src;                   /* source pointer in case of copy */
661     u16 *       p_red;                                            /* red table */
662     u16 *       p_green;                                        /* green table */
663     u16 *       p_blue;                                          /* blue table */
664     int         i_uval, i_yval, i_vval;                             /* samples */   
665     int         i_x, i_y;                               /* picture coordinates */
666     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
667     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
668
669     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
670     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
671     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
672     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
673     p_red   = p_vout->tables.yuv.rgb16.p_red;
674     p_green = p_vout->tables.yuv.rgb16.p_green;
675     p_blue  = p_vout->tables.yuv.rgb16.p_blue;
676     i_chroma_width =    i_width / 2;
677     i_chroma_eol =      i_eol / 2;
678     CONVERT_YUV_RGB( 422 )
679 }
680
681 /*******************************************************************************
682  * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
683  *******************************************************************************/
684 static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic,
685                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
686                                 int i_width, int i_height, int i_eol, int i_pic_eol,
687                                 int i_scale, int i_matrix_coefficients )
688 {
689     u16 *       p_pic_src;                   /* source pointer in case of copy */
690     u16 *       p_red;                                            /* red table */
691     u16 *       p_green;                                        /* green table */
692     u16 *       p_blue;                                          /* blue table */
693     int         i_uval, i_yval, i_vval;                             /* samples */   
694     int         i_x, i_y;                               /* picture coordinates */
695     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
696     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
697
698     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
699     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
700     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
701     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
702     p_red   = p_vout->tables.yuv.rgb16.p_red;
703     p_green = p_vout->tables.yuv.rgb16.p_green;
704     p_blue  = p_vout->tables.yuv.rgb16.p_blue;
705     i_chroma_width =    i_width;
706     i_chroma_eol =      i_eol;
707     CONVERT_YUV_RGB( 444 )
708 }
709
710 /*******************************************************************************
711  * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
712  *******************************************************************************/
713 static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic,
714                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
715                                 int i_width, int i_height, int i_eol, int i_pic_eol,
716                                 int i_scale, int i_matrix_coefficients )
717 {
718     //???
719 }
720
721 /*******************************************************************************
722  * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
723  *******************************************************************************/
724 static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic,
725                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
726                                 int i_width, int i_height, int i_eol, int i_pic_eol,
727                                 int i_scale, int i_matrix_coefficients )
728 {
729     //???
730 }
731
732 /*******************************************************************************
733  * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
734  *******************************************************************************/
735 static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic,
736                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
737                                 int i_width, int i_height, int i_eol, int i_pic_eol,
738                                 int i_scale, int i_matrix_coefficients )
739 {    
740     //???
741 }
742
743 /*******************************************************************************
744  * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
745  *******************************************************************************/
746 static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic,
747                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
748                                 int i_width, int i_height, int i_eol, int i_pic_eol,
749                                 int i_scale, int i_matrix_coefficients )
750 {
751     u32 *       p_pic_src;                   /* source pointer in case of copy */
752     u32 *       p_red;                                            /* red table */
753     u32 *       p_green;                                        /* green table */
754     u32 *       p_blue;                                          /* blue table */
755     int         i_uval, i_yval, i_vval;                             /* samples */   
756     int         i_x, i_y;                               /* picture coordinates */
757     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
758     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
759
760     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
761     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
762     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
763     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
764     p_red   = p_vout->tables.yuv.rgb32.p_red;
765     p_green = p_vout->tables.yuv.rgb32.p_green;
766     p_blue  = p_vout->tables.yuv.rgb32.p_blue;
767     i_chroma_width =    i_width / 2;
768     i_chroma_eol =      i_eol / 2;
769     CONVERT_YUV_RGB( 420 )
770 }
771
772 /*******************************************************************************
773  * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
774  *******************************************************************************/
775 static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic,
776                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
777                                 int i_width, int i_height, int i_eol, int i_pic_eol,
778                                 int i_scale, int i_matrix_coefficients )
779 {
780     u32 *       p_pic_src;                   /* source pointer in case of copy */
781     u32 *       p_red;                                            /* red table */
782     u32 *       p_green;                                        /* green table */
783     u32 *       p_blue;                                          /* blue table */
784     int         i_uval, i_yval, i_vval;                             /* samples */   
785     int         i_x, i_y;                               /* picture coordinates */
786     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
787     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
788
789     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
790     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
791     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
792     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
793     p_red   = p_vout->tables.yuv.rgb32.p_red;
794     p_green = p_vout->tables.yuv.rgb32.p_green;
795     p_blue  = p_vout->tables.yuv.rgb32.p_blue;
796     i_chroma_width =    i_width / 2;
797     i_chroma_eol =      i_eol / 2;
798     CONVERT_YUV_RGB( 422 )
799 }
800
801 /*******************************************************************************
802  * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
803  *******************************************************************************/
804 static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic,
805                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
806                                 int i_width, int i_height, int i_eol, int i_pic_eol,
807                                 int i_scale, int i_matrix_coefficients )
808 {
809     u32 *       p_pic_src;                   /* source pointer in case of copy */
810     u32 *       p_red;                                            /* red table */
811     u32 *       p_green;                                        /* green table */
812     u32 *       p_blue;                                          /* blue table */
813     int         i_uval, i_yval, i_vval;                             /* samples */   
814     int         i_x, i_y;                               /* picture coordinates */
815     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
816     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
817
818     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
819     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
820     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
821     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
822     p_red   = p_vout->tables.yuv.rgb32.p_red;
823     p_green = p_vout->tables.yuv.rgb32.p_green;
824     p_blue  = p_vout->tables.yuv.rgb32.p_blue;
825     i_chroma_width =    i_width;
826     i_chroma_eol =      i_eol;
827     CONVERT_YUV_RGB( 444 )
828 }
829
830 /*******************************************************************************
831  * Scale16: 15 or 16 bpp picture scaling
832  *******************************************************************************/
833 static void Scale16( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
834                      int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
835 {
836     //???
837 }
838
839 /*******************************************************************************
840  * Scale24: 24 bpp picture scaling
841  *******************************************************************************/
842 static void Scale24( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
843                      int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
844 {
845     //???
846 }
847
848 /*******************************************************************************
849  * Scale32: 32 bpp picture scaling
850  *******************************************************************************/
851 static void Scale32( p_vout_thread_t p_vout, void *p_pic, void *p_buffer, 
852                      int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
853 {
854     //???
855 }
856
857 //-------------------- walken code follow --------------------------------
858
859 /*
860  * YUV to RGB routines.
861  *
862  * these routines calculate r, g and b values from each pixel's y, u and v.
863  * these r, g an b values are then passed thru a table lookup to take the
864  * gamma curve into account and find the corresponding pixel value.
865  *
866  * the table must store more than 3*256 values because of the possibility
867  * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
868  * values are in the following intervals :
869  * -176 to 255+176 for red
870  * -133 to 255+133 for green
871  * -222 to 255+222 for blue
872  *
873  * If the input y,u,v values are right, the r,g,b results are not expected
874  * to move out of the 0 to 255 interval but who knows what will happen in
875  * real use...
876  *
877  * the red, green and blue conversion tables are stored in a single 1935-entry
878  * array. The respective positions of each component in the array have been
879  * calculated to minimize the cache interactions of the 3 tables.
880  */
881
882 int rgbTable16 (short table [1935],
883                        int redMask, int greenMask, int blueMask,
884                        unsigned char gamma[256])
885 {
886     int redRight;
887     int redLeft;
888     int greenRight;
889     int greenLeft;
890     int blueRight;
891     int blueLeft;
892     short * redTable;
893     short * greenTable;
894     short * blueTable;
895     int i;
896     int y;
897
898     MaskToShift (&redRight, &redLeft, redMask);    
899     MaskToShift (&greenRight, &greenLeft, greenMask);    
900     MaskToShift (&blueRight, &blueLeft, blueMask);
901
902     /*
903      * green blue red +- 2 just to be sure
904      * green = 0-525 [151-370]
905      * blue = 594-1297 [834-1053] <834-29>
906      * red = 1323-1934 [1517-1736] <493-712>
907      */
908
909     redTable = table + 1501;
910     greenTable = table + 135;
911     blueTable = table + 818;
912
913     for (i = 0; i < 178; i++) {
914         redTable[i-178] = 0;
915         redTable[i+256] = redMask;
916     }
917     for (i = 0; i < 135; i++) {
918         greenTable[i-135] = 0;
919         greenTable[i+256] = greenMask;
920     }
921     for (i = 0; i < 224; i++) {
922         blueTable[i-224] = 0;
923         blueTable[i+256] = blueMask;
924     }
925
926     for (i = 0; i < 256; i++) {
927         y = gamma[i];
928         redTable[i] = ((y >> redRight) << redLeft);
929         greenTable[i] = ((y >> greenRight) << greenLeft);
930         blueTable[i] = ((y >> blueRight) << blueLeft);
931     }
932
933     return 0;
934 }
935
936 static int rgbTable32 (int table [1935],
937                        int redMask, int greenMask, int blueMask,
938                        unsigned char gamma[256])
939 {
940     int redRight;
941     int redLeft;
942     int greenRight;
943     int greenLeft;
944     int blueRight;
945     int blueLeft;
946     int * redTable;
947     int * greenTable;
948     int * blueTable;
949     int i;
950     int y;
951
952     MaskToShift (&redRight, &redLeft, redMask);
953     MaskToShift (&greenRight, &greenLeft, greenMask);
954     MaskToShift (&blueRight, &blueLeft, blueMask);
955     
956
957     /*
958      * green blue red +- 2 just to be sure
959      * green = 0-525 [151-370]
960      * blue = 594-1297 [834-1053] <834-29>
961      * red = 1323-1934 [1517-1736] <493-712>
962      */
963
964     redTable = table + 1501;
965     greenTable = table + 135;
966     blueTable = table + 818;
967
968     for (i = 0; i < 178; i++) {
969         redTable[i-178] = 0;
970         redTable[i+256] = redMask;
971     }
972     for (i = 0; i < 135; i++) {
973         greenTable[i-135] = 0;
974         greenTable[i+256] = greenMask;
975     }
976     for (i = 0; i < 224; i++) {
977         blueTable[i-224] = 0;
978         blueTable[i+256] = blueMask;
979     }
980
981     for (i = 0; i < 256; i++) {
982         y = gamma[i];
983         redTable[i] = ((y >> redRight) << redLeft);
984         greenTable[i] = ((y >> greenRight) << greenLeft);
985         blueTable[i] = ((y >> blueRight) << blueLeft);
986     }
987
988     return 0;
989 }
990
991 #define SHIFT 20
992 #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
993 #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
994 #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
995 #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
996
997  void yuvToRgb16 (unsigned char * Y,
998                         unsigned char * U, unsigned char * V,
999                         short * dest, short table[1935], int width)
1000 {
1001     int i;
1002     int u;
1003     int v;
1004     int uvRed;
1005     int uvGreen;
1006     int uvBlue;
1007     short * tableY;
1008
1009     i = width >> 4;
1010     while (i--) {
1011         u = *(U++);
1012         v = *(V++);
1013         uvRed = (V_RED_COEF*v) >> SHIFT;
1014         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1015         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1016
1017         tableY = table + *(Y++);
1018         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1019                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1020                             uvGreen] |
1021                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1022
1023         tableY = table + *(Y++);
1024         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1025                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1026                             uvGreen] |
1027                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1028
1029         u = *(U++);
1030         v = *(V++);
1031         uvRed = (V_RED_COEF*v) >> SHIFT;
1032         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1033         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1034
1035         tableY = table + *(Y++);
1036         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1037                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1038                             uvGreen] |
1039                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1040
1041         tableY = table + *(Y++);
1042         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1043                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1044                             uvGreen] |
1045                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1046
1047         u = *(U++);
1048         v = *(V++);
1049         uvRed = (V_RED_COEF*v) >> SHIFT;
1050         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1051         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1052
1053         tableY = table + *(Y++);
1054         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1055                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1056                             uvGreen] |
1057                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1058
1059         tableY = table + *(Y++);
1060         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1061                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1062                             uvGreen] |
1063                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1064
1065         u = *(U++);
1066         v = *(V++);
1067         uvRed = (V_RED_COEF*v) >> SHIFT;
1068         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1069         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1070
1071         tableY = table + *(Y++);
1072         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1073                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1074                             uvGreen] |
1075                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1076
1077         tableY = table + *(Y++);
1078         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1079                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1080                             uvGreen] |
1081                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1082
1083         u = *(U++);
1084         v = *(V++);
1085         uvRed = (V_RED_COEF*v) >> SHIFT;
1086         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1087         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1088
1089         tableY = table + *(Y++);
1090         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1091                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1092                             uvGreen] |
1093                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1094
1095         tableY = table + *(Y++);
1096         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1097                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1098                             uvGreen] |
1099                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1100
1101         u = *(U++);
1102         v = *(V++);
1103         uvRed = (V_RED_COEF*v) >> SHIFT;
1104         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1105         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1106
1107         tableY = table + *(Y++);
1108         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1109                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1110                             uvGreen] |
1111                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1112
1113         tableY = table + *(Y++);
1114         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1115                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1116                             uvGreen] |
1117                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1118
1119         u = *(U++);
1120         v = *(V++);
1121         uvRed = (V_RED_COEF*v) >> SHIFT;
1122         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1123         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1124
1125         tableY = table + *(Y++);
1126         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1127                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1128                             uvGreen] |
1129                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1130
1131         tableY = table + *(Y++);
1132         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1133                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1134                             uvGreen] |
1135                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1136
1137         u = *(U++);
1138         v = *(V++);
1139         uvRed = (V_RED_COEF*v) >> SHIFT;
1140         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1141         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1142
1143         tableY = table + *(Y++);
1144         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1145                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1146                             uvGreen] |
1147                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1148
1149         tableY = table + *(Y++);
1150         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1151                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1152                             uvGreen] |
1153                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1154     }
1155
1156     i = (width & 15) >> 1;
1157     while (i--) {
1158         u = *(U++);
1159         v = *(V++);
1160         uvRed = (V_RED_COEF*v) >> SHIFT;
1161         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1162         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1163
1164         tableY = table + *(Y++);
1165         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1166                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1167                             uvGreen] |
1168                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1169
1170         tableY = table + *(Y++);
1171         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1172                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1173                             uvGreen] |
1174                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1175     }
1176
1177     if (width & 1) {
1178         u = *(U++);
1179         v = *(V++);
1180         uvRed = (V_RED_COEF*v) >> SHIFT;
1181         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1182         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1183
1184         tableY = table + *(Y++);
1185         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1186                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1187                             uvGreen] |
1188                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1189     }
1190 }
1191
1192 static void yuvToRgb24 (unsigned char * Y,
1193                         unsigned char * U, unsigned char * V,
1194                         char * dest, int table[1935], int width)
1195 {
1196     int i;
1197     int u;
1198     int v;
1199     int uvRed;
1200     int uvGreen;
1201     int uvBlue;
1202     int * tableY;
1203     int tmp24;
1204
1205     i = width >> 3;
1206     while (i--) {
1207         u = *(U++);
1208         v = *(V++);
1209         uvRed = (V_RED_COEF*v) >> SHIFT;
1210         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1211         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1212
1213         tableY = table + *(Y++);
1214         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1215                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1216                         uvGreen] |
1217                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1218         *(dest++) = tmp24;
1219         *(dest++) = tmp24 >> 8;
1220         *(dest++) = tmp24 >> 16;
1221
1222         tableY = table + *(Y++);
1223         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1224                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1225                         uvGreen] |
1226                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1227         *(dest++) = tmp24;
1228         *(dest++) = tmp24 >> 8;
1229         *(dest++) = tmp24 >> 16;
1230
1231         u = *(U++);
1232         v = *(V++);
1233         uvRed = (V_RED_COEF*v) >> SHIFT;
1234         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1235         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1236
1237         tableY = table + *(Y++);
1238         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1239                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1240                         uvGreen] |
1241                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1242         *(dest++) = tmp24;
1243         *(dest++) = tmp24 >> 8;
1244         *(dest++) = tmp24 >> 16;
1245
1246         tableY = table + *(Y++);
1247         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1248                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1249                         uvGreen] |
1250                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1251         *(dest++) = tmp24;
1252         *(dest++) = tmp24 >> 8;
1253         *(dest++) = tmp24 >> 16;
1254
1255         u = *(U++);
1256         v = *(V++);
1257         uvRed = (V_RED_COEF*v) >> SHIFT;
1258         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1259         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1260
1261         tableY = table + *(Y++);
1262         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1263                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1264                         uvGreen] |
1265                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1266         *(dest++) = tmp24;
1267         *(dest++) = tmp24 >> 8;
1268         *(dest++) = tmp24 >> 16;
1269
1270         tableY = table + *(Y++);
1271         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1272                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1273                         uvGreen] |
1274                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1275         *(dest++) = tmp24;
1276         *(dest++) = tmp24 >> 8;
1277         *(dest++) = tmp24 >> 16;
1278
1279         u = *(U++);
1280         v = *(V++);
1281         uvRed = (V_RED_COEF*v) >> SHIFT;
1282         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1283         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1284
1285         tableY = table + *(Y++);
1286         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1287                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1288                         uvGreen] |
1289                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1290         *(dest++) = tmp24;
1291         *(dest++) = tmp24 >> 8;
1292         *(dest++) = tmp24 >> 16;
1293
1294         tableY = table + *(Y++);
1295         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1296                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1297                         uvGreen] |
1298                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1299         *(dest++) = tmp24;
1300         *(dest++) = tmp24 >> 8;
1301         *(dest++) = tmp24 >> 16;
1302     }
1303
1304     i = (width & 7) >> 1;
1305     while (i--) {
1306         u = *(U++);
1307         v = *(V++);
1308         uvRed = (V_RED_COEF*v) >> SHIFT;
1309         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1310         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1311
1312         tableY = table + *(Y++);
1313         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1314                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1315                         uvGreen] |
1316                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1317         *(dest++) = tmp24;
1318         *(dest++) = tmp24 >> 8;
1319         *(dest++) = tmp24 >> 16;
1320
1321         tableY = table + *(Y++);
1322         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1323                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1324                         uvGreen] |
1325                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1326         *(dest++) = tmp24;
1327         *(dest++) = tmp24 >> 8;
1328         *(dest++) = tmp24 >> 16;
1329     }
1330
1331     if (width & 1) {
1332         u = *(U++);
1333         v = *(V++);
1334         uvRed = (V_RED_COEF*v) >> SHIFT;
1335         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1336         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1337
1338         tableY = table + *(Y++);
1339         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1340                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1341                         uvGreen] |
1342                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1343         *(dest++) = tmp24;
1344         *(dest++) = tmp24 >> 8;
1345         *(dest++) = tmp24 >> 16;
1346     }
1347 }
1348
1349 static void yuvToRgb32 (unsigned char * Y,
1350                         unsigned char * U, unsigned char * V,
1351                         int * dest, int table[1935], int width)
1352 {
1353     int i;
1354     int u;
1355     int v;
1356     int uvRed;
1357     int uvGreen;
1358     int uvBlue;
1359     int * tableY;
1360
1361     i = width >> 4;
1362     while (i--) {
1363         u = *(U++);
1364         v = *(V++);
1365         uvRed = (V_RED_COEF*v) >> SHIFT;
1366         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1367         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1368
1369         tableY = table + *(Y++);
1370         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1371                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1372                             uvGreen] |
1373                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1374
1375         tableY = table + *(Y++);
1376         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1377                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1378                             uvGreen] |
1379                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1380
1381         u = *(U++);
1382         v = *(V++);
1383         uvRed = (V_RED_COEF*v) >> SHIFT;
1384         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1385         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1386
1387         tableY = table + *(Y++);
1388         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1389                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1390                             uvGreen] |
1391                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1392
1393         tableY = table + *(Y++);
1394         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1395                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1396                             uvGreen] |
1397                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1398
1399         u = *(U++);
1400         v = *(V++);
1401         uvRed = (V_RED_COEF*v) >> SHIFT;
1402         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1403         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1404
1405         tableY = table + *(Y++);
1406         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1407                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1408                             uvGreen] |
1409                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1410
1411         tableY = table + *(Y++);
1412         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1413                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1414                             uvGreen] |
1415                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1416
1417         u = *(U++);
1418         v = *(V++);
1419         uvRed = (V_RED_COEF*v) >> SHIFT;
1420         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1421         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1422
1423         tableY = table + *(Y++);
1424         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1425                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1426                             uvGreen] |
1427                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1428
1429         tableY = table + *(Y++);
1430         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1431                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1432                             uvGreen] |
1433                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1434
1435         u = *(U++);
1436         v = *(V++);
1437         uvRed = (V_RED_COEF*v) >> SHIFT;
1438         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1439         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1440
1441         tableY = table + *(Y++);
1442         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1443                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1444                             uvGreen] |
1445                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1446
1447         tableY = table + *(Y++);
1448         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1449                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1450                             uvGreen] |
1451                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1452
1453         u = *(U++);
1454         v = *(V++);
1455         uvRed = (V_RED_COEF*v) >> SHIFT;
1456         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1457         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1458
1459         tableY = table + *(Y++);
1460         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1461                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1462                             uvGreen] |
1463                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1464
1465         tableY = table + *(Y++);
1466         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1467                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1468                             uvGreen] |
1469                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1470
1471         u = *(U++);
1472         v = *(V++);
1473         uvRed = (V_RED_COEF*v) >> SHIFT;
1474         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1475         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1476
1477         tableY = table + *(Y++);
1478         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1479                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1480                             uvGreen] |
1481                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1482
1483         tableY = table + *(Y++);
1484         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1485                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1486                             uvGreen] |
1487                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1488
1489         u = *(U++);
1490         v = *(V++);
1491         uvRed = (V_RED_COEF*v) >> SHIFT;
1492         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1493         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1494
1495         tableY = table + *(Y++);
1496         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1497                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1498                             uvGreen] |
1499                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1500
1501         tableY = table + *(Y++);
1502         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1503                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1504                             uvGreen] |
1505                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1506     }
1507
1508     i = (width & 15) >> 1;
1509     while (i--) {
1510         u = *(U++);
1511         v = *(V++);
1512         uvRed = (V_RED_COEF*v) >> SHIFT;
1513         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1514         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1515
1516         tableY = table + *(Y++);
1517         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1518                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1519                             uvGreen] |
1520                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1521
1522         tableY = table + *(Y++);
1523         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1524                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1525                             uvGreen] |
1526                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1527     }
1528
1529     if (width & 1) {
1530         u = *(U++);
1531         v = *(V++);
1532         uvRed = (V_RED_COEF*v) >> SHIFT;
1533         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1534         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1535
1536         tableY = table + *(Y++);
1537         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1538                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1539                             uvGreen] |
1540                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1541     }
1542 }
1543
1544 /* API routines */
1545