]> git.sesse.net Git - vlc/blob - src/video_output/video_yuv.c
Correction du segfault en gris.
[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 //?? no more used ?
33 const int MATRIX_COEFFICIENTS_TABLE[8][4] =
34 {
35   {117504, 138453, 13954, 34903},       /* no sequence_display_extension */
36   {117504, 138453, 13954, 34903},       /* ITU-R Rec. 709 (1990) */
37   {104597, 132201, 25675, 53279},       /* unspecified */
38   {104597, 132201, 25675, 53279},       /* reserved */
39   {104448, 132798, 24759, 53109},       /* FCC */
40   {104597, 132201, 25675, 53279},       /* ITU-R Rec. 624-4 System B, G */
41   {104597, 132201, 25675, 53279},       /* SMPTE 170M */
42   {117579, 136230, 16907, 35559}        /* SMPTE 240M (1987) */
43 };
44
45 /* Margins and offsets in convertion tables - Margins are used in case a RGB
46  * RGB convertion would give a value outside the 0-255 range. Offsets have been
47  * calculated to avoid using the same cache line for 2 tables. Convertion tables
48  * are 2*MARGIN + 256 long and stores pixels.*/
49 #define RED_MARGIN      178
50 #define GREEN_MARGIN    135
51 #define BLUE_MARGIN     224
52 #define RED_OFFSET      1501                                   /* 1323 to 1935 */
53 #define GREEN_OFFSET    135                                        /* 0 to 526 */
54 #define BLUE_OFFSET     818                                     /* 594 to 1298 */
55 #define RGB_TABLE_SIZE  1935                               /* total table size */
56
57 #define GRAY_MARGIN     384
58 #define GRAY_TABLE_SIZE 1024                               /* total table size */
59
60 //??
61 #define SHIFT 20
62 #define U_GREEN_COEF    ((int)(-0.391 * (1<<SHIFT) / 1.164))
63 #define U_BLUE_COEF     ((int)(2.018 * (1<<SHIFT) / 1.164))
64 #define V_RED_COEF      ((int)(1.596 * (1<<SHIFT) / 1.164))
65 #define V_GREEN_COEF    ((int)(-0.813 * (1<<SHIFT) / 1.164))
66
67 /*******************************************************************************
68  * Local prototypes
69  *******************************************************************************/
70 static int      BinaryLog         ( u32 i );
71 static void     MaskToShift       ( int *pi_right, int *pi_left, u32 i_mask );
72 static void     SetGammaTable     ( int *pi_table, double f_gamma );
73 static void     SetYUV            ( vout_thread_t *p_vout );
74
75 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,
76                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
77                                     int i_matrix_coefficients );
78 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,
79                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
80                                     int i_matrix_coefficients );
81 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,
82                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
83                                     int i_matrix_coefficients );
84 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,
85                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
86                                     int i_matrix_coefficients );
87 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,
88                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
89                                     int i_matrix_coefficients );
90 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,
91                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
92                                     int i_matrix_coefficients );
93 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,
94                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
95                                     int i_matrix_coefficients );
96 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,
97                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
98                                     int i_matrix_coefficients );
99 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,
100                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
101                                     int i_matrix_coefficients );
102 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,
103                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
104                                     int i_matrix_coefficients );
105 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,
106                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
107                                     int i_matrix_coefficients );
108 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,
109                                     int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
110                                     int i_matrix_coefficients );
111
112 /*******************************************************************************
113  * CLIP_BYTE macro: boundary detection
114  *******************************************************************************
115  * Return parameter if between 0 and 255, else return nearest boundary (0 or 
116  * 255). This macro is used to build translations tables.
117  *******************************************************************************/
118 #define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
119
120 /*******************************************************************************
121  * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel convertion blocks
122  *******************************************************************************
123  * These convertion routines are used by YUV convertion functions.
124  * Convertion are made from p_y, p_u, p_v, which are modified, to p_buffer,
125  * which is also modified.
126  *******************************************************************************/
127 #define CONVERT_Y_PIXEL                                                                 \
128     /* Only Y sample is present */                                                      \
129     p_ybase = p_yuv + *p_y++;                                                           \
130     *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] |               \
131         p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] |   \
132         p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];                       \
133
134 #define CONVERT_YUV_PIXEL                                                       \
135     /* Y, U and V samples are present */                                        \
136     i_uval =    *p_u++;                                                         \
137     i_vval =    *p_v++;                                                         \
138     i_red =     (V_RED_COEF * i_vval) >> SHIFT;                                 \
139     i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;       \
140     i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;                                \
141     CONVERT_Y_PIXEL                                                             \
142
143 /*******************************************************************************
144  * vout_InitYUV: allocate and initialize translations tables
145  *******************************************************************************
146  * This function will allocate memory to store translation tables, depending
147  * of the screen depth.
148  *******************************************************************************/
149 int vout_InitYUV( vout_thread_t *p_vout )
150 {
151     size_t      tables_size;                          /* tables size, in bytes */
152     
153     /* Computes tables size */
154     switch( p_vout->i_screen_depth )
155     {
156     case 15:
157     case 16:
158         tables_size = sizeof( u16 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
159         break;        
160     case 24:        
161     case 32:
162 #ifndef DEBUG
163     default:        
164 #endif
165         tables_size = sizeof( u32 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);        
166         break;        
167 #ifdef DEBUG
168     default:
169         intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
170         tables_size = 0;
171         break;        
172 #endif      
173     }
174     
175     /* Allocate memory */
176     p_vout->yuv.p_base = malloc( tables_size );
177     if( p_vout->yuv.p_base == NULL )
178     {
179         intf_ErrMsg("error: %s\n", strerror(ENOMEM));
180         return( 1 );                
181     }
182
183     /* Allocate memory for convertion buffer and offset array */
184     p_vout->yuv.p_buffer = malloc( VOUT_MAX_WIDTH * p_vout->i_bytes_per_pixel );
185     if( p_vout->yuv.p_buffer == NULL )
186     {
187         intf_ErrMsg("error: %s\n", strerror(ENOMEM));
188         free( p_vout->yuv.p_base );
189         return( 1 );                
190     }
191     p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) );    
192     if( p_vout->yuv.p_offset == NULL )
193     {
194         intf_ErrMsg("error: %s\n", strerror(ENOMEM));
195         free( p_vout->yuv.p_base );
196         free( p_vout->yuv.p_buffer );        
197         return( 1 );                
198     }
199
200     /* Initialize tables */
201     SetYUV( p_vout );
202     return( 0 );    
203 }
204
205 /*******************************************************************************
206  * vout_ResetTables: re-initialize translations tables
207  *******************************************************************************
208  * This function will initialize the tables allocated by vout_CreateTables and
209  * set functions pointers.
210  *******************************************************************************/
211 int vout_ResetYUV( vout_thread_t *p_vout )
212 {
213     vout_EndYUV( p_vout );    
214     return( vout_InitYUV( p_vout ) );    
215 }
216
217 /*******************************************************************************
218  * vout_EndYUV: destroy translations tables
219  *******************************************************************************
220  * Free memory allocated by vout_CreateTables.
221  *******************************************************************************/
222 void vout_EndYUV( vout_thread_t *p_vout )
223 {
224     free( p_vout->yuv.p_base );
225     free( p_vout->yuv.p_buffer );
226     free( p_vout->yuv.p_offset );    
227 }
228
229 /* following functions are local */
230
231 /*******************************************************************************
232  * BinaryLog: computes the base 2 log of a binary value
233  *******************************************************************************
234  * This functions is used by MaskToShift during tables initialisation, to
235  * get a bit index from a binary value.
236  *******************************************************************************/
237 static int BinaryLog(u32 i)
238 {
239     int i_log;
240
241     i_log = 0;
242     if (i & 0xffff0000) 
243     {        
244         i_log = 16;
245     }    
246     if (i & 0xff00ff00) 
247     {        
248         i_log += 8;
249     }    
250     if (i & 0xf0f0f0f0) 
251     {        
252         i_log += 4;
253     }    
254     if (i & 0xcccccccc) 
255     {        
256         i_log += 2;
257     }    
258     if (i & 0xaaaaaaaa) 
259     {        
260         i_log++;
261     }    
262     if (i != ((u32)1 << i_log))
263     {        
264         intf_ErrMsg("internal error: binary log overflow\n");        
265     }    
266
267     return( i_log );
268 }
269
270 /*******************************************************************************
271  * MaskToShift: Transform a color mask into right and left shifts
272  *******************************************************************************
273  * This function is used during table initialisation. It can return a value
274  *******************************************************************************/
275 static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
276 {
277     u32 i_low, i_high;                   /* lower hand higher bits of the mask */
278
279     /* Get bits */
280     i_low =  i_mask & (- i_mask);                     /* lower bit of the mask */
281     i_high = i_mask + i_low;                         /* higher bit of the mask */
282
283     /* Transform bits into an index */
284     i_low =  BinaryLog (i_low);
285     i_high = BinaryLog (i_high);
286
287     /* Update pointers and return */
288     *pi_left =   i_low;
289     *pi_right = (8 - i_high + i_low);
290 }
291
292 /*******************************************************************************
293  * SetGammaTable: return intensity table transformed by gamma curve.
294  *******************************************************************************
295  * pi_table is a table of 256 entries from 0 to 255.
296  *******************************************************************************/
297 static void SetGammaTable( int *pi_table, double f_gamma )
298 {
299     int         i_y;                                         /* base intensity */
300
301     /* Use exp(gamma) instead of gamma */
302     f_gamma = exp(f_gamma );
303
304     /* Build gamma table */
305     for( i_y = 0; i_y < 256; i_y++ )
306     {
307         pi_table[ i_y ] = pow( (double)i_y / 256, f_gamma ) * 256;
308     }
309  }
310
311 /*******************************************************************************
312  * SetYUV: compute tables and set function pointers
313 + *******************************************************************************/
314 static void SetYUV( vout_thread_t *p_vout )
315 {
316     int         pi_gamma[256];                                  /* gamma table */    
317     int         i_index;                                    /* index in tables */
318     int         i_red_right, i_red_left;                         /* red shifts */
319     int         i_green_right, i_green_left;                   /* green shifts */
320     int         i_blue_right, i_blue_left;                      /* blue shifts */
321
322     /* Build gamma table */    
323     SetGammaTable( pi_gamma, p_vout->f_gamma );
324     
325     /*          
326      * Set color masks and shifts
327      */
328     switch( p_vout->i_screen_depth )
329     {
330     case 15:
331         MaskToShift( &i_red_right,   &i_red_left,   0xf800 );
332         MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
333         MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );        
334         break;        
335     case 16:
336         MaskToShift( &i_red_right,   &i_red_left,   0xf800 );
337         MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
338         MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );
339         break;        
340     case 24:
341     case 32:        
342         MaskToShift( &i_red_right,   &i_red_left,   0x00ff0000 );
343         MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
344         MaskToShift( &i_blue_right,  &i_blue_left,  0x000000ff );
345         break;
346 #ifdef DEBUG
347     default:
348         intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
349         break;        
350 #endif      
351     }
352
353     /*
354      * Set pointers and build YUV tables
355      */        
356     if( p_vout->b_grayscale )
357     {
358         /* Grayscale: build gray table */
359         switch( p_vout->i_screen_depth )
360         {
361         case 15:
362         case 16:         
363             p_vout->yuv.yuv.p_gray16 =  (u16 *)p_vout->yuv.p_base + GRAY_MARGIN;
364             for( i_index = -GRAY_MARGIN; i_index < 256 + GRAY_MARGIN; i_index++) 
365             {
366                 p_vout->yuv.yuv.p_gray16[ i_index ] = 
367                     ((pi_gamma[CLIP_BYTE( i_index )] >> i_red_right)   << i_red_left)   |
368                     ((pi_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
369                     ((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right)  << i_blue_left);
370             }
371             break;        
372         case 24:
373         case 32:        
374             p_vout->yuv.yuv.p_gray32 =  (u32 *)p_vout->yuv.p_base + GRAY_MARGIN;
375             for( i_index = -GRAY_MARGIN; i_index < 256 + GRAY_MARGIN; i_index++) 
376             {
377                 p_vout->yuv.yuv.p_gray32[ i_index ] = 
378                     ((pi_gamma[CLIP_BYTE( i_index )] >> i_red_right)   << i_red_left)   |
379                     ((pi_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
380                     ((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right)  << i_blue_left);
381             }        
382             break;        
383         }
384     }
385     else
386     {
387         /* Color: build red, green and blue tables */
388         switch( p_vout->i_screen_depth )
389         {
390         case 15:
391         case 16:            
392             p_vout->yuv.yuv.p_rgb16 = (u16 *)p_vout->yuv.p_base;
393             for( i_index = 0; i_index < RED_MARGIN; i_index++ )
394             {
395                 p_vout->yuv.yuv.p_rgb16[RED_OFFSET - RED_MARGIN + i_index] = (pi_gamma[0]>>i_red_right)<<i_red_left;
396                 p_vout->yuv.yuv.p_rgb16[RED_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_red_right)<<i_red_left;                
397             }
398             for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
399             {
400                 p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET - GREEN_MARGIN + i_index] = (pi_gamma[0]>>i_green_right)<<i_green_left;
401                 p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_green_right)<<i_green_left;
402             }
403             for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
404             {
405                 p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET - BLUE_MARGIN + i_index] = (pi_gamma[0]>>i_blue_right)<<i_blue_left;
406                 p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + BLUE_MARGIN + i_index] = (pi_gamma[255]>>i_blue_right)<<i_blue_left;                
407             }
408             for( i_index = 0; i_index < 256; i_index++ )
409             {
410                 p_vout->yuv.yuv.p_rgb16[RED_OFFSET + i_index] = (pi_gamma[i_index]>>i_red_right)<<i_red_left;
411                 p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + i_index] = (pi_gamma[i_index]>>i_green_right)<<i_green_left;
412                 p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + i_index] = (pi_gamma[i_index]>>i_blue_right)<<i_blue_left;
413             }            
414             break;        
415         case 24:
416         case 32:
417             p_vout->yuv.yuv.p_rgb32 = (u32 *)p_vout->yuv.p_base;
418             for( i_index = 0; i_index < RED_MARGIN; i_index++ )
419             {
420                 p_vout->yuv.yuv.p_rgb32[RED_OFFSET - RED_MARGIN + i_index] = (pi_gamma[0]>>i_red_right)<<i_red_left;
421                 p_vout->yuv.yuv.p_rgb32[RED_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_red_right)<<i_red_left;                
422             }
423             for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
424             {
425                 p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET - GREEN_MARGIN + i_index] = (pi_gamma[0]>>i_green_right)<<i_green_left;
426                 p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_green_right)<<i_green_left;
427             }
428             for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
429             {
430                 p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET - BLUE_MARGIN + i_index] = (pi_gamma[0]>>i_blue_right)<<i_blue_left;
431                 p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + BLUE_MARGIN + i_index] = (pi_gamma[255]>>i_blue_right)<<i_blue_left;                
432             }
433             for( i_index = 0; i_index < 256; i_index++ )
434             {
435                 p_vout->yuv.yuv.p_rgb32[RED_OFFSET + i_index] = (pi_gamma[i_index]>>i_red_right)<<i_red_left;
436                 p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + i_index] = (pi_gamma[i_index]>>i_green_right)<<i_green_left;
437                 p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + i_index] = (pi_gamma[i_index]>>i_blue_right)<<i_blue_left;
438             }            
439             break;        
440         }
441     }    
442
443     /*
444      * Set functions pointers
445      */
446     if( p_vout->b_grayscale )
447     {
448         /* Grayscale */
449         switch( p_vout->i_screen_depth )
450         {
451         case 15:
452         case 16:  
453             p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;        
454             p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray16;        
455             p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray16;        
456             break;        
457         case 24:
458             p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;        
459             p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray24;        
460             p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray24;        
461             break;        
462         case 32:        
463             p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;        
464             p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray32;        
465             p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray32;        
466             break;        
467         }        
468     }
469     else
470     {
471         /* Color */
472         switch( p_vout->i_screen_depth )
473         {
474         case 15:
475         case 16:  
476             p_vout->yuv.p_Convert420 =   (vout_yuv_convert_t *) ConvertYUV420RGB16;        
477             p_vout->yuv.p_Convert422 =   (vout_yuv_convert_t *) ConvertYUV422RGB16;        
478             p_vout->yuv.p_Convert444 =   (vout_yuv_convert_t *) ConvertYUV444RGB16;        
479             break;        
480         case 24:
481             p_vout->yuv.p_Convert420 =   (vout_yuv_convert_t *) ConvertYUV420RGB24;        
482             p_vout->yuv.p_Convert422 =   (vout_yuv_convert_t *) ConvertYUV422RGB24;        
483             p_vout->yuv.p_Convert444 =   (vout_yuv_convert_t *) ConvertYUV444RGB24;        
484             break;        
485         case 32:        
486             p_vout->yuv.p_Convert420 =   (vout_yuv_convert_t *) ConvertYUV420RGB32;        
487             p_vout->yuv.p_Convert422 =   (vout_yuv_convert_t *) ConvertYUV422RGB32;        
488             p_vout->yuv.p_Convert444 =   (vout_yuv_convert_t *) ConvertYUV444RGB32;        
489             break;        
490         }
491     }        
492 }
493
494 /*******************************************************************************
495  * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
496  *******************************************************************************/
497 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,
498                              int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
499                              int i_matrix_coefficients )
500 {
501     boolean_t   b_horizontal_scaling;               /* horizontal scaling type */
502     int         i_vertical_scaling;                   /* vertical scaling type */
503     int         i_x, i_y;                   /* horizontal and vertical indexes */
504     int         i_scale_count;                         /* scale modulo counter */
505     u16 *       p_gray;                               /* base convertion table */
506     u16 *       p_pic_start;         /* beginning of the current line for copy */
507     u16 *       p_buffer_start;                     /* convertion buffer start */
508     u16 *       p_buffer;                         /* convertion buffer pointer */
509     int *       p_offset_start;                          /* offset array start */
510     int *       p_offset;                              /* offset array pointer */
511     
512     /* 
513      * Initialize some values  - i_pic_line_width will store the line skip 
514      */
515     i_pic_line_width -= i_pic_width;
516     p_gray =            p_vout->yuv.yuv.p_gray16;    
517     p_buffer_start =    p_vout->yuv.p_buffer;        
518     p_offset_start =    p_vout->yuv.p_offset;                    
519     
520     /* 
521      * Set scalings 
522      */
523     if( i_pic_width - i_width > 0 )
524     {
525         /* Prepare scaling array for horizontal extension */
526         b_horizontal_scaling =  1;   
527         p_offset =              p_offset_start;
528         i_scale_count =         i_pic_width;
529         for( i_x = i_width; i_x--; )
530         {
531             while( (i_scale_count -= i_width) > 0 )
532             {
533                 *p_offset++ = 0;                
534             }
535             *p_offset++ = 1;            
536             i_scale_count += i_pic_width;            
537         }        
538     }
539     else if( i_pic_width - i_width < 0 )
540     {
541         /* Prepare scaling array for horizontal reduction */
542         b_horizontal_scaling =  1;
543         p_offset =              p_offset_start;        
544         i_scale_count =         i_pic_width;
545         for( i_x = i_pic_width; i_x--; )
546         {
547             *p_offset = 1;            
548             while( (i_scale_count -= i_pic_width) >= 0 )
549             {                
550                 *p_offset += 1;                
551             }
552             p_offset++;
553             i_scale_count += i_width;
554         }        
555     }
556     else
557     {
558         /* No horizontal scaling: YUV convertion is done directly to picture */          
559         b_horizontal_scaling = 0;        
560     }
561     if( i_pic_height - i_height > 0 )
562     {
563         i_vertical_scaling = 1;        
564     }
565     else if( i_pic_height - i_height < 0 )
566     {
567         i_vertical_scaling = -1;        
568     }
569     else
570     {
571         i_vertical_scaling = 0;        
572     }
573
574     /*
575      * Perform convertion
576      */
577     i_scale_count = i_pic_height;
578     for( i_y = 0; i_y < i_height; i_y++ )
579     {
580         /* Mark beginnning of line for possible later line copy, and initialize
581          * buffer */
582         p_pic_start =   p_pic;
583         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;        
584
585         /* Do YUV convertion to buffer - YUV picture is always formed of 16
586          * pixels wide blocks */
587         for( i_x = i_width / 16; i_x--;  )
588         {
589             *p_buffer++ = p_gray[ *p_y++ ];
590             *p_buffer++ = p_gray[ *p_y++ ];
591             *p_buffer++ = p_gray[ *p_y++ ];
592             *p_buffer++ = p_gray[ *p_y++ ];
593             *p_buffer++ = p_gray[ *p_y++ ];
594             *p_buffer++ = p_gray[ *p_y++ ];
595             *p_buffer++ = p_gray[ *p_y++ ];
596             *p_buffer++ = p_gray[ *p_y++ ];
597             *p_buffer++ = p_gray[ *p_y++ ];
598             *p_buffer++ = p_gray[ *p_y++ ];
599             *p_buffer++ = p_gray[ *p_y++ ];
600             *p_buffer++ = p_gray[ *p_y++ ];
601             *p_buffer++ = p_gray[ *p_y++ ];
602             *p_buffer++ = p_gray[ *p_y++ ];
603             *p_buffer++ = p_gray[ *p_y++ ];
604             *p_buffer++ = p_gray[ *p_y++ ];
605         }             
606
607         if( b_horizontal_scaling )
608         {
609             /* Horizontal scaling, convertion has been done to buffer.
610              * Rewind buffer and offset, then copy and scale line */
611             p_buffer = p_buffer_start;
612             p_offset = p_offset_start;            
613             for( i_x = i_pic_width / 16; i_x--; )
614             {
615                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
616                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
617                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
618                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
619                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
620                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
621                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
622                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
623                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
624                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
625                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
626                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
627                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
628                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
629                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
630                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
631             }            
632         }        
633         else
634         {
635             /* No scaling, convertion has been done directly in picture memory.
636              * Increment of picture pointer to end of line is still needed */
637             p_pic += i_pic_width;            
638         }
639
640         /* End of line: skip picture to reach beginning of next line */
641         p_pic += i_pic_line_width;
642  
643         /* 
644          * Handle vertical scaling. The current line can be copied or next one
645          * can be ignored.
646          */
647         switch( i_vertical_scaling )
648         {
649         case -1:                         /* vertical scaling factor is < 1 */
650             while( (i_scale_count -= i_pic_height) >= 0 )
651             {                
652                 /* Height reduction: skip next source line */
653                 p_y += i_width;
654                 i_y++;                
655             }            
656             i_scale_count += i_height;
657             break;            
658         case 1:                          /* vertical scaling factor is > 1 */
659             while( (i_scale_count -= i_height) > 0 )
660             {                
661                 /* Height increment: copy previous picture line */
662                 for( i_x = i_pic_width / 16; i_x--; )
663                 {
664                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
665                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
666                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
667                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
668                 }
669                 p_pic +=        i_pic_line_width;
670                 p_pic_start +=  i_pic_line_width;
671             }
672             i_scale_count += i_pic_height; 
673             break;
674         }
675     }
676 }
677
678 /*******************************************************************************
679  * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
680  *******************************************************************************/
681 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,
682                              int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
683                              int i_matrix_coefficients )
684 {
685     //??
686 }
687
688 /*******************************************************************************
689  * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
690  *******************************************************************************/
691 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,
692                              int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
693                              int i_matrix_coefficients )
694 {
695     //??
696 }
697
698 /*******************************************************************************
699  * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
700  *******************************************************************************/
701 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,
702                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
703                                 int i_matrix_coefficients )
704 {
705 /* MMX version */
706   //  int                 i_chroma_width, i_chroma_skip;      /* width and eol for chroma */
707 /*
708     i_chroma_width =    i_width / 2;
709     i_chroma_skip =     i_skip / 2;
710     ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height, 
711                            (i_width + i_skip) * sizeof( yuv_data_t ), 
712                            (i_chroma_width + i_chroma_skip) * sizeof( yuv_data_t),
713                            i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
714                            p_vout->i_screen_depth == 15 );    
715 */
716     boolean_t   b_horizontal_scaling;               /* horizontal scaling type */
717     int         i_vertical_scaling;                   /* vertical scaling type */
718     int         i_x, i_y;                   /* horizontal and vertical indexes */
719     int         i_scale_count;                         /* scale modulo counter */
720     int         i_uval, i_vval;                             /* U and V samples */
721     int         i_red, i_green, i_blue;            /* U and V modified samples */
722     int         i_chroma_width;                                /* chroma width */
723     u16 *       p_yuv;                                /* base convertion table */
724     u16 *       p_ybase;                       /* Y dependant convertion table */   
725     u16 *       p_pic_start;         /* beginning of the current line for copy */
726     u16 *       p_buffer_start;                     /* convertion buffer start */
727     u16 *       p_buffer;                         /* convertion buffer pointer */
728     int *       p_offset_start;                          /* offset array start */
729     int *       p_offset;                              /* offset array pointer */
730     
731     /* 
732      * Initialize some values  - i_pic_line_width will store the line skip 
733      */
734     i_pic_line_width -= i_pic_width;
735     i_chroma_width =    i_width / 2;
736     p_yuv =             p_vout->yuv.yuv.p_rgb16;
737     p_buffer_start =    p_vout->yuv.p_buffer;        
738     p_offset_start =    p_vout->yuv.p_offset;                    
739    
740     /* 
741      * Set scalings 
742      */
743     if( i_pic_width - i_width > 0 )
744     {
745         /* Prepare scaling array for horizontal extension */
746         b_horizontal_scaling =  1;   
747         p_offset =              p_offset_start;
748         i_scale_count =         i_pic_width;
749         for( i_x = i_width; i_x--; )
750         {
751             while( (i_scale_count -= i_width) > 0 )
752             {
753                 *p_offset++ = 0;                
754             }
755             *p_offset++ = 1;            
756             i_scale_count += i_pic_width;            
757         }        
758     }
759     else if( i_pic_width - i_width < 0 )
760     {
761         /* Prepare scaling array for horizontal reduction */
762         b_horizontal_scaling =  1;
763         p_offset =              p_offset_start;        
764         i_scale_count =         i_pic_width;
765         for( i_x = i_pic_width; i_x--; )
766         {
767             *p_offset = 1;            
768             while( (i_scale_count -= i_pic_width) >= 0 )
769             {                
770                 *p_offset += 1;                
771             }
772             p_offset++;
773             i_scale_count += i_width;
774         }        
775     }
776     else
777     {
778         /* No horizontal scaling: YUV convertion is done directly to picture */          
779         b_horizontal_scaling =  0;
780     }
781     if( i_pic_height - i_height > 0 )
782     {
783         i_vertical_scaling = 1;        
784     }
785     else if( i_pic_height - i_height < 0 )
786     {
787         i_vertical_scaling = -1;        
788     }
789     else
790     {
791         i_vertical_scaling = 0;        
792     }
793
794     /*
795      * Perform convertion
796      */
797     i_scale_count = i_pic_height;
798     for( i_y = 0; i_y < i_height; i_y++ )
799     {
800         /* Mark beginnning of line for possible later line copy, and initialize
801          * buffer */
802         p_pic_start =   p_pic;
803         p_buffer =      b_horizontal_scaling ? p_buffer_start : p_pic;        
804
805         /* Do YUV convertion to buffer - YUV picture is always formed of 16
806          * pixels wide blocks */
807         for( i_x = i_width / 16; i_x--;  )
808         {
809             CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
810             CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
811             CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
812             CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
813             CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
814             CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
815             CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
816             CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
817         }             
818
819         if( b_horizontal_scaling )
820         {
821             /* Horizontal scaling, convertion has been done to buffer.
822              * Rewind buffer and offset, then copy and scale line */
823             p_buffer = p_buffer_start;
824             p_offset = p_offset_start;            
825             for( i_x = i_pic_width / 16; i_x--; )
826             {
827                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
828                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
829                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
830                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
831                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
832                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
833                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
834                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
835                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
836                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
837                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
838                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
839                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
840                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
841                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
842                 *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                
843             }            
844         }        
845         else
846         {
847             /* No scaling, convertion has been done directly in picture memory.
848              * Increment of picture pointer to end of line is still needed */
849             p_pic += i_pic_width;            
850         }
851
852         /* If line is odd, rewind U and V samples */
853         if( !(i_y & 0x1) )
854         {
855             p_u -= i_chroma_width;
856             p_v -= i_chroma_width;
857         }
858
859         /* End of line: skip picture to reach beginning of next line */
860         p_pic += i_pic_line_width;
861  
862         /* 
863          * Handle vertical scaling. The current line can be copied or next one
864          * can be ignored.
865          */
866         switch( i_vertical_scaling )
867         {
868         case -1:                         /* vertical scaling factor is < 1 */
869             while( (i_scale_count -= i_pic_height) >= 0 )
870             {                
871                 /* Height reduction: skip next source line */
872                 p_y += i_width;
873                 if( ++i_y & 0x1 )
874                 {
875                     p_u += i_chroma_width;
876                     p_v += i_chroma_width;
877                 }                
878             }            
879             i_scale_count += i_height;
880             break;            
881         case 1:                          /* vertical scaling factor is > 1 */
882             while( (i_scale_count -= i_height) > 0 )
883             {                
884                 /* Height increment: copy previous picture line */
885                 for( i_x = i_pic_width / 16; i_x--; )
886                 {
887                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
888                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
889                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
890                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
891                 }
892                 p_pic +=        i_pic_line_width;
893                 p_pic_start +=  i_pic_line_width;
894             }
895             i_scale_count += i_pic_height; 
896             break;
897         }
898     }
899 }
900
901 /*******************************************************************************
902  * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
903  *******************************************************************************/
904 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,
905                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
906                                 int i_matrix_coefficients )
907 {
908     //??
909 }
910
911 /*******************************************************************************
912  * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
913  *******************************************************************************/
914 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,
915                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
916                                 int i_matrix_coefficients )
917 {
918     //??
919 }
920
921 /*******************************************************************************
922  * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
923  *******************************************************************************/
924 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,
925                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
926                                 int i_matrix_coefficients )
927 {
928     //???
929 }
930
931 /*******************************************************************************
932  * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
933  *******************************************************************************/
934 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,
935                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
936                                 int i_matrix_coefficients )
937 {
938     //???
939 }
940
941 /*******************************************************************************
942  * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
943  *******************************************************************************/
944 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,
945                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
946                                 int i_matrix_coefficients )
947 {    
948     //???
949 }
950
951 /*******************************************************************************
952  * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
953  *******************************************************************************/
954 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,
955                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
956                                 int i_matrix_coefficients )
957 {
958     //??
959 }
960
961 /*******************************************************************************
962  * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
963  *******************************************************************************/
964 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,
965                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
966                                 int i_matrix_coefficients )
967 {
968     //??
969 }
970
971 /*******************************************************************************
972  * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
973  *******************************************************************************/
974 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,
975                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
976                                 int i_matrix_coefficients )
977 {
978     //??
979 }
980
981 //-------------------- walken code follow ---------------------------------------
982
983 /*
984  * YUV to RGB routines.
985  *
986  * these routines calculate r, g and b values from each pixel's y, u and v.
987  * these r, g an b values are then passed thru a table lookup to take the
988  * gamma curve into account and find the corresponding pixel value.
989  *
990  * the table must store more than 3*256 values because of the possibility
991  * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
992  * values are in the following intervals :
993  * -176 to 255+176 for red
994  * -133 to 255+133 for green
995  * -222 to 255+222 for blue
996  *
997  * If the input y,u,v values are right, the r,g,b results are not expected
998  * to move out of the 0 to 255 interval but who knows what will happen in
999  * real use...
1000  *
1001  * the red, green and blue conversion tables are stored in a single 1935-entry
1002  * array. The respective positions of each component in the array have been
1003  * calculated to minimize the cache interactions of the 3 tables.
1004  */
1005
1006 static void yuvToRgb24 (unsigned char * Y,
1007                         unsigned char * U, unsigned char * V,
1008                         char * dest, int table[1935], int width)
1009 {
1010     int i;
1011     int u;
1012     int v;
1013     int uvRed;
1014     int uvGreen;
1015     int uvBlue;
1016     int * tableY;
1017     int tmp24;
1018
1019     i = width >> 3;
1020     while (i--) {
1021         u = *(U++);
1022         v = *(V++);
1023         uvRed = (V_RED_COEF*v) >> SHIFT;
1024         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1025         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1026
1027         tableY = table + *(Y++);
1028         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1029                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1030                         uvGreen] |
1031                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1032         *(dest++) = tmp24;
1033         *(dest++) = tmp24 >> 8;
1034         *(dest++) = tmp24 >> 16;
1035
1036         tableY = table + *(Y++);
1037         tmp24 = (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         *(dest++) = tmp24;
1042         *(dest++) = tmp24 >> 8;
1043         *(dest++) = tmp24 >> 16;
1044
1045         u = *(U++);
1046         v = *(V++);
1047         uvRed = (V_RED_COEF*v) >> SHIFT;
1048         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1049         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1050
1051         tableY = table + *(Y++);
1052         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1053                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1054                         uvGreen] |
1055                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1056         *(dest++) = tmp24;
1057         *(dest++) = tmp24 >> 8;
1058         *(dest++) = tmp24 >> 16;
1059
1060         tableY = table + *(Y++);
1061         tmp24 = (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         *(dest++) = tmp24;
1066         *(dest++) = tmp24 >> 8;
1067         *(dest++) = tmp24 >> 16;
1068
1069         u = *(U++);
1070         v = *(V++);
1071         uvRed = (V_RED_COEF*v) >> SHIFT;
1072         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1073         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1074
1075         tableY = table + *(Y++);
1076         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1077                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1078                         uvGreen] |
1079                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1080         *(dest++) = tmp24;
1081         *(dest++) = tmp24 >> 8;
1082         *(dest++) = tmp24 >> 16;
1083
1084         tableY = table + *(Y++);
1085         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1086                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1087                         uvGreen] |
1088                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1089         *(dest++) = tmp24;
1090         *(dest++) = tmp24 >> 8;
1091         *(dest++) = tmp24 >> 16;
1092
1093         u = *(U++);
1094         v = *(V++);
1095         uvRed = (V_RED_COEF*v) >> SHIFT;
1096         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1097         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1098
1099         tableY = table + *(Y++);
1100         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1101                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1102                         uvGreen] |
1103                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1104         *(dest++) = tmp24;
1105         *(dest++) = tmp24 >> 8;
1106         *(dest++) = tmp24 >> 16;
1107
1108         tableY = table + *(Y++);
1109         tmp24 = (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         *(dest++) = tmp24;
1114         *(dest++) = tmp24 >> 8;
1115         *(dest++) = tmp24 >> 16;
1116     }
1117
1118     i = (width & 7) >> 1;
1119     while (i--) {
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         tmp24 = (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         *(dest++) = tmp24;
1132         *(dest++) = tmp24 >> 8;
1133         *(dest++) = tmp24 >> 16;
1134
1135         tableY = table + *(Y++);
1136         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1137                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1138                         uvGreen] |
1139                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1140         *(dest++) = tmp24;
1141         *(dest++) = tmp24 >> 8;
1142         *(dest++) = tmp24 >> 16;
1143     }
1144
1145     if (width & 1) {
1146         u = *(U++);
1147         v = *(V++);
1148         uvRed = (V_RED_COEF*v) >> SHIFT;
1149         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1150         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1151
1152         tableY = table + *(Y++);
1153         tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1154                  tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1155                         uvGreen] |
1156                  tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1157         *(dest++) = tmp24;
1158         *(dest++) = tmp24 >> 8;
1159         *(dest++) = tmp24 >> 16;
1160     }
1161 }
1162
1163 static void yuvToRgb32 (unsigned char * Y,
1164                         unsigned char * U, unsigned char * V,
1165                         int * dest, int table[1935], int width)
1166 {
1167     int i;
1168     int u;
1169     int v;
1170     int uvRed;
1171     int uvGreen;
1172     int uvBlue;
1173     int * tableY;
1174
1175     i = width >> 4;
1176     while (i--) {
1177         u = *(U++);
1178         v = *(V++);
1179         uvRed = (V_RED_COEF*v) >> SHIFT;
1180         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1181         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1182
1183         tableY = table + *(Y++);
1184         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1185                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1186                             uvGreen] |
1187                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1188
1189         tableY = table + *(Y++);
1190         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1191                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1192                             uvGreen] |
1193                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1194
1195         u = *(U++);
1196         v = *(V++);
1197         uvRed = (V_RED_COEF*v) >> SHIFT;
1198         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1199         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1200
1201         tableY = table + *(Y++);
1202         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1203                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1204                             uvGreen] |
1205                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1206
1207         tableY = table + *(Y++);
1208         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1209                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1210                             uvGreen] |
1211                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1212
1213         u = *(U++);
1214         v = *(V++);
1215         uvRed = (V_RED_COEF*v) >> SHIFT;
1216         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1217         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1218
1219         tableY = table + *(Y++);
1220         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1221                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1222                             uvGreen] |
1223                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1224
1225         tableY = table + *(Y++);
1226         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1227                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1228                             uvGreen] |
1229                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1230
1231         u = *(U++);
1232         v = *(V++);
1233         uvRed = (V_RED_COEF*v) >> SHIFT;
1234         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1235         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1236
1237         tableY = table + *(Y++);
1238         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1239                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1240                             uvGreen] |
1241                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1242
1243         tableY = table + *(Y++);
1244         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1245                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1246                             uvGreen] |
1247                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1248
1249         u = *(U++);
1250         v = *(V++);
1251         uvRed = (V_RED_COEF*v) >> SHIFT;
1252         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1253         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1254
1255         tableY = table + *(Y++);
1256         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1257                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1258                             uvGreen] |
1259                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1260
1261         tableY = table + *(Y++);
1262         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1263                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1264                             uvGreen] |
1265                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1266
1267         u = *(U++);
1268         v = *(V++);
1269         uvRed = (V_RED_COEF*v) >> SHIFT;
1270         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1271         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1272
1273         tableY = table + *(Y++);
1274         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1275                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1276                             uvGreen] |
1277                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1278
1279         tableY = table + *(Y++);
1280         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1281                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1282                             uvGreen] |
1283                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1284
1285         u = *(U++);
1286         v = *(V++);
1287         uvRed = (V_RED_COEF*v) >> SHIFT;
1288         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1289         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1290
1291         tableY = table + *(Y++);
1292         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1293                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1294                             uvGreen] |
1295                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1296
1297         tableY = table + *(Y++);
1298         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1299                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1300                             uvGreen] |
1301                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1302
1303         u = *(U++);
1304         v = *(V++);
1305         uvRed = (V_RED_COEF*v) >> SHIFT;
1306         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1307         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1308
1309         tableY = table + *(Y++);
1310         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1311                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1312                             uvGreen] |
1313                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1314
1315         tableY = table + *(Y++);
1316         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1317                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1318                             uvGreen] |
1319                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1320     }
1321
1322     i = (width & 15) >> 1;
1323     while (i--) {
1324         u = *(U++);
1325         v = *(V++);
1326         uvRed = (V_RED_COEF*v) >> SHIFT;
1327         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1328         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1329
1330         tableY = table + *(Y++);
1331         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1332                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1333                             uvGreen] |
1334                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1335
1336         tableY = table + *(Y++);
1337         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1338                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1339                             uvGreen] |
1340                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1341     }
1342
1343     if (width & 1) {
1344         u = *(U++);
1345         v = *(V++);
1346         uvRed = (V_RED_COEF*v) >> SHIFT;
1347         uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1348         uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1349
1350         tableY = table + *(Y++);
1351         *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1352                      tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1353                             uvGreen] |
1354                      tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1355     }
1356 }