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) */
45 #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
46 #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
47 #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
48 #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
50 /*******************************************************************************
52 *******************************************************************************/
53 static int BinaryLog ( u32 i );
54 static void MaskToShift ( int *pi_right, int *pi_left, u32 i_mask );
55 static void SetGammaTable ( int *pi_table, double f_gamma );
56 static void SetYUV ( vout_thread_t *p_vout );
58 static void ConvertY4Gray16 ( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
59 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
60 int i_matrix_coefficients );
61 static void ConvertY4Gray24 ( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
62 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
63 int i_matrix_coefficients );
64 static void ConvertY4Gray32 ( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
65 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
66 int i_matrix_coefficients );
67 static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
68 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
69 int i_matrix_coefficients );
70 static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
71 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
72 int i_matrix_coefficients );
73 static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
74 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
75 int i_matrix_coefficients );
76 static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
77 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
78 int i_matrix_coefficients );
79 static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
80 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
81 int i_matrix_coefficients );
82 static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
83 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
84 int i_matrix_coefficients );
85 static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
86 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
87 int i_matrix_coefficients );
88 static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
89 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
90 int i_matrix_coefficients );
91 static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
92 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
93 int i_matrix_coefficients );
95 /*******************************************************************************
96 * CLIP_BYTE macro: boundary detection
97 *******************************************************************************
98 * Return parameter if between 0 and 255, else return nearest boundary (0 or
99 * 255). This macro is used to build translations tables.
100 *******************************************************************************/
101 #define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
103 /*******************************************************************************
104 * CONVERT_YUV_GRAY macro: grayscale YUV convertion
105 *******************************************************************************
106 * This macro does not perform any scaling, but crops the picture. It is
107 * provided as a temporary way of implementing an YUV convertion function.
108 *******************************************************************************/
109 #define CONVERT_YUV_GRAY \
110 /* Change boundaries according to picture size */ \
111 i_width = MIN( i_width, i_pic_width ); \
112 i_height = MIN( i_height, i_pic_height ); \
113 i_pic_line_width -= i_width; \
116 for (i_y = 0; i_y < i_height ; i_y++) \
118 for (i_x = 0; i_x < i_width; ) \
120 /* Convert 16 pixels (width is always multiple of 16 */ \
121 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
122 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
123 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
124 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
125 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
126 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
127 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
128 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
129 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
130 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
131 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
132 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
133 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
134 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
135 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
136 p_pic[i_x++] = p_gray[ p_y[i_x] ]; \
139 /* Skip until beginning of next line */ \
140 p_pic += i_pic_line_width; \
143 /*******************************************************************************
144 * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel convertion blocks
145 *******************************************************************************
146 * These convertion routines are used by YUV convertion functions.
147 * Convertion are made from p_y, p_u, p_v, which are modified, to p_buffer,
148 * which is also modified.
149 *******************************************************************************/
150 #define CONVERT_Y_PIXEL \
151 /* Only Y sample is present */ \
152 p_ybase = p_yuv + *(p_y++); \
153 *p_buffer++ = p_ybase[1501 - ((V_RED_COEF*128)>>SHIFT) + i_red] | \
154 p_ybase[135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) + i_green ] | \
155 p_ybase[818 - ((U_BLUE_COEF*128)>>SHIFT) + i_blue]; \
157 #define CONVERT_YUV_PIXEL \
158 /* Y, U and V samples are present */ \
161 i_red = (V_RED_COEF * i_vval) >> SHIFT; \
162 i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
163 i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
166 /*******************************************************************************
167 * vout_InitYUV: allocate and initialize translations tables
168 *******************************************************************************
169 * This function will allocate memory to store translation tables, depending
170 * of the screen depth.
171 *******************************************************************************/
172 int vout_InitYUV( vout_thread_t *p_vout )
174 size_t tables_size; /* tables size, in bytes */
176 /* Computes tables size */
177 switch( p_vout->i_screen_depth )
181 tables_size = sizeof( u16 ) * (1024 * (p_vout->b_grayscale ? 1 : 3) + 1935);
188 tables_size = sizeof( u32 ) * (1024 * (p_vout->b_grayscale ? 1 : 3) + 1935);
192 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
198 /* Allocate memory */
199 p_vout->yuv.p_base = malloc( tables_size );
200 if( p_vout->yuv.p_base == NULL )
202 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
206 /* Allocate memory for convertion buffer and offset array */
207 p_vout->yuv.p_buffer = malloc( VOUT_MAX_WIDTH * p_vout->i_bytes_per_pixel );
208 if( p_vout->yuv.p_buffer == NULL )
210 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
211 free( p_vout->yuv.p_base );
214 p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) );
215 if( p_vout->yuv.p_offset == NULL )
217 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
218 free( p_vout->yuv.p_base );
219 free( p_vout->yuv.p_buffer );
223 /* Initialize tables */
228 /*******************************************************************************
229 * vout_ResetTables: re-initialize translations tables
230 *******************************************************************************
231 * This function will initialize the tables allocated by vout_CreateTables and
232 * set functions pointers.
233 *******************************************************************************/
234 int vout_ResetYUV( vout_thread_t *p_vout )
236 vout_EndYUV( p_vout );
237 return( vout_InitYUV( p_vout ) );
240 /*******************************************************************************
241 * vout_EndYUV: destroy translations tables
242 *******************************************************************************
243 * Free memory allocated by vout_CreateTables.
244 *******************************************************************************/
245 void vout_EndYUV( vout_thread_t *p_vout )
247 free( p_vout->yuv.p_base );
248 free( p_vout->yuv.p_buffer );
249 free( p_vout->yuv.p_offset );
252 /* following functions are local */
254 /*******************************************************************************
255 * BinaryLog: computes the base 2 log of a binary value
256 *******************************************************************************
257 * This functions is used by MaskToShift during tables initialisation, to
258 * get a bit index from a binary value.
259 *******************************************************************************/
260 static int BinaryLog(u32 i)
285 if (i != ((u32)1 << i_log))
287 intf_ErrMsg("internal error: binary log overflow\n");
293 /*******************************************************************************
294 * MaskToShift: Transform a color mask into right and left shifts
295 *******************************************************************************
296 * This function is used during table initialisation. It can return a value
297 *******************************************************************************/
298 static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
300 u32 i_low, i_high; /* lower hand higher bits of the mask */
303 i_low = i_mask & (- i_mask); /* lower bit of the mask */
304 i_high = i_mask + i_low; /* higher bit of the mask */
306 /* Transform bits into an index */
307 i_low = BinaryLog (i_low);
308 i_high = BinaryLog (i_high);
310 /* Update pointers and return */
312 *pi_right = (8 - i_high + i_low);
315 /*******************************************************************************
316 * SetGammaTable: return intensity table transformed by gamma curve.
317 *******************************************************************************
318 * pi_table is a table of 256 entries from 0 to 255.
319 *******************************************************************************/
320 static void SetGammaTable( int *pi_table, double f_gamma )
322 int i_y; /* base intensity */
324 /* Use exp(gamma) instead of gamma */
325 f_gamma = exp(f_gamma );
327 /* Build gamma table */
328 for( i_y = 0; i_y < 256; i_y++ )
330 pi_table[ i_y ] = pow( (double)i_y / 256, f_gamma ) * 256;
334 /*******************************************************************************
335 * SetYUV: compute tables and set function pointers
336 + *******************************************************************************/
337 static void SetYUV( vout_thread_t *p_vout )
339 int pi_gamma[256]; /* gamma table */
340 int i_index; /* index in tables */
341 int i_red_right, i_red_left; /* red shifts */
342 int i_green_right, i_green_left; /* green shifts */
343 int i_blue_right, i_blue_left; /* blue shifts */
345 /* Build gamma table */
346 SetGammaTable( pi_gamma, p_vout->f_gamma );
349 * Set color masks and shifts
351 switch( p_vout->i_screen_depth )
354 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
355 MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
356 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
359 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
360 MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
361 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
365 MaskToShift( &i_red_right, &i_red_left, 0x00ff0000 );
366 MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
367 MaskToShift( &i_blue_right, &i_blue_left, 0x000000ff );
371 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
377 * Set pointers and build YUV tables
379 if( p_vout->b_grayscale )
381 /* Grayscale: build gray table */
382 switch( p_vout->i_screen_depth )
386 p_vout->yuv.yuv.gray16.p_gray = (u16 *)p_vout->yuv.p_base + 384;
387 for( i_index = -384; i_index < 640; i_index++)
389 p_vout->yuv.yuv.gray16.p_gray[ i_index ] =
390 ((pi_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
391 ((pi_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
392 ((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
397 p_vout->yuv.yuv.gray32.p_gray = (u32 *)p_vout->yuv.p_base + 384;
398 for( i_index = -384; i_index < 640; i_index++)
400 p_vout->yuv.yuv.gray32.p_gray[ i_index ] =
401 ((pi_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
402 ((pi_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
403 ((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
410 /* Color: build red, green and blue tables */
411 switch( p_vout->i_screen_depth )
415 p_vout->yuv.yuv.rgb16.p_red = (u16 *)p_vout->yuv.p_base + 384;
416 p_vout->yuv.yuv.rgb16.p_green = (u16 *)p_vout->yuv.p_base + 1024 + 384;
417 p_vout->yuv.yuv.rgb16.p_blue = (u16 *)p_vout->yuv.p_base + 2*1024 + 384;
418 p_vout->yuv.yuv2.p_rgb16 = (u16 *)p_vout->yuv.p_base + 3*1024;
419 for( i_index = -384; i_index < 640; i_index++)
421 p_vout->yuv.yuv.rgb16.p_red[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
422 p_vout->yuv.yuv.rgb16.p_green[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
423 p_vout->yuv.yuv.rgb16.p_blue[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
425 for( i_index = 0; i_index < 178; i_index++ )
427 p_vout->yuv.yuv2.p_rgb16[1501 - 178 + i_index] = (pi_gamma[0]>>i_red_right)<<i_red_left;
428 p_vout->yuv.yuv2.p_rgb16[1501 + 256 + i_index] = (pi_gamma[255]>>i_red_right)<<i_red_left;
430 for( i_index = 0; i_index < 135; i_index++ )
432 p_vout->yuv.yuv2.p_rgb16[135 - 135 + i_index] = (pi_gamma[0]>>i_green_right)<<i_green_left;
433 p_vout->yuv.yuv2.p_rgb16[135 + 256 + i_index] = (pi_gamma[255]>>i_green_right)<<i_green_left;
435 for( i_index = 0; i_index < 224; i_index++ )
437 p_vout->yuv.yuv2.p_rgb16[818 - 224 + i_index] = (pi_gamma[0]>>i_blue_right)<<i_blue_left;
438 p_vout->yuv.yuv2.p_rgb16[818 + 256 + i_index] = (pi_gamma[255]>>i_blue_right)<<i_blue_left;
440 for( i_index = 0; i_index < 256; i_index++ )
442 p_vout->yuv.yuv2.p_rgb16[1501 + i_index] = (pi_gamma[i_index]>>i_red_right)<<i_red_left;
443 p_vout->yuv.yuv2.p_rgb16[135 + i_index] = (pi_gamma[i_index]>>i_green_right)<<i_green_left;
444 p_vout->yuv.yuv2.p_rgb16[818 + i_index] = (pi_gamma[i_index]>>i_blue_right)<<i_blue_left;
449 p_vout->yuv.yuv.rgb32.p_red = (u32 *)p_vout->yuv.p_base + 384;
450 p_vout->yuv.yuv.rgb32.p_green = (u32 *)p_vout->yuv.p_base + 1024 + 384;
451 p_vout->yuv.yuv.rgb32.p_blue = (u32 *)p_vout->yuv.p_base + 2*1024 + 384;
452 p_vout->yuv.yuv2.p_rgb32 = (u32 *)p_vout->yuv.p_base + 3*1024;
453 for( i_index = -384; i_index < 640; i_index++)
455 p_vout->yuv.yuv.rgb32.p_red[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
456 p_vout->yuv.yuv.rgb32.p_green[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
457 p_vout->yuv.yuv.rgb32.p_blue[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
465 * Set functions pointers
467 if( p_vout->b_grayscale )
470 switch( p_vout->i_screen_depth )
474 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
475 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
476 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
479 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
480 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
481 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
484 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
485 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
486 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
493 switch( p_vout->i_screen_depth )
497 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
498 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
499 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
502 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
503 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
504 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
507 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
508 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
509 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
515 /*******************************************************************************
516 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
517 *******************************************************************************/
518 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,
519 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
520 int i_matrix_coefficients )
522 u16 * p_gray; /* gray table */
523 int i_x, i_y; /* picture coordinates */
525 p_gray = p_vout->yuv.yuv.gray16.p_gray;
529 /*******************************************************************************
530 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
531 *******************************************************************************/
532 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,
533 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
534 int i_matrix_coefficients )
539 /*******************************************************************************
540 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
541 *******************************************************************************/
542 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,
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 )
546 u32 * p_gray; /* gray table */
547 int i_x, i_y; /* picture coordinates */
549 p_gray = p_vout->yuv.yuv.gray32.p_gray;
553 /*******************************************************************************
554 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
555 *******************************************************************************/
556 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,
557 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
558 int i_matrix_coefficients )
561 // int i_chroma_width, i_chroma_skip; /* width and eol for chroma */
563 i_chroma_width = i_width / 2;
564 i_chroma_skip = i_skip / 2;
565 ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height,
566 (i_width + i_skip) * sizeof( yuv_data_t ),
567 (i_chroma_width + i_chroma_skip) * sizeof( yuv_data_t),
568 i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
569 p_vout->i_screen_depth == 15 );
571 boolean_t b_horizontal_scaling; /* horizontal scaling type */
572 int i_vertical_scaling; /* vertical scaling type */
573 int i_x, i_y; /* horizontal and vertical indexes */
574 int i_scale_count; /* scale modulo counter */
575 int i_uval, i_vval; /* U and V samples */
576 int i_red, i_green, i_blue; /* U and V modified samples */
577 int i_chroma_width; /* chroma width */
578 u16 * p_yuv; /* base convertion table */
579 u16 * p_ybase; /* Y dependant convertion table */
580 u16 * p_pic_start; /* beginning of the current line for copy */
581 u16 * p_buffer_start; /* convertion buffer start */
582 u16 * p_buffer; /* convertion buffer pointer */
583 int * p_offset_start; /* offset array start */
584 int * p_offset; /* offset array pointer */
587 * Initialize some values - i_pic_line_width will store the line skip
589 i_pic_line_width -= i_pic_width;
590 i_chroma_width = i_width / 2;
591 p_yuv = p_vout->yuv.yuv2.p_rgb16;
596 if( i_pic_width - i_width > 0 )
598 /* Prepare scaling array for horizontal extension */
599 b_horizontal_scaling = 1;
600 p_buffer_start = p_vout->yuv.p_buffer;
601 p_offset_start = p_vout->yuv.p_offset;
602 p_offset = p_offset_start;
603 i_scale_count = i_pic_width;
604 for( i_x = i_width; i_x--; )
606 while( (i_scale_count -= i_width) > 0 )
611 i_scale_count += i_pic_width;
614 else if( i_pic_width - i_width < 0 )
616 /* Prepare scaling array for horizontal reduction */
617 b_horizontal_scaling = 1;
618 p_buffer_start = p_vout->yuv.p_buffer;
619 p_offset_start = p_vout->yuv.p_offset;
620 p_offset = p_offset_start;
621 i_scale_count = i_pic_width;
622 for( i_x = i_pic_width; i_x--; )
625 while( (i_scale_count -= i_pic_width) >= 0 )
630 i_scale_count += i_width;
635 /* No horizontal scaling: YUV convertion is done directly to picture */
636 b_horizontal_scaling = 0;
637 p_buffer_start = p_pic;
638 p_offset_start = NULL; /* to avoid warning */
640 if( i_pic_height - i_height > 0 )
642 i_vertical_scaling = 1;
644 else if( i_pic_height - i_height < 0 )
646 i_vertical_scaling = -1;
650 i_vertical_scaling = 0;
656 i_scale_count = i_pic_height;
657 for( i_y = 0; i_y < i_height; i_y++ )
659 /* Mark beginnning of line for possible later line copy, and initialize
662 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
664 /* Do YUV convertion to buffer - YUV picture is always formed of 16
665 * pixels wide blocks */
666 for( i_x = i_width / 16; i_x--; )
668 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
669 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
670 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
671 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
672 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
673 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
674 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
675 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
678 if( b_horizontal_scaling )
680 /* Horizontal scaling, convertion has been done to buffer.
681 * Rewind buffer and offset, then copy and scale line */
682 p_buffer = p_buffer_start;
683 p_offset = p_offset_start;
684 for( i_x = i_pic_width / 16; i_x--; )
686 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
687 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
688 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
689 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
690 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
691 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
692 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
693 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
694 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
695 *p_pic++ = *p_buffer; p_buffer += *p_offset++;
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++;
706 /* No scaling, convertion has been done directly in picture memory.
707 * Increment of picture pointer to end of line is still needed */
708 p_pic += i_pic_width;
711 /* If line is odd, rewind U and V samples */
714 p_u -= i_chroma_width;
715 p_v -= i_chroma_width;
718 /* End of line: skip picture to reach beginning of next line */
719 p_pic += i_pic_line_width;
722 * Handle vertical scaling. The current line can be copied or next one
725 switch( i_vertical_scaling )
727 case -1: /* vertical scaling factor is < 1 */
728 while( (i_scale_count -= i_pic_height) >= 0 )
730 /* Height reduction: skip next source line */
732 if( ! (++i_y & 0x1) )
734 p_u += i_chroma_width;
735 p_v += i_chroma_width;
738 i_scale_count += i_height;
740 case 1: /* vertical scaling factor is > 1 */
741 while( (i_scale_count -= i_height) > 0 )
743 /* Height increment: copy previous picture line */
744 for( i_x = i_pic_width / 16; i_x--; )
746 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
747 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
748 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
749 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );
751 p_pic += i_pic_line_width;
752 p_pic_start += i_pic_line_width;
754 i_scale_count += i_pic_height;
760 /*******************************************************************************
761 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
762 *******************************************************************************/
763 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,
764 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
765 int i_matrix_coefficients )
770 /*******************************************************************************
771 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
772 *******************************************************************************/
773 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,
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 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
782 *******************************************************************************/
783 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,
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 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
792 *******************************************************************************/
793 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,
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 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
802 *******************************************************************************/
803 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,
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 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
812 *******************************************************************************/
813 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,
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 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
822 *******************************************************************************/
823 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,
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 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
832 *******************************************************************************/
833 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,
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 //-------------------- walken code follow ---------------------------------------
843 * YUV to RGB routines.
845 * these routines calculate r, g and b values from each pixel's y, u and v.
846 * these r, g an b values are then passed thru a table lookup to take the
847 * gamma curve into account and find the corresponding pixel value.
849 * the table must store more than 3*256 values because of the possibility
850 * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
851 * values are in the following intervals :
852 * -176 to 255+176 for red
853 * -133 to 255+133 for green
854 * -222 to 255+222 for blue
856 * If the input y,u,v values are right, the r,g,b results are not expected
857 * to move out of the 0 to 255 interval but who knows what will happen in
860 * the red, green and blue conversion tables are stored in a single 1935-entry
861 * array. The respective positions of each component in the array have been
862 * calculated to minimize the cache interactions of the 3 tables.
865 static int rgbTable32 (int table [1935],
866 int redMask, int greenMask, int blueMask,
867 unsigned char gamma[256])
881 MaskToShift (&redRight, &redLeft, redMask);
882 MaskToShift (&greenRight, &greenLeft, greenMask);
883 MaskToShift (&blueRight, &blueLeft, blueMask);
887 * green blue red +- 2 just to be sure
888 * green = 0-525 [151-370]
889 * blue = 594-1297 [834-1053] <834-29>
890 * red = 1323-1934 [1517-1736] <493-712>
893 redTable = table + 1501;
894 greenTable = table + 135;
895 blueTable = table + 818;
897 for (i = 0; i < 178; i++) {
899 redTable[i+256] = redMask;
901 for (i = 0; i < 135; i++) {
902 greenTable[i-135] = 0;
903 greenTable[i+256] = greenMask;
905 for (i = 0; i < 224; i++) {
906 blueTable[i-224] = 0;
907 blueTable[i+256] = blueMask;
910 for (i = 0; i < 256; i++) {
912 redTable[i] = ((y >> redRight) << redLeft);
913 greenTable[i] = ((y >> greenRight) << greenLeft);
914 blueTable[i] = ((y >> blueRight) << blueLeft);
921 static void yuvToRgb24 (unsigned char * Y,
922 unsigned char * U, unsigned char * V,
923 char * dest, int table[1935], int width)
938 uvRed = (V_RED_COEF*v) >> SHIFT;
939 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
940 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
942 tableY = table + *(Y++);
943 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
944 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
946 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
948 *(dest++) = tmp24 >> 8;
949 *(dest++) = tmp24 >> 16;
951 tableY = table + *(Y++);
952 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
953 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
955 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
957 *(dest++) = tmp24 >> 8;
958 *(dest++) = tmp24 >> 16;
962 uvRed = (V_RED_COEF*v) >> SHIFT;
963 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
964 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
966 tableY = table + *(Y++);
967 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
968 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
970 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
972 *(dest++) = tmp24 >> 8;
973 *(dest++) = tmp24 >> 16;
975 tableY = table + *(Y++);
976 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
977 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
979 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
981 *(dest++) = tmp24 >> 8;
982 *(dest++) = tmp24 >> 16;
986 uvRed = (V_RED_COEF*v) >> SHIFT;
987 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
988 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
990 tableY = table + *(Y++);
991 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
992 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
994 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
996 *(dest++) = tmp24 >> 8;
997 *(dest++) = tmp24 >> 16;
999 tableY = table + *(Y++);
1000 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1001 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1003 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1005 *(dest++) = tmp24 >> 8;
1006 *(dest++) = tmp24 >> 16;
1010 uvRed = (V_RED_COEF*v) >> SHIFT;
1011 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1012 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1014 tableY = table + *(Y++);
1015 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1016 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1018 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1020 *(dest++) = tmp24 >> 8;
1021 *(dest++) = tmp24 >> 16;
1023 tableY = table + *(Y++);
1024 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1025 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1027 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1029 *(dest++) = tmp24 >> 8;
1030 *(dest++) = tmp24 >> 16;
1033 i = (width & 7) >> 1;
1037 uvRed = (V_RED_COEF*v) >> SHIFT;
1038 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1039 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1041 tableY = table + *(Y++);
1042 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1043 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1045 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1047 *(dest++) = tmp24 >> 8;
1048 *(dest++) = tmp24 >> 16;
1050 tableY = table + *(Y++);
1051 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1052 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1054 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1056 *(dest++) = tmp24 >> 8;
1057 *(dest++) = tmp24 >> 16;
1063 uvRed = (V_RED_COEF*v) >> SHIFT;
1064 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1065 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1067 tableY = table + *(Y++);
1068 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1069 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1071 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1073 *(dest++) = tmp24 >> 8;
1074 *(dest++) = tmp24 >> 16;
1078 static void yuvToRgb32 (unsigned char * Y,
1079 unsigned char * U, unsigned char * V,
1080 int * dest, int table[1935], int width)
1094 uvRed = (V_RED_COEF*v) >> SHIFT;
1095 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1096 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1098 tableY = table + *(Y++);
1099 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1100 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1102 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1104 tableY = table + *(Y++);
1105 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1106 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1108 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1112 uvRed = (V_RED_COEF*v) >> SHIFT;
1113 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1114 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1116 tableY = table + *(Y++);
1117 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1118 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1120 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1122 tableY = table + *(Y++);
1123 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1124 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1126 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1130 uvRed = (V_RED_COEF*v) >> SHIFT;
1131 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1132 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1134 tableY = table + *(Y++);
1135 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1136 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1138 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1140 tableY = table + *(Y++);
1141 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1142 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1144 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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;
1152 tableY = table + *(Y++);
1153 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1154 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1156 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1158 tableY = table + *(Y++);
1159 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1160 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1162 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1166 uvRed = (V_RED_COEF*v) >> SHIFT;
1167 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1168 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1170 tableY = table + *(Y++);
1171 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1172 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1174 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1176 tableY = table + *(Y++);
1177 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1178 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1180 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1184 uvRed = (V_RED_COEF*v) >> SHIFT;
1185 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1186 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1188 tableY = table + *(Y++);
1189 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1190 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1192 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1194 tableY = table + *(Y++);
1195 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1196 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1198 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1202 uvRed = (V_RED_COEF*v) >> SHIFT;
1203 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1204 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1206 tableY = table + *(Y++);
1207 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1208 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1210 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1212 tableY = table + *(Y++);
1213 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1214 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1216 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1220 uvRed = (V_RED_COEF*v) >> SHIFT;
1221 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1222 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1224 tableY = table + *(Y++);
1225 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1226 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1228 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1230 tableY = table + *(Y++);
1231 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1232 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1234 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1237 i = (width & 15) >> 1;
1241 uvRed = (V_RED_COEF*v) >> SHIFT;
1242 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1243 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1245 tableY = table + *(Y++);
1246 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1247 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1249 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1251 tableY = table + *(Y++);
1252 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1253 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1255 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1261 uvRed = (V_RED_COEF*v) >> SHIFT;
1262 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1263 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1265 tableY = table + *(Y++);
1266 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1267 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1269 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);