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 /* Color masks for different color depths - 8bpp masks can be choosen, since
32 * colormaps instead of hardware-defined colors are used. */
34 #define RED_8BPP_MASK 0xe0
35 #define GREEN_8BPP_MASK 0x1c
36 #define BLUE_8BPP_MASK 0x03
38 #define RED_15BPP_MASK 0xf800
39 #define GREEN_15BPP_MASK 0x03e0
40 #define BLUE_15BPP_MASK 0x001f
42 #define RED_16BPP_MASK 0xf800
43 #define GREEN_16BPP_MASK 0x07e0
44 #define BLUE_16BPP_MASK 0x001f
46 #define RED_24BPP_MASK 0xff0000
47 #define GREEN_24BPP_MASK 0x00ff00
48 #define BLUE_24BPP_MASK 0x0000ff
50 /* RGB/YUV inversion matrix (ISO/IEC 13818-2 section 6.3.6, table 6.9) */
52 const int MATRIX_COEFFICIENTS_TABLE[8][4] =
54 {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
55 {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
56 {104597, 132201, 25675, 53279}, /* unspecified */
57 {104597, 132201, 25675, 53279}, /* reserved */
58 {104448, 132798, 24759, 53109}, /* FCC */
59 {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
60 {104597, 132201, 25675, 53279}, /* SMPTE 170M */
61 {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */
64 /* Margins and offsets in conversion tables - Margins are used in case a RGB
65 * RGB conversion would give a value outside the 0-255 range. Offsets have been
66 * calculated to avoid using the same cache line for 2 tables. conversion tables
67 * are 2*MARGIN + 256 long and stores pixels.*/
68 #define RED_MARGIN 178
69 #define GREEN_MARGIN 135
70 #define BLUE_MARGIN 224
71 #define RED_OFFSET 1501 /* 1323 to 1935 */
72 #define GREEN_OFFSET 135 /* 0 to 526 */
73 #define BLUE_OFFSET 818 /* 594 to 1298 */
74 #define RGB_TABLE_SIZE 1935 /* total table size */
76 #define GRAY_MARGIN 384
77 #define GRAY_TABLE_SIZE 1024 /* total table size */
81 #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
82 #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
83 #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
84 #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
86 /*******************************************************************************
88 *******************************************************************************/
89 static void SetGammaTable ( int *pi_table, double f_gamma );
90 static void SetYUV ( vout_thread_t *p_vout );
91 static void SetOffset ( int i_width, int i_height, int i_pic_width, int i_pic_height,
92 boolean_t *pb_h_scaling, int *pi_v_scaling, int *p_offset );
94 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,
95 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
96 int i_matrix_coefficients );
97 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,
98 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
99 int i_matrix_coefficients );
100 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,
101 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
102 int i_matrix_coefficients );
103 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,
104 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
105 int i_matrix_coefficients );
106 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,
107 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
108 int i_matrix_coefficients );
109 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,
110 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
111 int i_matrix_coefficients );
112 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,
113 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
114 int i_matrix_coefficients );
115 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,
116 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
117 int i_matrix_coefficients );
118 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,
119 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
120 int i_matrix_coefficients );
121 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,
122 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
123 int i_matrix_coefficients );
124 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,
125 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
126 int i_matrix_coefficients );
127 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,
128 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
129 int i_matrix_coefficients );
130 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,
131 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
132 int i_matrix_coefficients );
133 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,
134 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
135 int i_matrix_coefficients );
136 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,
137 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
138 int i_matrix_coefficients );
139 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,
140 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
141 int i_matrix_coefficients );
143 /*****************************************************************************
144 * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel conversion blocks
145 *****************************************************************************
146 * These conversion routines are used by YUV conversion functions.
147 * conversion are made from p_y, p_u, p_v, which are modified, to p_buffer,
148 * which is also modified.
149 *****************************************************************************/
150 #define CONVERT_Y_PIXEL( BPP ) \
151 /* Only Y sample is present */ \
152 p_ybase = p_yuv + *p_y++; \
153 *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] | \
154 p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) \
155 + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
157 #define CONVERT_YUV_PIXEL( BPP ) \
158 /* Y, U and V samples are present */ \
161 i_red = (V_RED_COEF * i_vval) >> SHIFT; \
162 i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
163 i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
164 CONVERT_Y_PIXEL( BPP ) \
166 /*****************************************************************************
167 * SCALE_WIDTH: scale a line horizontally
168 *****************************************************************************
169 * This macro scale a line using rendering buffer and offset array. It works
170 * for 1, 2 and 4 Bpp.
171 *****************************************************************************/
172 #define SCALE_WIDTH \
173 if( b_horizontal_scaling ) \
175 /* Horizontal scaling, conversion has been done to buffer. \
176 * Rewind buffer and offset, then copy and scale line */ \
177 p_buffer = p_buffer_start; \
178 p_offset = p_offset_start; \
179 for( i_x = i_pic_width / 16; i_x--; ) \
181 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
182 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
183 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
184 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
185 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
186 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
187 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
188 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
189 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
190 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
191 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
192 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
193 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
194 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
195 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
196 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
198 p_pic += i_pic_line_width; \
202 /* No scaling, conversion has been done directly in picture memory. \
203 * Increment of picture pointer to end of line is still needed */ \
204 p_pic += i_pic_width + i_pic_line_width; \
207 /*****************************************************************************
208 * SCALE_HEIGHT: handle vertical scaling
209 *****************************************************************************
210 * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
211 * 444 for RGB conversion, or 400 for gray convertion. It works for 1, 2, 3
213 *****************************************************************************/
214 #define SCALE_HEIGHT( CHROMA, BPP ) \
215 /* If line is odd, rewind 4:2:0 U and V samples */ \
216 if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
218 p_u -= i_chroma_width; \
219 p_v -= i_chroma_width; \
223 * Handle vertical scaling. The current line can be copied or next one \
226 switch( i_vertical_scaling ) \
228 case -1: /* vertical scaling factor is < 1 */ \
229 while( (i_scale_count -= i_pic_height) >= 0 ) \
231 /* Height reduction: skip next source line */ \
234 if( (CHROMA == 420) || (CHROMA == 422) ) \
238 p_u += i_chroma_width; \
239 p_v += i_chroma_width; \
242 else if( CHROMA == 444 ) \
248 i_scale_count += i_height; \
250 case 1: /* vertical scaling factor is > 1 */ \
251 while( (i_scale_count -= i_height) > 0 ) \
253 /* Height increment: copy previous picture line */ \
254 for( i_x = i_pic_width / 16; i_x--; ) \
256 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
257 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
258 if( BPP > 1 ) /* 2, 3, 4 Bpp */ \
260 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
261 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
263 if( BPP > 2 ) /* 3, 4 Bpp */ \
265 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
266 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
268 if( BPP > 3 ) /* 4 Bpp */ \
270 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
271 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
274 p_pic += i_pic_line_width; \
275 p_pic_start += i_pic_line_width; \
277 i_scale_count += i_pic_height; \
281 /*****************************************************************************
282 * vout_InitYUV: allocate and initialize translations tables
283 *****************************************************************************
284 * This function will allocate memory to store translation tables, depending
285 * of the screen depth.
286 *****************************************************************************/
287 int vout_InitYUV( vout_thread_t *p_vout )
289 size_t tables_size; /* tables size, in bytes */
291 /* Computes tables size - 3 Bpp use 32 bits pixel entries in tables */
292 switch( p_vout->i_bytes_per_pixel )
295 tables_size = sizeof( u8 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
298 tables_size = sizeof( u16 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
303 tables_size = sizeof( u32 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
307 /* Allocate memory */
308 p_vout->yuv.p_base = malloc( tables_size );
309 if( p_vout->yuv.p_base == NULL )
311 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
315 /* Allocate memory for conversion buffer and offset array */
316 p_vout->yuv.p_buffer = malloc( VOUT_MAX_WIDTH * p_vout->i_bytes_per_pixel );
317 if( p_vout->yuv.p_buffer == NULL )
319 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
320 free( p_vout->yuv.p_base );
323 p_vout->yuv.p_offset = malloc( p_vout->i_width * sizeof( int ) );
324 if( p_vout->yuv.p_offset == NULL )
326 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
327 free( p_vout->yuv.p_base );
328 free( p_vout->yuv.p_buffer );
332 /* Initialize tables */
337 /*****************************************************************************
338 * vout_ResetTables: re-initialize translations tables
339 *****************************************************************************
340 * This function will initialize the tables allocated by vout_CreateTables and
341 * set functions pointers.
342 *****************************************************************************/
343 int vout_ResetYUV( vout_thread_t *p_vout )
345 vout_EndYUV( p_vout );
346 return( vout_InitYUV( p_vout ) );
349 /*****************************************************************************
350 * vout_EndYUV: destroy translations tables
351 *****************************************************************************
352 * Free memory allocated by vout_CreateTables.
353 *****************************************************************************/
354 void vout_EndYUV( vout_thread_t *p_vout )
356 free( p_vout->yuv.p_base );
357 free( p_vout->yuv.p_buffer );
358 free( p_vout->yuv.p_offset );
361 /* following functions are local */
363 /*****************************************************************************
364 * SetGammaTable: return intensity table transformed by gamma curve.
365 *****************************************************************************
366 * pi_table is a table of 256 entries from 0 to 255.
367 *****************************************************************************/
368 static void SetGammaTable( int *pi_table, double f_gamma )
370 int i_y; /* base intensity */
372 /* Use exp(gamma) instead of gamma */
373 f_gamma = exp(f_gamma );
375 /* Build gamma table */
376 for( i_y = 0; i_y < 256; i_y++ )
378 pi_table[ i_y ] = pow( (double)i_y / 256, f_gamma ) * 256;
382 /*****************************************************************************
383 * SetYUV: compute tables and set function pointers
384 + *****************************************************************************/
385 static void SetYUV( vout_thread_t *p_vout )
387 int pi_gamma[256]; /* gamma table */
388 int i_index; /* index in tables */
390 /* Build gamma table */
391 SetGammaTable( pi_gamma, p_vout->f_gamma );
394 * Set pointers and build YUV tables
396 if( p_vout->b_grayscale )
398 /* Grayscale: build gray table */
399 switch( p_vout->i_bytes_per_pixel )
402 p_vout->yuv.yuv.p_gray8 = (u8 *)p_vout->yuv.p_base + GRAY_MARGIN;
403 for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
405 p_vout->yuv.yuv.p_gray8[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
406 p_vout->yuv.yuv.p_gray8[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
408 for( i_index = 0; i_index < 256; i_index++)
410 p_vout->yuv.yuv.p_gray8[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
414 p_vout->yuv.yuv.p_gray16 = (u16 *)p_vout->yuv.p_base + GRAY_MARGIN;
415 for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
417 p_vout->yuv.yuv.p_gray16[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
418 p_vout->yuv.yuv.p_gray16[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
420 for( i_index = 0; i_index < 256; i_index++)
422 p_vout->yuv.yuv.p_gray16[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
427 p_vout->yuv.yuv.p_gray32 = (u32 *)p_vout->yuv.p_base + GRAY_MARGIN;
428 for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
430 p_vout->yuv.yuv.p_gray32[ -i_index ] = RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
431 p_vout->yuv.yuv.p_gray32[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
433 for( i_index = 0; i_index < 256; i_index++)
435 p_vout->yuv.yuv.p_gray32[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
442 /* Color: build red, green and blue tables */
443 switch( p_vout->i_bytes_per_pixel )
446 p_vout->yuv.yuv.p_rgb8 = (u8 *)p_vout->yuv.p_base;
447 for( i_index = 0; i_index < RED_MARGIN; i_index++ )
449 p_vout->yuv.yuv.p_rgb8[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
450 p_vout->yuv.yuv.p_rgb8[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
452 for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
454 p_vout->yuv.yuv.p_rgb8[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
455 p_vout->yuv.yuv.p_rgb8[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
457 for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
459 p_vout->yuv.yuv.p_rgb8[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
460 p_vout->yuv.yuv.p_rgb8[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
462 for( i_index = 0; i_index < 256; i_index++ )
464 p_vout->yuv.yuv.p_rgb8[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
465 p_vout->yuv.yuv.p_rgb8[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
466 p_vout->yuv.yuv.p_rgb8[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
470 p_vout->yuv.yuv.p_rgb16 = (u16 *)p_vout->yuv.p_base;
471 for( i_index = 0; i_index < RED_MARGIN; i_index++ )
473 p_vout->yuv.yuv.p_rgb16[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
474 p_vout->yuv.yuv.p_rgb16[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
476 for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
478 p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
479 p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
481 for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
483 p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
484 p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
486 for( i_index = 0; i_index < 256; i_index++ )
488 p_vout->yuv.yuv.p_rgb16[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
489 p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
490 p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
495 p_vout->yuv.yuv.p_rgb32 = (u32 *)p_vout->yuv.p_base;
496 for( i_index = 0; i_index < RED_MARGIN; i_index++ )
498 p_vout->yuv.yuv.p_rgb32[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
499 p_vout->yuv.yuv.p_rgb32[RED_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
501 for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
503 p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
504 p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + 256 + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
506 for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
508 p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
509 p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
511 for( i_index = 0; i_index < 256; i_index++ )
513 p_vout->yuv.yuv.p_rgb32[RED_OFFSET + i_index] = RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
514 p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
515 p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] );
522 * Set functions pointers
524 if( p_vout->b_grayscale )
527 switch( p_vout->i_bytes_per_pixel )
530 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray8;
531 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray8;
532 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray8;
535 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
536 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray16;
537 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray16;
540 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
541 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray24;
542 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray24;
545 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
546 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray32;
547 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray32;
554 switch( p_vout->i_bytes_per_pixel )
557 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB8;
558 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB8;
559 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB8;
562 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
563 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
564 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
567 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
568 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
569 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
572 p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
573 p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
574 p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
580 /*****************************************************************************
581 * SetOffset: build offset array for conversion functions
582 *****************************************************************************
583 * This function will build an offset array used in later conversion functions.
584 * It will also set horizontal and vertical scaling indicators.
585 *****************************************************************************/
586 static void SetOffset( int i_width, int i_height, int i_pic_width, int i_pic_height,
587 boolean_t *pb_h_scaling, int *pi_v_scaling, int *p_offset )
589 int i_x; /* x position in destination */
590 int i_scale_count; /* modulo counter */
593 * Prepare horizontal offset array
595 if( i_pic_width - i_width > 0 )
597 /* Prepare scaling array for horizontal extension */
599 i_scale_count = i_pic_width;
600 for( i_x = i_width; i_x--; )
602 while( (i_scale_count -= i_width) > 0 )
607 i_scale_count += i_pic_width;
610 else if( i_pic_width - i_width < 0 )
612 /* Prepare scaling array for horizontal reduction */
614 i_scale_count = i_pic_width;
615 for( i_x = i_pic_width; i_x--; )
618 while( (i_scale_count -= i_pic_width) >= 0 )
623 i_scale_count += i_width;
628 /* No horizontal scaling: YUV conversion is done directly to picture */
633 * Set vertical scaling indicator
635 if( i_pic_height - i_height > 0 )
639 else if( i_pic_height - i_height < 0 )
649 /*****************************************************************************
650 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
651 *****************************************************************************/
652 static void ConvertY4Gray8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y,
653 yuv_data_t *p_u, yuv_data_t *p_v, int i_width,
654 int i_height, int i_pic_width, int i_pic_height,
655 int i_pic_line_width, int i_matrix_coefficients )
657 boolean_t b_horizontal_scaling; /* horizontal scaling type */
658 int i_vertical_scaling; /* vertical scaling type */
659 int i_x, i_y; /* horizontal and vertical indexes */
660 int i_scale_count; /* scale modulo counter */
661 int i_chroma_width; /* chroma width, not used */
662 u8 * p_gray; /* base conversion table */
663 u8 * p_pic_start; /* beginning of the current line for copy */
664 u8 * p_buffer_start; /* conversion buffer start */
665 u8 * p_buffer; /* conversion buffer pointer */
666 int * p_offset_start; /* offset array start */
667 int * p_offset; /* offset array pointer */
670 * Initialize some values - i_pic_line_width will store the line skip
672 i_pic_line_width -= i_pic_width;
673 p_gray = p_vout->yuv.yuv.p_gray8;
674 p_buffer_start = p_vout->yuv.p_buffer;
675 p_offset_start = p_vout->yuv.p_offset;
676 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
677 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
682 i_scale_count = i_pic_height;
683 for( i_y = 0; i_y < i_height; i_y++ )
685 /* Mark beginnning of line for possible later line copy, and initialize
688 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
690 /* Do YUV conversion to buffer - YUV picture is always formed of 16
691 * pixels wide blocks */
692 for( i_x = i_width / 16; i_x--; )
694 *p_buffer++ = *p_y++;
695 *p_buffer++ = *p_y++;
696 *p_buffer++ = *p_y++;
697 *p_buffer++ = *p_y++;
698 *p_buffer++ = *p_y++;
699 *p_buffer++ = *p_y++;
700 *p_buffer++ = *p_y++;
701 *p_buffer++ = *p_y++;
702 *p_buffer++ = *p_y++;
703 *p_buffer++ = *p_y++;
704 *p_buffer++ = *p_y++;
705 *p_buffer++ = *p_y++;
706 *p_buffer++ = *p_y++;
707 *p_buffer++ = *p_y++;
708 *p_buffer++ = *p_y++;
709 *p_buffer++ = *p_y++;
712 /* Do horizontal and vertical scaling */
714 SCALE_HEIGHT(400, 1);
718 /*****************************************************************************
719 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
720 *****************************************************************************/
721 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,
722 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
723 int i_matrix_coefficients )
725 boolean_t b_horizontal_scaling; /* horizontal scaling type */
726 int i_vertical_scaling; /* vertical scaling type */
727 int i_x, i_y; /* horizontal and vertical indexes */
728 int i_scale_count; /* scale modulo counter */
729 int i_chroma_width; /* chroma width, not used */
730 u16 * p_gray; /* base conversion table */
731 u16 * p_pic_start; /* beginning of the current line for copy */
732 u16 * p_buffer_start; /* conversion buffer start */
733 u16 * p_buffer; /* conversion buffer pointer */
734 int * p_offset_start; /* offset array start */
735 int * p_offset; /* offset array pointer */
738 * Initialize some values - i_pic_line_width will store the line skip
740 i_pic_line_width -= i_pic_width;
741 p_gray = p_vout->yuv.yuv.p_gray16;
742 p_buffer_start = p_vout->yuv.p_buffer;
743 p_offset_start = p_vout->yuv.p_offset;
744 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
745 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
750 i_scale_count = i_pic_height;
751 for( i_y = 0; i_y < i_height; i_y++ )
753 /* Mark beginnning of line for possible later line copy, and initialize
756 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
758 /* Do YUV conversion to buffer - YUV picture is always formed of 16
759 * pixels wide blocks */
760 for( i_x = i_width / 16; i_x--; )
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++ ];
776 *p_buffer++ = p_gray[ *p_y++ ];
777 *p_buffer++ = p_gray[ *p_y++ ];
780 /* Do horizontal and vertical scaling */
782 SCALE_HEIGHT(400, 2);
786 /*****************************************************************************
787 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 3 Bpp
788 *****************************************************************************/
789 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,
790 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
791 int i_matrix_coefficients )
796 /*****************************************************************************
797 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
798 *****************************************************************************/
799 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,
800 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
801 int i_matrix_coefficients )
803 boolean_t b_horizontal_scaling; /* horizontal scaling type */
804 int i_vertical_scaling; /* vertical scaling type */
805 int i_x, i_y; /* horizontal and vertical indexes */
806 int i_scale_count; /* scale modulo counter */
807 int i_chroma_width; /* chroma width, not used */
808 u32 * p_gray; /* base conversion table */
809 u32 * p_pic_start; /* beginning of the current line for copy */
810 u32 * p_buffer_start; /* conversion buffer start */
811 u32 * p_buffer; /* conversion buffer pointer */
812 int * p_offset_start; /* offset array start */
813 int * p_offset; /* offset array pointer */
816 * Initialize some values - i_pic_line_width will store the line skip
818 i_pic_line_width -= i_pic_width;
819 p_gray = p_vout->yuv.yuv.p_gray32;
820 p_buffer_start = p_vout->yuv.p_buffer;
821 p_offset_start = p_vout->yuv.p_offset;
822 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
823 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
828 i_scale_count = i_pic_height;
829 for( i_y = 0; i_y < i_height; i_y++ )
831 /* Mark beginnning of line for possible later line copy, and initialize
834 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
836 /* Do YUV conversion to buffer - YUV picture is always formed of 16
837 * pixels wide blocks */
838 for( i_x = i_width / 16; i_x--; )
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++ ];
844 *p_buffer++ = p_gray[ *p_y++ ];
845 *p_buffer++ = p_gray[ *p_y++ ];
846 *p_buffer++ = p_gray[ *p_y++ ];
847 *p_buffer++ = p_gray[ *p_y++ ];
848 *p_buffer++ = p_gray[ *p_y++ ];
849 *p_buffer++ = p_gray[ *p_y++ ];
850 *p_buffer++ = p_gray[ *p_y++ ];
851 *p_buffer++ = p_gray[ *p_y++ ];
852 *p_buffer++ = p_gray[ *p_y++ ];
853 *p_buffer++ = p_gray[ *p_y++ ];
854 *p_buffer++ = p_gray[ *p_y++ ];
855 *p_buffer++ = p_gray[ *p_y++ ];
858 /* Do horizontal and vertical scaling */
860 SCALE_HEIGHT(400, 4);
864 /*****************************************************************************
865 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
866 *****************************************************************************/
867 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,
868 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
869 int i_matrix_coefficients )
871 boolean_t b_horizontal_scaling; /* horizontal scaling type */
872 int i_vertical_scaling; /* vertical scaling type */
873 int i_x, i_y; /* horizontal and vertical indexes */
874 int i_scale_count; /* scale modulo counter */
875 int i_uval, i_vval; /* U and V samples */
876 int i_red, i_green, i_blue; /* U and V modified samples */
877 int i_chroma_width; /* chroma width */
878 u8 * p_yuv; /* base conversion table */
879 u8 * p_ybase; /* Y dependant conversion table */
880 u8 * p_pic_start; /* beginning of the current line for copy */
881 u8 * p_buffer_start; /* conversion buffer start */
882 u8 * p_buffer; /* conversion buffer pointer */
883 u8 * p_foo; /* conversion buffer pointer */
884 int * p_offset_start; /* offset array start */
885 int * p_offset; /* offset array pointer */
888 * Initialize some values - i_pic_line_width will store the line skip
890 i_pic_line_width -= i_pic_width;
891 i_chroma_width = i_width / 2;
892 p_yuv = p_vout->yuv.yuv.p_rgb8;
893 p_buffer_start = p_vout->yuv.p_buffer;
894 p_offset_start = p_vout->yuv.p_offset;
895 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
896 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
901 i_scale_count = i_pic_height;
902 for( i_y = 0; i_y < i_height; i_y++ )
904 /* Mark beginnning of line for possible later line copy, and initialize
907 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
909 /* Do YUV conversion to buffer - YUV picture is always formed of 16
910 * pixels wide blocks */
911 for( i_x = i_width / 16; i_x--; )
913 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
914 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
915 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
916 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
917 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
918 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
919 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
920 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
921 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
922 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
923 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
924 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
925 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
926 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
927 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u) >> 5) * 9 + ((*p_v) >> 5) ];
928 *p_buffer++ = p_vout->lookup[ ((*p_y++ - 8) >> 4) * 81 + ((*p_u++) >> 5) * 9 + ((*p_v++) >> 5) ];
931 /* Do horizontal and vertical scaling */
933 SCALE_HEIGHT(420, 1);
937 /*****************************************************************************
938 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
939 *****************************************************************************/
940 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,
941 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
942 int i_matrix_coefficients )
944 boolean_t b_horizontal_scaling; /* horizontal scaling type */
945 int i_vertical_scaling; /* vertical scaling type */
946 int i_x, i_y; /* horizontal and vertical indexes */
947 int i_scale_count; /* scale modulo counter */
948 int i_uval, i_vval; /* U and V samples */
949 int i_red, i_green, i_blue; /* U and V modified samples */
950 int i_chroma_width; /* chroma width */
951 u8 * p_yuv; /* base conversion table */
952 u8 * p_ybase; /* Y dependant conversion table */
953 u8 * p_pic_start; /* beginning of the current line for copy */
954 u8 * p_buffer_start; /* conversion buffer start */
955 u8 * p_buffer; /* conversion buffer pointer */
956 int * p_offset_start; /* offset array start */
957 int * p_offset; /* offset array pointer */
960 * Initialize some values - i_pic_line_width will store the line skip
962 i_pic_line_width -= i_pic_width;
963 i_chroma_width = i_width / 2;
964 p_yuv = p_vout->yuv.yuv.p_rgb8;
965 p_buffer_start = p_vout->yuv.p_buffer;
966 p_offset_start = p_vout->yuv.p_offset;
967 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
968 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
973 i_scale_count = i_pic_height;
974 for( i_y = 0; i_y < i_height; i_y++ )
976 /* Mark beginnning of line for possible later line copy, and initialize
979 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
981 /* Do YUV conversion to buffer - YUV picture is always formed of 16
982 * pixels wide blocks */
983 for( i_x = i_width / 16; i_x--; )
985 CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
986 CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
987 CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
988 CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
989 CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
990 CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
991 CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
992 CONVERT_YUV_PIXEL(1); CONVERT_Y_PIXEL(1);
995 /* Do horizontal and vertical scaling */
997 SCALE_HEIGHT(422, 1);
1001 /*****************************************************************************
1002 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
1003 *****************************************************************************/
1004 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,
1005 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1006 int i_matrix_coefficients )
1008 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1009 int i_vertical_scaling; /* vertical scaling type */
1010 int i_x, i_y; /* horizontal and vertical indexes */
1011 int i_scale_count; /* scale modulo counter */
1012 int i_uval, i_vval; /* U and V samples */
1013 int i_red, i_green, i_blue; /* U and V modified samples */
1014 int i_chroma_width; /* chroma width, not used */
1015 u8 * p_yuv; /* base conversion table */
1016 u8 * p_ybase; /* Y dependant conversion table */
1017 u8 * p_pic_start; /* beginning of the current line for copy */
1018 u8 * p_buffer_start; /* conversion buffer start */
1019 u8 * p_buffer; /* conversion buffer pointer */
1020 int * p_offset_start; /* offset array start */
1021 int * p_offset; /* offset array pointer */
1024 * Initialize some values - i_pic_line_width will store the line skip
1026 i_pic_line_width -= i_pic_width;
1027 p_yuv = p_vout->yuv.yuv.p_rgb8;
1028 p_buffer_start = p_vout->yuv.p_buffer;
1029 p_offset_start = p_vout->yuv.p_offset;
1030 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1031 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1034 * Perform conversion
1036 i_scale_count = i_pic_height;
1037 for( i_y = 0; i_y < i_height; i_y++ )
1039 /* Mark beginnning of line for possible later line copy, and initialize
1041 p_pic_start = p_pic;
1042 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1044 /* Do YUV conversion to buffer - YUV picture is always formed of 16
1045 * pixels wide blocks */
1046 for( i_x = i_width / 16; i_x--; )
1048 CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
1049 CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
1050 CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
1051 CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
1052 CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
1053 CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
1054 CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
1055 CONVERT_YUV_PIXEL(1); CONVERT_YUV_PIXEL(1);
1058 /* Do horizontal and vertical scaling */
1060 SCALE_HEIGHT(444, 1);
1064 /*****************************************************************************
1065 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
1066 *****************************************************************************/
1067 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,
1068 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1069 int i_matrix_coefficients )
1072 // int i_chroma_width, i_chroma_skip; /* width and eol for chroma */
1074 i_chroma_width = i_width / 2;
1075 i_chroma_skip = i_skip / 2;
1076 ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height,
1077 (i_width + i_skip) * sizeof( yuv_data_t ),
1078 (i_chroma_width + i_chroma_skip) * sizeof( yuv_data_t),
1079 i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
1080 p_vout->i_screen_depth == 15 );
1082 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1083 int i_vertical_scaling; /* vertical scaling type */
1084 int i_x, i_y; /* horizontal and vertical indexes */
1085 int i_scale_count; /* scale modulo counter */
1086 int i_uval, i_vval; /* U and V samples */
1087 int i_red, i_green, i_blue; /* U and V modified samples */
1088 int i_chroma_width; /* chroma width */
1089 u16 * p_yuv; /* base conversion table */
1090 u16 * p_ybase; /* Y dependant conversion table */
1091 u16 * p_pic_start; /* beginning of the current line for copy */
1092 u16 * p_buffer_start; /* conversion buffer start */
1093 u16 * p_buffer; /* conversion buffer pointer */
1094 int * p_offset_start; /* offset array start */
1095 int * p_offset; /* offset array pointer */
1098 * Initialize some values - i_pic_line_width will store the line skip
1100 i_pic_line_width -= i_pic_width;
1101 i_chroma_width = i_width / 2;
1102 p_yuv = p_vout->yuv.yuv.p_rgb16;
1103 p_buffer_start = p_vout->yuv.p_buffer;
1104 p_offset_start = p_vout->yuv.p_offset;
1105 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1106 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1109 * Perform conversion
1111 i_scale_count = i_pic_height;
1112 for( i_y = 0; i_y < i_height; i_y++ )
1114 /* Mark beginnning of line for possible later line copy, and initialize
1116 p_pic_start = p_pic;
1117 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1119 /* Do YUV conversion to buffer - YUV picture is always formed of 16
1120 * pixels wide blocks */
1121 for( i_x = i_width / 16; i_x--; )
1123 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1124 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1125 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1126 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1127 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1128 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1129 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1130 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1133 /* Do horizontal and vertical scaling */
1135 SCALE_HEIGHT(420, 2);
1139 /*****************************************************************************
1140 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
1141 *****************************************************************************/
1142 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,
1143 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1144 int i_matrix_coefficients )
1146 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1147 int i_vertical_scaling; /* vertical scaling type */
1148 int i_x, i_y; /* horizontal and vertical indexes */
1149 int i_scale_count; /* scale modulo counter */
1150 int i_uval, i_vval; /* U and V samples */
1151 int i_red, i_green, i_blue; /* U and V modified samples */
1152 int i_chroma_width; /* chroma width */
1153 u16 * p_yuv; /* base conversion table */
1154 u16 * p_ybase; /* Y dependant conversion table */
1155 u16 * p_pic_start; /* beginning of the current line for copy */
1156 u16 * p_buffer_start; /* conversion buffer start */
1157 u16 * p_buffer; /* conversion buffer pointer */
1158 int * p_offset_start; /* offset array start */
1159 int * p_offset; /* offset array pointer */
1162 * Initialize some values - i_pic_line_width will store the line skip
1164 i_pic_line_width -= i_pic_width;
1165 i_chroma_width = i_width / 2;
1166 p_yuv = p_vout->yuv.yuv.p_rgb16;
1167 p_buffer_start = p_vout->yuv.p_buffer;
1168 p_offset_start = p_vout->yuv.p_offset;
1169 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1170 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1173 * Perform conversion
1175 i_scale_count = i_pic_height;
1176 for( i_y = 0; i_y < i_height; i_y++ )
1178 /* Mark beginnning of line for possible later line copy, and initialize
1180 p_pic_start = p_pic;
1181 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1183 /* Do YUV conversion to buffer - YUV picture is always formed of 16
1184 * pixels wide blocks */
1185 for( i_x = i_width / 16; i_x--; )
1187 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1188 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1189 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1190 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1191 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1192 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1193 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1194 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
1197 /* Do horizontal and vertical scaling */
1199 SCALE_HEIGHT(422, 2);
1203 /*****************************************************************************
1204 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
1205 *****************************************************************************/
1206 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,
1207 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1208 int i_matrix_coefficients )
1210 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1211 int i_vertical_scaling; /* vertical scaling type */
1212 int i_x, i_y; /* horizontal and vertical indexes */
1213 int i_scale_count; /* scale modulo counter */
1214 int i_uval, i_vval; /* U and V samples */
1215 int i_red, i_green, i_blue; /* U and V modified samples */
1216 int i_chroma_width; /* chroma width, not used */
1217 u16 * p_yuv; /* base conversion table */
1218 u16 * p_ybase; /* Y dependant conversion table */
1219 u16 * p_pic_start; /* beginning of the current line for copy */
1220 u16 * p_buffer_start; /* conversion buffer start */
1221 u16 * p_buffer; /* conversion buffer pointer */
1222 int * p_offset_start; /* offset array start */
1223 int * p_offset; /* offset array pointer */
1226 * Initialize some values - i_pic_line_width will store the line skip
1228 i_pic_line_width -= i_pic_width;
1229 p_yuv = p_vout->yuv.yuv.p_rgb16;
1230 p_buffer_start = p_vout->yuv.p_buffer;
1231 p_offset_start = p_vout->yuv.p_offset;
1232 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1233 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1236 * Perform conversion
1238 i_scale_count = i_pic_height;
1239 for( i_y = 0; i_y < i_height; i_y++ )
1241 /* Mark beginnning of line for possible later line copy, and initialize
1243 p_pic_start = p_pic;
1244 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1246 /* Do YUV conversion to buffer - YUV picture is always formed of 16
1247 * pixels wide blocks */
1248 for( i_x = i_width / 16; i_x--; )
1250 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
1251 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
1252 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
1253 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
1254 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
1255 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
1256 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
1257 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
1260 /* Do horizontal and vertical scaling */
1262 SCALE_HEIGHT(444, 2);
1266 /*****************************************************************************
1267 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 3 Bpp
1268 *****************************************************************************/
1269 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,
1270 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1271 int i_matrix_coefficients )
1276 /*****************************************************************************
1277 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 3 Bpp
1278 *****************************************************************************/
1279 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,
1280 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1281 int i_matrix_coefficients )
1286 /*****************************************************************************
1287 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 3 Bpp
1288 *****************************************************************************/
1289 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,
1290 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1291 int i_matrix_coefficients )
1296 /*****************************************************************************
1297 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
1298 *****************************************************************************/
1299 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,
1300 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1301 int i_matrix_coefficients )
1303 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1304 int i_vertical_scaling; /* vertical scaling type */
1305 int i_x, i_y; /* horizontal and vertical indexes */
1306 int i_scale_count; /* scale modulo counter */
1307 int i_uval, i_vval; /* U and V samples */
1308 int i_red, i_green, i_blue; /* U and V modified samples */
1309 int i_chroma_width; /* chroma width */
1310 u32 * p_yuv; /* base conversion table */
1311 u32 * p_ybase; /* Y dependant conversion table */
1312 u32 * p_pic_start; /* beginning of the current line for copy */
1313 u32 * p_buffer_start; /* conversion buffer start */
1314 u32 * p_buffer; /* conversion buffer pointer */
1315 int * p_offset_start; /* offset array start */
1316 int * p_offset; /* offset array pointer */
1319 * Initialize some values - i_pic_line_width will store the line skip
1321 i_pic_line_width -= i_pic_width;
1322 i_chroma_width = i_width / 2;
1323 p_yuv = p_vout->yuv.yuv.p_rgb32;
1324 p_buffer_start = p_vout->yuv.p_buffer;
1325 p_offset_start = p_vout->yuv.p_offset;
1326 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1327 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1330 * Perform conversion
1332 i_scale_count = i_pic_height;
1333 for( i_y = 0; i_y < i_height; i_y++ )
1335 /* Mark beginnning of line for possible later line copy, and initialize
1337 p_pic_start = p_pic;
1338 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1340 /* Do YUV conversion to buffer - YUV picture is always formed of 16
1341 * pixels wide blocks */
1342 for( i_x = i_width / 16; i_x--; )
1344 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1345 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1346 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1347 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1348 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1349 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1350 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1351 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1354 /* Do horizontal and vertical scaling */
1356 SCALE_HEIGHT(420, 4);
1360 /*****************************************************************************
1361 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
1362 *****************************************************************************/
1363 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,
1364 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1365 int i_matrix_coefficients )
1367 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1368 int i_vertical_scaling; /* vertical scaling type */
1369 int i_x, i_y; /* horizontal and vertical indexes */
1370 int i_scale_count; /* scale modulo counter */
1371 int i_uval, i_vval; /* U and V samples */
1372 int i_red, i_green, i_blue; /* U and V modified samples */
1373 int i_chroma_width; /* chroma width */
1374 u32 * p_yuv; /* base conversion table */
1375 u32 * p_ybase; /* Y dependant conversion table */
1376 u32 * p_pic_start; /* beginning of the current line for copy */
1377 u32 * p_buffer_start; /* conversion buffer start */
1378 u32 * p_buffer; /* conversion buffer pointer */
1379 int * p_offset_start; /* offset array start */
1380 int * p_offset; /* offset array pointer */
1383 * Initialize some values - i_pic_line_width will store the line skip
1385 i_pic_line_width -= i_pic_width;
1386 i_chroma_width = i_width / 2;
1387 p_yuv = p_vout->yuv.yuv.p_rgb32;
1388 p_buffer_start = p_vout->yuv.p_buffer;
1389 p_offset_start = p_vout->yuv.p_offset;
1390 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1391 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1394 * Perform conversion
1396 i_scale_count = i_pic_height;
1397 for( i_y = 0; i_y < i_height; i_y++ )
1399 /* Mark beginnning of line for possible later line copy, and initialize
1401 p_pic_start = p_pic;
1402 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1404 /* Do YUV conversion to buffer - YUV picture is always formed of 16
1405 * pixels wide blocks */
1406 for( i_x = i_width / 16; i_x--; )
1408 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1409 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1410 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1411 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1412 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1413 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1414 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1415 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
1418 /* Do horizontal and vertical scaling */
1420 SCALE_HEIGHT(422, 4);
1424 /*****************************************************************************
1425 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
1426 *****************************************************************************/
1427 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,
1428 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
1429 int i_matrix_coefficients )
1431 boolean_t b_horizontal_scaling; /* horizontal scaling type */
1432 int i_vertical_scaling; /* vertical scaling type */
1433 int i_x, i_y; /* horizontal and vertical indexes */
1434 int i_scale_count; /* scale modulo counter */
1435 int i_uval, i_vval; /* U and V samples */
1436 int i_red, i_green, i_blue; /* U and V modified samples */
1437 int i_chroma_width; /* chroma width, not used */
1438 u32 * p_yuv; /* base conversion table */
1439 u32 * p_ybase; /* Y dependant conversion table */
1440 u32 * p_pic_start; /* beginning of the current line for copy */
1441 u32 * p_buffer_start; /* conversion buffer start */
1442 u32 * p_buffer; /* conversion buffer pointer */
1443 int * p_offset_start; /* offset array start */
1444 int * p_offset; /* offset array pointer */
1447 * Initialize some values - i_pic_line_width will store the line skip
1449 i_pic_line_width -= i_pic_width;
1450 p_yuv = p_vout->yuv.yuv.p_rgb32;
1451 p_buffer_start = p_vout->yuv.p_buffer;
1452 p_offset_start = p_vout->yuv.p_offset;
1453 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
1454 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start );
1457 * Perform conversion
1459 i_scale_count = i_pic_height;
1460 for( i_y = 0; i_y < i_height; i_y++ )
1462 /* Mark beginnning of line for possible later line copy, and initialize
1464 p_pic_start = p_pic;
1465 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
1467 /* Do YUV conversion to buffer - YUV picture is always formed of 16
1468 * pixels wide blocks */
1469 for( i_x = i_width / 16; i_x--; )
1471 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
1472 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
1473 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
1474 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
1475 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
1476 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
1477 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
1478 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
1481 /* Do horizontal and vertical scaling */
1483 SCALE_HEIGHT(444, 4);
1487 //-------------------- walken code follows ------------------------------------
1490 * YUV to RGB routines.
1492 * these routines calculate r, g and b values from each pixel's y, u and v.
1493 * these r, g an b values are then passed thru a table lookup to take the
1494 * gamma curve into account and find the corresponding pixel value.
1496 * the table must store more than 3*256 values because of the possibility
1497 * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
1498 * values are in the following intervals :
1499 * -176 to 255+176 for red
1500 * -133 to 255+133 for green
1501 * -222 to 255+222 for blue
1503 * If the input y,u,v values are right, the r,g,b results are not expected
1504 * to move out of the 0 to 255 interval but who knows what will happen in
1507 * the red, green and blue conversion tables are stored in a single 1935-entry
1508 * array. The respective positions of each component in the array have been
1509 * calculated to minimize the cache interactions of the 3 tables.
1514 static void yuvToRgb24 (unsigned char * Y,
1515 unsigned char * U, unsigned char * V,
1516 char * dest, int table[1935], int width)
1531 uvRed = (V_RED_COEF*v) >> SHIFT;
1532 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1533 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1535 tableY = table + *(Y++);
1536 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1537 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1539 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1541 *(dest++) = tmp24 >> 8;
1542 *(dest++) = tmp24 >> 16;
1544 tableY = table + *(Y++);
1545 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1546 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1548 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1550 *(dest++) = tmp24 >> 8;
1551 *(dest++) = tmp24 >> 16;
1555 uvRed = (V_RED_COEF*v) >> SHIFT;
1556 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1557 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1559 tableY = table + *(Y++);
1560 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1561 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1563 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1565 *(dest++) = tmp24 >> 8;
1566 *(dest++) = tmp24 >> 16;
1568 tableY = table + *(Y++);
1569 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1570 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1572 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1574 *(dest++) = tmp24 >> 8;
1575 *(dest++) = tmp24 >> 16;
1579 uvRed = (V_RED_COEF*v) >> SHIFT;
1580 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1581 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1583 tableY = table + *(Y++);
1584 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1585 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1587 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1589 *(dest++) = tmp24 >> 8;
1590 *(dest++) = tmp24 >> 16;
1592 tableY = table + *(Y++);
1593 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1594 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1596 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1598 *(dest++) = tmp24 >> 8;
1599 *(dest++) = tmp24 >> 16;
1603 uvRed = (V_RED_COEF*v) >> SHIFT;
1604 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1605 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1607 tableY = table + *(Y++);
1608 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1609 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1611 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1613 *(dest++) = tmp24 >> 8;
1614 *(dest++) = tmp24 >> 16;
1616 tableY = table + *(Y++);
1617 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1618 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1620 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1622 *(dest++) = tmp24 >> 8;
1623 *(dest++) = tmp24 >> 16;
1626 i = (width & 7) >> 1;
1630 uvRed = (V_RED_COEF*v) >> SHIFT;
1631 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1632 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1634 tableY = table + *(Y++);
1635 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1636 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1638 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1640 *(dest++) = tmp24 >> 8;
1641 *(dest++) = tmp24 >> 16;
1643 tableY = table + *(Y++);
1644 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1645 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1647 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1649 *(dest++) = tmp24 >> 8;
1650 *(dest++) = tmp24 >> 16;
1656 uvRed = (V_RED_COEF*v) >> SHIFT;
1657 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1658 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1660 tableY = table + *(Y++);
1661 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1662 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1664 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1666 *(dest++) = tmp24 >> 8;
1667 *(dest++) = tmp24 >> 16;