1 /*******************************************************************************
2 * video_yuv.c: YUV transformation functions
4 *******************************************************************************
5 * Provides functions to perform the YUV conversion. The functions provided here
6 * are a complete and portable C implementation, and may be replaced in certain
7 * case by optimized functions.
8 *******************************************************************************/
10 /*******************************************************************************
12 *******************************************************************************/
21 #include "vlc_thread.h"
23 #include "video_output.h"
24 #include "video_yuv.h"
27 /*******************************************************************************
29 *******************************************************************************/
31 /* RGB/YUV inversion matrix (ISO/IEC 13818-2 section 6.3.6, table 6.9) */
32 const int MATRIX_COEFFICIENTS_TABLE[8][4] =
34 {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
35 {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
36 {104597, 132201, 25675, 53279}, /* unspecified */
37 {104597, 132201, 25675, 53279}, /* reserved */
38 {104448, 132798, 24759, 53109}, /* FCC */
39 {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
40 {104597, 132201, 25675, 53279}, /* SMPTE 170M */
41 {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */
44 /*******************************************************************************
46 *******************************************************************************/
47 static int BinaryLog ( u32 i );
48 static void MaskToShift ( int *pi_right, int *pi_left, u32 i_mask );
49 static void SetTables ( vout_thread_t *p_vout );
51 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,
52 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
53 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,
54 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
55 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,
56 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
57 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,
58 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
59 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,
60 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
61 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,
62 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
63 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,
64 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
65 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,
66 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
67 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,
68 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
69 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,
70 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
71 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,
72 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
73 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,
74 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
75 static void Scale16 ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
76 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
77 static void Scale24 ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
78 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
79 static void Scale32 ( 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 );
82 /*******************************************************************************
83 * CLIP_BYTE macro: boundary detection
84 *******************************************************************************
85 * Return parameter if between 0 and 255, else return nearest boundary (0 or
86 * 255). This macro is used to build translations tables.
87 *******************************************************************************/
88 #define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
90 /*******************************************************************************
91 * LINE_COPY macro: memcopy using 16 pixels blocks
92 *******************************************************************************
94 * p_pic destination pointer
95 * p_pic_src source pointer
98 *******************************************************************************/
100 for( i_x = 0; i_x < i_width; i_x+=16 ) \
102 *p_pic++ = *p_pic_src++; \
103 *p_pic++ = *p_pic_src++; \
104 *p_pic++ = *p_pic_src++; \
105 *p_pic++ = *p_pic_src++; \
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++; \
120 /*******************************************************************************
121 * CONVERT_YUV_GRAY macro: grayscale YUV convertion
122 *******************************************************************************
124 * ...see vout_convert_t
125 * i_x, i_y coordinates
126 * i_pic_copy same type as p_pic
127 * p_gray gray translation table
128 *******************************************************************************/
129 #define CONVERT_YUV_GRAY \
130 for (i_y = 0; i_y < i_height ; i_y++) \
132 for (i_x = 0; i_x < i_width; i_x += 16) \
134 /* Convert 16 pixels (width is always multiple of 16 */ \
135 *p_pic++ = p_gray[ *p_y++ ]; \
136 *p_pic++ = p_gray[ *p_y++ ]; \
137 *p_pic++ = p_gray[ *p_y++ ]; \
138 *p_pic++ = p_gray[ *p_y++ ]; \
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++ ]; \
153 /* Handle scale factor */ \
154 if( i_scale && ! (i_y % i_scale) ) \
158 /* Copy previous line */ \
159 p_pic_src = p_pic - i_width; \
160 p_pic += i_pic_eol; \
165 /* Ignore next line */ \
166 p_y += i_eol + i_width; \
171 /* Skip until beginning of next line */ \
172 p_pic += i_pic_eol; \
176 /*******************************************************************************
177 * CONVERT_YUV_RGB: color YUV convertion
178 *******************************************************************************
180 * CHROMA 420, 422 or 444
182 * ...see vout_convert_t
183 * i_x, i_y coordinates
184 * i_uval, i_yval, i_vval samples
185 * p_pic_src same type as p_pic
186 * i_chroma_width chroma width
187 * i_chroma_eol chroma eol
188 * p_red red translation table
189 * p_green green translation table
190 * p_blue blue translation table
191 * i_crv, i_cgu, i_cgv, i_cbu matrix coefficients
192 *******************************************************************************/
193 #define CONVERT_YUV_RGB( CHROMA ) \
194 for (i_y = 0; i_y < i_height ; i_y++) \
196 for (i_x = 0; i_x < i_width; i_x += 2 ) \
198 /* First sample (complete) */ \
199 i_yval = 76309 * *p_y++ - 1188177; \
200 i_uval = *p_u++ - 128; \
201 i_vval = *p_v++ - 128; \
203 p_red [(i_yval+i_crv*i_vval) >>16] | \
204 p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval) >>16] | \
205 p_blue [(i_yval+i_cbu*i_uval) >>16]; \
206 i_yval = 76309 * *p_y++ - 1188177; \
207 /* Second sample (partial) */ \
208 if( CHROMA == 444 ) \
210 i_uval = *p_u++ - 128; \
211 i_vval = *p_v++ - 128; \
214 p_red [(i_yval+i_crv*i_vval) >>16] | \
215 p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval) >>16] | \
216 p_blue [(i_yval+i_cbu*i_uval) >>16]; \
219 /* Handle scale factor and rewind in 4:2:0 */ \
220 if( i_scale && ! (i_y % i_scale) ) \
224 /* Copy previous line, rewind if required */ \
225 p_pic_src = p_pic - i_width; \
226 p_pic += i_pic_eol; \
228 if( (CHROMA == 420) && !(i_y & 0x1) ) \
230 p_u -= i_chroma_width; \
231 p_v -= i_chroma_width; \
235 p_u += i_chroma_eol; \
236 p_v += i_chroma_eol; \
241 /* Ignore next line */ \
242 p_y += i_eol + i_width; \
243 p_u += i_chroma_eol; \
244 p_v += i_chroma_eol; \
248 else if( (CHROMA == 420) && !(i_y & 0x1) ) \
250 p_u -= i_chroma_width; \
251 p_v -= i_chroma_width; \
255 p_u += i_chroma_eol; \
256 p_v += i_chroma_eol; \
259 /* Skip until beginning of next line */ \
260 p_pic += i_pic_eol; \
265 /*******************************************************************************
266 * vout_InitTables: allocate and initialize translations tables
267 *******************************************************************************
268 * This function will allocate memory to store translation tables, depending
269 * of the screen depth.
270 *******************************************************************************/
271 int vout_InitTables( vout_thread_t *p_vout )
273 size_t tables_size; /* tables size, in bytes */
275 /* Computes tables size */
276 switch( p_vout->i_screen_depth )
280 tables_size = sizeof( u16 ) * 1024 * (p_vout->b_grayscale ? 1 : 3);
287 tables_size = sizeof( u32 ) * 1024 * (p_vout->b_grayscale ? 1 : 3);
291 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
297 /* Allocate memory */
298 p_vout->tables.p_base = malloc( tables_size );
299 if( p_vout->tables.p_base == NULL )
301 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
305 /* Initialize tables */
310 /*******************************************************************************
311 * vout_ResetTables: re-initialize translations tables
312 *******************************************************************************
313 * This function will initialize the tables allocated by vout_CreateTables and
314 * set functions pointers.
315 *******************************************************************************/
316 int vout_ResetTables( vout_thread_t *p_vout )
318 vout_EndTables( p_vout );
319 return( vout_InitTables( p_vout ) );
322 /*******************************************************************************
323 * vout_EndTables: destroy translations tables
324 *******************************************************************************
325 * Free memory allocated by vout_CreateTables.
326 *******************************************************************************/
327 void vout_EndTables( vout_thread_t *p_vout )
329 free( p_vout->tables.p_base );
332 /* following functions are local */
334 /*******************************************************************************
335 * BinaryLog: computes the base 2 log of a binary value
336 *******************************************************************************
337 * This functions is used by MaskToShift during tables initialisation, to
338 * get a bit index from a binary value.
339 *******************************************************************************/
340 static int BinaryLog(u32 i)
365 if (i != ((u32)1 << i_log))
367 intf_ErrMsg("internal error: binary log overflow\n");
373 /*******************************************************************************
374 * MaskToShift: Transform a color mask into right and left shifts
375 *******************************************************************************
376 * This function is used during table initialisation. It can return a value
377 *******************************************************************************/
378 static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
380 u32 i_low, i_high; /* lower hand higher bits of the mask */
383 i_low = i_mask & (- i_mask); /* lower bit of the mask */
384 i_high = i_mask + i_low; /* higher bit of the mask */
386 /* Transform bits into an index */
387 i_low = BinaryLog (i_low);
388 i_high = BinaryLog (i_high);
390 /* Update pointers and return */
392 *pi_right = (8 - i_high + i_low);
395 /*******************************************************************************
396 * SetTables: compute tables and set function pointers
397 *******************************************************************************/
398 static void SetTables( vout_thread_t *p_vout )
400 u8 i_gamma[256]; /* gamma table */
401 int i_index; /* index in tables */
402 int i_red_right, i_red_left; /* red shifts */
403 int i_green_right, i_green_left; /* green shifts */
404 int i_blue_right, i_blue_left; /* blue shifts */
409 for( i_index = 0; i_index < 256; i_index++ )
411 i_gamma[i_index] = 255. * pow( (double)i_index / 255., exp(p_vout->f_gamma) );
415 * Set color masks and shifts
417 switch( p_vout->i_screen_depth )
420 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
421 MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
422 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
425 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
426 MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
427 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
431 MaskToShift( &i_red_right, &i_red_left, 0x00ff0000 );
432 MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
433 MaskToShift( &i_blue_right, &i_blue_left, 0x000000ff );
437 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
443 * Set pointers and build YUV tables
445 if( p_vout->b_grayscale )
447 /* Grayscale: build gray table */
448 switch( p_vout->i_screen_depth )
452 p_vout->tables.yuv.gray16.p_gray = (u16 *)p_vout->tables.p_base + 384;
453 for( i_index = -384; i_index < 640; i_index++)
455 p_vout->tables.yuv.gray16.p_gray[ i_index ] =
456 ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
457 ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
458 ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
463 p_vout->tables.yuv.gray32.p_gray = (u32 *)p_vout->tables.p_base + 384;
464 for( i_index = -384; i_index < 640; i_index++)
466 p_vout->tables.yuv.gray32.p_gray[ i_index ] =
467 ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
468 ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
469 ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
476 /* Color: build red, green and blue tables */
477 switch( p_vout->i_screen_depth )
481 p_vout->tables.yuv.rgb16.p_red = (u16 *)p_vout->tables.p_base + 384;
482 p_vout->tables.yuv.rgb16.p_green = (u16 *)p_vout->tables.p_base + 1024 + 384;
483 p_vout->tables.yuv.rgb16.p_blue = (u16 *)p_vout->tables.p_base + 2*1024 + 384;
484 for( i_index = -384; i_index < 640; i_index++)
486 p_vout->tables.yuv.rgb16.p_red[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
487 p_vout->tables.yuv.rgb16.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
488 p_vout->tables.yuv.rgb16.p_blue[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
493 p_vout->tables.yuv.rgb32.p_red = (u32 *)p_vout->tables.p_base + 384;
494 p_vout->tables.yuv.rgb32.p_green = (u32 *)p_vout->tables.p_base + 1024 + 384;
495 p_vout->tables.yuv.rgb32.p_blue = (u32 *)p_vout->tables.p_base + 2*1024 + 384;
496 for( i_index = -384; i_index < 640; i_index++)
498 p_vout->tables.yuv.rgb32.p_red[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
499 p_vout->tables.yuv.rgb32.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
500 p_vout->tables.yuv.rgb32.p_blue[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
507 * Set functions pointers
509 if( p_vout->b_grayscale )
512 switch( p_vout->i_screen_depth )
516 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
517 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
518 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
519 p_vout->p_Scale = (vout_scale_t *) Scale16;
522 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
523 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
524 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
525 p_vout->p_Scale = (vout_scale_t *) Scale24;
528 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
529 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
530 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
531 p_vout->p_Scale = (vout_scale_t *) Scale32;
538 switch( p_vout->i_screen_depth )
542 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB16;
543 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB16;
544 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB16;
545 p_vout->p_Scale = (vout_scale_t *) Scale16;
548 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB24;
549 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB24;
550 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB24;
551 p_vout->p_Scale = (vout_scale_t *) Scale24;
554 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB32;
555 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB32;
556 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB32;
557 p_vout->p_Scale = (vout_scale_t *) Scale32;
563 /*******************************************************************************
564 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
565 *******************************************************************************/
566 static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic,
567 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
568 int i_width, int i_height, int i_eol, int i_pic_eol,
569 int i_scale, int i_matrix_coefficients )
571 u16 * p_pic_src; /* source pointer in case of copy */
572 u16 * p_gray; /* gray table */
573 int i_x, i_y; /* picture coordinates */
575 p_gray = p_vout->tables.yuv.gray16.p_gray;
579 /*******************************************************************************
580 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
581 *******************************************************************************/
582 static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic,
583 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
584 int i_width, int i_height, int i_eol, int i_pic_eol,
585 int i_scale, int i_matrix_coefficients )
590 /*******************************************************************************
591 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
592 *******************************************************************************/
593 static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic,
594 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
595 int i_width, int i_height, int i_eol, int i_pic_eol,
596 int i_scale, int i_matrix_coefficients )
598 u32 * p_pic_src; /* source pointer in case of copy */
599 u32 * p_gray; /* gray table */
600 int i_x, i_y; /* picture coordinates */
602 p_gray = p_vout->tables.yuv.gray32.p_gray;
606 /*******************************************************************************
607 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
608 *******************************************************************************/
609 static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic,
610 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
611 int i_width, int i_height, int i_eol, int i_pic_eol,
612 int i_scale, int i_matrix_coefficients )
615 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
617 i_chroma_width = i_width / 2;
618 i_chroma_eol = i_eol / 2;
619 ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height,
620 (i_width + i_eol) * sizeof( yuv_data_t ),
621 (i_chroma_width + i_chroma_eol) * sizeof( yuv_data_t),
622 i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
623 p_vout->i_screen_depth == 15 );
625 u16 * p_pic_src; /* source pointer in case of copy */
626 u16 * p_red; /* red table */
627 u16 * p_green; /* green table */
628 u16 * p_blue; /* blue table */
629 int i_uval, i_yval, i_vval; /* samples */
630 int i_x, i_y; /* picture coordinates */
631 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
632 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
634 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
635 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
636 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
637 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
638 p_red = p_vout->tables.yuv.rgb16.p_red;
639 p_green = p_vout->tables.yuv.rgb16.p_green;
640 p_blue = p_vout->tables.yuv.rgb16.p_blue;
641 i_chroma_width = i_width / 2;
642 i_chroma_eol = i_eol / 2;
643 CONVERT_YUV_RGB( 420 )
647 /*******************************************************************************
648 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
649 *******************************************************************************/
650 static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic,
651 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
652 int i_width, int i_height, int i_eol, int i_pic_eol,
653 int i_scale, int i_matrix_coefficients )
655 u16 * p_pic_src; /* source pointer in case of copy */
656 u16 * p_red; /* red table */
657 u16 * p_green; /* green table */
658 u16 * p_blue; /* blue table */
659 int i_uval, i_yval, i_vval; /* samples */
660 int i_x, i_y; /* picture coordinates */
661 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
662 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
664 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
665 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
666 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
667 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
668 p_red = p_vout->tables.yuv.rgb16.p_red;
669 p_green = p_vout->tables.yuv.rgb16.p_green;
670 p_blue = p_vout->tables.yuv.rgb16.p_blue;
671 i_chroma_width = i_width / 2;
672 i_chroma_eol = i_eol / 2;
673 CONVERT_YUV_RGB( 422 )
676 /*******************************************************************************
677 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
678 *******************************************************************************/
679 static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic,
680 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
681 int i_width, int i_height, int i_eol, int i_pic_eol,
682 int i_scale, int i_matrix_coefficients )
684 u16 * p_pic_src; /* source pointer in case of copy */
685 u16 * p_red; /* red table */
686 u16 * p_green; /* green table */
687 u16 * p_blue; /* blue table */
688 int i_uval, i_yval, i_vval; /* samples */
689 int i_x, i_y; /* picture coordinates */
690 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
691 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
693 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
694 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
695 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
696 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
697 p_red = p_vout->tables.yuv.rgb16.p_red;
698 p_green = p_vout->tables.yuv.rgb16.p_green;
699 p_blue = p_vout->tables.yuv.rgb16.p_blue;
700 i_chroma_width = i_width;
701 i_chroma_eol = i_eol;
702 CONVERT_YUV_RGB( 444 )
705 /*******************************************************************************
706 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
707 *******************************************************************************/
708 static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic,
709 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
710 int i_width, int i_height, int i_eol, int i_pic_eol,
711 int i_scale, int i_matrix_coefficients )
716 /*******************************************************************************
717 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
718 *******************************************************************************/
719 static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic,
720 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
721 int i_width, int i_height, int i_eol, int i_pic_eol,
722 int i_scale, int i_matrix_coefficients )
727 /*******************************************************************************
728 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
729 *******************************************************************************/
730 static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic,
731 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
732 int i_width, int i_height, int i_eol, int i_pic_eol,
733 int i_scale, int i_matrix_coefficients )
738 /*******************************************************************************
739 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
740 *******************************************************************************/
741 static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic,
742 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
743 int i_width, int i_height, int i_eol, int i_pic_eol,
744 int i_scale, int i_matrix_coefficients )
746 u32 * p_pic_src; /* source pointer in case of copy */
747 u32 * p_red; /* red table */
748 u32 * p_green; /* green table */
749 u32 * p_blue; /* blue table */
750 int i_uval, i_yval, i_vval; /* samples */
751 int i_x, i_y; /* picture coordinates */
752 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
753 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
755 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
756 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
757 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
758 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
759 p_red = p_vout->tables.yuv.rgb32.p_red;
760 p_green = p_vout->tables.yuv.rgb32.p_green;
761 p_blue = p_vout->tables.yuv.rgb32.p_blue;
762 i_chroma_width = i_width / 2;
763 i_chroma_eol = i_eol / 2;
764 CONVERT_YUV_RGB( 420 )
767 /*******************************************************************************
768 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
769 *******************************************************************************/
770 static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic,
771 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
772 int i_width, int i_height, int i_eol, int i_pic_eol,
773 int i_scale, int i_matrix_coefficients )
775 u32 * p_pic_src; /* source pointer in case of copy */
776 u32 * p_red; /* red table */
777 u32 * p_green; /* green table */
778 u32 * p_blue; /* blue table */
779 int i_uval, i_yval, i_vval; /* samples */
780 int i_x, i_y; /* picture coordinates */
781 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
782 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
784 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
785 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
786 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
787 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
788 p_red = p_vout->tables.yuv.rgb32.p_red;
789 p_green = p_vout->tables.yuv.rgb32.p_green;
790 p_blue = p_vout->tables.yuv.rgb32.p_blue;
791 i_chroma_width = i_width / 2;
792 i_chroma_eol = i_eol / 2;
793 CONVERT_YUV_RGB( 422 )
796 /*******************************************************************************
797 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
798 *******************************************************************************/
799 static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic,
800 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
801 int i_width, int i_height, int i_eol, int i_pic_eol,
802 int i_scale, int i_matrix_coefficients )
804 u32 * p_pic_src; /* source pointer in case of copy */
805 u32 * p_red; /* red table */
806 u32 * p_green; /* green table */
807 u32 * p_blue; /* blue table */
808 int i_uval, i_yval, i_vval; /* samples */
809 int i_x, i_y; /* picture coordinates */
810 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
811 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
813 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
814 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
815 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
816 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
817 p_red = p_vout->tables.yuv.rgb32.p_red;
818 p_green = p_vout->tables.yuv.rgb32.p_green;
819 p_blue = p_vout->tables.yuv.rgb32.p_blue;
820 i_chroma_width = i_width;
821 i_chroma_eol = i_eol;
822 CONVERT_YUV_RGB( 444 )
825 /*******************************************************************************
826 * Scale16: 15 or 16 bpp picture scaling
827 *******************************************************************************/
828 static void Scale16( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
829 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
834 /*******************************************************************************
835 * Scale24: 24 bpp picture scaling
836 *******************************************************************************/
837 static void Scale24( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
838 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
843 /*******************************************************************************
844 * Scale32: 32 bpp picture scaling
845 *******************************************************************************/
846 static void Scale32( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
847 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
852 //-------------------- walken code follow --------------------------------
855 * YUV to RGB routines.
857 * these routines calculate r, g and b values from each pixel's y, u and v.
858 * these r, g an b values are then passed thru a table lookup to take the
859 * gamma curve into account and find the corresponding pixel value.
861 * the table must store more than 3*256 values because of the possibility
862 * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
863 * values are in the following intervals :
864 * -176 to 255+176 for red
865 * -133 to 255+133 for green
866 * -222 to 255+222 for blue
868 * If the input y,u,v values are right, the r,g,b results are not expected
869 * to move out of the 0 to 255 interval but who knows what will happen in
872 * the red, green and blue conversion tables are stored in a single 1935-entry
873 * array. The respective positions of each component in the array have been
874 * calculated to minimize the cache interactions of the 3 tables.
877 int rgbTable16 (short table [1935],
878 int redMask, int greenMask, int blueMask,
879 unsigned char gamma[256])
893 MaskToShift (&redRight, &redLeft, redMask);
894 MaskToShift (&greenRight, &greenLeft, greenMask);
895 MaskToShift (&blueRight, &blueLeft, blueMask);
898 * green blue red +- 2 just to be sure
899 * green = 0-525 [151-370]
900 * blue = 594-1297 [834-1053] <834-29>
901 * red = 1323-1934 [1517-1736] <493-712>
904 redTable = table + 1501;
905 greenTable = table + 135;
906 blueTable = table + 818;
908 for (i = 0; i < 178; i++) {
910 redTable[i+256] = redMask;
912 for (i = 0; i < 135; i++) {
913 greenTable[i-135] = 0;
914 greenTable[i+256] = greenMask;
916 for (i = 0; i < 224; i++) {
917 blueTable[i-224] = 0;
918 blueTable[i+256] = blueMask;
921 for (i = 0; i < 256; i++) {
923 redTable[i] = ((y >> redRight) << redLeft);
924 greenTable[i] = ((y >> greenRight) << greenLeft);
925 blueTable[i] = ((y >> blueRight) << blueLeft);
931 static int rgbTable32 (int table [1935],
932 int redMask, int greenMask, int blueMask,
933 unsigned char gamma[256])
947 MaskToShift (&redRight, &redLeft, redMask);
948 MaskToShift (&greenRight, &greenLeft, greenMask);
949 MaskToShift (&blueRight, &blueLeft, blueMask);
953 * green blue red +- 2 just to be sure
954 * green = 0-525 [151-370]
955 * blue = 594-1297 [834-1053] <834-29>
956 * red = 1323-1934 [1517-1736] <493-712>
959 redTable = table + 1501;
960 greenTable = table + 135;
961 blueTable = table + 818;
963 for (i = 0; i < 178; i++) {
965 redTable[i+256] = redMask;
967 for (i = 0; i < 135; i++) {
968 greenTable[i-135] = 0;
969 greenTable[i+256] = greenMask;
971 for (i = 0; i < 224; i++) {
972 blueTable[i-224] = 0;
973 blueTable[i+256] = blueMask;
976 for (i = 0; i < 256; i++) {
978 redTable[i] = ((y >> redRight) << redLeft);
979 greenTable[i] = ((y >> greenRight) << greenLeft);
980 blueTable[i] = ((y >> blueRight) << blueLeft);
987 #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
988 #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
989 #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
990 #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
992 void yuvToRgb16 (unsigned char * Y,
993 unsigned char * U, unsigned char * V,
994 short * dest, short table[1935], int width)
1008 uvRed = (V_RED_COEF*v) >> SHIFT;
1009 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1010 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1012 tableY = table + *(Y++);
1013 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1014 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1016 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1018 tableY = table + *(Y++);
1019 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1020 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1022 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1026 uvRed = (V_RED_COEF*v) >> SHIFT;
1027 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1028 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1030 tableY = table + *(Y++);
1031 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1032 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1034 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1036 tableY = table + *(Y++);
1037 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1038 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1040 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1044 uvRed = (V_RED_COEF*v) >> SHIFT;
1045 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1046 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1048 tableY = table + *(Y++);
1049 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1050 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1052 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1054 tableY = table + *(Y++);
1055 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1056 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1058 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1062 uvRed = (V_RED_COEF*v) >> SHIFT;
1063 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1064 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1066 tableY = table + *(Y++);
1067 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1068 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1070 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1072 tableY = table + *(Y++);
1073 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1074 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1076 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1080 uvRed = (V_RED_COEF*v) >> SHIFT;
1081 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1082 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1084 tableY = table + *(Y++);
1085 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1086 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1088 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1090 tableY = table + *(Y++);
1091 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1092 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1094 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1098 uvRed = (V_RED_COEF*v) >> SHIFT;
1099 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1100 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1102 tableY = table + *(Y++);
1103 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1104 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1106 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1108 tableY = table + *(Y++);
1109 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1110 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1112 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1116 uvRed = (V_RED_COEF*v) >> SHIFT;
1117 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1118 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1120 tableY = table + *(Y++);
1121 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1122 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1124 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1126 tableY = table + *(Y++);
1127 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1128 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1130 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1134 uvRed = (V_RED_COEF*v) >> SHIFT;
1135 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1136 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1138 tableY = table + *(Y++);
1139 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1140 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1142 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1144 tableY = table + *(Y++);
1145 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1146 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1148 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1151 i = (width & 15) >> 1;
1155 uvRed = (V_RED_COEF*v) >> SHIFT;
1156 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1157 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1159 tableY = table + *(Y++);
1160 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1161 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1163 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1165 tableY = table + *(Y++);
1166 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1167 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1169 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1175 uvRed = (V_RED_COEF*v) >> SHIFT;
1176 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1177 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1179 tableY = table + *(Y++);
1180 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1181 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1183 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1187 static void yuvToRgb24 (unsigned char * Y,
1188 unsigned char * U, unsigned char * V,
1189 char * dest, int table[1935], int width)
1204 uvRed = (V_RED_COEF*v) >> SHIFT;
1205 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1206 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1208 tableY = table + *(Y++);
1209 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1210 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1212 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1214 *(dest++) = tmp24 >> 8;
1215 *(dest++) = tmp24 >> 16;
1217 tableY = table + *(Y++);
1218 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1219 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1221 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1223 *(dest++) = tmp24 >> 8;
1224 *(dest++) = tmp24 >> 16;
1228 uvRed = (V_RED_COEF*v) >> SHIFT;
1229 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1230 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1232 tableY = table + *(Y++);
1233 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1234 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1236 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1238 *(dest++) = tmp24 >> 8;
1239 *(dest++) = tmp24 >> 16;
1241 tableY = table + *(Y++);
1242 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1243 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1245 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1247 *(dest++) = tmp24 >> 8;
1248 *(dest++) = tmp24 >> 16;
1252 uvRed = (V_RED_COEF*v) >> SHIFT;
1253 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1254 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1256 tableY = table + *(Y++);
1257 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1258 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1260 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1262 *(dest++) = tmp24 >> 8;
1263 *(dest++) = tmp24 >> 16;
1265 tableY = table + *(Y++);
1266 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1267 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1269 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1271 *(dest++) = tmp24 >> 8;
1272 *(dest++) = tmp24 >> 16;
1276 uvRed = (V_RED_COEF*v) >> SHIFT;
1277 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1278 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1280 tableY = table + *(Y++);
1281 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1282 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1284 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1286 *(dest++) = tmp24 >> 8;
1287 *(dest++) = tmp24 >> 16;
1289 tableY = table + *(Y++);
1290 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1291 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1293 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1295 *(dest++) = tmp24 >> 8;
1296 *(dest++) = tmp24 >> 16;
1299 i = (width & 7) >> 1;
1303 uvRed = (V_RED_COEF*v) >> SHIFT;
1304 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1305 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1307 tableY = table + *(Y++);
1308 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1309 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1311 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1313 *(dest++) = tmp24 >> 8;
1314 *(dest++) = tmp24 >> 16;
1316 tableY = table + *(Y++);
1317 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1318 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1320 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1322 *(dest++) = tmp24 >> 8;
1323 *(dest++) = tmp24 >> 16;
1329 uvRed = (V_RED_COEF*v) >> SHIFT;
1330 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1331 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1333 tableY = table + *(Y++);
1334 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1335 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1337 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1339 *(dest++) = tmp24 >> 8;
1340 *(dest++) = tmp24 >> 16;
1344 static void yuvToRgb32 (unsigned char * Y,
1345 unsigned char * U, unsigned char * V,
1346 int * dest, int table[1935], int width)
1360 uvRed = (V_RED_COEF*v) >> SHIFT;
1361 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1362 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1364 tableY = table + *(Y++);
1365 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1366 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1368 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1370 tableY = table + *(Y++);
1371 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1372 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1374 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1378 uvRed = (V_RED_COEF*v) >> SHIFT;
1379 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1380 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1382 tableY = table + *(Y++);
1383 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1384 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1386 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1388 tableY = table + *(Y++);
1389 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1390 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1392 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1396 uvRed = (V_RED_COEF*v) >> SHIFT;
1397 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1398 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1400 tableY = table + *(Y++);
1401 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1402 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1404 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1406 tableY = table + *(Y++);
1407 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1408 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1410 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1414 uvRed = (V_RED_COEF*v) >> SHIFT;
1415 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1416 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1418 tableY = table + *(Y++);
1419 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1420 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1422 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1424 tableY = table + *(Y++);
1425 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1426 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1428 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1432 uvRed = (V_RED_COEF*v) >> SHIFT;
1433 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1434 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1436 tableY = table + *(Y++);
1437 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1438 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1440 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1442 tableY = table + *(Y++);
1443 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1444 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1446 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1450 uvRed = (V_RED_COEF*v) >> SHIFT;
1451 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1452 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1454 tableY = table + *(Y++);
1455 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1456 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1458 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1460 tableY = table + *(Y++);
1461 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1462 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1464 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1468 uvRed = (V_RED_COEF*v) >> SHIFT;
1469 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1470 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1472 tableY = table + *(Y++);
1473 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1474 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1476 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1478 tableY = table + *(Y++);
1479 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1480 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1482 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1486 uvRed = (V_RED_COEF*v) >> SHIFT;
1487 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1488 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1490 tableY = table + *(Y++);
1491 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1492 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1494 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1496 tableY = table + *(Y++);
1497 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1498 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1500 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1503 i = (width & 15) >> 1;
1507 uvRed = (V_RED_COEF*v) >> SHIFT;
1508 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1509 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1511 tableY = table + *(Y++);
1512 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1513 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1515 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1517 tableY = table + *(Y++);
1518 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1519 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1521 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1527 uvRed = (V_RED_COEF*v) >> SHIFT;
1528 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1529 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1531 tableY = table + *(Y++);
1532 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1533 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1535 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);