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 *******************************************************************************/
19 #include <X11/Xlib.h> /* for video_sys.h in X11 mode */
25 #include "vlc_thread.h"
27 #include "video_output.h"
28 #include "video_yuv.h"
31 /*******************************************************************************
33 *******************************************************************************/
35 /* RGB/YUV inversion matrix (ISO/IEC 13818-2 section 6.3.6, table 6.9) */
36 const int MATRIX_COEFFICIENTS_TABLE[8][4] =
38 {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
39 {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
40 {104597, 132201, 25675, 53279}, /* unspecified */
41 {104597, 132201, 25675, 53279}, /* reserved */
42 {104448, 132798, 24759, 53109}, /* FCC */
43 {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
44 {104597, 132201, 25675, 53279}, /* SMPTE 170M */
45 {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */
48 /*******************************************************************************
50 *******************************************************************************/
51 static int BinaryLog ( u32 i );
52 static void MaskToShift ( int *pi_right, int *pi_left, u32 i_mask );
53 static void SetTables ( vout_thread_t *p_vout );
55 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,
56 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
57 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,
58 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
59 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,
60 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
61 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,
62 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
63 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,
64 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
65 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,
66 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
67 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,
68 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
69 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,
70 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
71 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,
72 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
73 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,
74 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
75 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,
76 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
77 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,
78 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
79 static void Scale16 ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
80 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
81 static void Scale24 ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
82 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
83 static void Scale32 ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
84 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
86 /*******************************************************************************
87 * CLIP_BYTE macro: boundary detection
88 *******************************************************************************
89 * Return parameter if between 0 and 255, else return nearest boundary (0 or
90 * 255). This macro is used to build translations tables.
91 *******************************************************************************/
92 #define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
94 /*******************************************************************************
95 * LINE_COPY macro: memcopy using 16 pixels blocks
96 *******************************************************************************
98 * p_pic destination pointer
99 * p_pic_src source pointer
102 *******************************************************************************/
104 for( i_x = 0; i_x < i_width; i_x+=16 ) \
106 *p_pic++ = *p_pic_src++; \
107 *p_pic++ = *p_pic_src++; \
108 *p_pic++ = *p_pic_src++; \
109 *p_pic++ = *p_pic_src++; \
110 *p_pic++ = *p_pic_src++; \
111 *p_pic++ = *p_pic_src++; \
112 *p_pic++ = *p_pic_src++; \
113 *p_pic++ = *p_pic_src++; \
114 *p_pic++ = *p_pic_src++; \
115 *p_pic++ = *p_pic_src++; \
116 *p_pic++ = *p_pic_src++; \
117 *p_pic++ = *p_pic_src++; \
118 *p_pic++ = *p_pic_src++; \
119 *p_pic++ = *p_pic_src++; \
120 *p_pic++ = *p_pic_src++; \
121 *p_pic++ = *p_pic_src++; \
124 /*******************************************************************************
125 * CONVERT_YUV_GRAY macro: grayscale YUV convertion
126 *******************************************************************************
128 * ...see vout_convert_t
129 * i_x, i_y coordinates
130 * i_pic_copy same type as p_pic
131 * p_gray gray translation table
132 *******************************************************************************/
133 #define CONVERT_YUV_GRAY \
134 for (i_y = 0; i_y < i_height ; i_y++) \
136 for (i_x = 0; i_x < i_width; i_x += 16) \
138 /* Convert 16 pixels (width is always multiple of 16 */ \
139 *p_pic++ = p_gray[ *p_y++ ]; \
140 *p_pic++ = p_gray[ *p_y++ ]; \
141 *p_pic++ = p_gray[ *p_y++ ]; \
142 *p_pic++ = p_gray[ *p_y++ ]; \
143 *p_pic++ = p_gray[ *p_y++ ]; \
144 *p_pic++ = p_gray[ *p_y++ ]; \
145 *p_pic++ = p_gray[ *p_y++ ]; \
146 *p_pic++ = p_gray[ *p_y++ ]; \
147 *p_pic++ = p_gray[ *p_y++ ]; \
148 *p_pic++ = p_gray[ *p_y++ ]; \
149 *p_pic++ = p_gray[ *p_y++ ]; \
150 *p_pic++ = p_gray[ *p_y++ ]; \
151 *p_pic++ = p_gray[ *p_y++ ]; \
152 *p_pic++ = p_gray[ *p_y++ ]; \
153 *p_pic++ = p_gray[ *p_y++ ]; \
154 *p_pic++ = p_gray[ *p_y++ ]; \
157 /* Handle scale factor */ \
158 if( i_scale && ! (i_y % i_scale) ) \
162 /* Copy previous line */ \
163 p_pic_src = p_pic - i_width; \
164 p_pic += i_pic_eol; \
169 /* Ignore next line */ \
170 p_y += i_eol + i_width; \
175 /* Skip until beginning of next line */ \
176 p_pic += i_pic_eol; \
180 /*******************************************************************************
181 * CONVERT_YUV_RGB: color YUV convertion
182 *******************************************************************************
184 * CHROMA 420, 422 or 444
186 * ...see vout_convert_t
187 * i_x, i_y coordinates
188 * i_uval, i_yval, i_vval samples
189 * p_pic_src same type as p_pic
190 * i_chroma_width chroma width
191 * i_chroma_eol chroma eol
192 * p_red red translation table
193 * p_green green translation table
194 * p_blue blue translation table
195 * i_crv, i_cgu, i_cgv, i_cbu matrix coefficients
196 *******************************************************************************/
197 #define CONVERT_YUV_RGB( CHROMA ) \
198 for (i_y = 0; i_y < i_height ; i_y++) \
200 for (i_x = 0; i_x < i_width; i_x += 2 ) \
202 /* First sample (complete) */ \
203 i_yval = 76309 * *p_y++ - 1188177; \
204 i_uval = *p_u++ - 128; \
205 i_vval = *p_v++ - 128; \
207 p_red [(i_yval+i_crv*i_vval) >>16] | \
208 p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval) >>16] | \
209 p_blue [(i_yval+i_cbu*i_uval) >>16]; \
210 i_yval = 76309 * *p_y++ - 1188177; \
211 /* Second sample (partial) */ \
212 if( CHROMA == 444 ) \
214 i_uval = *p_u++ - 128; \
215 i_vval = *p_v++ - 128; \
218 p_red [(i_yval+i_crv*i_vval) >>16] | \
219 p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval) >>16] | \
220 p_blue [(i_yval+i_cbu*i_uval) >>16]; \
223 /* Handle scale factor and rewind in 4:2:0 */ \
224 if( i_scale && ! (i_y % i_scale) ) \
228 /* Copy previous line, rewind if required */ \
229 p_pic_src = p_pic - i_width; \
230 p_pic += i_pic_eol; \
232 if( (CHROMA == 420) && !(i_y & 0x1) ) \
234 p_u -= i_chroma_width; \
235 p_v -= i_chroma_width; \
239 p_u += i_chroma_eol; \
240 p_v += i_chroma_eol; \
245 /* Ignore next line */ \
246 p_y += i_eol + i_width; \
247 p_u += i_chroma_eol; \
248 p_v += i_chroma_eol; \
252 else if( (CHROMA == 420) && !(i_y & 0x1) ) \
254 p_u -= i_chroma_width; \
255 p_v -= i_chroma_width; \
259 p_u += i_chroma_eol; \
260 p_v += i_chroma_eol; \
263 /* Skip until beginning of next line */ \
264 p_pic += i_pic_eol; \
269 /*******************************************************************************
270 * vout_InitTables: allocate and initialize translations tables
271 *******************************************************************************
272 * This function will allocate memory to store translation tables, depending
273 * of the screen depth.
274 *******************************************************************************/
275 int vout_InitTables( vout_thread_t *p_vout )
277 size_t tables_size; /* tables size, in bytes */
279 /* Computes tables size */
280 switch( p_vout->i_screen_depth )
284 tables_size = sizeof( u16 ) * 1024 * (p_vout->b_grayscale ? 1 : 3);
291 tables_size = sizeof( u32 ) * 1024 * (p_vout->b_grayscale ? 1 : 3);
295 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
301 /* Allocate memory */
302 p_vout->tables.p_base = malloc( tables_size );
303 if( p_vout->tables.p_base == NULL )
305 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
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_ResetTables( vout_thread_t *p_vout )
322 // ?? realloc if b_grayscale or i_screen_depth changed
327 /*******************************************************************************
328 * vout_EndTables: destroy translations tables
329 *******************************************************************************
330 * Free memory allocated by vout_CreateTables.
331 *******************************************************************************/
332 void vout_EndTables( vout_thread_t *p_vout )
334 free( p_vout->tables.p_base );
337 /* following functions are local */
339 /*******************************************************************************
340 * BinaryLog: computes the base 2 log of a binary value
341 *******************************************************************************
342 * This functions is used by MaskToShift during tables initialisation, to
343 * get a bit index from a binary value.
344 *******************************************************************************/
345 static int BinaryLog(u32 i)
370 if (i != ((u32)1 << i_log))
372 intf_ErrMsg("internal error: binary log overflow\n");
378 /*******************************************************************************
379 * MaskToShift: Transform a color mask into right and left shifts
380 *******************************************************************************
381 * This function is used during table initialisation. It can return a value
382 *******************************************************************************/
383 static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
385 u32 i_low, i_high; /* lower hand higher bits of the mask */
388 i_low = i_mask & (- i_mask); /* lower bit of the mask */
389 i_high = i_mask + i_low; /* higher bit of the mask */
391 /* Transform bits into an index */
392 i_low = BinaryLog (i_low);
393 i_high = BinaryLog (i_high);
395 /* Update pointers and return */
397 *pi_right = (8 - i_high + i_low);
400 /*******************************************************************************
401 * SetTables: compute tables and set function pointers
402 *******************************************************************************/
403 static void SetTables( vout_thread_t *p_vout )
405 u8 i_gamma[256]; /* gamma table */
406 int i_index; /* index in tables */
407 int i_red_right, i_red_left; /* red shifts */
408 int i_green_right, i_green_left; /* green shifts */
409 int i_blue_right, i_blue_left; /* blue shifts */
414 for( i_index = 0; i_index < 256; i_index++ )
416 i_gamma[i_index] = 255. * pow( (double)i_index / 255., p_vout->f_gamma );
420 * Set color masks and shifts
422 switch( p_vout->i_screen_depth )
425 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
426 MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
427 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
430 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
431 MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
432 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
436 MaskToShift( &i_red_right, &i_red_left, 0x00ff0000 );
437 MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
438 MaskToShift( &i_blue_right, &i_blue_left, 0x000000ff );
442 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
448 * Set pointers and build YUV tables
450 if( p_vout->b_grayscale )
452 /* Grayscale: build gray table */
453 switch( p_vout->i_screen_depth )
457 p_vout->tables.yuv.gray16.p_gray = (u16 *)p_vout->tables.p_base + 384;
458 for( i_index = -384; i_index < 640; i_index++)
460 p_vout->tables.yuv.gray16.p_gray[ i_index ] =
461 ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
462 ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
463 ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
468 p_vout->tables.yuv.gray32.p_gray = (u32 *)p_vout->tables.p_base + 384;
469 for( i_index = -384; i_index < 640; i_index++)
471 p_vout->tables.yuv.gray32.p_gray[ i_index ] =
472 ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
473 ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
474 ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
481 /* Color: build red, green and blue tables */
482 switch( p_vout->i_screen_depth )
486 p_vout->tables.yuv.rgb16.p_red = (u16 *)p_vout->tables.p_base + 384;
487 p_vout->tables.yuv.rgb16.p_green = (u16 *)p_vout->tables.p_base + 1024 + 384;
488 p_vout->tables.yuv.rgb16.p_blue = (u16 *)p_vout->tables.p_base + 2*1024 + 384;
489 for( i_index = -384; i_index < 640; i_index++)
491 p_vout->tables.yuv.rgb16.p_red[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
492 p_vout->tables.yuv.rgb16.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
493 p_vout->tables.yuv.rgb16.p_blue[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
498 p_vout->tables.yuv.rgb32.p_red = (u32 *)p_vout->tables.p_base + 384;
499 p_vout->tables.yuv.rgb32.p_green = (u32 *)p_vout->tables.p_base + 1024 + 384;
500 p_vout->tables.yuv.rgb32.p_blue = (u32 *)p_vout->tables.p_base + 2*1024 + 384;
501 for( i_index = -384; i_index < 640; i_index++)
503 p_vout->tables.yuv.rgb32.p_red[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
504 p_vout->tables.yuv.rgb32.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
505 p_vout->tables.yuv.rgb32.p_blue[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
512 * Set functions pointers
514 if( p_vout->b_grayscale )
517 switch( p_vout->i_screen_depth )
521 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
522 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
523 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
524 p_vout->p_Scale = (vout_scale_t *) Scale16;
527 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
528 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
529 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
530 p_vout->p_Scale = (vout_scale_t *) Scale24;
533 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
534 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
535 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
536 p_vout->p_Scale = (vout_scale_t *) Scale32;
543 switch( p_vout->i_screen_depth )
547 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB16;
548 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB16;
549 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB16;
550 p_vout->p_Scale = (vout_scale_t *) Scale16;
553 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB24;
554 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB24;
555 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB24;
556 p_vout->p_Scale = (vout_scale_t *) Scale24;
559 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB32;
560 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB32;
561 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB32;
562 p_vout->p_Scale = (vout_scale_t *) Scale32;
568 /*******************************************************************************
569 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
570 *******************************************************************************/
571 static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic,
572 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
573 int i_width, int i_height, int i_eol, int i_pic_eol,
574 int i_scale, int i_matrix_coefficients )
576 u16 * p_pic_src; /* source pointer in case of copy */
577 u16 * p_gray; /* gray table */
578 int i_x, i_y; /* picture coordinates */
580 p_gray = p_vout->tables.yuv.gray16.p_gray;
584 /*******************************************************************************
585 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
586 *******************************************************************************/
587 static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic,
588 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
589 int i_width, int i_height, int i_eol, int i_pic_eol,
590 int i_scale, int i_matrix_coefficients )
595 /*******************************************************************************
596 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
597 *******************************************************************************/
598 static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic,
599 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
600 int i_width, int i_height, int i_eol, int i_pic_eol,
601 int i_scale, int i_matrix_coefficients )
603 u32 * p_pic_src; /* source pointer in case of copy */
604 u32 * p_gray; /* gray table */
605 int i_x, i_y; /* picture coordinates */
607 p_gray = p_vout->tables.yuv.gray32.p_gray;
611 /*******************************************************************************
612 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
613 *******************************************************************************/
614 static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic,
615 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
616 int i_width, int i_height, int i_eol, int i_pic_eol,
617 int i_scale, int i_matrix_coefficients )
620 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
622 i_chroma_width = i_width / 2;
623 i_chroma_eol = i_eol / 2;
624 ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height,
625 (i_width + i_eol) * sizeof( yuv_data_t ),
626 (i_chroma_width + i_chroma_eol) * sizeof( yuv_data_t),
627 i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
628 p_vout->i_screen_depth == 15 );
630 u16 * p_pic_src; /* source pointer in case of copy */
631 u16 * p_red; /* red table */
632 u16 * p_green; /* green table */
633 u16 * p_blue; /* blue table */
634 int i_uval, i_yval, i_vval; /* samples */
635 int i_x, i_y; /* picture coordinates */
636 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
637 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
639 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
640 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
641 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
642 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
643 p_red = p_vout->tables.yuv.rgb16.p_red;
644 p_green = p_vout->tables.yuv.rgb16.p_green;
645 p_blue = p_vout->tables.yuv.rgb16.p_blue;
646 i_chroma_width = i_width / 2;
647 i_chroma_eol = i_eol / 2;
648 CONVERT_YUV_RGB( 420 )
652 /*******************************************************************************
653 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
654 *******************************************************************************/
655 static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic,
656 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
657 int i_width, int i_height, int i_eol, int i_pic_eol,
658 int i_scale, int i_matrix_coefficients )
660 u16 * p_pic_src; /* source pointer in case of copy */
661 u16 * p_red; /* red table */
662 u16 * p_green; /* green table */
663 u16 * p_blue; /* blue table */
664 int i_uval, i_yval, i_vval; /* samples */
665 int i_x, i_y; /* picture coordinates */
666 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
667 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
669 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
670 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
671 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
672 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
673 p_red = p_vout->tables.yuv.rgb16.p_red;
674 p_green = p_vout->tables.yuv.rgb16.p_green;
675 p_blue = p_vout->tables.yuv.rgb16.p_blue;
676 i_chroma_width = i_width / 2;
677 i_chroma_eol = i_eol / 2;
678 CONVERT_YUV_RGB( 422 )
681 /*******************************************************************************
682 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
683 *******************************************************************************/
684 static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic,
685 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
686 int i_width, int i_height, int i_eol, int i_pic_eol,
687 int i_scale, int i_matrix_coefficients )
689 u16 * p_pic_src; /* source pointer in case of copy */
690 u16 * p_red; /* red table */
691 u16 * p_green; /* green table */
692 u16 * p_blue; /* blue table */
693 int i_uval, i_yval, i_vval; /* samples */
694 int i_x, i_y; /* picture coordinates */
695 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
696 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
698 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
699 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
700 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
701 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
702 p_red = p_vout->tables.yuv.rgb16.p_red;
703 p_green = p_vout->tables.yuv.rgb16.p_green;
704 p_blue = p_vout->tables.yuv.rgb16.p_blue;
705 i_chroma_width = i_width;
706 i_chroma_eol = i_eol;
707 CONVERT_YUV_RGB( 444 )
710 /*******************************************************************************
711 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
712 *******************************************************************************/
713 static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic,
714 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
715 int i_width, int i_height, int i_eol, int i_pic_eol,
716 int i_scale, int i_matrix_coefficients )
721 /*******************************************************************************
722 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
723 *******************************************************************************/
724 static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic,
725 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
726 int i_width, int i_height, int i_eol, int i_pic_eol,
727 int i_scale, int i_matrix_coefficients )
732 /*******************************************************************************
733 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
734 *******************************************************************************/
735 static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic,
736 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
737 int i_width, int i_height, int i_eol, int i_pic_eol,
738 int i_scale, int i_matrix_coefficients )
743 /*******************************************************************************
744 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
745 *******************************************************************************/
746 static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic,
747 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
748 int i_width, int i_height, int i_eol, int i_pic_eol,
749 int i_scale, int i_matrix_coefficients )
751 u32 * p_pic_src; /* source pointer in case of copy */
752 u32 * p_red; /* red table */
753 u32 * p_green; /* green table */
754 u32 * p_blue; /* blue table */
755 int i_uval, i_yval, i_vval; /* samples */
756 int i_x, i_y; /* picture coordinates */
757 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
758 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
760 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
761 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
762 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
763 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
764 p_red = p_vout->tables.yuv.rgb32.p_red;
765 p_green = p_vout->tables.yuv.rgb32.p_green;
766 p_blue = p_vout->tables.yuv.rgb32.p_blue;
767 i_chroma_width = i_width / 2;
768 i_chroma_eol = i_eol / 2;
769 CONVERT_YUV_RGB( 420 )
772 /*******************************************************************************
773 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
774 *******************************************************************************/
775 static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic,
776 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
777 int i_width, int i_height, int i_eol, int i_pic_eol,
778 int i_scale, int i_matrix_coefficients )
780 u32 * p_pic_src; /* source pointer in case of copy */
781 u32 * p_red; /* red table */
782 u32 * p_green; /* green table */
783 u32 * p_blue; /* blue table */
784 int i_uval, i_yval, i_vval; /* samples */
785 int i_x, i_y; /* picture coordinates */
786 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
787 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
789 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
790 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
791 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
792 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
793 p_red = p_vout->tables.yuv.rgb32.p_red;
794 p_green = p_vout->tables.yuv.rgb32.p_green;
795 p_blue = p_vout->tables.yuv.rgb32.p_blue;
796 i_chroma_width = i_width / 2;
797 i_chroma_eol = i_eol / 2;
798 CONVERT_YUV_RGB( 422 )
801 /*******************************************************************************
802 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
803 *******************************************************************************/
804 static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic,
805 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
806 int i_width, int i_height, int i_eol, int i_pic_eol,
807 int i_scale, int i_matrix_coefficients )
809 u32 * p_pic_src; /* source pointer in case of copy */
810 u32 * p_red; /* red table */
811 u32 * p_green; /* green table */
812 u32 * p_blue; /* blue table */
813 int i_uval, i_yval, i_vval; /* samples */
814 int i_x, i_y; /* picture coordinates */
815 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
816 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
818 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
819 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
820 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
821 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
822 p_red = p_vout->tables.yuv.rgb32.p_red;
823 p_green = p_vout->tables.yuv.rgb32.p_green;
824 p_blue = p_vout->tables.yuv.rgb32.p_blue;
825 i_chroma_width = i_width;
826 i_chroma_eol = i_eol;
827 CONVERT_YUV_RGB( 444 )
830 /*******************************************************************************
831 * Scale16: 15 or 16 bpp picture scaling
832 *******************************************************************************/
833 static void Scale16( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
834 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
839 /*******************************************************************************
840 * Scale24: 24 bpp picture scaling
841 *******************************************************************************/
842 static void Scale24( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
843 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
848 /*******************************************************************************
849 * Scale32: 32 bpp picture scaling
850 *******************************************************************************/
851 static void Scale32( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
852 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
857 //-------------------- walken code follow --------------------------------
860 * YUV to RGB routines.
862 * these routines calculate r, g and b values from each pixel's y, u and v.
863 * these r, g an b values are then passed thru a table lookup to take the
864 * gamma curve into account and find the corresponding pixel value.
866 * the table must store more than 3*256 values because of the possibility
867 * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
868 * values are in the following intervals :
869 * -176 to 255+176 for red
870 * -133 to 255+133 for green
871 * -222 to 255+222 for blue
873 * If the input y,u,v values are right, the r,g,b results are not expected
874 * to move out of the 0 to 255 interval but who knows what will happen in
877 * the red, green and blue conversion tables are stored in a single 1935-entry
878 * array. The respective positions of each component in the array have been
879 * calculated to minimize the cache interactions of the 3 tables.
882 int rgbTable16 (short table [1935],
883 int redMask, int greenMask, int blueMask,
884 unsigned char gamma[256])
898 MaskToShift (&redRight, &redLeft, redMask);
899 MaskToShift (&greenRight, &greenLeft, greenMask);
900 MaskToShift (&blueRight, &blueLeft, blueMask);
903 * green blue red +- 2 just to be sure
904 * green = 0-525 [151-370]
905 * blue = 594-1297 [834-1053] <834-29>
906 * red = 1323-1934 [1517-1736] <493-712>
909 redTable = table + 1501;
910 greenTable = table + 135;
911 blueTable = table + 818;
913 for (i = 0; i < 178; i++) {
915 redTable[i+256] = redMask;
917 for (i = 0; i < 135; i++) {
918 greenTable[i-135] = 0;
919 greenTable[i+256] = greenMask;
921 for (i = 0; i < 224; i++) {
922 blueTable[i-224] = 0;
923 blueTable[i+256] = blueMask;
926 for (i = 0; i < 256; i++) {
928 redTable[i] = ((y >> redRight) << redLeft);
929 greenTable[i] = ((y >> greenRight) << greenLeft);
930 blueTable[i] = ((y >> blueRight) << blueLeft);
936 static int rgbTable32 (int table [1935],
937 int redMask, int greenMask, int blueMask,
938 unsigned char gamma[256])
952 MaskToShift (&redRight, &redLeft, redMask);
953 MaskToShift (&greenRight, &greenLeft, greenMask);
954 MaskToShift (&blueRight, &blueLeft, blueMask);
958 * green blue red +- 2 just to be sure
959 * green = 0-525 [151-370]
960 * blue = 594-1297 [834-1053] <834-29>
961 * red = 1323-1934 [1517-1736] <493-712>
964 redTable = table + 1501;
965 greenTable = table + 135;
966 blueTable = table + 818;
968 for (i = 0; i < 178; i++) {
970 redTable[i+256] = redMask;
972 for (i = 0; i < 135; i++) {
973 greenTable[i-135] = 0;
974 greenTable[i+256] = greenMask;
976 for (i = 0; i < 224; i++) {
977 blueTable[i-224] = 0;
978 blueTable[i+256] = blueMask;
981 for (i = 0; i < 256; i++) {
983 redTable[i] = ((y >> redRight) << redLeft);
984 greenTable[i] = ((y >> greenRight) << greenLeft);
985 blueTable[i] = ((y >> blueRight) << blueLeft);
992 #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
993 #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
994 #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
995 #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
997 void yuvToRgb16 (unsigned char * Y,
998 unsigned char * U, unsigned char * V,
999 short * dest, short table[1935], int width)
1013 uvRed = (V_RED_COEF*v) >> SHIFT;
1014 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1015 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1017 tableY = table + *(Y++);
1018 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1019 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1021 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1023 tableY = table + *(Y++);
1024 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1025 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1027 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1031 uvRed = (V_RED_COEF*v) >> SHIFT;
1032 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1033 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1035 tableY = table + *(Y++);
1036 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1037 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1039 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1041 tableY = table + *(Y++);
1042 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1043 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1045 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1049 uvRed = (V_RED_COEF*v) >> SHIFT;
1050 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1051 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1053 tableY = table + *(Y++);
1054 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1055 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1057 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1059 tableY = table + *(Y++);
1060 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1061 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1063 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1067 uvRed = (V_RED_COEF*v) >> SHIFT;
1068 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1069 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1071 tableY = table + *(Y++);
1072 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1073 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1075 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1077 tableY = table + *(Y++);
1078 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1079 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1081 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1085 uvRed = (V_RED_COEF*v) >> SHIFT;
1086 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1087 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1089 tableY = table + *(Y++);
1090 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1091 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1093 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1095 tableY = table + *(Y++);
1096 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1097 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1099 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1103 uvRed = (V_RED_COEF*v) >> SHIFT;
1104 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1105 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1107 tableY = table + *(Y++);
1108 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1109 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1111 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1113 tableY = table + *(Y++);
1114 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1115 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1117 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1121 uvRed = (V_RED_COEF*v) >> SHIFT;
1122 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1123 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1125 tableY = table + *(Y++);
1126 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1127 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1129 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1131 tableY = table + *(Y++);
1132 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1133 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1135 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1139 uvRed = (V_RED_COEF*v) >> SHIFT;
1140 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1141 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1143 tableY = table + *(Y++);
1144 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1145 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1147 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1149 tableY = table + *(Y++);
1150 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1151 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1153 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1156 i = (width & 15) >> 1;
1160 uvRed = (V_RED_COEF*v) >> SHIFT;
1161 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1162 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1164 tableY = table + *(Y++);
1165 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1166 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1168 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1170 tableY = table + *(Y++);
1171 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1172 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1174 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1180 uvRed = (V_RED_COEF*v) >> SHIFT;
1181 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1182 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1184 tableY = table + *(Y++);
1185 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1186 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1188 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1192 static void yuvToRgb24 (unsigned char * Y,
1193 unsigned char * U, unsigned char * V,
1194 char * dest, int table[1935], int width)
1209 uvRed = (V_RED_COEF*v) >> SHIFT;
1210 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1211 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1213 tableY = table + *(Y++);
1214 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1215 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1217 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1219 *(dest++) = tmp24 >> 8;
1220 *(dest++) = tmp24 >> 16;
1222 tableY = table + *(Y++);
1223 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1224 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1226 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1228 *(dest++) = tmp24 >> 8;
1229 *(dest++) = tmp24 >> 16;
1233 uvRed = (V_RED_COEF*v) >> SHIFT;
1234 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1235 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1237 tableY = table + *(Y++);
1238 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1239 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1241 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1243 *(dest++) = tmp24 >> 8;
1244 *(dest++) = tmp24 >> 16;
1246 tableY = table + *(Y++);
1247 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1248 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1250 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1252 *(dest++) = tmp24 >> 8;
1253 *(dest++) = tmp24 >> 16;
1257 uvRed = (V_RED_COEF*v) >> SHIFT;
1258 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1259 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1261 tableY = table + *(Y++);
1262 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1263 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1265 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1267 *(dest++) = tmp24 >> 8;
1268 *(dest++) = tmp24 >> 16;
1270 tableY = table + *(Y++);
1271 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1272 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1274 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1276 *(dest++) = tmp24 >> 8;
1277 *(dest++) = tmp24 >> 16;
1281 uvRed = (V_RED_COEF*v) >> SHIFT;
1282 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1283 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1285 tableY = table + *(Y++);
1286 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1287 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1289 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1291 *(dest++) = tmp24 >> 8;
1292 *(dest++) = tmp24 >> 16;
1294 tableY = table + *(Y++);
1295 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1296 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1298 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1300 *(dest++) = tmp24 >> 8;
1301 *(dest++) = tmp24 >> 16;
1304 i = (width & 7) >> 1;
1308 uvRed = (V_RED_COEF*v) >> SHIFT;
1309 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1310 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1312 tableY = table + *(Y++);
1313 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1314 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1316 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1318 *(dest++) = tmp24 >> 8;
1319 *(dest++) = tmp24 >> 16;
1321 tableY = table + *(Y++);
1322 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1323 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1325 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1327 *(dest++) = tmp24 >> 8;
1328 *(dest++) = tmp24 >> 16;
1334 uvRed = (V_RED_COEF*v) >> SHIFT;
1335 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1336 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1338 tableY = table + *(Y++);
1339 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1340 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1342 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1344 *(dest++) = tmp24 >> 8;
1345 *(dest++) = tmp24 >> 16;
1349 static void yuvToRgb32 (unsigned char * Y,
1350 unsigned char * U, unsigned char * V,
1351 int * dest, int table[1935], int width)
1365 uvRed = (V_RED_COEF*v) >> SHIFT;
1366 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1367 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1369 tableY = table + *(Y++);
1370 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1371 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1373 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1375 tableY = table + *(Y++);
1376 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1377 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1379 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1383 uvRed = (V_RED_COEF*v) >> SHIFT;
1384 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1385 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1387 tableY = table + *(Y++);
1388 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1389 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1391 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1393 tableY = table + *(Y++);
1394 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1395 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1397 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1401 uvRed = (V_RED_COEF*v) >> SHIFT;
1402 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1403 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1405 tableY = table + *(Y++);
1406 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1407 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1409 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1411 tableY = table + *(Y++);
1412 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1413 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1415 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1419 uvRed = (V_RED_COEF*v) >> SHIFT;
1420 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1421 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1423 tableY = table + *(Y++);
1424 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1425 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1427 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1429 tableY = table + *(Y++);
1430 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1431 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1433 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1437 uvRed = (V_RED_COEF*v) >> SHIFT;
1438 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1439 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1441 tableY = table + *(Y++);
1442 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1443 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1445 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1447 tableY = table + *(Y++);
1448 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1449 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1451 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1455 uvRed = (V_RED_COEF*v) >> SHIFT;
1456 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1457 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1459 tableY = table + *(Y++);
1460 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1461 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1463 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1465 tableY = table + *(Y++);
1466 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1467 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1469 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1473 uvRed = (V_RED_COEF*v) >> SHIFT;
1474 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1475 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1477 tableY = table + *(Y++);
1478 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1479 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1481 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1483 tableY = table + *(Y++);
1484 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1485 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1487 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1491 uvRed = (V_RED_COEF*v) >> SHIFT;
1492 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1493 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1495 tableY = table + *(Y++);
1496 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1497 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1499 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1501 tableY = table + *(Y++);
1502 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1503 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1505 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1508 i = (width & 15) >> 1;
1512 uvRed = (V_RED_COEF*v) >> SHIFT;
1513 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1514 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1516 tableY = table + *(Y++);
1517 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1518 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1520 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1522 tableY = table + *(Y++);
1523 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1524 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1526 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1532 uvRed = (V_RED_COEF*v) >> SHIFT;
1533 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1534 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1536 tableY = table + *(Y++);
1537 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1538 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1540 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);