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) */
33 const int MATRIX_COEFFICIENTS_TABLE[8][4] =
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) */
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 */
57 #define GRAY_MARGIN 384
58 #define GRAY_TABLE_SIZE 1024 /* total table size */
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))
67 /*******************************************************************************
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 );
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 );
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) )
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]; \
134 #define CONVERT_YUV_PIXEL \
135 /* Y, U and V samples are present */ \
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; \
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 )
151 size_t tables_size; /* tables size, in bytes */
153 /* Computes tables size */
154 switch( p_vout->i_screen_depth )
158 tables_size = sizeof( u16 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
165 tables_size = sizeof( u32 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
169 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
175 /* Allocate memory */
176 p_vout->yuv.p_base = malloc( tables_size );
177 if( p_vout->yuv.p_base == NULL )
179 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
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 )
187 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
188 free( p_vout->yuv.p_base );
191 p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) );
192 if( p_vout->yuv.p_offset == NULL )
194 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
195 free( p_vout->yuv.p_base );
196 free( p_vout->yuv.p_buffer );
200 /* Initialize tables */
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 )
213 vout_EndYUV( p_vout );
214 return( vout_InitYUV( p_vout ) );
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 )
224 free( p_vout->yuv.p_base );
225 free( p_vout->yuv.p_buffer );
226 free( p_vout->yuv.p_offset );
229 /* following functions are local */
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)
262 if (i != ((u32)1 << i_log))
264 intf_ErrMsg("internal error: binary log overflow\n");
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)
277 u32 i_low, i_high; /* lower hand higher bits of the mask */
280 i_low = i_mask & (- i_mask); /* lower bit of the mask */
281 i_high = i_mask + i_low; /* higher bit of the mask */
283 /* Transform bits into an index */
284 i_low = BinaryLog (i_low);
285 i_high = BinaryLog (i_high);
287 /* Update pointers and return */
289 *pi_right = (8 - i_high + i_low);
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 )
299 int i_y; /* base intensity */
301 /* Use exp(gamma) instead of gamma */
302 f_gamma = exp(f_gamma );
304 /* Build gamma table */
305 for( i_y = 0; i_y < 256; i_y++ )
307 pi_table[ i_y ] = pow( (double)i_y / 256, f_gamma ) * 256;
311 /*******************************************************************************
312 * SetYUV: compute tables and set function pointers
313 + *******************************************************************************/
314 static void SetYUV( vout_thread_t *p_vout )
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 */
322 /* Build gamma table */
323 SetGammaTable( pi_gamma, p_vout->f_gamma );
326 * Set color masks and shifts
328 switch( p_vout->i_screen_depth )
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 );
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 );
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 );
348 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
354 * Set pointers and build YUV tables
356 if( p_vout->b_grayscale )
358 /* Grayscale: build gray table */
359 switch( p_vout->i_screen_depth )
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++)
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);
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++)
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);
387 /* Color: build red, green and blue tables */
388 switch( p_vout->i_screen_depth )
392 p_vout->yuv.yuv.p_rgb16 = (u16 *)p_vout->yuv.p_base;
393 for( i_index = 0; i_index < RED_MARGIN; i_index++ )
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;
398 for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
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;
403 for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
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;
408 for( i_index = 0; i_index < 256; i_index++ )
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;
417 p_vout->yuv.yuv.p_rgb32 = (u32 *)p_vout->yuv.p_base;
418 for( i_index = 0; i_index < RED_MARGIN; i_index++ )
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;
423 for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
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;
428 for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
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;
433 for( i_index = 0; i_index < 256; i_index++ )
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;
444 * Set functions pointers
446 if( p_vout->b_grayscale )
449 switch( p_vout->i_screen_depth )
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;
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;
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;
472 switch( p_vout->i_screen_depth )
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;
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;
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;
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 )
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 */
513 * Initialize some values - i_pic_line_width will store the line skip
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;
523 if( i_pic_width - i_width > 0 )
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--; )
531 while( (i_scale_count -= i_width) > 0 )
536 i_scale_count += i_pic_width;
539 else if( i_pic_width - i_width < 0 )
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--; )
548 while( (i_scale_count -= i_pic_width) >= 0 )
553 i_scale_count += i_width;
558 /* No horizontal scaling: YUV convertion is done directly to picture */
559 b_horizontal_scaling = 0;
561 if( i_pic_height - i_height > 0 )
563 i_vertical_scaling = 1;
565 else if( i_pic_height - i_height < 0 )
567 i_vertical_scaling = -1;
571 i_vertical_scaling = 0;
577 i_scale_count = i_pic_height;
578 for( i_y = 0; i_y < i_height; i_y++ )
580 /* Mark beginnning of line for possible later line copy, and initialize
583 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
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--; )
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++ ];
607 if( b_horizontal_scaling )
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--; )
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++;
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;
640 /* End of line: skip picture to reach beginning of next line */
641 p_pic += i_pic_line_width;
644 * Handle vertical scaling. The current line can be copied or next one
647 switch( i_vertical_scaling )
649 case -1: /* vertical scaling factor is < 1 */
650 while( (i_scale_count -= i_pic_height) >= 0 )
652 /* Height reduction: skip next source line */
656 i_scale_count += i_height;
658 case 1: /* vertical scaling factor is > 1 */
659 while( (i_scale_count -= i_height) > 0 )
661 /* Height increment: copy previous picture line */
662 for( i_x = i_pic_width / 16; i_x--; )
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)++ );
669 p_pic += i_pic_line_width;
670 p_pic_start += i_pic_line_width;
672 i_scale_count += i_pic_height;
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 )
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 )
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 )
706 // int i_chroma_width, i_chroma_skip; /* width and eol for chroma */
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 );
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 */
732 * Initialize some values - i_pic_line_width will store the line skip
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;
743 if( i_pic_width - i_width > 0 )
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--; )
751 while( (i_scale_count -= i_width) > 0 )
756 i_scale_count += i_pic_width;
759 else if( i_pic_width - i_width < 0 )
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--; )
768 while( (i_scale_count -= i_pic_width) >= 0 )
773 i_scale_count += i_width;
778 /* No horizontal scaling: YUV convertion is done directly to picture */
779 b_horizontal_scaling = 0;
781 if( i_pic_height - i_height > 0 )
783 i_vertical_scaling = 1;
785 else if( i_pic_height - i_height < 0 )
787 i_vertical_scaling = -1;
791 i_vertical_scaling = 0;
797 i_scale_count = i_pic_height;
798 for( i_y = 0; i_y < i_height; i_y++ )
800 /* Mark beginnning of line for possible later line copy, and initialize
803 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
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--; )
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;
819 if( b_horizontal_scaling )
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--; )
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++;
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;
852 /* If line is odd, rewind U and V samples */
855 p_u -= i_chroma_width;
856 p_v -= i_chroma_width;
859 /* End of line: skip picture to reach beginning of next line */
860 p_pic += i_pic_line_width;
863 * Handle vertical scaling. The current line can be copied or next one
866 switch( i_vertical_scaling )
868 case -1: /* vertical scaling factor is < 1 */
869 while( (i_scale_count -= i_pic_height) >= 0 )
871 /* Height reduction: skip next source line */
875 p_u += i_chroma_width;
876 p_v += i_chroma_width;
879 i_scale_count += i_height;
881 case 1: /* vertical scaling factor is > 1 */
882 while( (i_scale_count -= i_height) > 0 )
884 /* Height increment: copy previous picture line */
885 for( i_x = i_pic_width / 16; i_x--; )
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)++ );
892 p_pic += i_pic_line_width;
893 p_pic_start += i_pic_line_width;
895 i_scale_count += i_pic_height;
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
981 //-------------------- walken code follow ---------------------------------------
984 * YUV to RGB routines.
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.
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
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
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.
1006 static void yuvToRgb24 (unsigned char * Y,
1007 unsigned char * U, unsigned char * V,
1008 char * dest, int table[1935], int width)
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;
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) +
1031 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1033 *(dest++) = tmp24 >> 8;
1034 *(dest++) = tmp24 >> 16;
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) +
1040 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1042 *(dest++) = tmp24 >> 8;
1043 *(dest++) = tmp24 >> 16;
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;
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) +
1055 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1057 *(dest++) = tmp24 >> 8;
1058 *(dest++) = tmp24 >> 16;
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) +
1064 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1066 *(dest++) = tmp24 >> 8;
1067 *(dest++) = tmp24 >> 16;
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;
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) +
1079 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1081 *(dest++) = tmp24 >> 8;
1082 *(dest++) = tmp24 >> 16;
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) +
1088 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1090 *(dest++) = tmp24 >> 8;
1091 *(dest++) = tmp24 >> 16;
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;
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) +
1103 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1105 *(dest++) = tmp24 >> 8;
1106 *(dest++) = tmp24 >> 16;
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) +
1112 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1114 *(dest++) = tmp24 >> 8;
1115 *(dest++) = tmp24 >> 16;
1118 i = (width & 7) >> 1;
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;
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) +
1130 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1132 *(dest++) = tmp24 >> 8;
1133 *(dest++) = tmp24 >> 16;
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) +
1139 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1141 *(dest++) = tmp24 >> 8;
1142 *(dest++) = tmp24 >> 16;
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 tmp24 = (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 *(dest++) = tmp24 >> 8;
1159 *(dest++) = tmp24 >> 16;
1163 static void yuvToRgb32 (unsigned char * Y,
1164 unsigned char * U, unsigned char * V,
1165 int * dest, int table[1935], int width)
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;
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) +
1187 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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) +
1193 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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;
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) +
1205 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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) +
1211 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]);
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) +
1229 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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;
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) +
1241 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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) +
1247 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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;
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) +
1259 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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) +
1265 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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;
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) +
1277 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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) +
1283 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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;
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) +
1295 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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) +
1301 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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;
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) +
1313 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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) +
1319 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1322 i = (width & 15) >> 1;
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;
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) +
1334 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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) +
1340 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
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;
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) +
1354 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);