]> git.sesse.net Git - vlc/blob - src/video_output/video_yuv.c
Ajout de fonctions yuv permettant un scaling 'exotique' en fin du
[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
76 /*******************************************************************************
77  * CLIP_BYTE macro: boundary detection
78  *******************************************************************************
79  * Return parameter if between 0 and 255, else return nearest boundary (0 or 
80  * 255). This macro is used to build translations tables.
81  *******************************************************************************/
82 #define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
83
84 /*******************************************************************************
85  * LINE_COPY macro: memcopy using 16 pixels blocks
86  *******************************************************************************
87  * Variables:
88  *      p_pic                   destination pointer
89  *      p_pic_src               source pointer
90  *      i_width                 width
91  *      i_x                     index
92  *******************************************************************************/
93 #define LINE_COPY                                                       \
94 for( i_x = 0; i_x < i_width; i_x+=16 )                                  \
95 {                                                                       \
96     *p_pic++ = *p_pic_src++;                                            \
97     *p_pic++ = *p_pic_src++;                                            \
98     *p_pic++ = *p_pic_src++;                                            \
99     *p_pic++ = *p_pic_src++;                                            \
100     *p_pic++ = *p_pic_src++;                                            \
101     *p_pic++ = *p_pic_src++;                                            \
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 }
113
114 /*******************************************************************************
115  * CONVERT_YUV_GRAY macro: grayscale YUV convertion
116  *******************************************************************************
117  * Variables:
118  *      ...see vout_convert_t
119  *      i_x, i_y                coordinates
120  *      i_pic_copy              same type as p_pic
121  *      p_gray                  gray translation table
122  *******************************************************************************/
123 #define CONVERT_YUV_GRAY                                                \
124 for (i_y = 0; i_y < i_height ; i_y++)                                   \
125 {                                                                       \
126     for (i_x = 0; i_x < i_width; i_x += 16)                             \
127     {                                                                   \
128         /* Convert 16 pixels (width is always multiple of 16 */         \
129         *p_pic++ = p_gray[ *p_y++ ];                                    \
130         *p_pic++ = p_gray[ *p_y++ ];                                    \
131         *p_pic++ = p_gray[ *p_y++ ];                                    \
132         *p_pic++ = p_gray[ *p_y++ ];                                    \
133         *p_pic++ = p_gray[ *p_y++ ];                                    \
134         *p_pic++ = p_gray[ *p_y++ ];                                    \
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     }                                                                   \
146                                                                         \
147     /* Handle scale factor */                                           \
148     if( i_scale && ! (i_y % i_scale) )                                  \
149     {                                                                   \
150         if( i_scale < 0 )                                               \
151         {                                                               \
152             /* Copy previous line */                                    \
153             p_pic_src = p_pic - i_width;                                \
154             p_pic += i_pic_eol;                                         \
155             LINE_COPY                                                   \
156         }                                                               \
157         else                                                            \
158         {                                                               \
159             /* Ignore next line */                                      \
160             p_y += i_eol + i_width;                                     \
161             i_y++;                                                      \
162         }                                                               \
163     }                                                                   \
164                                                                         \
165     /* Skip until beginning of next line */                             \
166     p_pic += i_pic_eol;                                                 \
167     p_y   += i_eol;                                                     \
168 }
169
170 /*******************************************************************************
171  * CONVERT_YUV_RGB: color YUV convertion
172  *******************************************************************************
173  * Parameters
174  *      CHROMA                          420, 422 or 444
175  * Variables:
176  *      ...see vout_convert_t
177  *      i_x, i_y                        coordinates
178  *      i_uval, i_yval, i_vval          samples
179  *      p_pic_src                       same type as p_pic
180  *      i_chroma_width                  chroma width
181  *      i_chroma_eol                    chroma eol
182  *      p_red                           red translation table
183  *      p_green                         green translation table
184  *      p_blue                          blue translation table
185  *      i_crv, i_cgu, i_cgv, i_cbu      matrix coefficients
186  *******************************************************************************/
187 #define CONVERT_YUV_RGB( CHROMA )                                       \
188 for (i_y = 0; i_y < i_height ; i_y++)                                   \
189 {                                                                       \
190     for (i_x = 0; i_x < i_width; i_x += 2 )                             \
191     {                                                                   \
192         /* First sample (complete) */                                   \
193         i_yval = 76309 * *p_y++ - 1188177;                              \
194         i_uval = *p_u++ - 128;                                          \
195         i_vval = *p_v++ - 128;                                          \
196         *p_pic++ =                                                      \
197             p_red  [(i_yval+i_crv*i_vval)                >>16] |        \
198             p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval)   >>16] |        \
199             p_blue [(i_yval+i_cbu*i_uval)                >>16];         \
200         i_yval = 76309 * *p_y++ - 1188177;                              \
201         /* Second sample (partial) */                                   \
202         if( CHROMA == 444 )                                             \
203         {                                                               \
204             i_uval = *p_u++ - 128;                                      \
205             i_vval = *p_v++ - 128;                                      \
206         }                                                               \
207         *p_pic++ =                                                      \
208             p_red  [(i_yval+i_crv*i_vval)                >>16] |        \
209             p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval)   >>16] |        \
210             p_blue [(i_yval+i_cbu*i_uval)                >>16];         \
211     }                                                                   \
212                                                                         \
213     /* Handle scale factor and rewind in 4:2:0 */                       \
214     if( i_scale && ! (i_y % i_scale) )                                  \
215     {                                                                   \
216         if( i_scale < 0 )                                               \
217         {                                                               \
218             /* Copy previous line, rewind if required */                \
219             p_pic_src = p_pic - i_width;                                \
220             p_pic += i_pic_eol;                                         \
221             LINE_COPY                                                   \
222             if( (CHROMA == 420) && !(i_y & 0x1) )                       \
223             {                                                           \
224                 p_u -= i_chroma_width;                                  \
225                 p_v -= i_chroma_width;                                  \
226             }                                                           \
227             else                                                        \
228             {                                                           \
229                 p_u += i_chroma_eol;                                    \
230                 p_v += i_chroma_eol;                                    \
231             }                                                           \
232         }                                                               \
233         else                                                            \
234         {                                                               \
235             /* Ignore next line */                                      \
236             p_y += i_eol + i_width;                                     \
237             p_u += i_chroma_eol;                                        \
238             p_v += i_chroma_eol;                                        \
239             i_y++;                                                      \
240         }                                                               \
241     }                                                                   \
242     else if( (CHROMA == 420) && !(i_y & 0x1) )                          \
243     {                                                                   \
244         p_u -= i_chroma_width;                                          \
245         p_v -= i_chroma_width;                                          \
246     }                                                                   \
247     else                                                                \
248     {                                                                   \
249         p_u += i_chroma_eol;                                            \
250         p_v += i_chroma_eol;                                            \
251     }                                                                   \
252                                                                         \
253     /* Skip until beginning of next line */                             \
254     p_pic += i_pic_eol;                                                 \
255     p_y   += i_eol;                                                     \
256 }
257
258
259 /*******************************************************************************
260  * vout_InitTables: allocate and initialize translations tables
261  *******************************************************************************
262  * This function will allocate memory to store translation tables, depending
263  * of the screen depth.
264  *******************************************************************************/
265 int vout_InitTables( vout_thread_t *p_vout )
266 {
267     size_t      tables_size;                          /* tables size, in bytes */
268     
269     /* Computes tables size */
270     switch( p_vout->i_screen_depth )
271     {
272     case 15:
273     case 16:
274         tables_size = sizeof( u16 ) * 1024 * (p_vout->b_grayscale ? 1 : 3);
275         break;        
276     case 24:        
277     case 32:
278 #ifndef DEBUG
279     default:        
280 #endif
281         tables_size = sizeof( u32 ) * 1024 * (p_vout->b_grayscale ? 1 : 3);        
282         break;        
283 #ifdef DEBUG
284     default:
285         intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
286         tables_size = 0;
287         break;        
288 #endif      
289     }
290     
291     /* Allocate memory */
292     p_vout->tables.p_base = malloc( tables_size );
293     if( p_vout->tables.p_base == NULL )
294     {
295         intf_ErrMsg("error: %s\n", strerror(ENOMEM));
296         return( 1 );                
297     }
298
299     /* Initialize tables */
300     SetTables( p_vout );    
301     return( 0 );    
302 }
303
304 /*******************************************************************************
305  * vout_ResetTables: re-initialize translations tables
306  *******************************************************************************
307  * This function will initialize the tables allocated by vout_CreateTables and
308  * set functions pointers.
309  *******************************************************************************/
310 int vout_ResetTables( vout_thread_t *p_vout )
311 {
312     vout_EndTables( p_vout );    
313     return( vout_InitTables( p_vout ) );    
314 }
315
316 /*******************************************************************************
317  * vout_EndTables: destroy translations tables
318  *******************************************************************************
319  * Free memory allocated by vout_CreateTables.
320  *******************************************************************************/
321 void vout_EndTables( vout_thread_t *p_vout )
322 {
323     free( p_vout->tables.p_base );
324 }
325
326 /* following functions are local */
327
328 /*******************************************************************************
329  * BinaryLog: computes the base 2 log of a binary value
330  *******************************************************************************
331  * This functions is used by MaskToShift during tables initialisation, to
332  * get a bit index from a binary value.
333  *******************************************************************************/
334 static int BinaryLog(u32 i)
335 {
336     int i_log;
337
338     i_log = 0;
339     if (i & 0xffff0000) 
340     {        
341         i_log = 16;
342     }    
343     if (i & 0xff00ff00) 
344     {        
345         i_log += 8;
346     }    
347     if (i & 0xf0f0f0f0) 
348     {        
349         i_log += 4;
350     }    
351     if (i & 0xcccccccc) 
352     {        
353         i_log += 2;
354     }    
355     if (i & 0xaaaaaaaa) 
356     {        
357         i_log++;
358     }    
359     if (i != ((u32)1 << i_log))
360     {        
361         intf_ErrMsg("internal error: binary log overflow\n");        
362     }    
363
364     return( i_log );
365 }
366
367 /*******************************************************************************
368  * MaskToShift: Transform a color mask into right and left shifts
369  *******************************************************************************
370  * This function is used during table initialisation. It can return a value
371  *******************************************************************************/
372 static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
373 {
374     u32 i_low, i_high;                   /* lower hand higher bits of the mask */
375
376     /* Get bits */
377     i_low =  i_mask & (- i_mask);                     /* lower bit of the mask */
378     i_high = i_mask + i_low;                         /* higher bit of the mask */
379
380     /* Transform bits into an index */
381     i_low =  BinaryLog (i_low);
382     i_high = BinaryLog (i_high);
383
384     /* Update pointers and return */
385     *pi_left =   i_low;
386     *pi_right = (8 - i_high + i_low);
387 }
388
389 /*******************************************************************************
390  * SetTables: compute tables and set function pointers
391  *******************************************************************************/
392 static void SetTables( vout_thread_t *p_vout )
393 {
394     u8          i_gamma[256];                                   /* gamma table */    
395     int         i_index;                                    /* index in tables */
396     int         i_red_right, i_red_left;                         /* red shifts */
397     int         i_green_right, i_green_left;                   /* green shifts */
398     int         i_blue_right, i_blue_left;                      /* blue shifts */
399
400     /*
401      * Build gamma table 
402      */     
403     for( i_index = 0; i_index < 256; i_index++ )
404     {
405         i_gamma[i_index] = 255. * pow( (double)i_index / 255., exp(p_vout->f_gamma) );        
406     }
407
408     /*          
409      * Set color masks and shifts
410      */
411     switch( p_vout->i_screen_depth )
412     {
413     case 15:
414         MaskToShift( &i_red_right,   &i_red_left,   0x7c00 );
415         MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
416         MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );        
417         break;        
418     case 16:
419         MaskToShift( &i_red_right,   &i_red_left,   0xf800 );
420         MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
421         MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );
422         break;        
423     case 24:
424     case 32:        
425         MaskToShift( &i_red_right,   &i_red_left,   0x00ff0000 );
426         MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
427         MaskToShift( &i_blue_right,  &i_blue_left,  0x000000ff );
428         break;
429 #ifdef DEBUG
430     default:
431         intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
432         break;        
433 #endif      
434     }
435
436     /*
437      * Set pointers and build YUV tables
438      */        
439     if( p_vout->b_grayscale )
440     {
441         /* Grayscale: build gray table */
442         switch( p_vout->i_screen_depth )
443         {
444         case 15:
445         case 16:         
446             p_vout->tables.yuv.gray16.p_gray =  (u16 *)p_vout->tables.p_base + 384;
447             for( i_index = -384; i_index < 640; i_index++) 
448             {
449                 p_vout->tables.yuv.gray16.p_gray[ i_index ] = 
450                     ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right)   << i_red_left)   |
451                     ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
452                     ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right)  << i_blue_left);                
453             }
454             break;        
455         case 24:
456         case 32:        
457             p_vout->tables.yuv.gray32.p_gray =  (u32 *)p_vout->tables.p_base + 384;
458             for( i_index = -384; i_index < 640; i_index++) 
459             {
460                 p_vout->tables.yuv.gray32.p_gray[ i_index ] = 
461                     ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right)   << i_red_left)   |
462                     ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
463                     ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right)  << i_blue_left);                
464             }        
465             break;        
466         }
467     }
468     else
469     {
470         /* Color: build red, green and blue tables */
471         switch( p_vout->i_screen_depth )
472         {
473         case 15:
474         case 16:            
475             p_vout->tables.yuv.rgb16.p_red =    (u16 *)p_vout->tables.p_base +          384;
476             p_vout->tables.yuv.rgb16.p_green =  (u16 *)p_vout->tables.p_base +   1024 + 384;
477             p_vout->tables.yuv.rgb16.p_blue =   (u16 *)p_vout->tables.p_base + 2*1024 + 384;
478             for( i_index = -384; i_index < 640; i_index++) 
479             {
480                 p_vout->tables.yuv.rgb16.p_red[i_index] =   (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
481                 p_vout->tables.yuv.rgb16.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
482                 p_vout->tables.yuv.rgb16.p_blue[i_index] =  (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
483             }
484             break;        
485         case 24:
486         case 32:
487             p_vout->tables.yuv.rgb32.p_red =    (u32 *)p_vout->tables.p_base +          384;
488             p_vout->tables.yuv.rgb32.p_green =  (u32 *)p_vout->tables.p_base +   1024 + 384;
489             p_vout->tables.yuv.rgb32.p_blue =   (u32 *)p_vout->tables.p_base + 2*1024 + 384;
490             for( i_index = -384; i_index < 640; i_index++) 
491             {
492                 p_vout->tables.yuv.rgb32.p_red[i_index] =   (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
493                 p_vout->tables.yuv.rgb32.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
494                 p_vout->tables.yuv.rgb32.p_blue[i_index] =  (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
495             }
496             break;        
497         }
498     }    
499     
500     /*
501      * Set functions pointers
502      */
503     if( p_vout->b_grayscale )
504     {
505         /* Grayscale */
506         switch( p_vout->i_screen_depth )
507         {
508         case 15:
509         case 16:  
510             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;        
511             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;        
512             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;        
513             break;        
514         case 24:
515             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;        
516             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;        
517             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;        
518             break;        
519         case 32:        
520             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;        
521             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;        
522             p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;        
523             break;        
524         }        
525     }
526     else
527     {
528         /* Color */
529         switch( p_vout->i_screen_depth )
530         {
531         case 15:
532         case 16:  
533             p_vout->p_ConvertYUV420 =   (vout_convert_t *) ConvertYUV420RGB16;        
534             p_vout->p_ConvertYUV422 =   (vout_convert_t *) ConvertYUV422RGB16;        
535             p_vout->p_ConvertYUV444 =   (vout_convert_t *) ConvertYUV444RGB16;        
536             break;        
537         case 24:
538             p_vout->p_ConvertYUV420 =   (vout_convert_t *) ConvertYUV420RGB24;        
539             p_vout->p_ConvertYUV422 =   (vout_convert_t *) ConvertYUV422RGB24;        
540             p_vout->p_ConvertYUV444 =   (vout_convert_t *) ConvertYUV444RGB24;        
541             break;        
542         case 32:        
543             p_vout->p_ConvertYUV420 =   (vout_convert_t *) ConvertYUV420RGB32;        
544             p_vout->p_ConvertYUV422 =   (vout_convert_t *) ConvertYUV422RGB32;        
545             p_vout->p_ConvertYUV444 =   (vout_convert_t *) ConvertYUV444RGB32;        
546             break;        
547         }
548     }        
549 }
550
551 /*******************************************************************************
552  * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
553  *******************************************************************************/
554 static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic,
555                              yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
556                              int i_width, int i_height, int i_eol, int i_pic_eol,
557                              int i_scale, int i_matrix_coefficients )
558 {
559     u16 *       p_pic_src;                   /* source pointer in case of copy */
560     u16 *       p_gray;                                          /* gray table */    
561     int         i_x, i_y;                               /* picture coordinates */
562     
563     p_gray = p_vout->tables.yuv.gray16.p_gray;
564     CONVERT_YUV_GRAY
565 }
566
567 /*******************************************************************************
568  * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
569  *******************************************************************************/
570 static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic,
571                              yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
572                              int i_width, int i_height, int i_eol, int i_pic_eol,
573                              int i_scale, int i_matrix_coefficients )
574 {
575     //??
576 }
577
578 /*******************************************************************************
579  * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
580  *******************************************************************************/
581 static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic,
582                              yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
583                              int i_width, int i_height, int i_eol, int i_pic_eol,
584                              int i_scale, int i_matrix_coefficients )
585 {
586     u32 *       p_pic_src;                   /* source pointer in case of copy */
587     u32 *       p_gray;                                          /* gray table */    
588     int         i_x, i_y;                               /* picture coordinates */
589     
590     p_gray = p_vout->tables.yuv.gray32.p_gray;
591     CONVERT_YUV_GRAY
592 }
593
594 /*******************************************************************************
595  * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
596  *******************************************************************************/
597 static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic,
598                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
599                                 int i_width, int i_height, int i_eol, int i_pic_eol,
600                                 int i_scale, int i_matrix_coefficients )
601 {
602 #ifdef HAVE_MMX
603     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
604
605     i_chroma_width =    i_width / 2;
606     i_chroma_eol =      i_eol / 2;
607     ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height, 
608                            (i_width + i_eol) * sizeof( yuv_data_t ), 
609                            (i_chroma_width + i_chroma_eol) * sizeof( yuv_data_t),
610                            i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
611                            p_vout->i_screen_depth == 15 );    
612 #else
613     u16 *       p_pic_src;                   /* source pointer in case of copy */
614     u16 *       p_red;                                            /* red table */
615     u16 *       p_green;                                        /* green table */
616     u16 *       p_blue;                                          /* blue table */
617     int         i_uval, i_yval, i_vval;                             /* samples */   
618     int         i_x, i_y;                               /* picture coordinates */
619     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
620     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
621
622     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
623     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
624     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
625     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
626     p_red   = p_vout->tables.yuv.rgb16.p_red;
627     p_green = p_vout->tables.yuv.rgb16.p_green;
628     p_blue  = p_vout->tables.yuv.rgb16.p_blue;
629     i_chroma_width =    i_width / 2;
630     i_chroma_eol =      i_eol / 2;
631     CONVERT_YUV_RGB( 420 )
632 #endif
633 }
634
635 /*******************************************************************************
636  * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
637  *******************************************************************************/
638 static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic,
639                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
640                                 int i_width, int i_height, int i_eol, int i_pic_eol,
641                                 int i_scale, int i_matrix_coefficients )
642 {
643     u16 *       p_pic_src;                   /* source pointer in case of copy */
644     u16 *       p_red;                                            /* red table */
645     u16 *       p_green;                                        /* green table */
646     u16 *       p_blue;                                          /* blue table */
647     int         i_uval, i_yval, i_vval;                             /* samples */   
648     int         i_x, i_y;                               /* picture coordinates */
649     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
650     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
651
652     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
653     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
654     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
655     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
656     p_red   = p_vout->tables.yuv.rgb16.p_red;
657     p_green = p_vout->tables.yuv.rgb16.p_green;
658     p_blue  = p_vout->tables.yuv.rgb16.p_blue;
659     i_chroma_width =    i_width / 2;
660     i_chroma_eol =      i_eol / 2;
661     CONVERT_YUV_RGB( 422 )
662 }
663
664 /*******************************************************************************
665  * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
666  *******************************************************************************/
667 static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic,
668                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
669                                 int i_width, int i_height, int i_eol, int i_pic_eol,
670                                 int i_scale, int i_matrix_coefficients )
671 {
672     u16 *       p_pic_src;                   /* source pointer in case of copy */
673     u16 *       p_red;                                            /* red table */
674     u16 *       p_green;                                        /* green table */
675     u16 *       p_blue;                                          /* blue table */
676     int         i_uval, i_yval, i_vval;                             /* samples */   
677     int         i_x, i_y;                               /* picture coordinates */
678     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
679     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
680
681     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
682     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
683     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
684     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
685     p_red   = p_vout->tables.yuv.rgb16.p_red;
686     p_green = p_vout->tables.yuv.rgb16.p_green;
687     p_blue  = p_vout->tables.yuv.rgb16.p_blue;
688     i_chroma_width =    i_width;
689     i_chroma_eol =      i_eol;
690     CONVERT_YUV_RGB( 444 )
691 }
692
693 /*******************************************************************************
694  * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
695  *******************************************************************************/
696 static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic,
697                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
698                                 int i_width, int i_height, int i_eol, int i_pic_eol,
699                                 int i_scale, int i_matrix_coefficients )
700 {
701     //???
702 }
703
704 /*******************************************************************************
705  * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
706  *******************************************************************************/
707 static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic,
708                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
709                                 int i_width, int i_height, int i_eol, int i_pic_eol,
710                                 int i_scale, int i_matrix_coefficients )
711 {
712     //???
713 }
714
715 /*******************************************************************************
716  * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
717  *******************************************************************************/
718 static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic,
719                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
720                                 int i_width, int i_height, int i_eol, int i_pic_eol,
721                                 int i_scale, int i_matrix_coefficients )
722 {    
723     //???
724 }
725
726 /*******************************************************************************
727  * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
728  *******************************************************************************/
729 static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic,
730                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
731                                 int i_width, int i_height, int i_eol, int i_pic_eol,
732                                 int i_scale, int i_matrix_coefficients )
733 {
734     u32 *       p_pic_src;                   /* source pointer in case of copy */
735     u32 *       p_red;                                            /* red table */
736     u32 *       p_green;                                        /* green table */
737     u32 *       p_blue;                                          /* blue table */
738     int         i_uval, i_yval, i_vval;                             /* samples */   
739     int         i_x, i_y;                               /* picture coordinates */
740     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
741     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
742
743     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
744     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
745     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
746     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
747     p_red   = p_vout->tables.yuv.rgb32.p_red;
748     p_green = p_vout->tables.yuv.rgb32.p_green;
749     p_blue  = p_vout->tables.yuv.rgb32.p_blue;
750     i_chroma_width =    i_width / 2;
751     i_chroma_eol =      i_eol / 2;
752     CONVERT_YUV_RGB( 420 )
753 }
754
755 /*******************************************************************************
756  * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
757  *******************************************************************************/
758 static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic,
759                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
760                                 int i_width, int i_height, int i_eol, int i_pic_eol,
761                                 int i_scale, int i_matrix_coefficients )
762 {
763     u32 *       p_pic_src;                   /* source pointer in case of copy */
764     u32 *       p_red;                                            /* red table */
765     u32 *       p_green;                                        /* green table */
766     u32 *       p_blue;                                          /* blue table */
767     int         i_uval, i_yval, i_vval;                             /* samples */   
768     int         i_x, i_y;                               /* picture coordinates */
769     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
770     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
771
772     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
773     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
774     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
775     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
776     p_red   = p_vout->tables.yuv.rgb32.p_red;
777     p_green = p_vout->tables.yuv.rgb32.p_green;
778     p_blue  = p_vout->tables.yuv.rgb32.p_blue;
779     i_chroma_width =    i_width / 2;
780     i_chroma_eol =      i_eol / 2;
781     CONVERT_YUV_RGB( 422 )
782 }
783
784 /*******************************************************************************
785  * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
786  *******************************************************************************/
787 static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic,
788                                 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
789                                 int i_width, int i_height, int i_eol, int i_pic_eol,
790                                 int i_scale, int i_matrix_coefficients )
791 {
792     u32 *       p_pic_src;                   /* source pointer in case of copy */
793     u32 *       p_red;                                            /* red table */
794     u32 *       p_green;                                        /* green table */
795     u32 *       p_blue;                                          /* blue table */
796     int         i_uval, i_yval, i_vval;                             /* samples */   
797     int         i_x, i_y;                               /* picture coordinates */
798     int         i_chroma_width, i_chroma_eol;      /* width and eol for chroma */
799     int         i_crv, i_cbu, i_cgu, i_cgv;     /* transformation coefficients */
800
801     i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
802     i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
803     i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
804     i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
805     p_red   = p_vout->tables.yuv.rgb32.p_red;
806     p_green = p_vout->tables.yuv.rgb32.p_green;
807     p_blue  = p_vout->tables.yuv.rgb32.p_blue;
808     i_chroma_width =    i_width;
809     i_chroma_eol =      i_eol;
810     CONVERT_YUV_RGB( 444 )
811 }
812
813 //-------------------- walken code follow ---------------------------------------
814
815 /*
816  * YUV to RGB routines.
817  *
818  * these routines calculate r, g and b values from each pixel's y, u and v.
819  * these r, g an b values are then passed thru a table lookup to take the
820  * gamma curve into account and find the corresponding pixel value.
821  *
822  * the table must store more than 3*256 values because of the possibility
823  * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
824  * values are in the following intervals :
825  * -176 to 255+176 for red
826  * -133 to 255+133 for green
827  * -222 to 255+222 for blue
828  *
829  * If the input y,u,v values are right, the r,g,b results are not expected
830  * to move out of the 0 to 255 interval but who knows what will happen in
831  * real use...
832  *
833  * the red, green and blue conversion tables are stored in a single 1935-entry
834  * array. The respective positions of each component in the array have been
835  * calculated to minimize the cache interactions of the 3 tables.
836  */
837
838 int rgbTable16 (short table [1935],
839                        int redMask, int greenMask, int blueMask,
840                        unsigned char gamma[256])
841 {
842     int redRight;
843     int redLeft;
844     int greenRight;
845     int greenLeft;
846     int blueRight;
847     int blueLeft;
848     short * redTable;
849     short * greenTable;
850     short * blueTable;
851     int i;
852     int y;
853
854     MaskToShift (&redRight, &redLeft, redMask);    
855     MaskToShift (&greenRight, &greenLeft, greenMask);    
856     MaskToShift (&blueRight, &blueLeft, blueMask);
857
858     /*
859      * green blue red +- 2 just to be sure
860      * green = 0-525 [151-370]
861      * blue = 594-1297 [834-1053] <834-29>
862      * red = 1323-1934 [1517-1736] <493-712>
863      */
864
865     redTable = table + 1501;
866     greenTable = table + 135;
867     blueTable = table + 818;
868
869     for (i = 0; i < 178; i++) {
870         redTable[i-178] = 0;
871         redTable[i+256] = redMask;
872     }
873     for (i = 0; i < 135; i++) {
874         greenTable[i-135] = 0;
875         greenTable[i+256] = greenMask;
876     }
877     for (i = 0; i < 224; i++) {
878         blueTable[i-224] = 0;
879         blueTable[i+256] = blueMask;
880     }
881
882     for (i = 0; i < 256; i++) {
883         y = gamma[i];
884         redTable[i] = ((y >> redRight) << redLeft);
885         greenTable[i] = ((y >> greenRight) << greenLeft);
886         blueTable[i] = ((y >> blueRight) << blueLeft);
887     }
888
889     return 0;
890 }
891
892 static int rgbTable32 (int table [1935],
893                        int redMask, int greenMask, int blueMask,
894                        unsigned char gamma[256])
895 {
896     int redRight;
897     int redLeft;
898     int greenRight;
899     int greenLeft;
900     int blueRight;
901     int blueLeft;
902     int * redTable;
903     int * greenTable;
904     int * blueTable;
905     int i;
906     int y;
907
908     MaskToShift (&redRight, &redLeft, redMask);
909     MaskToShift (&greenRight, &greenLeft, greenMask);
910     MaskToShift (&blueRight, &blueLeft, blueMask);
911     
912
913     /*
914      * green blue red +- 2 just to be sure
915      * green = 0-525 [151-370]
916      * blue = 594-1297 [834-1053] <834-29>
917      * red = 1323-1934 [1517-1736] <493-712>
918      */
919
920     redTable = table + 1501;
921     greenTable = table + 135;
922     blueTable = table + 818;
923
924     for (i = 0; i < 178; i++) {
925         redTable[i-178] = 0;
926         redTable[i+256] = redMask;
927     }
928     for (i = 0; i < 135; i++) {
929         greenTable[i-135] = 0;
930         greenTable[i+256] = greenMask;
931     }
932     for (i = 0; i < 224; i++) {
933         blueTable[i-224] = 0;
934         blueTable[i+256] = blueMask;
935     }
936
937     for (i = 0; i < 256; i++) {
938         y = gamma[i];
939         redTable[i] = ((y >> redRight) << redLeft);
940         greenTable[i] = ((y >> greenRight) << greenLeft);
941         blueTable[i] = ((y >> blueRight) << blueLeft);
942     }
943
944     return 0;
945 }
946
947 #define SHIFT 20
948 #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
949 #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
950 #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
951 #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
952
953  void yuvToRgb16 (unsigned char * Y,
954                         unsigned char * U, unsigned char * V,
955                         short * dest, short table[1935], int width)
956 {
957     int i;
958     int u;
959     int v;
960     int uvRed;
961     int uvGreen;
962     int uvBlue;
963     short * tableY;
964
965     i = width >> 4;
966     while (i--) {
967         u = *(U++);
968         v = *(V++);
969         uvRed = (V_RED_COEF*v) >> SHIFT;
970         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
971         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
972
973         tableY = table + *(Y++);
974         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
975                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
976                             uvGreen] |
977                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
978
979         tableY = table + *(Y++);
980         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
981                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
982                             uvGreen] |
983                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
984
985         u = *(U++);
986         v = *(V++);
987         uvRed = (V_RED_COEF*v) >> SHIFT;
988         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
989         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
990
991         tableY = table + *(Y++);
992         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
993                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
994                             uvGreen] |
995                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
996
997         tableY = table + *(Y++);
998         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
999                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1000                             uvGreen] |
1001                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1002
1003         u = *(U++);
1004         v = *(V++);
1005         uvRed = (V_RED_COEF*v) >> SHIFT;
1006         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1007         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1008
1009         tableY = table + *(Y++);
1010         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1011                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1012                             uvGreen] |
1013                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1014
1015         tableY = table + *(Y++);
1016         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1017                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1018                             uvGreen] |
1019                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1020
1021         u = *(U++);
1022         v = *(V++);
1023         uvRed = (V_RED_COEF*v) >> SHIFT;
1024         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1025         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1026
1027         tableY = table + *(Y++);
1028         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1029                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1030                             uvGreen] |
1031                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1032
1033         tableY = table + *(Y++);
1034         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1035                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1036                             uvGreen] |
1037                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1038
1039         u = *(U++);
1040         v = *(V++);
1041         uvRed = (V_RED_COEF*v) >> SHIFT;
1042         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1043         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1044
1045         tableY = table + *(Y++);
1046         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1047                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1048                             uvGreen] |
1049                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1050
1051         tableY = table + *(Y++);
1052         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1053                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1054                             uvGreen] |
1055                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1056
1057         u = *(U++);
1058         v = *(V++);
1059         uvRed = (V_RED_COEF*v) >> SHIFT;
1060         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1061         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1062
1063         tableY = table + *(Y++);
1064         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1065                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1066                             uvGreen] |
1067                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1068
1069         tableY = table + *(Y++);
1070         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1071                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1072                             uvGreen] |
1073                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1074
1075         u = *(U++);
1076         v = *(V++);
1077         uvRed = (V_RED_COEF*v) >> SHIFT;
1078         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1079         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1080
1081         tableY = table + *(Y++);
1082         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1083                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1084                             uvGreen] |
1085                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1086
1087         tableY = table + *(Y++);
1088         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1089                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1090                             uvGreen] |
1091                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1092
1093         u = *(U++);
1094         v = *(V++);
1095         uvRed = (V_RED_COEF*v) >> SHIFT;
1096         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1097         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1098
1099         tableY = table + *(Y++);
1100         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1101                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1102                             uvGreen] |
1103                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1104
1105         tableY = table + *(Y++);
1106         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1107                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1108                             uvGreen] |
1109                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1110     }
1111
1112     i = (width & 15) >> 1;
1113     while (i--) {
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
1133     if (width & 1) {
1134         u = *(U++);
1135         v = *(V++);
1136         uvRed = (V_RED_COEF*v) >> SHIFT;
1137         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1138         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1139
1140         tableY = table + *(Y++);
1141         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1142                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1143                             uvGreen] |
1144                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1145     }
1146 }
1147
1148 static void yuvToRgb24 (unsigned char * Y,
1149                         unsigned char * U, unsigned char * V,
1150                         char * dest, int table[1935], int width)
1151 {
1152     int i;
1153     int u;
1154     int v;
1155     int uvRed;
1156     int uvGreen;
1157     int uvBlue;
1158     int * tableY;
1159     int tmp24;
1160
1161     i = width >> 3;
1162     while (i--) {
1163         u = *(U++);
1164         v = *(V++);
1165         uvRed = (V_RED_COEF*v) >> SHIFT;
1166         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1167         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1168
1169         tableY = table + *(Y++);
1170         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1171                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1172                         uvGreen] |
1173                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1174         *(dest++) = tmp24;
1175         *(dest++) = tmp24 >> 8;
1176         *(dest++) = tmp24 >> 16;
1177
1178         tableY = table + *(Y++);
1179         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1180                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1181                         uvGreen] |
1182                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1183         *(dest++) = tmp24;
1184         *(dest++) = tmp24 >> 8;
1185         *(dest++) = tmp24 >> 16;
1186
1187         u = *(U++);
1188         v = *(V++);
1189         uvRed = (V_RED_COEF*v) >> SHIFT;
1190         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1191         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1192
1193         tableY = table + *(Y++);
1194         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1195                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1196                         uvGreen] |
1197                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1198         *(dest++) = tmp24;
1199         *(dest++) = tmp24 >> 8;
1200         *(dest++) = tmp24 >> 16;
1201
1202         tableY = table + *(Y++);
1203         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1204                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1205                         uvGreen] |
1206                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1207         *(dest++) = tmp24;
1208         *(dest++) = tmp24 >> 8;
1209         *(dest++) = tmp24 >> 16;
1210
1211         u = *(U++);
1212         v = *(V++);
1213         uvRed = (V_RED_COEF*v) >> SHIFT;
1214         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1215         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
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         tableY = table + *(Y++);
1227         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1228                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1229                         uvGreen] |
1230                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1231         *(dest++) = tmp24;
1232         *(dest++) = tmp24 >> 8;
1233         *(dest++) = tmp24 >> 16;
1234
1235         u = *(U++);
1236         v = *(V++);
1237         uvRed = (V_RED_COEF*v) >> SHIFT;
1238         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1239         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
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         tableY = table + *(Y++);
1251         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1252                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1253                         uvGreen] |
1254                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1255         *(dest++) = tmp24;
1256         *(dest++) = tmp24 >> 8;
1257         *(dest++) = tmp24 >> 16;
1258     }
1259
1260     i = (width & 7) >> 1;
1261     while (i--) {
1262         u = *(U++);
1263         v = *(V++);
1264         uvRed = (V_RED_COEF*v) >> SHIFT;
1265         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1266         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1267
1268         tableY = table + *(Y++);
1269         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1270                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1271                         uvGreen] |
1272                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1273         *(dest++) = tmp24;
1274         *(dest++) = tmp24 >> 8;
1275         *(dest++) = tmp24 >> 16;
1276
1277         tableY = table + *(Y++);
1278         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1279                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1280                         uvGreen] |
1281                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1282         *(dest++) = tmp24;
1283         *(dest++) = tmp24 >> 8;
1284         *(dest++) = tmp24 >> 16;
1285     }
1286
1287     if (width & 1) {
1288         u = *(U++);
1289         v = *(V++);
1290         uvRed = (V_RED_COEF*v) >> SHIFT;
1291         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1292         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1293
1294         tableY = table + *(Y++);
1295         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1296                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1297                         uvGreen] |
1298                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1299         *(dest++) = tmp24;
1300         *(dest++) = tmp24 >> 8;
1301         *(dest++) = tmp24 >> 16;
1302     }
1303 }
1304
1305 static void yuvToRgb32 (unsigned char * Y,
1306                         unsigned char * U, unsigned char * V,
1307                         int * dest, int table[1935], int width)
1308 {
1309     int i;
1310     int u;
1311     int v;
1312     int uvRed;
1313     int uvGreen;
1314     int uvBlue;
1315     int * tableY;
1316
1317     i = width >> 4;
1318     while (i--) {
1319         u = *(U++);
1320         v = *(V++);
1321         uvRed = (V_RED_COEF*v) >> SHIFT;
1322         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1323         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1324
1325         tableY = table + *(Y++);
1326         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1327                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1328                             uvGreen] |
1329                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1330
1331         tableY = table + *(Y++);
1332         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1333                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1334                             uvGreen] |
1335                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1336
1337         u = *(U++);
1338         v = *(V++);
1339         uvRed = (V_RED_COEF*v) >> SHIFT;
1340         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1341         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1342
1343         tableY = table + *(Y++);
1344         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1345                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1346                             uvGreen] |
1347                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1348
1349         tableY = table + *(Y++);
1350         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1351                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1352                             uvGreen] |
1353                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1354
1355         u = *(U++);
1356         v = *(V++);
1357         uvRed = (V_RED_COEF*v) >> SHIFT;
1358         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1359         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1360
1361         tableY = table + *(Y++);
1362         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1363                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1364                             uvGreen] |
1365                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1366
1367         tableY = table + *(Y++);
1368         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1369                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1370                             uvGreen] |
1371                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1372
1373         u = *(U++);
1374         v = *(V++);
1375         uvRed = (V_RED_COEF*v) >> SHIFT;
1376         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1377         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1378
1379         tableY = table + *(Y++);
1380         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1381                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1382                             uvGreen] |
1383                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1384
1385         tableY = table + *(Y++);
1386         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1387                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1388                             uvGreen] |
1389                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1390
1391         u = *(U++);
1392         v = *(V++);
1393         uvRed = (V_RED_COEF*v) >> SHIFT;
1394         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1395         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1396
1397         tableY = table + *(Y++);
1398         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1399                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1400                             uvGreen] |
1401                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1402
1403         tableY = table + *(Y++);
1404         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1405                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1406                             uvGreen] |
1407                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1408
1409         u = *(U++);
1410         v = *(V++);
1411         uvRed = (V_RED_COEF*v) >> SHIFT;
1412         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1413         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1414
1415         tableY = table + *(Y++);
1416         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1417                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1418                             uvGreen] |
1419                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1420
1421         tableY = table + *(Y++);
1422         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1423                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1424                             uvGreen] |
1425                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1426
1427         u = *(U++);
1428         v = *(V++);
1429         uvRed = (V_RED_COEF*v) >> SHIFT;
1430         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1431         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1432
1433         tableY = table + *(Y++);
1434         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1435                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1436                             uvGreen] |
1437                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1438
1439         tableY = table + *(Y++);
1440         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1441                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1442                             uvGreen] |
1443                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1444
1445         u = *(U++);
1446         v = *(V++);
1447         uvRed = (V_RED_COEF*v) >> SHIFT;
1448         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1449         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1450
1451         tableY = table + *(Y++);
1452         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1453                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1454                             uvGreen] |
1455                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1456
1457         tableY = table + *(Y++);
1458         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1459                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1460                             uvGreen] |
1461                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1462     }
1463
1464     i = (width & 15) >> 1;
1465     while (i--) {
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
1485     if (width & 1) {
1486         u = *(U++);
1487         v = *(V++);
1488         uvRed = (V_RED_COEF*v) >> SHIFT;
1489         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1490         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1491
1492         tableY = table + *(Y++);
1493         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1494                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1495                             uvGreen] |
1496                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1497     }
1498 }
1499
1500 /* yuv routines with scaling */
1501 /* 4:2:2 i, 16 bpp*/
1502
1503 void yuv422ToRgb16_scaled (unsigned char * Y,
1504                         unsigned char * U, unsigned char * V,
1505                         short * dest, short table[1935], int width , int dest_width,
1506             int height, int dest_height, int skip, int dest_skip,short * buffer)
1507 {
1508     int i, i_hcount, i_vcount, j, k;
1509     int u;
1510     int v;
1511     int uvRed;
1512     int uvGreen;
1513     int uvBlue;
1514     short * tableY;
1515     short pix;
1516
1517     if ( ( width < dest_width ) && ( height < dest_height ) )
1518     {
1519         i_vcount = dest_height;
1520         k = height;
1521         while ( k-- )
1522         {
1523             j = 0;
1524             i = width >> 1;
1525             i_hcount = dest_width;
1526             while ( i-- ) 
1527             {
1528                     u = *(U++);
1529                     v = *(V++);
1530                     uvRed = (V_RED_COEF*v) >> SHIFT;
1531                     uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1532                     uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1533
1534                     tableY = table + *(Y++);
1535                     pix = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1536                                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)
1537                        >>SHIFT) + uvGreen] |
1538                                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1539                 while ( ( i_hcount -= width ) >= 0 )
1540                 {
1541                     buffer[j++] = pix;
1542                 }
1543                 i_hcount += dest_width;
1544             
1545                     tableY = table + *(Y++);
1546                     pix = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1547                                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)
1548                        >>SHIFT) + uvGreen] |
1549                                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1550                 while ( ( i_hcount -= width ) >= 0 )
1551                 {
1552                     buffer[j++] = pix;
1553                 }
1554                 i_hcount += dest_width;
1555             }
1556             while ( ( i_vcount -= height ) >= 0 )
1557             {
1558             for (j=0; j<dest_width; j+=16)
1559                 {
1560                     dest[j]=buffer[j];
1561                     dest[j+1]=buffer[j+1];
1562                     dest[j+2]=buffer[j+2];
1563                     dest[j+3]=buffer[j+3];
1564                     dest[j+4]=buffer[j+4];
1565                     dest[j+6]=buffer[j+7];
1566                     dest[j+8]=buffer[j+9];
1567                     dest[j+10]=buffer[j+10];
1568                     dest[j+11]=buffer[j+11];
1569                     dest[j+12]=buffer[j+12];
1570                     dest[j+13]=buffer[j+13];
1571                     dest[j+14]=buffer[j+14];
1572                     dest[j+15]=buffer[j+15];
1573                 }
1574                 dest += dest_skip;
1575             }
1576         i_vcount += dest_height;
1577         }
1578     }
1579     else if ( ( width > dest_width ) && ( height < dest_height ) )
1580     {
1581         i_vcount = dest_height;
1582         k = height;
1583         while ( k-- )
1584         {
1585             j = 0;
1586             i_hcount = 0;
1587             i = width >> 1;
1588             while ( i-- ) 
1589             {
1590                 u = *(U++);
1591                 v = *(V++);
1592                 uvRed = (V_RED_COEF*v) >> SHIFT;
1593                 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1594                 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1595                                                                         
1596                     if ( ( i_hcount -= dest_width ) >= 0 )
1597                     Y++;
1598                 else
1599                 {
1600                     tableY = table + *(Y++);
1601                     buffer[j++] = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + 
1602                                    uvRed] | 
1603                                    tableY [135 - 
1604                                    (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1605                                    uvGreen] |
1606                                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + 
1607                                    uvBlue]);
1608                     i_hcount += width;
1609                 }
1610                 if ( ( i_hcount -= dest_width ) >= 0 )
1611                     Y++;
1612                 else
1613                 {     
1614                     tableY = table + *(Y++);
1615                     buffer[j++] = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + 
1616                                    uvRed] |
1617                                    tableY [135 - 
1618                                    (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1619                                    uvGreen] |
1620                                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + 
1621                                    uvBlue]);
1622                                    i_hcount += width;
1623                 }
1624             }
1625             while ( ( i_vcount -= height ) >= 0 )
1626             {
1627                 for (j=0; j<dest_width; j+=16)
1628                  {
1629                     dest[j]=buffer[j];
1630                     dest[j+1]=buffer[j+1];
1631                     dest[j+2]=buffer[j+2];
1632                     dest[j+3]=buffer[j+3];
1633                     dest[j+4]=buffer[j+4];
1634                     dest[j+6]=buffer[j+7];
1635                     dest[j+8]=buffer[j+9];
1636                     dest[j+10]=buffer[j+10];
1637                     dest[j+11]=buffer[j+11];
1638                     dest[j+12]=buffer[j+12];
1639                     dest[j+13]=buffer[j+13];
1640                     dest[j+14]=buffer[j+14];
1641                     dest[j+15]=buffer[j+15];
1642                 }
1643                 dest += dest_skip;
1644             }
1645             i_vcount += dest_height;
1646         }
1647     }
1648     else if ( ( width < dest_width ) && ( height > dest_height ) )
1649     {
1650         i_vcount = 0;
1651         k = height;
1652         while ( k-- )
1653         {
1654             j = 0;
1655             i = width >> 1;
1656             i_hcount = dest_width;
1657             while ( i-- ) 
1658             {
1659                     u = *(U++);
1660                     v = *(V++);
1661                     uvRed = (V_RED_COEF*v) >> SHIFT;
1662                     uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1663                     uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1664
1665                     tableY = table + *(Y++);
1666                     pix = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1667                                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)
1668                        >>SHIFT) + uvGreen] |
1669                                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1670                 while ( ( i_hcount -= width ) >= 0 )
1671                 {
1672                     dest[j++] = pix;
1673                 }
1674                 i_hcount += dest_width;
1675             
1676                     tableY = table + *(Y++);
1677                     pix = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1678                                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)
1679                        >>SHIFT) + uvGreen] |
1680                                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1681                 while ( ( i_hcount -= width ) >= 0 )
1682                 {
1683                     dest[j++] = pix;
1684                 }
1685                 i_hcount += dest_width;
1686             }
1687             while ( ( i_vcount -= height ) >= 0 )
1688             {
1689                 Y += skip;
1690                 U += skip >> 1;
1691                 V += skip >> 1;
1692             }
1693             i_vcount += dest_height;
1694         }
1695     }
1696     else if ( ( width > dest_width ) && ( height > dest_height ) )
1697     {
1698         i_vcount = dest_height;
1699         k = height;
1700         while ( k-- )
1701         {
1702             j = 0;
1703             i_hcount = 0;
1704             i = width >> 1;
1705             while ( i-- ) 
1706             {
1707                 u = *(U++);
1708                 v = *(V++);
1709                 uvRed = (V_RED_COEF*v) >> SHIFT;
1710                 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1711                 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1712                                                                         
1713                     if ( ( i_hcount -= dest_width ) >= 0 )
1714                     Y++;
1715                 else
1716                 {
1717                     tableY = table + *(Y++);
1718                     dest[j++] = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + 
1719                                  uvRed] | 
1720                                  tableY [135 - 
1721                                  (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1722                                  uvGreen] |
1723                                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + 
1724                                  uvBlue]);
1725                     i_hcount += width;
1726                 }
1727                 if ( ( i_hcount -= dest_width ) >= 0 )
1728                     Y++;
1729                 else
1730                 {     
1731                     tableY = table + *(Y++);
1732                     dest[j++] = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + 
1733                                  uvRed] |
1734                                  tableY [135 - 
1735                                  (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1736                                  uvGreen] |
1737                                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + 
1738                                  uvBlue]);
1739                                  i_hcount += width;
1740                 }
1741             }
1742             while ( ( i_vcount -= height ) >= 0 )
1743             {
1744                 Y += skip;
1745                 U += skip >> 1;
1746                 V += skip >> 1;
1747             }
1748             i_vcount += dest_height;
1749         }
1750     }
1751 }
1752
1753 /* yuv routines with scaling */
1754 /* 4:2:0 i, 16 bpp*/
1755
1756 void yuv420ToRgb16_scaled (unsigned char * Y,
1757                         unsigned char * U, unsigned char * V,
1758                         short * dest, short table[1935], int width , int dest_width,
1759             int height, int dest_height, int skip, int dest_skip,short * buffer)
1760 {
1761     int i, i_hcount, i_vcount, j, k;
1762     int u;
1763     int v;
1764     int uvRed;
1765     int uvGreen;
1766     int uvBlue;
1767     short * tableY;
1768     short pix;
1769
1770     if ( ( width < dest_width ) && ( height < dest_height ) )
1771     {
1772         i_vcount = dest_height;
1773         k = height >> 1;
1774         while ( k-- )
1775         {
1776             j = 0;
1777             i = width >> 1;
1778             i_hcount = dest_width;
1779             while ( i-- ) 
1780             {
1781                     u = *(U++);
1782                     v = *(V++);
1783                     uvRed = (V_RED_COEF*v) >> SHIFT;
1784                     uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1785                     uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1786
1787                     tableY = table + *(Y++);
1788                     pix = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1789                                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)
1790                        >>SHIFT) + uvGreen] |
1791                                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1792                 while ( ( i_hcount -= width ) >= 0 )
1793                 {
1794                     buffer[j++] = pix;
1795                 }
1796                 i_hcount += dest_width;
1797             
1798                     tableY = table + *(Y++);
1799                     pix = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1800                                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)
1801                        >>SHIFT) + uvGreen] |
1802                                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1803                 while ( ( i_hcount -= width ) >= 0 )
1804                 {
1805                     buffer[j++] = pix;
1806                 }
1807                 i_hcount += dest_width;
1808             }
1809             while ( ( i_vcount -= height ) >= 0 )
1810             {
1811                 for (j=0; j<dest_width; j+=16)
1812                     {
1813                         dest[j]=buffer[j];
1814                         dest[j+1]=buffer[j+1];
1815                         dest[j+2]=buffer[j+2];
1816                         dest[j+3]=buffer[j+3];
1817                         dest[j+4]=buffer[j+4];
1818                         dest[j+6]=buffer[j+7];
1819                         dest[j+8]=buffer[j+9];
1820                         dest[j+10]=buffer[j+10];
1821                         dest[j+11]=buffer[j+11];
1822                         dest[j+12]=buffer[j+12];
1823                         dest[j+13]=buffer[j+13];
1824                         dest[j+14]=buffer[j+14];
1825                         dest[j+15]=buffer[j+15];
1826                     }
1827                 dest += dest_skip;
1828             }
1829             i_vcount += dest_height;
1830             U -= skip >> 1;
1831             V -= skip >> 1;
1832             j = 0;
1833             i = width >> 1;
1834             i_hcount = dest_width;
1835             while ( i-- ) 
1836             {
1837                     u = *(U++);
1838                     v = *(V++);
1839                     uvRed = (V_RED_COEF*v) >> SHIFT;
1840                     uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1841                     uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1842
1843                     tableY = table + *(Y++);
1844                     pix = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1845                                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)
1846                        >>SHIFT) + uvGreen] |
1847                                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1848                 while ( ( i_hcount -= width ) >= 0 )
1849                 {
1850                     buffer[j++] = pix;
1851                 }
1852                 i_hcount += dest_width;
1853             
1854                     tableY = table + *(Y++);
1855                     pix = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1856                                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)
1857                        >>SHIFT) + uvGreen] |
1858                                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1859                 while ( ( i_hcount -= width ) >= 0 )
1860                 {
1861                     buffer[j++] = pix;
1862                 }
1863                 i_hcount += dest_width;
1864             }
1865             while ( ( i_vcount -= height ) >= 0 )
1866             {
1867                 for (j=0; j<dest_width; j+=16)
1868                     {
1869                         dest[j]=buffer[j];
1870                         dest[j+1]=buffer[j+1];
1871                         dest[j+2]=buffer[j+2];
1872                         dest[j+3]=buffer[j+3];
1873                         dest[j+4]=buffer[j+4];
1874                         dest[j+6]=buffer[j+7];
1875                         dest[j+8]=buffer[j+9];
1876                         dest[j+10]=buffer[j+10];
1877                         dest[j+11]=buffer[j+11];
1878                         dest[j+12]=buffer[j+12];
1879                         dest[j+13]=buffer[j+13];
1880                         dest[j+14]=buffer[j+14];
1881                         dest[j+15]=buffer[j+15];
1882                     }
1883                 dest += dest_skip;
1884             }
1885             i_vcount += dest_height;
1886         }
1887     }
1888     else if ( ( width > dest_width ) && ( height < dest_height ) )
1889     {
1890         i_vcount = dest_height;
1891         k = height;
1892         while ( k-- )
1893         {
1894             j = 0;
1895             i_hcount = 0;
1896             i = width >> 1;
1897             while ( i-- ) 
1898             {
1899                 u = *(U++);
1900                 v = *(V++);
1901                 uvRed = (V_RED_COEF*v) >> SHIFT;
1902                 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1903                 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1904                                                                         
1905                     if ( ( i_hcount -= dest_width ) >= 0 )
1906                     Y++;
1907                 else
1908                 {
1909                     tableY = table + *(Y++);
1910                     buffer[j++] = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + 
1911                                    uvRed] | 
1912                                    tableY [135 - 
1913                                    (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1914                                    uvGreen] |
1915                                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + 
1916                                    uvBlue]);
1917                     i_hcount += width;
1918                 }
1919                 if ( ( i_hcount -= dest_width ) >= 0 )
1920                     Y++;
1921                 else
1922                 {     
1923                     tableY = table + *(Y++);
1924                     buffer[j++] = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + 
1925                                    uvRed] |
1926                                    tableY [135 - 
1927                                    (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1928                                    uvGreen] |
1929                                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + 
1930                                    uvBlue]);
1931                                    i_hcount += width;
1932                 }
1933             }
1934             while ( ( i_vcount -= height ) >= 0 )
1935             {
1936                 for (j=0; j<dest_width; j+=16)
1937                  {
1938                     dest[j]=buffer[j];
1939                     dest[j+1]=buffer[j+1];
1940                     dest[j+2]=buffer[j+2];
1941                     dest[j+3]=buffer[j+3];
1942                     dest[j+4]=buffer[j+4];
1943                     dest[j+6]=buffer[j+7];
1944                     dest[j+8]=buffer[j+9];
1945                     dest[j+10]=buffer[j+10];
1946                     dest[j+11]=buffer[j+11];
1947                     dest[j+12]=buffer[j+12];
1948                     dest[j+13]=buffer[j+13];
1949                     dest[j+14]=buffer[j+14];
1950                     dest[j+15]=buffer[j+15];
1951                 }
1952                 dest += dest_skip;
1953             }
1954             i_vcount += dest_height;
1955             U -= skip >> 1;
1956             V -= skip >> 1;
1957             j = 0;
1958             i_hcount = 0;
1959             i = width >> 1;
1960             while ( i-- ) 
1961             {
1962                 u = *(U++);
1963                 v = *(V++);
1964                 uvRed = (V_RED_COEF*v) >> SHIFT;
1965                 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1966                 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1967                                                                         
1968                     if ( ( i_hcount -= dest_width ) >= 0 )
1969                     Y++;
1970                 else
1971                 {
1972                     tableY = table + *(Y++);
1973                     buffer[j++] = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + 
1974                                    uvRed] | 
1975                                    tableY [135 - 
1976                                    (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1977                                    uvGreen] |
1978                                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + 
1979                                    uvBlue]);
1980                     i_hcount += width;
1981                 }
1982                 if ( ( i_hcount -= dest_width ) >= 0 )
1983                     Y++;
1984                 else
1985                 {     
1986                     tableY = table + *(Y++);
1987                     buffer[j++] = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + 
1988                                    uvRed] |
1989                                    tableY [135 - 
1990                                    (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1991                                    uvGreen] |
1992                                    tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + 
1993                                    uvBlue]);
1994                                    i_hcount += width;
1995                 }
1996             }
1997             while ( ( i_vcount -= height ) >= 0 )
1998             {
1999                 for (j=0; j<dest_width; j+=16)
2000                  {
2001                     dest[j]=buffer[j];
2002                     dest[j+1]=buffer[j+1];
2003                     dest[j+2]=buffer[j+2];
2004                     dest[j+3]=buffer[j+3];
2005                     dest[j+4]=buffer[j+4];
2006                     dest[j+6]=buffer[j+7];
2007                     dest[j+8]=buffer[j+9];
2008                     dest[j+10]=buffer[j+10];
2009                     dest[j+11]=buffer[j+11];
2010                     dest[j+12]=buffer[j+12];
2011                     dest[j+13]=buffer[j+13];
2012                     dest[j+14]=buffer[j+14];
2013                     dest[j+15]=buffer[j+15];
2014                 }
2015                 dest += dest_skip;
2016             }
2017             i_vcount += dest_height;
2018         }
2019     }
2020     else if ( ( width < dest_width ) && ( height > dest_height ) )
2021     {
2022         i_vcount = 0;
2023         k = height;
2024         while ( k-- )
2025         {
2026             j = 0;
2027             i = width >> 1;
2028             i_hcount = dest_width;
2029             while ( i-- ) 
2030             {
2031                     u = *(U++);
2032                     v = *(V++);
2033                     uvRed = (V_RED_COEF*v) >> SHIFT;
2034                     uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
2035                     uvBlue = (U_BLUE_COEF*u) >> SHIFT;
2036
2037                     tableY = table + *(Y++);
2038                     pix = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
2039                                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)
2040                        >>SHIFT) + uvGreen] |
2041                                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
2042                 while ( ( i_hcount -= width ) >= 0 )
2043                 {
2044                     dest[j++] = pix;
2045                 }
2046                 i_hcount += dest_width;
2047             
2048                     tableY = table + *(Y++);
2049                     pix = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
2050                                tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)
2051                        >>SHIFT) + uvGreen] |
2052                                tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
2053                 while ( ( i_hcount -= width ) >= 0 )
2054                 {
2055                     dest[j++] = pix;
2056                 }
2057                 i_hcount += dest_width;
2058             }
2059             j = 0;
2060             while ( ( i_vcount -= height ) >= 0 )
2061             {
2062                 Y += skip;
2063                 j++;
2064             }
2065             U += skip * ( j >> 1 );
2066             V += skip * ( j >> 1 );
2067             i_vcount += dest_height;
2068         }
2069     }
2070     else if ( ( width > dest_width ) && ( height > dest_height ) )
2071     {
2072         i_vcount = dest_height;
2073         k = height;
2074         while ( k-- )
2075         {
2076             j = 0;
2077             i_hcount = 0;
2078             i = width >> 1;
2079             while ( i-- ) 
2080             {
2081                 u = *(U++);
2082                 v = *(V++);
2083                 uvRed = (V_RED_COEF*v) >> SHIFT;
2084                 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
2085                 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
2086                                                                         
2087                     if ( ( i_hcount -= dest_width ) >= 0 )
2088                     Y++;
2089                 else
2090                 {
2091                     tableY = table + *(Y++);
2092                     dest[j++] = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + 
2093                                  uvRed] | 
2094                                  tableY [135 - 
2095                                  (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
2096                                  uvGreen] |
2097                                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + 
2098                                  uvBlue]);
2099                     i_hcount += width;
2100                 }
2101                 if ( ( i_hcount -= dest_width ) >= 0 )
2102                     Y++;
2103                 else
2104                 {     
2105                     tableY = table + *(Y++);
2106                     dest[j++] = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + 
2107                                  uvRed] |
2108                                  tableY [135 - 
2109                                  (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
2110                                  uvGreen] |
2111                                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + 
2112                                  uvBlue]);
2113                                  i_hcount += width;
2114                 }
2115             }
2116             j = 0;
2117             while ( ( i_vcount -= height ) >= 0 )
2118             {
2119                 Y += skip;
2120                 j++;
2121             }
2122             U += skip * ( j >> 1 );
2123             V += skip * ( j >> 1 );
2124             i_vcount += dest_height;
2125         }
2126     }
2127 }
2128