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