1 /*******************************************************************************
2 * video_yuv.c: YUV transformation functions
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 *******************************************************************************/
10 /*******************************************************************************
12 *******************************************************************************/
21 #include "vlc_thread.h"
23 #include "video_output.h"
24 #include "video_yuv.h"
27 /*******************************************************************************
29 *******************************************************************************/
31 /* RGB/YUV inversion matrix (ISO/IEC 13818-2 section 6.3.6, table 6.9) */
32 const int MATRIX_COEFFICIENTS_TABLE[8][4] =
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) */
44 /* Margins in convertion tables - these margins are used in case a RGB convertion
45 * would give a value outside the 0-255 range. */
46 #define RED_MARGIN 178
47 #define GREEN_MARGIN 135
48 #define BLUE_MARGIN 224
49 #define GRAY_MARGIN 384
53 #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
54 #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
55 #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
56 #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
58 /*******************************************************************************
60 *******************************************************************************/
61 static int BinaryLog ( u32 i );
62 static void MaskToShift ( int *pi_right, int *pi_left, u32 i_mask );
63 static void SetGammaTable ( int *pi_table, double f_gamma );
64 static void SetYUV ( vout_thread_t *p_vout );
66 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,
67 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
68 int i_matrix_coefficients );
69 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,
70 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
71 int i_matrix_coefficients );
72 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,
73 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
74 int i_matrix_coefficients );
75 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,
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 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,
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 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,
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 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,
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 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,
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 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,
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 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,
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 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,
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 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,
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 );
103 /*******************************************************************************
104 * CLIP_BYTE macro: boundary detection
105 *******************************************************************************
106 * Return parameter if between 0 and 255, else return nearest boundary (0 or
107 * 255). This macro is used to build translations tables.
108 *******************************************************************************/
109 #define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
111 /*******************************************************************************
112 * CONVERT_YUV_GRAY macro: grayscale YUV convertion
113 *******************************************************************************
114 * This macro does not perform any scaling, but crops the picture. It is
115 * provided as a temporary way of implementing an YUV convertion function.
116 *******************************************************************************/
117 #define CONVERT_YUV_GRAY \
118 /* Change boundaries according to picture size */ \
119 i_width = MIN( i_width, i_pic_width ); \
120 i_height = MIN( i_height, i_pic_height ); \
121 i_pic_line_width -= i_width; \
124 for (i_y = 0; i_y < i_height ; i_y++) \
126 for (i_x = 0; i_x < i_width; ) \
128 /* Convert 16 pixels (width is always multiple of 16 */ \
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 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
138 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
139 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
140 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
141 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
142 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
143 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
144 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
147 /* Skip until beginning of next line */ \
148 p_pic += i_pic_line_width; \
151 /*******************************************************************************
152 * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel convertion blocks
153 *******************************************************************************
154 * These convertion routines are used by YUV convertion functions.
155 * Convertion are made from p_y, p_u, p_v, which are modified, to p_buffer,
156 * which is also modified.
157 *******************************************************************************/
158 #define CONVERT_Y_PIXEL \
159 /* Only Y sample is present */ \
160 p_ybase = p_yuv + *(p_y++); \
161 *p_buffer++ = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] | \
162 p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] | \
163 p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue]; \
165 #define CONVERT_YUV_PIXEL \
166 /* Y, U and V samples are present */ \
169 i_red = (V_RED_COEF * i_vval) >> SHIFT; \
170 i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
171 i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
174 /*******************************************************************************
175 * vout_InitYUV: allocate and initialize translations tables
176 *******************************************************************************
177 * This function will allocate memory to store translation tables, depending
178 * of the screen depth.
179 *******************************************************************************/
180 int vout_InitYUV( vout_thread_t *p_vout )
182 size_t tables_size; /* tables size, in bytes */
184 /* Computes tables size */
185 switch( p_vout->i_screen_depth )
189 tables_size = sizeof( u16 ) * (p_vout->b_grayscale ? 1034 : 1935);
196 tables_size = sizeof( u32 ) * (p_vout->b_grayscale ? 1024 : 1935);
200 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
206 /* Allocate memory */
207 p_vout->yuv.p_base = malloc( tables_size );
208 if( p_vout->yuv.p_base == NULL )
210 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
214 /* Allocate memory for convertion buffer and offset array */
215 p_vout->yuv.p_buffer = malloc( VOUT_MAX_WIDTH * p_vout->i_bytes_per_pixel );
216 if( p_vout->yuv.p_buffer == NULL )
218 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
219 free( p_vout->yuv.p_base );
222 p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) );
223 if( p_vout->yuv.p_offset == NULL )
225 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
226 free( p_vout->yuv.p_base );
227 free( p_vout->yuv.p_buffer );
231 /* Initialize tables */
236 /*******************************************************************************
237 * vout_ResetTables: re-initialize translations tables
238 *******************************************************************************
239 * This function will initialize the tables allocated by vout_CreateTables and
240 * set functions pointers.
241 *******************************************************************************/
242 int vout_ResetYUV( vout_thread_t *p_vout )
244 vout_EndYUV( p_vout );
245 return( vout_InitYUV( p_vout ) );
248 /*******************************************************************************
249 * vout_EndYUV: destroy translations tables
250 *******************************************************************************
251 * Free memory allocated by vout_CreateTables.
252 *******************************************************************************/
253 void vout_EndYUV( vout_thread_t *p_vout )
255 free( p_vout->yuv.p_base );
256 free( p_vout->yuv.p_buffer );
257 free( p_vout->yuv.p_offset );
260 /* following functions are local */
262 /*******************************************************************************
263 * BinaryLog: computes the base 2 log of a binary value
264 *******************************************************************************
265 * This functions is used by MaskToShift during tables initialisation, to
266 * get a bit index from a binary value.
267 *******************************************************************************/
268 static int BinaryLog(u32 i)
293 if (i != ((u32)1 << i_log))
295 intf_ErrMsg("internal error: binary log overflow\n");
301 /*******************************************************************************
302 * MaskToShift: Transform a color mask into right and left shifts
303 *******************************************************************************
304 * This function is used during table initialisation. It can return a value
305 *******************************************************************************/
306 static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
308 u32 i_low, i_high; /* lower hand higher bits of the mask */
311 i_low = i_mask & (- i_mask); /* lower bit of the mask */
312 i_high = i_mask + i_low; /* higher bit of the mask */
314 /* Transform bits into an index */
315 i_low = BinaryLog (i_low);
316 i_high = BinaryLog (i_high);
318 /* Update pointers and return */
320 *pi_right = (8 - i_high + i_low);
323 /*******************************************************************************
324 * SetGammaTable: return intensity table transformed by gamma curve.
325 *******************************************************************************
326 * pi_table is a table of 256 entries from 0 to 255.
327 *******************************************************************************/
328 static void SetGammaTable( int *pi_table, double f_gamma )
330 int i_y; /* base intensity */
332 /* Use exp(gamma) instead of gamma */
333 f_gamma = exp(f_gamma );
335 /* Build gamma table */
336 for( i_y = 0; i_y < 256; i_y++ )
338 pi_table[ i_y ] = pow( (double)i_y / 256, f_gamma ) * 256;
342 /*******************************************************************************
343 * SetYUV: compute tables and set function pointers
344 + *******************************************************************************/
345 static void SetYUV( vout_thread_t *p_vout )
347 int pi_gamma[256]; /* gamma table */
348 int i_index; /* index in tables */
349 int i_red_right, i_red_left; /* red shifts */
350 int i_green_right, i_green_left; /* green shifts */
351 int i_blue_right, i_blue_left; /* blue shifts */
353 /* Build gamma table */
354 SetGammaTable( pi_gamma, p_vout->f_gamma );
357 * Set color masks and shifts
359 switch( p_vout->i_screen_depth )
362 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
363 MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
364 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
367 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
368 MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
369 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
373 MaskToShift( &i_red_right, &i_red_left, 0x00ff0000 );
374 MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
375 MaskToShift( &i_blue_right, &i_blue_left, 0x000000ff );
379 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
385 * Set pointers and build YUV tables
387 if( p_vout->b_grayscale )
389 /* Grayscale: build gray table */
390 switch( p_vout->i_screen_depth )
394 p_vout->yuv.yuv.p_gray16 = (u16 *)p_vout->yuv.p_base + GRAY_MARGIN;
395 for( i_index = -GRAY_MARGIN; i_index < 256 + GRAY_MARGIN; i_index++)
397 p_vout->yuv.yuv.p_gray16[ i_index ] =
398 ((pi_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
399 ((pi_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
400 ((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
405 p_vout->yuv.yuv.p_gray32 = (u32 *)p_vout->yuv.p_base + GRAY_MARGIN;
406 for( i_index = -GRAY_MARGIN; i_index < 256 + GRAY_MARGIN; i_index++)
408 p_vout->yuv.yuv.p_gray32[ i_index ] =
409 ((pi_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
410 ((pi_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
411 ((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
418 /* Color: build red, green and blue tables */
419 switch( p_vout->i_screen_depth )
423 p_vout->yuv.yuv.p_rgb16 = (u16 *)p_vout->yuv.p_base;
424 for( i_index = 0; i_index < RED_MARGIN; i_index++ )
426 p_vout->yuv.yuv.p_rgb16[1501 - RED_MARGIN + i_index] = (pi_gamma[0]>>i_red_right)<<i_red_left;
427 p_vout->yuv.yuv.p_rgb16[1501 + 256 + i_index] = (pi_gamma[255]>>i_red_right)<<i_red_left;
429 for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
431 p_vout->yuv.yuv.p_rgb16[135 - GREEN_MARGIN + i_index] = (pi_gamma[0]>>i_green_right)<<i_green_left;
432 p_vout->yuv.yuv.p_rgb16[135 + 256 + i_index] = (pi_gamma[255]>>i_green_right)<<i_green_left;
434 for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
436 p_vout->yuv.yuv.p_rgb16[818 - BLUE_MARGIN + i_index] = (pi_gamma[0]>>i_blue_right)<<i_blue_left;
437 p_vout->yuv.yuv.p_rgb16[818 + BLUE_MARGIN + i_index] = (pi_gamma[255]>>i_blue_right)<<i_blue_left;
439 for( i_index = 0; i_index < 256; i_index++ )
441 p_vout->yuv.yuv.p_rgb16[1501 + i_index] = (pi_gamma[i_index]>>i_red_right)<<i_red_left;
442 p_vout->yuv.yuv.p_rgb16[135 + i_index] = (pi_gamma[i_index]>>i_green_right)<<i_green_left;
443 p_vout->yuv.yuv.p_rgb16[818 + i_index] = (pi_gamma[i_index]>>i_blue_right)<<i_blue_left;
448 p_vout->yuv.yuv.p_rgb32 = (u32 *)p_vout->yuv.p_base;
449 for( i_index = 0; i_index < RED_MARGIN; i_index++ )
451 p_vout->yuv.yuv.p_rgb32[1501 - RED_MARGIN + i_index] = (pi_gamma[0]>>i_red_right)<<i_red_left;
452 p_vout->yuv.yuv.p_rgb32[1501 + 256 + i_index] = (pi_gamma[255]>>i_red_right)<<i_red_left;
454 for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
456 p_vout->yuv.yuv.p_rgb32[135 - GREEN_MARGIN + i_index] = (pi_gamma[0]>>i_green_right)<<i_green_left;
457 p_vout->yuv.yuv.p_rgb32[135 + 256 + i_index] = (pi_gamma[255]>>i_green_right)<<i_green_left;
459 for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
461 p_vout->yuv.yuv.p_rgb32[818 - BLUE_MARGIN + i_index] = (pi_gamma[0]>>i_blue_right)<<i_blue_left;
462 p_vout->yuv.yuv.p_rgb32[818 + BLUE_MARGIN + i_index] = (pi_gamma[255]>>i_blue_right)<<i_blue_left;
464 for( i_index = 0; i_index < 256; i_index++ )
466 p_vout->yuv.yuv.p_rgb32[1501 + i_index] = (pi_gamma[i_index]>>i_red_right)<<i_red_left;
467 p_vout->yuv.yuv.p_rgb32[135 + i_index] = (pi_gamma[i_index]>>i_green_right)<<i_green_left;
468 p_vout->yuv.yuv.p_rgb32[818 + i_index] = (pi_gamma[i_index]>>i_blue_right)<<i_blue_left;
475 * Set functions pointers
477 if( p_vout->b_grayscale )
480 switch( p_vout->i_screen_depth )
484 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
485 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
486 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
489 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
490 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
491 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
494 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
495 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
496 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
503 switch( p_vout->i_screen_depth )
507 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
508 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
509 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
512 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
513 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
514 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
517 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
518 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
519 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
525 /*******************************************************************************
526 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
527 *******************************************************************************/
528 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,
529 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
530 int i_matrix_coefficients )
532 u16 * p_gray; /* gray table */
533 int i_x, i_y; /* picture coordinates */
535 p_gray = p_vout->yuv.yuv.p_gray16;
539 /*******************************************************************************
540 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
541 *******************************************************************************/
542 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,
543 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
544 int i_matrix_coefficients )
549 /*******************************************************************************
550 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
551 *******************************************************************************/
552 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,
553 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
554 int i_matrix_coefficients )
556 u32 * p_gray; /* gray table */
557 int i_x, i_y; /* picture coordinates */
559 p_gray = p_vout->yuv.yuv.p_gray32;
563 /*******************************************************************************
564 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
565 *******************************************************************************/
566 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,
567 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
568 int i_matrix_coefficients )
571 // int i_chroma_width, i_chroma_skip; /* width and eol for chroma */
573 i_chroma_width = i_width / 2;
574 i_chroma_skip = i_skip / 2;
575 ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height,
576 (i_width + i_skip) * sizeof( yuv_data_t ),
577 (i_chroma_width + i_chroma_skip) * sizeof( yuv_data_t),
578 i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
579 p_vout->i_screen_depth == 15 );
581 boolean_t b_horizontal_scaling; /* horizontal scaling type */
582 int i_vertical_scaling; /* vertical scaling type */
583 int i_x, i_y; /* horizontal and vertical indexes */
584 int i_scale_count; /* scale modulo counter */
585 int i_uval, i_vval; /* U and V samples */
586 int i_red, i_green, i_blue; /* U and V modified samples */
587 int i_chroma_width; /* chroma width */
588 u16 * p_yuv; /* base convertion table */
589 u16 * p_ybase; /* Y dependant convertion table */
590 u16 * p_pic_start; /* beginning of the current line for copy */
591 u16 * p_buffer_start; /* convertion buffer start */
592 u16 * p_buffer; /* convertion buffer pointer */
593 int * p_offset_start; /* offset array start */
594 int * p_offset; /* offset array pointer */
597 * Initialize some values - i_pic_line_width will store the line skip
599 i_pic_line_width -= i_pic_width;
600 i_chroma_width = i_width / 2;
601 p_yuv = p_vout->yuv.yuv.p_rgb16;
606 if( i_pic_width - i_width > 0 )
608 /* Prepare scaling array for horizontal extension */
609 b_horizontal_scaling = 1;
610 p_buffer_start = p_vout->yuv.p_buffer;
611 p_offset_start = p_vout->yuv.p_offset;
612 p_offset = p_offset_start;
613 i_scale_count = i_pic_width;
614 for( i_x = i_width; i_x--; )
616 while( (i_scale_count -= i_width) > 0 )
621 i_scale_count += i_pic_width;
624 else if( i_pic_width - i_width < 0 )
626 /* Prepare scaling array for horizontal reduction */
627 b_horizontal_scaling = 1;
628 p_buffer_start = p_vout->yuv.p_buffer;
629 p_offset_start = p_vout->yuv.p_offset;
630 p_offset = p_offset_start;
631 i_scale_count = i_pic_width;
632 for( i_x = i_pic_width; i_x--; )
635 while( (i_scale_count -= i_pic_width) >= 0 )
640 i_scale_count += i_width;
645 /* No horizontal scaling: YUV convertion is done directly to picture */
646 b_horizontal_scaling = 0;
647 p_buffer_start = p_pic;
648 p_offset_start = NULL; /* to avoid warning */
650 if( i_pic_height - i_height > 0 )
652 i_vertical_scaling = 1;
654 else if( i_pic_height - i_height < 0 )
656 i_vertical_scaling = -1;
660 i_vertical_scaling = 0;
666 i_scale_count = i_pic_height;
667 for( i_y = 0; i_y < i_height; i_y++ )
669 /* Mark beginnning of line for possible later line copy, and initialize
672 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
674 /* Do YUV convertion to buffer - YUV picture is always formed of 16
675 * pixels wide blocks */
676 for( i_x = i_width / 16; i_x--; )
678 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
679 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
680 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
681 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
682 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
683 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
684 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
685 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
688 if( b_horizontal_scaling )
690 /* Horizontal scaling, convertion has been done to buffer.
691 * Rewind buffer and offset, then copy and scale line */
692 p_buffer = p_buffer_start;
693 p_offset = p_offset_start;
694 for( i_x = i_pic_width / 16; i_x--; )
696 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
697 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
698 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
699 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
700 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
701 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
702 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
703 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
704 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
705 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
706 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
707 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
708 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
709 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
710 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
711 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
716 /* No scaling, convertion has been done directly in picture memory.
717 * Increment of picture pointer to end of line is still needed */
718 p_pic += i_pic_width;
721 /* If line is odd, rewind U and V samples */
724 p_u -= i_chroma_width;
725 p_v -= i_chroma_width;
728 /* End of line: skip picture to reach beginning of next line */
729 p_pic += i_pic_line_width;
732 * Handle vertical scaling. The current line can be copied or next one
735 switch( i_vertical_scaling )
737 case -1: /* vertical scaling factor is < 1 */
738 while( (i_scale_count -= i_pic_height) >= 0 )
740 /* Height reduction: skip next source line */
744 p_u += i_chroma_width;
745 p_v += i_chroma_width;
748 i_scale_count += i_height;
750 case 1: /* vertical scaling factor is > 1 */
751 while( (i_scale_count -= i_height) > 0 )
753 /* Height increment: copy previous picture line */
754 for( i_x = i_pic_width / 16; i_x--; )
756 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
757 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
758 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
759 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
761 p_pic += i_pic_line_width;
762 p_pic_start += i_pic_line_width;
764 i_scale_count += i_pic_height;
770 /*******************************************************************************
771 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
772 *******************************************************************************/
773 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,
774 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
775 int i_matrix_coefficients )
780 /*******************************************************************************
781 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
782 *******************************************************************************/
783 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,
784 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
785 int i_matrix_coefficients )
790 /*******************************************************************************
791 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
792 *******************************************************************************/
793 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,
794 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
795 int i_matrix_coefficients )
800 /*******************************************************************************
801 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
802 *******************************************************************************/
803 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,
804 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
805 int i_matrix_coefficients )
810 /*******************************************************************************
811 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
812 *******************************************************************************/
813 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,
814 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
815 int i_matrix_coefficients )
820 /*******************************************************************************
821 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
822 *******************************************************************************/
823 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,
824 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
825 int i_matrix_coefficients )
830 /*******************************************************************************
831 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
832 *******************************************************************************/
833 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,
834 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
835 int i_matrix_coefficients )
840 /*******************************************************************************
841 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
842 *******************************************************************************/
843 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,
844 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
845 int i_matrix_coefficients )
850 //-------------------- walken code follow ---------------------------------------
853 * YUV to RGB routines.
855 * these routines calculate r, g and b values from each pixel's y, u and v.
856 * these r, g an b values are then passed thru a table lookup to take the
857 * gamma curve into account and find the corresponding pixel value.
859 * the table must store more than 3*256 values because of the possibility
860 * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
861 * values are in the following intervals :
862 * -176 to 255+176 for red
863 * -133 to 255+133 for green
864 * -222 to 255+222 for blue
866 * If the input y,u,v values are right, the r,g,b results are not expected
867 * to move out of the 0 to 255 interval but who knows what will happen in
870 * the red, green and blue conversion tables are stored in a single 1935-entry
871 * array. The respective positions of each component in the array have been
872 * calculated to minimize the cache interactions of the 3 tables.
875 static void yuvToRgb24 (unsigned char * Y,
876 unsigned char * U, unsigned char * V,
877 char * dest, int table[1935], int width)
892 uvRed = (V_RED_COEF*v) >> SHIFT;
893 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
894 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
896 tableY = table + *(Y++);
897 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
898 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
900 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
902 *(dest++) = tmp24 >> 8;
903 *(dest++) = tmp24 >> 16;
905 tableY = table + *(Y++);
906 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
907 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
909 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
911 *(dest++) = tmp24 >> 8;
912 *(dest++) = tmp24 >> 16;
916 uvRed = (V_RED_COEF*v) >> SHIFT;
917 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
918 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
920 tableY = table + *(Y++);
921 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
922 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
924 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
926 *(dest++) = tmp24 >> 8;
927 *(dest++) = tmp24 >> 16;
929 tableY = table + *(Y++);
930 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
931 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
933 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
935 *(dest++) = tmp24 >> 8;
936 *(dest++) = tmp24 >> 16;
940 uvRed = (V_RED_COEF*v) >> SHIFT;
941 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
942 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
944 tableY = table + *(Y++);
945 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
946 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
948 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
950 *(dest++) = tmp24 >> 8;
951 *(dest++) = tmp24 >> 16;
953 tableY = table + *(Y++);
954 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
955 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
957 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
959 *(dest++) = tmp24 >> 8;
960 *(dest++) = tmp24 >> 16;
964 uvRed = (V_RED_COEF*v) >> SHIFT;
965 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
966 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
968 tableY = table + *(Y++);
969 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
970 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
972 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
974 *(dest++) = tmp24 >> 8;
975 *(dest++) = tmp24 >> 16;
977 tableY = table + *(Y++);
978 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
979 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
981 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
983 *(dest++) = tmp24 >> 8;
984 *(dest++) = tmp24 >> 16;
987 i = (width & 7) >> 1;
991 uvRed = (V_RED_COEF*v) >> SHIFT;
992 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
993 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
995 tableY = table + *(Y++);
996 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
997 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
999 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1001 *(dest++) = tmp24 >> 8;
1002 *(dest++) = tmp24 >> 16;
1004 tableY = table + *(Y++);
1005 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1006 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1008 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1010 *(dest++) = tmp24 >> 8;
1011 *(dest++) = tmp24 >> 16;
1017 uvRed = (V_RED_COEF*v) >> SHIFT;
1018 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1019 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1021 tableY = table + *(Y++);
1022 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1023 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1025 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1027 *(dest++) = tmp24 >> 8;
1028 *(dest++) = tmp24 >> 16;
1032 static void yuvToRgb32 (unsigned char * Y,
1033 unsigned char * U, unsigned char * V,
1034 int * dest, int table[1935], int width)
1048 uvRed = (V_RED_COEF*v) >> SHIFT;
1049 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1050 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1052 tableY = table + *(Y++);
1053 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1054 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1056 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1058 tableY = table + *(Y++);
1059 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1060 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1062 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1066 uvRed = (V_RED_COEF*v) >> SHIFT;
1067 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1068 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1070 tableY = table + *(Y++);
1071 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1072 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1074 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1076 tableY = table + *(Y++);
1077 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1078 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1080 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1084 uvRed = (V_RED_COEF*v) >> SHIFT;
1085 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1086 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1088 tableY = table + *(Y++);
1089 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1090 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1092 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1094 tableY = table + *(Y++);
1095 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1096 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1098 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1102 uvRed = (V_RED_COEF*v) >> SHIFT;
1103 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1104 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1106 tableY = table + *(Y++);
1107 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1108 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1110 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1112 tableY = table + *(Y++);
1113 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1114 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1116 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1120 uvRed = (V_RED_COEF*v) >> SHIFT;
1121 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1122 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1124 tableY = table + *(Y++);
1125 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1126 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1128 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1130 tableY = table + *(Y++);
1131 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1132 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1134 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1138 uvRed = (V_RED_COEF*v) >> SHIFT;
1139 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1140 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1142 tableY = table + *(Y++);
1143 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1144 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1146 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1148 tableY = table + *(Y++);
1149 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1150 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1152 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1156 uvRed = (V_RED_COEF*v) >> SHIFT;
1157 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1158 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1160 tableY = table + *(Y++);
1161 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1162 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1164 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1166 tableY = table + *(Y++);
1167 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1168 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1170 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1174 uvRed = (V_RED_COEF*v) >> SHIFT;
1175 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1176 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1178 tableY = table + *(Y++);
1179 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1180 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1182 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1184 tableY = table + *(Y++);
1185 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1186 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1188 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1191 i = (width & 15) >> 1;
1195 uvRed = (V_RED_COEF*v) >> SHIFT;
1196 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1197 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1199 tableY = table + *(Y++);
1200 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1201 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1203 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1205 tableY = table + *(Y++);
1206 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1207 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1209 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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;
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) +
1223 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);