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