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 );
76 /*******************************************************************************
77 * CLIP_BYTE macro: boundary detection
78 *******************************************************************************
79 * Return parameter if between 0 and 255, else return nearest boundary (0 or
80 * 255). This macro is used to build translations tables.
81 *******************************************************************************/
82 #define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
84 /*******************************************************************************
85 * LINE_COPY macro: memcopy using 16 pixels blocks
86 *******************************************************************************
88 * p_pic destination pointer
89 * p_pic_src source pointer
92 *******************************************************************************/
94 for( i_x = 0; i_x < i_width; i_x+=16 ) \
96 *p_pic++ = *p_pic_src++; \
97 *p_pic++ = *p_pic_src++; \
98 *p_pic++ = *p_pic_src++; \
99 *p_pic++ = *p_pic_src++; \
100 *p_pic++ = *p_pic_src++; \
101 *p_pic++ = *p_pic_src++; \
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++; \
114 /*******************************************************************************
115 * CONVERT_YUV_GRAY macro: grayscale YUV convertion
116 *******************************************************************************
118 * ...see vout_convert_t
119 * i_x, i_y coordinates
120 * i_pic_copy same type as p_pic
121 * p_gray gray translation table
122 *******************************************************************************/
123 #define CONVERT_YUV_GRAY \
124 for (i_y = 0; i_y < i_height ; i_y++) \
126 for (i_x = 0; i_x < i_width; i_x += 16) \
128 /* Convert 16 pixels (width is always multiple of 16 */ \
129 *p_pic++ = p_gray[ *p_y++ ]; \
130 *p_pic++ = p_gray[ *p_y++ ]; \
131 *p_pic++ = p_gray[ *p_y++ ]; \
132 *p_pic++ = p_gray[ *p_y++ ]; \
133 *p_pic++ = p_gray[ *p_y++ ]; \
134 *p_pic++ = p_gray[ *p_y++ ]; \
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++ ]; \
147 /* Handle scale factor */ \
148 if( i_scale && ! (i_y % i_scale) ) \
152 /* Copy previous line */ \
153 p_pic_src = p_pic - i_width; \
154 p_pic += i_pic_eol; \
159 /* Ignore next line */ \
160 p_y += i_eol + i_width; \
165 /* Skip until beginning of next line */ \
166 p_pic += i_pic_eol; \
170 /*******************************************************************************
171 * CONVERT_YUV_RGB: color YUV convertion
172 *******************************************************************************
174 * CHROMA 420, 422 or 444
176 * ...see vout_convert_t
177 * i_x, i_y coordinates
178 * i_uval, i_yval, i_vval samples
179 * p_pic_src same type as p_pic
180 * i_chroma_width chroma width
181 * i_chroma_eol chroma eol
182 * p_red red translation table
183 * p_green green translation table
184 * p_blue blue translation table
185 * i_crv, i_cgu, i_cgv, i_cbu matrix coefficients
186 *******************************************************************************/
187 #define CONVERT_YUV_RGB( CHROMA ) \
188 for (i_y = 0; i_y < i_height ; i_y++) \
190 for (i_x = 0; i_x < i_width; i_x += 2 ) \
192 /* First sample (complete) */ \
193 i_yval = 76309 * *p_y++ - 1188177; \
194 i_uval = *p_u++ - 128; \
195 i_vval = *p_v++ - 128; \
197 p_red [(i_yval+i_crv*i_vval) >>16] | \
198 p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval) >>16] | \
199 p_blue [(i_yval+i_cbu*i_uval) >>16]; \
200 i_yval = 76309 * *p_y++ - 1188177; \
201 /* Second sample (partial) */ \
202 if( CHROMA == 444 ) \
204 i_uval = *p_u++ - 128; \
205 i_vval = *p_v++ - 128; \
208 p_red [(i_yval+i_crv*i_vval) >>16] | \
209 p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval) >>16] | \
210 p_blue [(i_yval+i_cbu*i_uval) >>16]; \
213 /* Handle scale factor and rewind in 4:2:0 */ \
214 if( i_scale && ! (i_y % i_scale) ) \
218 /* Copy previous line, rewind if required */ \
219 p_pic_src = p_pic - i_width; \
220 p_pic += i_pic_eol; \
222 if( (CHROMA == 420) && !(i_y & 0x1) ) \
224 p_u -= i_chroma_width; \
225 p_v -= i_chroma_width; \
229 p_u += i_chroma_eol; \
230 p_v += i_chroma_eol; \
235 /* Ignore next line */ \
236 p_y += i_eol + i_width; \
237 p_u += i_chroma_eol; \
238 p_v += i_chroma_eol; \
242 else if( (CHROMA == 420) && !(i_y & 0x1) ) \
244 p_u -= i_chroma_width; \
245 p_v -= i_chroma_width; \
249 p_u += i_chroma_eol; \
250 p_v += i_chroma_eol; \
253 /* Skip until beginning of next line */ \
254 p_pic += i_pic_eol; \
259 /*******************************************************************************
260 * vout_InitTables: allocate and initialize translations tables
261 *******************************************************************************
262 * This function will allocate memory to store translation tables, depending
263 * of the screen depth.
264 *******************************************************************************/
265 int vout_InitTables( vout_thread_t *p_vout )
267 size_t tables_size; /* tables size, in bytes */
269 /* Computes tables size */
270 switch( p_vout->i_screen_depth )
274 tables_size = sizeof( u16 ) * 1024 * (p_vout->b_grayscale ? 1 : 3);
281 tables_size = sizeof( u32 ) * 1024 * (p_vout->b_grayscale ? 1 : 3);
285 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
291 /* Allocate memory */
292 p_vout->tables.p_base = malloc( tables_size );
293 if( p_vout->tables.p_base == NULL )
295 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
299 /* Initialize tables */
304 /*******************************************************************************
305 * vout_ResetTables: re-initialize translations tables
306 *******************************************************************************
307 * This function will initialize the tables allocated by vout_CreateTables and
308 * set functions pointers.
309 *******************************************************************************/
310 int vout_ResetTables( vout_thread_t *p_vout )
312 vout_EndTables( p_vout );
313 return( vout_InitTables( p_vout ) );
316 /*******************************************************************************
317 * vout_EndTables: destroy translations tables
318 *******************************************************************************
319 * Free memory allocated by vout_CreateTables.
320 *******************************************************************************/
321 void vout_EndTables( vout_thread_t *p_vout )
323 free( p_vout->tables.p_base );
326 /* following functions are local */
328 /*******************************************************************************
329 * BinaryLog: computes the base 2 log of a binary value
330 *******************************************************************************
331 * This functions is used by MaskToShift during tables initialisation, to
332 * get a bit index from a binary value.
333 *******************************************************************************/
334 static int BinaryLog(u32 i)
359 if (i != ((u32)1 << i_log))
361 intf_ErrMsg("internal error: binary log overflow\n");
367 /*******************************************************************************
368 * MaskToShift: Transform a color mask into right and left shifts
369 *******************************************************************************
370 * This function is used during table initialisation. It can return a value
371 *******************************************************************************/
372 static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
374 u32 i_low, i_high; /* lower hand higher bits of the mask */
377 i_low = i_mask & (- i_mask); /* lower bit of the mask */
378 i_high = i_mask + i_low; /* higher bit of the mask */
380 /* Transform bits into an index */
381 i_low = BinaryLog (i_low);
382 i_high = BinaryLog (i_high);
384 /* Update pointers and return */
386 *pi_right = (8 - i_high + i_low);
389 /*******************************************************************************
390 * SetTables: compute tables and set function pointers
391 *******************************************************************************/
392 static void SetTables( vout_thread_t *p_vout )
394 u8 i_gamma[256]; /* gamma table */
395 int i_index; /* index in tables */
396 int i_red_right, i_red_left; /* red shifts */
397 int i_green_right, i_green_left; /* green shifts */
398 int i_blue_right, i_blue_left; /* blue shifts */
403 for( i_index = 0; i_index < 256; i_index++ )
405 i_gamma[i_index] = 255. * pow( (double)i_index / 255., exp(p_vout->f_gamma) );
409 * Set color masks and shifts
411 switch( p_vout->i_screen_depth )
414 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
415 MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
416 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
419 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
420 MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
421 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
425 MaskToShift( &i_red_right, &i_red_left, 0x00ff0000 );
426 MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
427 MaskToShift( &i_blue_right, &i_blue_left, 0x000000ff );
431 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
437 * Set pointers and build YUV tables
439 if( p_vout->b_grayscale )
441 /* Grayscale: build gray table */
442 switch( p_vout->i_screen_depth )
446 p_vout->tables.yuv.gray16.p_gray = (u16 *)p_vout->tables.p_base + 384;
447 for( i_index = -384; i_index < 640; i_index++)
449 p_vout->tables.yuv.gray16.p_gray[ i_index ] =
450 ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
451 ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
452 ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
457 p_vout->tables.yuv.gray32.p_gray = (u32 *)p_vout->tables.p_base + 384;
458 for( i_index = -384; i_index < 640; i_index++)
460 p_vout->tables.yuv.gray32.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);
470 /* Color: build red, green and blue tables */
471 switch( p_vout->i_screen_depth )
475 p_vout->tables.yuv.rgb16.p_red = (u16 *)p_vout->tables.p_base + 384;
476 p_vout->tables.yuv.rgb16.p_green = (u16 *)p_vout->tables.p_base + 1024 + 384;
477 p_vout->tables.yuv.rgb16.p_blue = (u16 *)p_vout->tables.p_base + 2*1024 + 384;
478 for( i_index = -384; i_index < 640; i_index++)
480 p_vout->tables.yuv.rgb16.p_red[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
481 p_vout->tables.yuv.rgb16.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
482 p_vout->tables.yuv.rgb16.p_blue[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
487 p_vout->tables.yuv.rgb32.p_red = (u32 *)p_vout->tables.p_base + 384;
488 p_vout->tables.yuv.rgb32.p_green = (u32 *)p_vout->tables.p_base + 1024 + 384;
489 p_vout->tables.yuv.rgb32.p_blue = (u32 *)p_vout->tables.p_base + 2*1024 + 384;
490 for( i_index = -384; i_index < 640; i_index++)
492 p_vout->tables.yuv.rgb32.p_red[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
493 p_vout->tables.yuv.rgb32.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
494 p_vout->tables.yuv.rgb32.p_blue[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
501 * Set functions pointers
503 if( p_vout->b_grayscale )
506 switch( p_vout->i_screen_depth )
510 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
511 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
512 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
515 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
516 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
517 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
520 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
521 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
522 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
529 switch( p_vout->i_screen_depth )
533 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB16;
534 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB16;
535 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB16;
538 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB24;
539 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB24;
540 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB24;
543 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB32;
544 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB32;
545 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB32;
551 /*******************************************************************************
552 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
553 *******************************************************************************/
554 static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic,
555 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
556 int i_width, int i_height, int i_eol, int i_pic_eol,
557 int i_scale, int i_matrix_coefficients )
559 u16 * p_pic_src; /* source pointer in case of copy */
560 u16 * p_gray; /* gray table */
561 int i_x, i_y; /* picture coordinates */
563 p_gray = p_vout->tables.yuv.gray16.p_gray;
567 /*******************************************************************************
568 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
569 *******************************************************************************/
570 static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic,
571 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
572 int i_width, int i_height, int i_eol, int i_pic_eol,
573 int i_scale, int i_matrix_coefficients )
578 /*******************************************************************************
579 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
580 *******************************************************************************/
581 static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic,
582 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
583 int i_width, int i_height, int i_eol, int i_pic_eol,
584 int i_scale, int i_matrix_coefficients )
586 u32 * p_pic_src; /* source pointer in case of copy */
587 u32 * p_gray; /* gray table */
588 int i_x, i_y; /* picture coordinates */
590 p_gray = p_vout->tables.yuv.gray32.p_gray;
594 /*******************************************************************************
595 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
596 *******************************************************************************/
597 static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic,
598 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
599 int i_width, int i_height, int i_eol, int i_pic_eol,
600 int i_scale, int i_matrix_coefficients )
603 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
605 i_chroma_width = i_width / 2;
606 i_chroma_eol = i_eol / 2;
607 ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height,
608 (i_width + i_eol) * sizeof( yuv_data_t ),
609 (i_chroma_width + i_chroma_eol) * sizeof( yuv_data_t),
610 i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
611 p_vout->i_screen_depth == 15 );
613 u16 * p_pic_src; /* source pointer in case of copy */
614 u16 * p_red; /* red table */
615 u16 * p_green; /* green table */
616 u16 * p_blue; /* blue table */
617 int i_uval, i_yval, i_vval; /* samples */
618 int i_x, i_y; /* picture coordinates */
619 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
620 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
622 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
623 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
624 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
625 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
626 p_red = p_vout->tables.yuv.rgb16.p_red;
627 p_green = p_vout->tables.yuv.rgb16.p_green;
628 p_blue = p_vout->tables.yuv.rgb16.p_blue;
629 i_chroma_width = i_width / 2;
630 i_chroma_eol = i_eol / 2;
631 CONVERT_YUV_RGB( 420 )
635 /*******************************************************************************
636 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
637 *******************************************************************************/
638 static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic,
639 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
640 int i_width, int i_height, int i_eol, int i_pic_eol,
641 int i_scale, int i_matrix_coefficients )
643 u16 * p_pic_src; /* source pointer in case of copy */
644 u16 * p_red; /* red table */
645 u16 * p_green; /* green table */
646 u16 * p_blue; /* blue table */
647 int i_uval, i_yval, i_vval; /* samples */
648 int i_x, i_y; /* picture coordinates */
649 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
650 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
652 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
653 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
654 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
655 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
656 p_red = p_vout->tables.yuv.rgb16.p_red;
657 p_green = p_vout->tables.yuv.rgb16.p_green;
658 p_blue = p_vout->tables.yuv.rgb16.p_blue;
659 i_chroma_width = i_width / 2;
660 i_chroma_eol = i_eol / 2;
661 CONVERT_YUV_RGB( 422 )
664 /*******************************************************************************
665 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
666 *******************************************************************************/
667 static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic,
668 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
669 int i_width, int i_height, int i_eol, int i_pic_eol,
670 int i_scale, int i_matrix_coefficients )
672 u16 * p_pic_src; /* source pointer in case of copy */
673 u16 * p_red; /* red table */
674 u16 * p_green; /* green table */
675 u16 * p_blue; /* blue table */
676 int i_uval, i_yval, i_vval; /* samples */
677 int i_x, i_y; /* picture coordinates */
678 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
679 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
681 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
682 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
683 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
684 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
685 p_red = p_vout->tables.yuv.rgb16.p_red;
686 p_green = p_vout->tables.yuv.rgb16.p_green;
687 p_blue = p_vout->tables.yuv.rgb16.p_blue;
688 i_chroma_width = i_width;
689 i_chroma_eol = i_eol;
690 CONVERT_YUV_RGB( 444 )
693 /*******************************************************************************
694 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
695 *******************************************************************************/
696 static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic,
697 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
698 int i_width, int i_height, int i_eol, int i_pic_eol,
699 int i_scale, int i_matrix_coefficients )
704 /*******************************************************************************
705 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
706 *******************************************************************************/
707 static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic,
708 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
709 int i_width, int i_height, int i_eol, int i_pic_eol,
710 int i_scale, int i_matrix_coefficients )
715 /*******************************************************************************
716 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
717 *******************************************************************************/
718 static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic,
719 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
720 int i_width, int i_height, int i_eol, int i_pic_eol,
721 int i_scale, int i_matrix_coefficients )
726 /*******************************************************************************
727 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
728 *******************************************************************************/
729 static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic,
730 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
731 int i_width, int i_height, int i_eol, int i_pic_eol,
732 int i_scale, int i_matrix_coefficients )
734 u32 * p_pic_src; /* source pointer in case of copy */
735 u32 * p_red; /* red table */
736 u32 * p_green; /* green table */
737 u32 * p_blue; /* blue table */
738 int i_uval, i_yval, i_vval; /* samples */
739 int i_x, i_y; /* picture coordinates */
740 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
741 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
743 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
744 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
745 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
746 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
747 p_red = p_vout->tables.yuv.rgb32.p_red;
748 p_green = p_vout->tables.yuv.rgb32.p_green;
749 p_blue = p_vout->tables.yuv.rgb32.p_blue;
750 i_chroma_width = i_width / 2;
751 i_chroma_eol = i_eol / 2;
752 CONVERT_YUV_RGB( 420 )
755 /*******************************************************************************
756 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
757 *******************************************************************************/
758 static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic,
759 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
760 int i_width, int i_height, int i_eol, int i_pic_eol,
761 int i_scale, int i_matrix_coefficients )
763 u32 * p_pic_src; /* source pointer in case of copy */
764 u32 * p_red; /* red table */
765 u32 * p_green; /* green table */
766 u32 * p_blue; /* blue table */
767 int i_uval, i_yval, i_vval; /* samples */
768 int i_x, i_y; /* picture coordinates */
769 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
770 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
772 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
773 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
774 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
775 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
776 p_red = p_vout->tables.yuv.rgb32.p_red;
777 p_green = p_vout->tables.yuv.rgb32.p_green;
778 p_blue = p_vout->tables.yuv.rgb32.p_blue;
779 i_chroma_width = i_width / 2;
780 i_chroma_eol = i_eol / 2;
781 CONVERT_YUV_RGB( 422 )
784 /*******************************************************************************
785 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
786 *******************************************************************************/
787 static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic,
788 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
789 int i_width, int i_height, int i_eol, int i_pic_eol,
790 int i_scale, int i_matrix_coefficients )
792 u32 * p_pic_src; /* source pointer in case of copy */
793 u32 * p_red; /* red table */
794 u32 * p_green; /* green table */
795 u32 * p_blue; /* blue table */
796 int i_uval, i_yval, i_vval; /* samples */
797 int i_x, i_y; /* picture coordinates */
798 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
799 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
801 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
802 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
803 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
804 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
805 p_red = p_vout->tables.yuv.rgb32.p_red;
806 p_green = p_vout->tables.yuv.rgb32.p_green;
807 p_blue = p_vout->tables.yuv.rgb32.p_blue;
808 i_chroma_width = i_width;
809 i_chroma_eol = i_eol;
810 CONVERT_YUV_RGB( 444 )
813 //-------------------- walken code follow --------------------------------
816 * YUV to RGB routines.
818 * these routines calculate r, g and b values from each pixel's y, u and v.
819 * these r, g an b values are then passed thru a table lookup to take the
820 * gamma curve into account and find the corresponding pixel value.
822 * the table must store more than 3*256 values because of the possibility
823 * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
824 * values are in the following intervals :
825 * -176 to 255+176 for red
826 * -133 to 255+133 for green
827 * -222 to 255+222 for blue
829 * If the input y,u,v values are right, the r,g,b results are not expected
830 * to move out of the 0 to 255 interval but who knows what will happen in
833 * the red, green and blue conversion tables are stored in a single 1935-entry
834 * array. The respective positions of each component in the array have been
835 * calculated to minimize the cache interactions of the 3 tables.
838 int rgbTable16 (short table [1935],
839 int redMask, int greenMask, int blueMask,
840 unsigned char gamma[256])
854 MaskToShift (&redRight, &redLeft, redMask);
855 MaskToShift (&greenRight, &greenLeft, greenMask);
856 MaskToShift (&blueRight, &blueLeft, blueMask);
859 * green blue red +- 2 just to be sure
860 * green = 0-525 [151-370]
861 * blue = 594-1297 [834-1053] <834-29>
862 * red = 1323-1934 [1517-1736] <493-712>
865 redTable = table + 1501;
866 greenTable = table + 135;
867 blueTable = table + 818;
869 for (i = 0; i < 178; i++) {
871 redTable[i+256] = redMask;
873 for (i = 0; i < 135; i++) {
874 greenTable[i-135] = 0;
875 greenTable[i+256] = greenMask;
877 for (i = 0; i < 224; i++) {
878 blueTable[i-224] = 0;
879 blueTable[i+256] = blueMask;
882 for (i = 0; i < 256; i++) {
884 redTable[i] = ((y >> redRight) << redLeft);
885 greenTable[i] = ((y >> greenRight) << greenLeft);
886 blueTable[i] = ((y >> blueRight) << blueLeft);
892 static int rgbTable32 (int table [1935],
893 int redMask, int greenMask, int blueMask,
894 unsigned char gamma[256])
908 MaskToShift (&redRight, &redLeft, redMask);
909 MaskToShift (&greenRight, &greenLeft, greenMask);
910 MaskToShift (&blueRight, &blueLeft, blueMask);
914 * green blue red +- 2 just to be sure
915 * green = 0-525 [151-370]
916 * blue = 594-1297 [834-1053] <834-29>
917 * red = 1323-1934 [1517-1736] <493-712>
920 redTable = table + 1501;
921 greenTable = table + 135;
922 blueTable = table + 818;
924 for (i = 0; i < 178; i++) {
926 redTable[i+256] = redMask;
928 for (i = 0; i < 135; i++) {
929 greenTable[i-135] = 0;
930 greenTable[i+256] = greenMask;
932 for (i = 0; i < 224; i++) {
933 blueTable[i-224] = 0;
934 blueTable[i+256] = blueMask;
937 for (i = 0; i < 256; i++) {
939 redTable[i] = ((y >> redRight) << redLeft);
940 greenTable[i] = ((y >> greenRight) << greenLeft);
941 blueTable[i] = ((y >> blueRight) << blueLeft);
948 #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
949 #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
950 #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
951 #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
953 void yuvToRgb16 (unsigned char * Y,
954 unsigned char * U, unsigned char * V,
955 short * dest, short table[1935], int width)
969 uvRed = (V_RED_COEF*v) >> SHIFT;
970 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
971 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
973 tableY = table + *(Y++);
974 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
975 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
977 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
979 tableY = table + *(Y++);
980 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
981 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
983 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
987 uvRed = (V_RED_COEF*v) >> SHIFT;
988 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
989 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
991 tableY = table + *(Y++);
992 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
993 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
995 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
997 tableY = table + *(Y++);
998 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
999 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1001 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1005 uvRed = (V_RED_COEF*v) >> SHIFT;
1006 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1007 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1009 tableY = table + *(Y++);
1010 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1011 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1013 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1015 tableY = table + *(Y++);
1016 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1017 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1019 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1023 uvRed = (V_RED_COEF*v) >> SHIFT;
1024 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1025 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1027 tableY = table + *(Y++);
1028 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1029 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1031 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1033 tableY = table + *(Y++);
1034 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1035 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1037 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1041 uvRed = (V_RED_COEF*v) >> SHIFT;
1042 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1043 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1045 tableY = table + *(Y++);
1046 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1047 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1049 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1051 tableY = table + *(Y++);
1052 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1053 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1055 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1059 uvRed = (V_RED_COEF*v) >> SHIFT;
1060 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1061 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1063 tableY = table + *(Y++);
1064 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1065 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1067 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1069 tableY = table + *(Y++);
1070 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1071 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1073 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1077 uvRed = (V_RED_COEF*v) >> SHIFT;
1078 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1079 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1081 tableY = table + *(Y++);
1082 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1083 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1085 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1087 tableY = table + *(Y++);
1088 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1089 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1091 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1095 uvRed = (V_RED_COEF*v) >> SHIFT;
1096 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1097 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1099 tableY = table + *(Y++);
1100 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1101 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1103 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1105 tableY = table + *(Y++);
1106 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1107 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1109 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1112 i = (width & 15) >> 1;
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]);
1136 uvRed = (V_RED_COEF*v) >> SHIFT;
1137 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1138 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1140 tableY = table + *(Y++);
1141 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1142 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1144 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1148 static void yuvToRgb24 (unsigned char * Y,
1149 unsigned char * U, unsigned char * V,
1150 char * dest, int table[1935], int width)
1165 uvRed = (V_RED_COEF*v) >> SHIFT;
1166 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1167 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1169 tableY = table + *(Y++);
1170 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1171 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1173 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1175 *(dest++) = tmp24 >> 8;
1176 *(dest++) = tmp24 >> 16;
1178 tableY = table + *(Y++);
1179 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1180 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1182 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1184 *(dest++) = tmp24 >> 8;
1185 *(dest++) = tmp24 >> 16;
1189 uvRed = (V_RED_COEF*v) >> SHIFT;
1190 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1191 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1193 tableY = table + *(Y++);
1194 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1195 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1197 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1199 *(dest++) = tmp24 >> 8;
1200 *(dest++) = tmp24 >> 16;
1202 tableY = table + *(Y++);
1203 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1204 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1206 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1208 *(dest++) = tmp24 >> 8;
1209 *(dest++) = tmp24 >> 16;
1213 uvRed = (V_RED_COEF*v) >> SHIFT;
1214 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1215 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
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;
1226 tableY = table + *(Y++);
1227 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1228 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1230 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1232 *(dest++) = tmp24 >> 8;
1233 *(dest++) = tmp24 >> 16;
1237 uvRed = (V_RED_COEF*v) >> SHIFT;
1238 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1239 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
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;
1250 tableY = table + *(Y++);
1251 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1252 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1254 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1256 *(dest++) = tmp24 >> 8;
1257 *(dest++) = tmp24 >> 16;
1260 i = (width & 7) >> 1;
1264 uvRed = (V_RED_COEF*v) >> SHIFT;
1265 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1266 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1268 tableY = table + *(Y++);
1269 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1270 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1272 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1274 *(dest++) = tmp24 >> 8;
1275 *(dest++) = tmp24 >> 16;
1277 tableY = table + *(Y++);
1278 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1279 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1281 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1283 *(dest++) = tmp24 >> 8;
1284 *(dest++) = tmp24 >> 16;
1290 uvRed = (V_RED_COEF*v) >> SHIFT;
1291 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1292 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
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;
1305 static void yuvToRgb32 (unsigned char * Y,
1306 unsigned char * U, unsigned char * V,
1307 int * dest, int table[1935], int width)
1321 uvRed = (V_RED_COEF*v) >> SHIFT;
1322 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1323 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1325 tableY = table + *(Y++);
1326 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1327 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1329 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1331 tableY = table + *(Y++);
1332 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1333 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1335 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1339 uvRed = (V_RED_COEF*v) >> SHIFT;
1340 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1341 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1343 tableY = table + *(Y++);
1344 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1345 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1347 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1349 tableY = table + *(Y++);
1350 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1351 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1353 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1357 uvRed = (V_RED_COEF*v) >> SHIFT;
1358 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1359 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1361 tableY = table + *(Y++);
1362 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1363 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1365 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1367 tableY = table + *(Y++);
1368 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1369 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1371 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1375 uvRed = (V_RED_COEF*v) >> SHIFT;
1376 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1377 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1379 tableY = table + *(Y++);
1380 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1381 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1383 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1385 tableY = table + *(Y++);
1386 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1387 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1389 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1393 uvRed = (V_RED_COEF*v) >> SHIFT;
1394 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1395 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1397 tableY = table + *(Y++);
1398 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1399 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1401 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1403 tableY = table + *(Y++);
1404 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1405 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1407 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1411 uvRed = (V_RED_COEF*v) >> SHIFT;
1412 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1413 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1415 tableY = table + *(Y++);
1416 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1417 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1419 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1421 tableY = table + *(Y++);
1422 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1423 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1425 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1429 uvRed = (V_RED_COEF*v) >> SHIFT;
1430 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1431 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1433 tableY = table + *(Y++);
1434 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1435 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1437 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1439 tableY = table + *(Y++);
1440 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1441 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1443 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1447 uvRed = (V_RED_COEF*v) >> SHIFT;
1448 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1449 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1451 tableY = table + *(Y++);
1452 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1453 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1455 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1457 tableY = table + *(Y++);
1458 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1459 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1461 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1464 i = (width & 15) >> 1;
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]);
1488 uvRed = (V_RED_COEF*v) >> SHIFT;
1489 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1490 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1492 tableY = table + *(Y++);
1493 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1494 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1496 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);