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