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 );
74 static void SetOffset ( int i_width, int i_height, int i_pic_width, int i_pic_height,
75 boolean_t *pb_h_scaling, int *pi_v_scaling, int *p_offset );
77 static void ConvertY4Gray8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
78 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
79 int i_matrix_coefficients );
80 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,
81 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
82 int i_matrix_coefficients );
83 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,
84 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
85 int i_matrix_coefficients );
86 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,
87 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
88 int i_matrix_coefficients );
89 static void ConvertYUV420RGB8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
90 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
91 int i_matrix_coefficients );
92 static void ConvertYUV422RGB8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
93 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
94 int i_matrix_coefficients );
95 static void ConvertYUV444RGB8 ( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
96 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
97 int i_matrix_coefficients );
98 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,
99 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
100 int i_matrix_coefficients );
101 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,
102 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
103 int i_matrix_coefficients );
104 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,
105 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
106 int i_matrix_coefficients );
107 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,
108 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
109 int i_matrix_coefficients );
110 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,
111 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
112 int i_matrix_coefficients );
113 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,
114 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
115 int i_matrix_coefficients );
116 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,
117 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
118 int i_matrix_coefficients );
119 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,
120 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
121 int i_matrix_coefficients );
122 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,
123 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
124 int i_matrix_coefficients );
126 /*****************************************************************************
127 * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel convertion blocks
128 *****************************************************************************
129 * These convertion routines are used by YUV convertion functions.
130 * Convertion are made from p_y, p_u, p_v, which are modified, to p_buffer,
131 * which is also modified.
132 *****************************************************************************/
133 #define CONVERT_Y_PIXEL \
134 /* Only Y sample is present */ \
135 p_ybase = p_yuv + *p_y++; \
136 *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] | \
137 p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) \
138 + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
140 #define CONVERT_YUV_PIXEL \
141 /* Y, U and V samples are present */ \
144 i_red = (V_RED_COEF * i_vval) >> SHIFT; \
145 i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
146 i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
149 /*****************************************************************************
150 * SCALE_WIDTH: scale a line horizontally
151 *****************************************************************************
152 * This macro scale a line using rendering buffer and offset array.
153 *****************************************************************************/
154 #define SCALE_WIDTH \
155 if( b_horizontal_scaling ) \
157 /* Horizontal scaling, convertion has been done to buffer. \
158 * Rewind buffer and offset, then copy and scale line */ \
159 p_buffer = p_buffer_start; \
160 p_offset = p_offset_start; \
161 for( i_x = i_pic_width / 16; i_x--; ) \
163 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
164 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
165 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
166 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
167 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
168 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
169 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
170 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
171 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
172 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
173 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
174 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
175 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
176 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
177 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
178 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
180 p_pic += i_pic_line_width; \
184 /* No scaling, convertion has been done directly in picture memory. \
185 * Increment of picture pointer to end of line is still needed */ \
186 p_pic += i_pic_width + i_pic_line_width; \
189 /*****************************************************************************
190 * SCALE_HEIGHT: handle vertical scaling
191 *****************************************************************************
192 * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
193 * 444 for RGB convertion, or 400 for gray convertion.
194 *****************************************************************************/
195 #define SCALE_HEIGHT( CHROMA ) \
196 /* If line is odd, rewind 4:2:0 U and V samples */ \
197 if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
199 p_u -= i_chroma_width; \
200 p_v -= i_chroma_width; \
204 * Handle vertical scaling. The current line can be copied or next one \
207 switch( i_vertical_scaling ) \
209 case -1: /* vertical scaling factor is < 1 */ \
210 while( (i_scale_count -= i_pic_height) >= 0 ) \
212 /* Height reduction: skip next source line */ \
215 if( (CHROMA == 420) || (CHROMA == 422) ) \
219 p_u += i_chroma_width; \
220 p_v += i_chroma_width; \
223 else if( CHROMA == 444 ) \
229 i_scale_count += i_height; \
231 case 1: /* vertical scaling factor is > 1 */ \
232 while( (i_scale_count -= i_height) > 0 ) \
234 /* Height increment: copy previous picture line */ \
235 for( i_x = i_pic_width / 16; i_x--; ) \
237 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
238 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
239 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
240 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
242 p_pic += i_pic_line_width; \
243 p_pic_start += i_pic_line_width; \
245 i_scale_count += i_pic_height; \
249 /*****************************************************************************
250 * vout_InitYUV: allocate and initialize translations tables
251 *****************************************************************************
252 * This function will allocate memory to store translation tables, depending
253 * of the screen depth.
254 *****************************************************************************/
255 int vout_InitYUV( vout_thread_t *p_vout )
257 size_t tables_size; /* tables size, in bytes */
259 /* Computes tables size */
260 switch( p_vout->i_screen_depth )
263 tables_size = sizeof( u8 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
267 tables_size = sizeof( u16 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
274 tables_size = sizeof( u32 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
278 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
284 /* Allocate memory */
285 p_vout->yuv.p_base = malloc( tables_size );
286 if( p_vout->yuv.p_base == NULL )
288 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
292 /* Allocate memory for convertion buffer and offset array */
293 p_vout->yuv.p_buffer = malloc( VOUT_MAX_WIDTH * p_vout->i_bytes_per_pixel );
294 if( p_vout->yuv.p_buffer == NULL )
296 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
297 free( p_vout->yuv.p_base );
300 p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) );
301 if( p_vout->yuv.p_offset == NULL )
303 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
304 free( p_vout->yuv.p_base );
305 free( p_vout->yuv.p_buffer );
309 /* Initialize tables */
314 /*****************************************************************************
315 * vout_ResetTables: re-initialize translations tables
316 *****************************************************************************
317 * This function will initialize the tables allocated by vout_CreateTables and
318 * set functions pointers.
319 *****************************************************************************/
320 int vout_ResetYUV( vout_thread_t *p_vout )
322 vout_EndYUV( p_vout );
323 return( vout_InitYUV( p_vout ) );
326 /*****************************************************************************
327 * vout_EndYUV: destroy translations tables
328 *****************************************************************************
329 * Free memory allocated by vout_CreateTables.
330 *****************************************************************************/
331 void vout_EndYUV( vout_thread_t *p_vout )
333 free( p_vout->yuv.p_base );
334 free( p_vout->yuv.p_buffer );
335 free( p_vout->yuv.p_offset );
338 /* following functions are local */
340 /*****************************************************************************
341 * BinaryLog: computes the base 2 log of a binary value
342 *****************************************************************************
343 * This functions is used by MaskToShift during tables initialisation, to
344 * get a bit index from a binary value.
345 *****************************************************************************/
346 static int BinaryLog(u32 i)
371 if (i != ((u32)1 << i_log))
373 intf_ErrMsg("internal error: binary log overflow\n");
379 /*****************************************************************************
380 * MaskToShift: Transform a color mask into right and left shifts
381 *****************************************************************************
382 * This function is used during table initialisation. It can return a value
383 *****************************************************************************/
384 static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
386 u32 i_low, i_high; /* lower hand higher bits of the mask */
389 i_low = i_mask & (- i_mask); /* lower bit of the mask */
390 i_high = i_mask + i_low; /* higher bit of the mask */
392 /* Transform bits into an index */
393 i_low = BinaryLog (i_low);
394 i_high = BinaryLog (i_high);
396 /* Update pointers and return */
398 *pi_right = (8 - i_high + i_low);
401 /*****************************************************************************
402 * SetGammaTable: return intensity table transformed by gamma curve.
403 *****************************************************************************
404 * pi_table is a table of 256 entries from 0 to 255.
405 *****************************************************************************/
406 static void SetGammaTable( int *pi_table, double f_gamma )
408 int i_y; /* base intensity */
410 /* Use exp(gamma) instead of gamma */
411 f_gamma = exp(f_gamma );
413 /* Build gamma table */
414 for( i_y = 0; i_y < 256; i_y++ )
416 pi_table[ i_y ] = pow( (double)i_y / 256, f_gamma ) * 256;
420 /*****************************************************************************
421 * SetYUV: compute tables and set function pointers
422 + *****************************************************************************/
423 static void SetYUV( vout_thread_t *p_vout )
425 int pi_gamma[256]; /* gamma table */
426 int i_index; /* index in tables */
427 int i_red_right, i_red_left; /* red shifts */
428 int i_green_right, i_green_left; /* green shifts */
429 int i_blue_right, i_blue_left; /* blue shifts */
431 /* Build gamma table */
432 SetGammaTable( pi_gamma, p_vout->f_gamma );
435 * Set color masks and shifts
437 switch( p_vout->i_screen_depth )
440 MaskToShift( &i_red_right, &i_red_left, 0xe0 );
441 MaskToShift( &i_green_right, &i_green_left, 0x1c );
442 MaskToShift( &i_blue_right, &i_blue_left, 0x03 );
445 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
446 MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
447 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
450 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
451 MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
452 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
456 MaskToShift( &i_red_right, &i_red_left, 0x00ff0000 );
457 MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
458 MaskToShift( &i_blue_right, &i_blue_left, 0x000000ff );
462 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
468 * Set pointers and build YUV tables
470 if( p_vout->b_grayscale )
472 /* Grayscale: build gray table */
473 switch( p_vout->i_screen_depth )
476 p_vout->yuv.yuv.p_gray8 = (u8 *)p_vout->yuv.p_base + GRAY_MARGIN;
480 p_vout->yuv.yuv.p_gray16 = (u16 *)p_vout->yuv.p_base + GRAY_MARGIN;
481 for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
483 p_vout->yuv.yuv.p_gray16[ -i_index ] =
484 ((pi_gamma[ 0 ] >> i_red_right) << i_red_left) |
485 ((pi_gamma[ 0 ] >> i_green_right) << i_green_left) |
486 ((pi_gamma[ 0 ] >> i_blue_right) << i_blue_left);
487 p_vout->yuv.yuv.p_gray16[ 256 + i_index ] =
488 ((pi_gamma[ 255 ] >> i_red_right) << i_red_left) |
489 ((pi_gamma[ 255 ] >> i_green_right) << i_green_left) |
490 ((pi_gamma[ 255 ] >> i_blue_right) << i_blue_left);
492 for( i_index = 0; i_index < 256; i_index++)
494 p_vout->yuv.yuv.p_gray16[ i_index ] =
495 ((pi_gamma[ i_index ] >> i_red_right) << i_red_left) |
496 ((pi_gamma[ i_index ] >> i_green_right) << i_green_left) |
497 ((pi_gamma[ i_index ] >> i_blue_right) << i_blue_left);
502 p_vout->yuv.yuv.p_gray32 = (u32 *)p_vout->yuv.p_base + GRAY_MARGIN;
503 for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
505 p_vout->yuv.yuv.p_gray32[ -i_index ] =
506 ((pi_gamma[ 0 ] >> i_red_right) << i_red_left) |
507 ((pi_gamma[ 0 ] >> i_green_right) << i_green_left) |
508 ((pi_gamma[ 0 ] >> i_blue_right) << i_blue_left);
509 p_vout->yuv.yuv.p_gray32[ 256 + i_index ] =
510 ((pi_gamma[ 255 ] >> i_red_right) << i_red_left) |
511 ((pi_gamma[ 255 ] >> i_green_right) << i_green_left) |
512 ((pi_gamma[ 255 ] >> i_blue_right) << i_blue_left);
514 for( i_index = 0; i_index < 256; i_index++)
516 p_vout->yuv.yuv.p_gray32[ i_index ] =
517 ((pi_gamma[ i_index ] >> i_red_right) << i_red_left) |
518 ((pi_gamma[ i_index ] >> i_green_right) << i_green_left) |
519 ((pi_gamma[ i_index ] >> i_blue_right) << i_blue_left);
526 /* Color: build red, green and blue tables */
527 switch( p_vout->i_screen_depth )
530 p_vout->yuv.yuv.p_rgb8 = (u8 *)p_vout->yuv.p_base;
534 p_vout->yuv.yuv.p_rgb16 = (u16 *)p_vout->yuv.p_base;
535 for( i_index = 0; i_index < RED_MARGIN; i_index++ )
537 p_vout->yuv.yuv.p_rgb16[RED_OFFSET - RED_MARGIN + i_index] = (pi_gamma[0]>>i_red_right)<<i_red_left;
538 p_vout->yuv.yuv.p_rgb16[RED_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_red_right)<<i_red_left;
540 for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
542 p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET - GREEN_MARGIN + i_index] = (pi_gamma[0]>>i_green_right) <<i_green_left;
543 p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_green_right)<<i_green_left;
545 for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
547 p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET - BLUE_MARGIN + i_index] = (pi_gamma[0]>>i_blue_right)<<i_blue_left;
548 p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + BLUE_MARGIN + i_index] = (pi_gamma[255]>>i_blue_right)<<i_blue_left;
550 for( i_index = 0; i_index < 256; i_index++ )
552 p_vout->yuv.yuv.p_rgb16[RED_OFFSET + i_index] = (pi_gamma[i_index]>>i_red_right)<<i_red_left;
553 p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + i_index] = (pi_gamma[i_index]>>i_green_right)<<i_green_left;
554 p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + i_index] = (pi_gamma[i_index]>>i_blue_right)<<i_blue_left;
559 p_vout->yuv.yuv.p_rgb32 = (u32 *)p_vout->yuv.p_base;
560 for( i_index = 0; i_index < RED_MARGIN; i_index++ )
562 p_vout->yuv.yuv.p_rgb32[RED_OFFSET - RED_MARGIN + i_index] = (pi_gamma[0]>>i_red_right)<<i_red_left;
563 p_vout->yuv.yuv.p_rgb32[RED_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_red_right)<<i_red_left;
565 for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
567 p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET - GREEN_MARGIN + i_index] = (pi_gamma[0]>>i_green_right)<<i_green_left;
568 p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_green_right)<<i_green_left;
570 for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
572 p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET - BLUE_MARGIN + i_index] = (pi_gamma[0]>>i_blue_right)<<i_blue_left;
573 p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + BLUE_MARGIN + i_index] = (pi_gamma[255]>>i_blue_right)<<i_blue_left;
575 for( i_index = 0; i_index < 256; i_index++ )
577 p_vout->yuv.yuv.p_rgb32[RED_OFFSET + i_index] = (pi_gamma[i_index]>>i_red_right)<<i_red_left;
578 p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + i_index] = (pi_gamma[i_index]>>i_green_right)<<i_green_left;
579 p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + i_index] = (pi_gamma[i_index]>>i_blue_right)<<i_blue_left;
586 * Set functions pointers
588 if( p_vout->b_grayscale )
591 switch( p_vout->i_screen_depth )
594 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray8;
595 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray8;
596 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray8;
600 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
601 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray16;
602 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray16;
605 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
606 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray24;
607 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray24;
610 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
611 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray32;
612 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray32;
619 switch( p_vout->i_screen_depth )
622 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB8;
623 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB8;
624 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB8;
628 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
629 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
630 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
633 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
634 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
635 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
638 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
639 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
640 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
646 /*****************************************************************************
647 * SetOffset: build offset array for convertion functions
648 *****************************************************************************
649 * This function will build an offset array used in later convertion functions.
650 * It will also set horizontal and vertical scaling indicators.
651 *****************************************************************************/
652 static void SetOffset( int i_width, int i_height, int i_pic_width, int i_pic_height,
653 boolean_t *pb_h_scaling, int *pi_v_scaling, int *p_offset )
655 int i_x; /* x position in destination */
656 int i_scale_count; /* modulo counter */
659 * Prepare horizontal offset array
661 if( i_pic_width - i_width > 0 )
663 /* Prepare scaling array for horizontal extension */
665 i_scale_count = i_pic_width;
666 for( i_x = i_width; i_x--; )
668 while( (i_scale_count -= i_width) > 0 )
673 i_scale_count += i_pic_width;
676 else if( i_pic_width - i_width < 0 )
678 /* Prepare scaling array for horizontal reduction */
680 i_scale_count = i_pic_width;
681 for( i_x = i_pic_width; i_x--; )
684 while( (i_scale_count -= i_pic_width) >= 0 )
689 i_scale_count += i_width;
694 /* No horizontal scaling: YUV convertion is done directly to picture */
699 * Set vertical scaling indicator
701 if( i_pic_height - i_height > 0 )
705 else if( i_pic_height - i_height < 0 )
715 /*****************************************************************************
716 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
717 *****************************************************************************/
718 static void ConvertY4Gray8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y,
719 yuv_data_t *p_u, yuv_data_t *p_v, int i_width,
720 int i_height, int i_pic_width, int i_pic_height,
721 int i_pic_line_width, int i_matrix_coefficients )
723 boolean_t b_horizontal_scaling; /* horizontal scaling type */
724 int i_vertical_scaling; /* vertical scaling type */
725 int i_x, i_y; /* horizontal and vertical indexes */
726 int i_scale_count; /* scale modulo counter */
727 int i_chroma_width; /* chroma width, not used */
728 u8 * p_gray; /* base convertion table */
729 u8 * p_pic_start; /* beginning of the current line for copy */
730 u8 * p_buffer_start; /* convertion buffer start */
731 u8 * p_buffer; /* convertion buffer pointer */
732 int * p_offset_start; /* offset array start */
733 int * p_offset; /* offset array pointer */
736 * Initialize some values - i_pic_line_width will store the line skip
738 i_pic_line_width -= i_pic_width;
739 p_gray = p_vout->yuv.yuv.p_gray8;
740 p_buffer_start = p_vout->yuv.p_buffer;
741 p_offset_start = p_vout->yuv.p_offset;
742 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
743 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
748 i_scale_count = i_pic_height;
749 for( i_y = 0; i_y < i_height; i_y++ )
751 /* Mark beginnning of line for possible later line copy, and initialize
754 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
756 /* Do YUV convertion to buffer - YUV picture is always formed of 16
757 * pixels wide blocks */
758 for( i_x = i_width / 16; i_x--; )
760 *p_buffer++ = p_gray[ *p_y++ ];
761 *p_buffer++ = p_gray[ *p_y++ ];
762 *p_buffer++ = p_gray[ *p_y++ ];
763 *p_buffer++ = p_gray[ *p_y++ ];
764 *p_buffer++ = p_gray[ *p_y++ ];
765 *p_buffer++ = p_gray[ *p_y++ ];
766 *p_buffer++ = p_gray[ *p_y++ ];
767 *p_buffer++ = p_gray[ *p_y++ ];
768 *p_buffer++ = p_gray[ *p_y++ ];
769 *p_buffer++ = p_gray[ *p_y++ ];
770 *p_buffer++ = p_gray[ *p_y++ ];
771 *p_buffer++ = p_gray[ *p_y++ ];
772 *p_buffer++ = p_gray[ *p_y++ ];
773 *p_buffer++ = p_gray[ *p_y++ ];
774 *p_buffer++ = p_gray[ *p_y++ ];
775 *p_buffer++ = p_gray[ *p_y++ ];
778 /* Do horizontal and vertical scaling */
784 /*****************************************************************************
785 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
786 *****************************************************************************/
787 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,
788 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
789 int i_matrix_coefficients )
791 boolean_t b_horizontal_scaling; /* horizontal scaling type */
792 int i_vertical_scaling; /* vertical scaling type */
793 int i_x, i_y; /* horizontal and vertical indexes */
794 int i_scale_count; /* scale modulo counter */
795 int i_chroma_width; /* chroma width, not used */
796 u16 * p_gray; /* base convertion table */
797 u16 * p_pic_start; /* beginning of the current line for copy */
798 u16 * p_buffer_start; /* convertion buffer start */
799 u16 * p_buffer; /* convertion buffer pointer */
800 int * p_offset_start; /* offset array start */
801 int * p_offset; /* offset array pointer */
804 * Initialize some values - i_pic_line_width will store the line skip
806 i_pic_line_width -= i_pic_width;
807 p_gray = p_vout->yuv.yuv.p_gray16;
808 p_buffer_start = p_vout->yuv.p_buffer;
809 p_offset_start = p_vout->yuv.p_offset;
810 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
811 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
816 i_scale_count = i_pic_height;
817 for( i_y = 0; i_y < i_height; i_y++ )
819 /* Mark beginnning of line for possible later line copy, and initialize
822 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
824 /* Do YUV convertion to buffer - YUV picture is always formed of 16
825 * pixels wide blocks */
826 for( i_x = i_width / 16; i_x--; )
828 *p_buffer++ = p_gray[ *p_y++ ];
829 *p_buffer++ = p_gray[ *p_y++ ];
830 *p_buffer++ = p_gray[ *p_y++ ];
831 *p_buffer++ = p_gray[ *p_y++ ];
832 *p_buffer++ = p_gray[ *p_y++ ];
833 *p_buffer++ = p_gray[ *p_y++ ];
834 *p_buffer++ = p_gray[ *p_y++ ];
835 *p_buffer++ = p_gray[ *p_y++ ];
836 *p_buffer++ = p_gray[ *p_y++ ];
837 *p_buffer++ = p_gray[ *p_y++ ];
838 *p_buffer++ = p_gray[ *p_y++ ];
839 *p_buffer++ = p_gray[ *p_y++ ];
840 *p_buffer++ = p_gray[ *p_y++ ];
841 *p_buffer++ = p_gray[ *p_y++ ];
842 *p_buffer++ = p_gray[ *p_y++ ];
843 *p_buffer++ = p_gray[ *p_y++ ];
846 /* Do horizontal and vertical scaling */
852 /*****************************************************************************
853 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
854 *****************************************************************************/
855 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,
856 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
857 int i_matrix_coefficients )
862 /*****************************************************************************
863 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
864 *****************************************************************************/
865 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,
866 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
867 int i_matrix_coefficients )
869 boolean_t b_horizontal_scaling; /* horizontal scaling type */
870 int i_vertical_scaling; /* vertical scaling type */
871 int i_x, i_y; /* horizontal and vertical indexes */
872 int i_scale_count; /* scale modulo counter */
873 int i_chroma_width; /* chroma width, not used */
874 u32 * p_gray; /* base convertion table */
875 u32 * p_pic_start; /* beginning of the current line for copy */
876 u32 * p_buffer_start; /* convertion buffer start */
877 u32 * p_buffer; /* convertion buffer pointer */
878 int * p_offset_start; /* offset array start */
879 int * p_offset; /* offset array pointer */
882 * Initialize some values - i_pic_line_width will store the line skip
884 i_pic_line_width -= i_pic_width;
885 p_gray = p_vout->yuv.yuv.p_gray32;
886 p_buffer_start = p_vout->yuv.p_buffer;
887 p_offset_start = p_vout->yuv.p_offset;
888 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
889 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
894 i_scale_count = i_pic_height;
895 for( i_y = 0; i_y < i_height; i_y++ )
897 /* Mark beginnning of line for possible later line copy, and initialize
900 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
902 /* Do YUV convertion to buffer - YUV picture is always formed of 16
903 * pixels wide blocks */
904 for( i_x = i_width / 16; i_x--; )
906 *p_buffer++ = p_gray[ *p_y++ ];
907 *p_buffer++ = p_gray[ *p_y++ ];
908 *p_buffer++ = p_gray[ *p_y++ ];
909 *p_buffer++ = p_gray[ *p_y++ ];
910 *p_buffer++ = p_gray[ *p_y++ ];
911 *p_buffer++ = p_gray[ *p_y++ ];
912 *p_buffer++ = p_gray[ *p_y++ ];
913 *p_buffer++ = p_gray[ *p_y++ ];
914 *p_buffer++ = p_gray[ *p_y++ ];
915 *p_buffer++ = p_gray[ *p_y++ ];
916 *p_buffer++ = p_gray[ *p_y++ ];
917 *p_buffer++ = p_gray[ *p_y++ ];
918 *p_buffer++ = p_gray[ *p_y++ ];
919 *p_buffer++ = p_gray[ *p_y++ ];
920 *p_buffer++ = p_gray[ *p_y++ ];
921 *p_buffer++ = p_gray[ *p_y++ ];
924 /* Do horizontal and vertical scaling */
930 /*****************************************************************************
931 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
932 *****************************************************************************/
933 static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
934 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
935 int i_matrix_coefficients )
937 boolean_t b_horizontal_scaling; /* horizontal scaling type */
938 int i_vertical_scaling; /* vertical scaling type */
939 int i_x, i_y; /* horizontal and vertical indexes */
940 int i_scale_count; /* scale modulo counter */
941 int i_uval, i_vval; /* U and V samples */
942 int i_red, i_green, i_blue; /* U and V modified samples */
943 int i_chroma_width; /* chroma width */
944 u8 * p_yuv; /* base convertion table */
945 u8 * p_ybase; /* Y dependant convertion table */
946 u8 * p_pic_start; /* beginning of the current line for copy */
947 u8 * p_buffer_start; /* convertion buffer start */
948 u8 * p_buffer; /* convertion buffer pointer */
949 int * p_offset_start; /* offset array start */
950 int * p_offset; /* offset array pointer */
953 * Initialize some values - i_pic_line_width will store the line skip
955 i_pic_line_width -= i_pic_width;
956 i_chroma_width = i_width / 2;
957 p_yuv = p_vout->yuv.yuv.p_rgb8;
958 p_buffer_start = p_vout->yuv.p_buffer;
959 p_offset_start = p_vout->yuv.p_offset;
960 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
961 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
966 i_scale_count = i_pic_height;
967 for( i_y = 0; i_y < i_height; i_y++ )
969 /* Mark beginnning of line for possible later line copy, and initialize
972 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
974 /* Do YUV convertion to buffer - YUV picture is always formed of 16
975 * pixels wide blocks */
976 for( i_x = i_width / 16; i_x--; )
978 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
979 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
980 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
981 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
982 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
983 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
984 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
985 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
988 /* Do horizontal and vertical scaling */
994 /*****************************************************************************
995 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
996 *****************************************************************************/
997 static void ConvertYUV422RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
998 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
999 int i_matrix_coefficients )
1001 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1002 int i_vertical_scaling; /* vertical scaling type */
1003 int i_x, i_y; /* horizontal and vertical indexes */
1004 int i_scale_count; /* scale modulo counter */
1005 int i_uval, i_vval; /* U and V samples */
1006 int i_red, i_green, i_blue; /* U and V modified samples */
1007 int i_chroma_width; /* chroma width */
1008 u8 * p_yuv; /* base convertion table */
1009 u8 * p_ybase; /* Y dependant convertion table */
1010 u8 * p_pic_start; /* beginning of the current line for copy */
1011 u8 * p_buffer_start; /* convertion buffer start */
1012 u8 * p_buffer; /* convertion buffer pointer */
1013 int * p_offset_start; /* offset array start */
1014 int * p_offset; /* offset array pointer */
1017 * Initialize some values - i_pic_line_width will store the line skip
1019 i_pic_line_width -= i_pic_width;
1020 i_chroma_width = i_width / 2;
1021 p_yuv = p_vout->yuv.yuv.p_rgb8;
1022 p_buffer_start = p_vout->yuv.p_buffer;
1023 p_offset_start = p_vout->yuv.p_offset;
1024 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1025 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1028 * Perform convertion
1030 i_scale_count = i_pic_height;
1031 for( i_y = 0; i_y < i_height; i_y++ )
1033 /* Mark beginnning of line for possible later line copy, and initialize
1035 p_pic_start = p_pic;
1036 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1038 /* Do YUV convertion to buffer - YUV picture is always formed of 16
1039 * pixels wide blocks */
1040 for( i_x = i_width / 16; i_x--; )
1042 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1043 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1044 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1045 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1046 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1047 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1048 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1049 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1052 /* Do horizontal and vertical scaling */
1058 /*****************************************************************************
1059 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
1060 *****************************************************************************/
1061 static void ConvertYUV444RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
1062 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1063 int i_matrix_coefficients )
1065 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1066 int i_vertical_scaling; /* vertical scaling type */
1067 int i_x, i_y; /* horizontal and vertical indexes */
1068 int i_scale_count; /* scale modulo counter */
1069 int i_uval, i_vval; /* U and V samples */
1070 int i_red, i_green, i_blue; /* U and V modified samples */
1071 int i_chroma_width; /* chroma width, not used */
1072 u8 * p_yuv; /* base convertion table */
1073 u8 * p_ybase; /* Y dependant convertion table */
1074 u8 * p_pic_start; /* beginning of the current line for copy */
1075 u8 * p_buffer_start; /* convertion buffer start */
1076 u8 * p_buffer; /* convertion buffer pointer */
1077 int * p_offset_start; /* offset array start */
1078 int * p_offset; /* offset array pointer */
1081 * Initialize some values - i_pic_line_width will store the line skip
1083 i_pic_line_width -= i_pic_width;
1084 p_yuv = p_vout->yuv.yuv.p_rgb8;
1085 p_buffer_start = p_vout->yuv.p_buffer;
1086 p_offset_start = p_vout->yuv.p_offset;
1087 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1088 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1091 * Perform convertion
1093 i_scale_count = i_pic_height;
1094 for( i_y = 0; i_y < i_height; i_y++ )
1096 /* Mark beginnning of line for possible later line copy, and initialize
1098 p_pic_start = p_pic;
1099 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1101 /* Do YUV convertion to buffer - YUV picture is always formed of 16
1102 * pixels wide blocks */
1103 for( i_x = i_width / 16; i_x--; )
1105 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1106 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1107 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1108 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1109 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1110 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1111 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1112 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1115 /* Do horizontal and vertical scaling */
1121 /*****************************************************************************
1122 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
1123 *****************************************************************************/
1124 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,
1125 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1126 int i_matrix_coefficients )
1129 // int i_chroma_width, i_chroma_skip; /* width and eol for chroma */
1131 i_chroma_width = i_width / 2;
1132 i_chroma_skip = i_skip / 2;
1133 ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height,
1134 (i_width + i_skip) * sizeof( yuv_data_t ),
1135 (i_chroma_width + i_chroma_skip) * sizeof( yuv_data_t),
1136 i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
1137 p_vout->i_screen_depth == 15 );
1139 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1140 int i_vertical_scaling; /* vertical scaling type */
1141 int i_x, i_y; /* horizontal and vertical indexes */
1142 int i_scale_count; /* scale modulo counter */
1143 int i_uval, i_vval; /* U and V samples */
1144 int i_red, i_green, i_blue; /* U and V modified samples */
1145 int i_chroma_width; /* chroma width */
1146 u16 * p_yuv; /* base convertion table */
1147 u16 * p_ybase; /* Y dependant convertion table */
1148 u16 * p_pic_start; /* beginning of the current line for copy */
1149 u16 * p_buffer_start; /* convertion buffer start */
1150 u16 * p_buffer; /* convertion buffer pointer */
1151 int * p_offset_start; /* offset array start */
1152 int * p_offset; /* offset array pointer */
1155 * Initialize some values - i_pic_line_width will store the line skip
1157 i_pic_line_width -= i_pic_width;
1158 i_chroma_width = i_width / 2;
1159 p_yuv = p_vout->yuv.yuv.p_rgb16;
1160 p_buffer_start = p_vout->yuv.p_buffer;
1161 p_offset_start = p_vout->yuv.p_offset;
1162 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1163 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1166 * Perform convertion
1168 i_scale_count = i_pic_height;
1169 for( i_y = 0; i_y < i_height; i_y++ )
1171 /* Mark beginnning of line for possible later line copy, and initialize
1173 p_pic_start = p_pic;
1174 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1176 /* Do YUV convertion to buffer - YUV picture is always formed of 16
1177 * pixels wide blocks */
1178 for( i_x = i_width / 16; i_x--; )
1180 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1181 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1182 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1183 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1184 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1185 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1186 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1187 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1190 /* Do horizontal and vertical scaling */
1196 /*****************************************************************************
1197 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
1198 *****************************************************************************/
1199 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,
1200 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1201 int i_matrix_coefficients )
1203 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1204 int i_vertical_scaling; /* vertical scaling type */
1205 int i_x, i_y; /* horizontal and vertical indexes */
1206 int i_scale_count; /* scale modulo counter */
1207 int i_uval, i_vval; /* U and V samples */
1208 int i_red, i_green, i_blue; /* U and V modified samples */
1209 int i_chroma_width; /* chroma width */
1210 u16 * p_yuv; /* base convertion table */
1211 u16 * p_ybase; /* Y dependant convertion table */
1212 u16 * p_pic_start; /* beginning of the current line for copy */
1213 u16 * p_buffer_start; /* convertion buffer start */
1214 u16 * p_buffer; /* convertion buffer pointer */
1215 int * p_offset_start; /* offset array start */
1216 int * p_offset; /* offset array pointer */
1219 * Initialize some values - i_pic_line_width will store the line skip
1221 i_pic_line_width -= i_pic_width;
1222 i_chroma_width = i_width / 2;
1223 p_yuv = p_vout->yuv.yuv.p_rgb16;
1224 p_buffer_start = p_vout->yuv.p_buffer;
1225 p_offset_start = p_vout->yuv.p_offset;
1226 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1227 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1230 * Perform convertion
1232 i_scale_count = i_pic_height;
1233 for( i_y = 0; i_y < i_height; i_y++ )
1235 /* Mark beginnning of line for possible later line copy, and initialize
1237 p_pic_start = p_pic;
1238 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1240 /* Do YUV convertion to buffer - YUV picture is always formed of 16
1241 * pixels wide blocks */
1242 for( i_x = i_width / 16; i_x--; )
1244 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1245 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1246 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1247 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1248 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1249 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1250 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1251 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1254 /* Do horizontal and vertical scaling */
1260 /*****************************************************************************
1261 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
1262 *****************************************************************************/
1263 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,
1264 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1265 int i_matrix_coefficients )
1267 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1268 int i_vertical_scaling; /* vertical scaling type */
1269 int i_x, i_y; /* horizontal and vertical indexes */
1270 int i_scale_count; /* scale modulo counter */
1271 int i_uval, i_vval; /* U and V samples */
1272 int i_red, i_green, i_blue; /* U and V modified samples */
1273 int i_chroma_width; /* chroma width, not used */
1274 u16 * p_yuv; /* base convertion table */
1275 u16 * p_ybase; /* Y dependant convertion table */
1276 u16 * p_pic_start; /* beginning of the current line for copy */
1277 u16 * p_buffer_start; /* convertion buffer start */
1278 u16 * p_buffer; /* convertion buffer pointer */
1279 int * p_offset_start; /* offset array start */
1280 int * p_offset; /* offset array pointer */
1283 * Initialize some values - i_pic_line_width will store the line skip
1285 i_pic_line_width -= i_pic_width;
1286 p_yuv = p_vout->yuv.yuv.p_rgb16;
1287 p_buffer_start = p_vout->yuv.p_buffer;
1288 p_offset_start = p_vout->yuv.p_offset;
1289 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1290 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1293 * Perform convertion
1295 i_scale_count = i_pic_height;
1296 for( i_y = 0; i_y < i_height; i_y++ )
1298 /* Mark beginnning of line for possible later line copy, and initialize
1300 p_pic_start = p_pic;
1301 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1303 /* Do YUV convertion to buffer - YUV picture is always formed of 16
1304 * pixels wide blocks */
1305 for( i_x = i_width / 16; i_x--; )
1307 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1308 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1309 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1310 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1311 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1312 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1313 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1314 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1317 /* Do horizontal and vertical scaling */
1323 /*****************************************************************************
1324 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
1325 *****************************************************************************/
1326 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,
1327 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1328 int i_matrix_coefficients )
1333 /*****************************************************************************
1334 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
1335 *****************************************************************************/
1336 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,
1337 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1338 int i_matrix_coefficients )
1343 /*****************************************************************************
1344 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
1345 *****************************************************************************/
1346 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,
1347 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1348 int i_matrix_coefficients )
1353 /*****************************************************************************
1354 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
1355 *****************************************************************************/
1356 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,
1357 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1358 int i_matrix_coefficients )
1360 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1361 int i_vertical_scaling; /* vertical scaling type */
1362 int i_x, i_y; /* horizontal and vertical indexes */
1363 int i_scale_count; /* scale modulo counter */
1364 int i_uval, i_vval; /* U and V samples */
1365 int i_red, i_green, i_blue; /* U and V modified samples */
1366 int i_chroma_width; /* chroma width */
1367 u32 * p_yuv; /* base convertion table */
1368 u32 * p_ybase; /* Y dependant convertion table */
1369 u32 * p_pic_start; /* beginning of the current line for copy */
1370 u32 * p_buffer_start; /* convertion buffer start */
1371 u32 * p_buffer; /* convertion buffer pointer */
1372 int * p_offset_start; /* offset array start */
1373 int * p_offset; /* offset array pointer */
1376 * Initialize some values - i_pic_line_width will store the line skip
1378 i_pic_line_width -= i_pic_width;
1379 i_chroma_width = i_width / 2;
1380 p_yuv = p_vout->yuv.yuv.p_rgb32;
1381 p_buffer_start = p_vout->yuv.p_buffer;
1382 p_offset_start = p_vout->yuv.p_offset;
1383 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1384 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1387 * Perform convertion
1389 i_scale_count = i_pic_height;
1390 for( i_y = 0; i_y < i_height; i_y++ )
1392 /* Mark beginnning of line for possible later line copy, and initialize
1394 p_pic_start = p_pic;
1395 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1397 /* Do YUV convertion to buffer - YUV picture is always formed of 16
1398 * pixels wide blocks */
1399 for( i_x = i_width / 16; i_x--; )
1401 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1402 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1403 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1404 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1405 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1406 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1407 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1408 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1411 /* Do horizontal and vertical scaling */
1417 /*****************************************************************************
1418 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
1419 *****************************************************************************/
1420 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,
1421 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1422 int i_matrix_coefficients )
1424 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1425 int i_vertical_scaling; /* vertical scaling type */
1426 int i_x, i_y; /* horizontal and vertical indexes */
1427 int i_scale_count; /* scale modulo counter */
1428 int i_uval, i_vval; /* U and V samples */
1429 int i_red, i_green, i_blue; /* U and V modified samples */
1430 int i_chroma_width; /* chroma width */
1431 u32 * p_yuv; /* base convertion table */
1432 u32 * p_ybase; /* Y dependant convertion table */
1433 u32 * p_pic_start; /* beginning of the current line for copy */
1434 u32 * p_buffer_start; /* convertion buffer start */
1435 u32 * p_buffer; /* convertion buffer pointer */
1436 int * p_offset_start; /* offset array start */
1437 int * p_offset; /* offset array pointer */
1440 * Initialize some values - i_pic_line_width will store the line skip
1442 i_pic_line_width -= i_pic_width;
1443 i_chroma_width = i_width / 2;
1444 p_yuv = p_vout->yuv.yuv.p_rgb32;
1445 p_buffer_start = p_vout->yuv.p_buffer;
1446 p_offset_start = p_vout->yuv.p_offset;
1447 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1448 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1451 * Perform convertion
1453 i_scale_count = i_pic_height;
1454 for( i_y = 0; i_y < i_height; i_y++ )
1456 /* Mark beginnning of line for possible later line copy, and initialize
1458 p_pic_start = p_pic;
1459 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1461 /* Do YUV convertion to buffer - YUV picture is always formed of 16
1462 * pixels wide blocks */
1463 for( i_x = i_width / 16; i_x--; )
1465 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1466 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1467 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1468 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1469 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1470 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1471 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1472 CONVERT_YUV_PIXEL; CONVERT_Y_PIXEL;
1475 /* Do horizontal and vertical scaling */
1481 /*****************************************************************************
1482 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
1483 *****************************************************************************/
1484 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,
1485 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1486 int i_matrix_coefficients )
1488 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1489 int i_vertical_scaling; /* vertical scaling type */
1490 int i_x, i_y; /* horizontal and vertical indexes */
1491 int i_scale_count; /* scale modulo counter */
1492 int i_uval, i_vval; /* U and V samples */
1493 int i_red, i_green, i_blue; /* U and V modified samples */
1494 int i_chroma_width; /* chroma width, not used */
1495 u32 * p_yuv; /* base convertion table */
1496 u32 * p_ybase; /* Y dependant convertion table */
1497 u32 * p_pic_start; /* beginning of the current line for copy */
1498 u32 * p_buffer_start; /* convertion buffer start */
1499 u32 * p_buffer; /* convertion buffer pointer */
1500 int * p_offset_start; /* offset array start */
1501 int * p_offset; /* offset array pointer */
1504 * Initialize some values - i_pic_line_width will store the line skip
1506 i_pic_line_width -= i_pic_width;
1507 p_yuv = p_vout->yuv.yuv.p_rgb32;
1508 p_buffer_start = p_vout->yuv.p_buffer;
1509 p_offset_start = p_vout->yuv.p_offset;
1510 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1511 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1514 * Perform convertion
1516 i_scale_count = i_pic_height;
1517 for( i_y = 0; i_y < i_height; i_y++ )
1519 /* Mark beginnning of line for possible later line copy, and initialize
1521 p_pic_start = p_pic;
1522 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1524 /* Do YUV convertion to buffer - YUV picture is always formed of 16
1525 * pixels wide blocks */
1526 for( i_x = i_width / 16; i_x--; )
1528 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1529 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1530 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1531 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1532 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1533 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1534 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1535 CONVERT_YUV_PIXEL; CONVERT_YUV_PIXEL;
1538 /* Do horizontal and vertical scaling */
1544 //-------------------- walken code follows ------------------------------------
1547 * YUV to RGB routines.
1549 * these routines calculate r, g and b values from each pixel's y, u and v.
1550 * these r, g an b values are then passed thru a table lookup to take the
1551 * gamma curve into account and find the corresponding pixel value.
1553 * the table must store more than 3*256 values because of the possibility
1554 * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
1555 * values are in the following intervals :
1556 * -176 to 255+176 for red
1557 * -133 to 255+133 for green
1558 * -222 to 255+222 for blue
1560 * If the input y,u,v values are right, the r,g,b results are not expected
1561 * to move out of the 0 to 255 interval but who knows what will happen in
1564 * the red, green and blue conversion tables are stored in a single 1935-entry
1565 * array. The respective positions of each component in the array have been
1566 * calculated to minimize the cache interactions of the 3 tables.
1570 static void yuvToRgb24 (unsigned char * Y,
1571 unsigned char * U, unsigned char * V,
1572 char * dest, int table[1935], int width)
1587 uvRed = (V_RED_COEF*v) >> SHIFT;
1588 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1589 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1591 tableY = table + *(Y++);
1592 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1593 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1595 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1597 *(dest++) = tmp24 >> 8;
1598 *(dest++) = tmp24 >> 16;
1600 tableY = table + *(Y++);
1601 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1602 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1604 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1606 *(dest++) = tmp24 >> 8;
1607 *(dest++) = tmp24 >> 16;
1611 uvRed = (V_RED_COEF*v) >> SHIFT;
1612 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1613 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1615 tableY = table + *(Y++);
1616 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1617 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1619 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1621 *(dest++) = tmp24 >> 8;
1622 *(dest++) = tmp24 >> 16;
1624 tableY = table + *(Y++);
1625 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1626 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1628 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1630 *(dest++) = tmp24 >> 8;
1631 *(dest++) = tmp24 >> 16;
1635 uvRed = (V_RED_COEF*v) >> SHIFT;
1636 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1637 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1639 tableY = table + *(Y++);
1640 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1641 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1643 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1645 *(dest++) = tmp24 >> 8;
1646 *(dest++) = tmp24 >> 16;
1648 tableY = table + *(Y++);
1649 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1650 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1652 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1654 *(dest++) = tmp24 >> 8;
1655 *(dest++) = tmp24 >> 16;
1659 uvRed = (V_RED_COEF*v) >> SHIFT;
1660 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1661 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1663 tableY = table + *(Y++);
1664 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1665 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1667 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1669 *(dest++) = tmp24 >> 8;
1670 *(dest++) = tmp24 >> 16;
1672 tableY = table + *(Y++);
1673 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1674 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1676 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1678 *(dest++) = tmp24 >> 8;
1679 *(dest++) = tmp24 >> 16;
1682 i = (width & 7) >> 1;
1686 uvRed = (V_RED_COEF*v) >> SHIFT;
1687 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1688 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1690 tableY = table + *(Y++);
1691 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1692 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1694 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1696 *(dest++) = tmp24 >> 8;
1697 *(dest++) = tmp24 >> 16;
1699 tableY = table + *(Y++);
1700 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1701 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1703 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1705 *(dest++) = tmp24 >> 8;
1706 *(dest++) = tmp24 >> 16;
1712 uvRed = (V_RED_COEF*v) >> SHIFT;
1713 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1714 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1716 tableY = table + *(Y++);
1717 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1718 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1720 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1722 *(dest++) = tmp24 >> 8;
1723 *(dest++) = tmp24 >> 16;