1 /*******************************************************************************
2 * video_yuv.c: YUV transformation functions
4 *******************************************************************************
5 * Provides functions to perform the YUV conversion. The functions provided here
6 * are a complete and portable C implementation, and may be replaced in certain
7 * case by optimized functions.
8 *******************************************************************************/
10 /*******************************************************************************
12 *******************************************************************************/
19 #include <X11/Xlib.h> /* for video_sys.h in X11 mode */
25 #include "vlc_thread.h"
27 #include "video_output.h"
30 /*******************************************************************************
32 *******************************************************************************/
34 /* RGB/YUV inversion matrix (ISO/IEC 13818-2 section 6.3.6, table 6.9) */
35 const int MATRIX_COEFFICIENTS_TABLE[8][4] =
37 {117504, 138453, 13954, 34903}, /* no sequence_display_extension */
38 {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
39 {104597, 132201, 25675, 53279}, /* unspecified */
40 {104597, 132201, 25675, 53279}, /* reserved */
41 {104448, 132798, 24759, 53109}, /* FCC */
42 {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
43 {104597, 132201, 25675, 53279}, /* SMPTE 170M */
44 {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */
47 /*******************************************************************************
49 *******************************************************************************/
50 static int BinaryLog ( u32 i );
51 static void MaskToShift ( int *pi_right, int *pi_left, u32 i_mask );
52 static void SetTables ( vout_thread_t *p_vout );
54 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,
55 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
56 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,
57 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
58 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,
59 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
60 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,
61 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
62 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,
63 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
64 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,
65 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
66 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,
67 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
68 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,
69 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
70 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,
71 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
72 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,
73 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
74 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,
75 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
76 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,
77 int i_width, int i_height, int i_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients );
78 static void Scale16 ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
79 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
80 static void Scale24 ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
81 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
82 static void Scale32 ( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
83 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta );
85 /*******************************************************************************
86 * CLIP_BYTE macro: boundary detection
87 *******************************************************************************
88 * Return parameter if between 0 and 255, else return nearest boundary (0 or
89 * 255). This macro is used to build translations tables.
90 *******************************************************************************/
91 #define CLIP_BYTE( i_val ) ( (i_val < 0) ? 0 : ((i_val > 255) ? 255 : i_val) )
93 /*******************************************************************************
94 * LINE_COPY macro: memcopy using 16 pixels blocks
95 *******************************************************************************
97 * p_pic destination pointer
98 * p_pic_src source pointer
101 *******************************************************************************/
103 for( i_x = 0; i_x < i_width; i_x+=16 ) \
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++; \
118 *p_pic++ = *p_pic_src++; \
119 *p_pic++ = *p_pic_src++; \
120 *p_pic++ = *p_pic_src++; \
123 /*******************************************************************************
124 * CONVERT_YUV_GRAY macro: grayscale YUV convertion
125 *******************************************************************************
127 * ...see vout_convert_t
128 * i_x, i_y coordinates
129 * i_pic_copy same type as p_pic
130 * p_gray gray translation table
131 *******************************************************************************/
132 #define CONVERT_YUV_GRAY \
133 for (i_y = 0; i_y < i_height ; i_y++) \
135 for (i_x = 0; i_x < i_width; i_x += 16) \
137 /* Convert 16 pixels (width is always multiple of 16 */ \
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++ ]; \
151 *p_pic++ = p_gray[ *p_y++ ]; \
152 *p_pic++ = p_gray[ *p_y++ ]; \
153 *p_pic++ = p_gray[ *p_y++ ]; \
156 /* Handle scale factor */ \
157 if( i_scale && ! (i_y % i_scale) ) \
161 /* Copy previous line */ \
162 p_pic_src = p_pic - i_width; \
163 p_pic += i_pic_eol; \
168 /* Ignore next line */ \
169 p_y += i_eol + i_width; \
174 /* Skip until beginning of next line */ \
175 p_pic += i_pic_eol; \
179 /*******************************************************************************
180 * CONVERT_YUV_RGB: color YUV convertion
181 *******************************************************************************
183 * CHROMA 420, 422 or 444
185 * ...see vout_convert_t
186 * i_x, i_y coordinates
187 * i_uval, i_yval, i_vval samples
188 * p_pic_src same type as p_pic
189 * i_chroma_width chroma width
190 * i_chroma_eol chroma eol
191 * p_red red translation table
192 * p_green green translation table
193 * p_blue blue translation table
194 * i_crv, i_cgu, i_cgv, i_cbu matrix coefficients
195 *******************************************************************************/
196 #define CONVERT_YUV_RGB( CHROMA ) \
197 for (i_y = 0; i_y < i_height ; i_y++) \
199 for (i_x = 0; i_x < i_width; i_x += 2 ) \
201 /* First sample (complete) */ \
202 i_yval = 76309 * *p_y++ - 1188177; \
203 i_uval = *p_u++ - 128; \
204 i_vval = *p_v++ - 128; \
206 p_red [(i_yval+i_crv*i_vval) >>16] | \
207 p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval) >>16] | \
208 p_blue [(i_yval+i_cbu*i_uval) >>16]; \
209 i_yval = 76309 * *p_y++ - 1188177; \
210 /* Second sample (partial) */ \
211 if( CHROMA == 444 ) \
213 i_uval = *p_u++ - 128; \
214 i_vval = *p_v++ - 128; \
217 p_red [(i_yval+i_crv*i_vval) >>16] | \
218 p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval) >>16] | \
219 p_blue [(i_yval+i_cbu*i_uval) >>16]; \
222 /* Handle scale factor and rewind in 4:2:0 */ \
223 if( i_scale && ! (i_y % i_scale) ) \
227 /* Copy previous line, rewind if required */ \
228 p_pic_src = p_pic - i_width; \
229 p_pic += i_pic_eol; \
231 if( (CHROMA == 420) && !(i_y & 0x1) ) \
233 p_u -= i_chroma_width; \
234 p_v -= i_chroma_width; \
238 p_u += i_chroma_eol; \
239 p_v += i_chroma_eol; \
244 /* Ignore next line */ \
245 p_y += i_eol + i_width; \
246 p_u += i_chroma_eol; \
247 p_v += i_chroma_eol; \
251 else if( (CHROMA == 420) && !(i_y & 0x1) ) \
253 p_u -= i_chroma_width; \
254 p_v -= i_chroma_width; \
258 p_u += i_chroma_eol; \
259 p_v += i_chroma_eol; \
262 /* Skip until beginning of next line */ \
263 p_pic += i_pic_eol; \
268 /*******************************************************************************
269 * vout_InitTables: allocate and initialize translations tables
270 *******************************************************************************
271 * This function will allocate memory to store translation tables, depending
272 * of the screen depth.
273 *******************************************************************************/
274 int vout_InitTables( vout_thread_t *p_vout )
276 size_t tables_size; /* tables size, in bytes */
278 /* Computes tables size */
280 tables_size = 4 * 4 * 1024;
282 /* Allocate memory */
283 p_vout->tables.p_base = malloc( tables_size );
284 if( p_vout->tables.p_base == NULL )
286 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
290 /* Initialize tables */
295 /*******************************************************************************
296 * vout_ResetTables: re-initialize translations tables
297 *******************************************************************************
298 * This function will initialize the tables allocated by vout_CreateTables and
299 * set functions pointers.
300 *******************************************************************************/
301 int vout_ResetTables( vout_thread_t *p_vout )
308 /*******************************************************************************
309 * vout_EndTables: destroy translations tables
310 *******************************************************************************
311 * Free memory allocated by vout_CreateTables.
312 *******************************************************************************/
313 void vout_EndTables( vout_thread_t *p_vout )
315 free( p_vout->tables.p_base );
318 /* following functions are local */
320 /*******************************************************************************
321 * BinaryLog: computes the base 2 log of a binary value
322 *******************************************************************************
323 * This functions is used by MaskToShift during tables initialisation, to
324 * get a bit index from a binary value.
325 *******************************************************************************/
326 static int BinaryLog(u32 i)
351 if (i != ((u32)1 << i_log))
353 intf_ErrMsg("internal error: binary log overflow\n");
359 /*******************************************************************************
360 * MaskToShift: Transform a color mask into right and left shifts
361 *******************************************************************************
362 * This function is used during table initialisation. It can return a value
363 *******************************************************************************/
364 static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
366 u32 i_low, i_high; /* lower hand higher bits of the mask */
369 i_low = i_mask & (- i_mask); /* lower bit of the mask */
370 i_high = i_mask + i_low; /* higher bit of the mask */
372 /* Transform bits into an index */
373 i_low = BinaryLog (i_low);
374 i_high = BinaryLog (i_high);
376 /* Update pointers and return */
378 *pi_right = (8 - i_high + i_low);
381 /*******************************************************************************
382 * SetTables: compute tables and set function pointers
383 *******************************************************************************/
384 static void SetTables( vout_thread_t *p_vout )
386 u8 i_gamma[256]; /* gamma table */
387 int i_index; /* index in tables */
388 int i_red_right, i_red_left; /* red shifts */
389 int i_green_right, i_green_left; /* green shifts */
390 int i_blue_right, i_blue_left; /* blue shifts */
395 for( i_index = 0; i_index < 256; i_index++ )
397 i_gamma[i_index] = 255. * pow( (double)i_index / 255., p_vout->f_gamma );
401 * Set color masks and shifts
403 switch( p_vout->i_screen_depth )
406 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
407 MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
408 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
411 MaskToShift( &i_red_right, &i_red_left, 0xf800 );
412 MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
413 MaskToShift( &i_blue_right, &i_blue_left, 0x001f );
417 MaskToShift( &i_red_right, &i_red_left, 0x00ff0000 );
418 MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
419 MaskToShift( &i_blue_right, &i_blue_left, 0x000000ff );
423 intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
429 * Set pointers and build YUV tables
431 if( p_vout->b_grayscale )
433 /* Grayscale: build gray table */
434 switch( p_vout->i_screen_depth )
438 p_vout->tables.yuv.gray16.p_gray = (u16 *)p_vout->tables.p_base + 384;
439 for( i_index = -384; i_index < 640; i_index++)
441 p_vout->tables.yuv.gray16.p_gray[ i_index ] =
442 ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
443 ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
444 ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
449 p_vout->tables.yuv.gray32.p_gray = (u32 *)p_vout->tables.p_base + 384;
450 for( i_index = -384; i_index < 640; i_index++)
452 p_vout->tables.yuv.gray32.p_gray[ i_index ] =
453 ((i_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
454 ((i_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
455 ((i_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
462 /* Color: build red, green and blue tables */
463 switch( p_vout->i_screen_depth )
467 p_vout->tables.yuv.rgb16.p_red = (u16 *)p_vout->tables.p_base + 384;
468 p_vout->tables.yuv.rgb16.p_green = (u16 *)p_vout->tables.p_base + 1024 + 384;
469 p_vout->tables.yuv.rgb16.p_blue = (u16 *)p_vout->tables.p_base + 2*1024 + 384;
470 for( i_index = -384; i_index < 640; i_index++)
472 p_vout->tables.yuv.rgb16.p_red[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
473 p_vout->tables.yuv.rgb16.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
474 p_vout->tables.yuv.rgb16.p_blue[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
479 p_vout->tables.yuv.rgb32.p_red = (u32 *)p_vout->tables.p_base + 384;
480 p_vout->tables.yuv.rgb32.p_green = (u32 *)p_vout->tables.p_base + 1024 + 384;
481 p_vout->tables.yuv.rgb32.p_blue = (u32 *)p_vout->tables.p_base + 2*1024 + 384;
482 for( i_index = -384; i_index < 640; i_index++)
484 p_vout->tables.yuv.rgb32.p_red[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
485 p_vout->tables.yuv.rgb32.p_green[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
486 p_vout->tables.yuv.rgb32.p_blue[i_index] = (i_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
493 * Set functions pointers
495 if( p_vout->b_grayscale )
498 switch( p_vout->i_screen_depth )
502 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
503 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
504 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
505 p_vout->p_Scale = (vout_scale_t *) Scale16;
508 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
509 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
510 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
511 p_vout->p_Scale = (vout_scale_t *) Scale24;
514 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
515 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
516 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
517 p_vout->p_Scale = (vout_scale_t *) Scale32;
524 switch( p_vout->i_screen_depth )
528 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB16;
529 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB16;
530 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB16;
531 p_vout->p_Scale = (vout_scale_t *) Scale16;
534 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB24;
535 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB24;
536 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB24;
537 p_vout->p_Scale = (vout_scale_t *) Scale24;
540 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB32;
541 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB32;
542 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB32;
543 p_vout->p_Scale = (vout_scale_t *) Scale32;
549 /*******************************************************************************
550 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
551 *******************************************************************************/
552 static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic,
553 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
554 int i_width, int i_height, int i_eol, int i_pic_eol,
555 int i_scale, int i_matrix_coefficients )
557 u16 * p_pic_src; /* source pointer in case of copy */
558 u16 * p_gray; /* gray table */
559 int i_x, i_y; /* picture coordinates */
561 p_gray = p_vout->tables.yuv.gray16.p_gray;
565 /*******************************************************************************
566 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
567 *******************************************************************************/
568 static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic,
569 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
570 int i_width, int i_height, int i_eol, int i_pic_eol,
571 int i_scale, int i_matrix_coefficients )
576 /*******************************************************************************
577 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
578 *******************************************************************************/
579 static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic,
580 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
581 int i_width, int i_height, int i_eol, int i_pic_eol,
582 int i_scale, int i_matrix_coefficients )
584 u32 * p_pic_src; /* source pointer in case of copy */
585 u32 * p_gray; /* gray table */
586 int i_x, i_y; /* picture coordinates */
588 p_gray = p_vout->tables.yuv.gray32.p_gray;
592 /*******************************************************************************
593 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
594 *******************************************************************************/
595 static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic,
596 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
597 int i_width, int i_height, int i_eol, int i_pic_eol,
598 int i_scale, int i_matrix_coefficients )
600 u16 * p_pic_src; /* source pointer in case of copy */
601 u16 * p_red; /* red table */
602 u16 * p_green; /* green table */
603 u16 * p_blue; /* blue table */
604 int i_uval, i_yval, i_vval; /* samples */
605 int i_x, i_y; /* picture coordinates */
606 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
607 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
609 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
610 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
611 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
612 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
613 p_red = p_vout->tables.yuv.rgb16.p_red;
614 p_green = p_vout->tables.yuv.rgb16.p_green;
615 p_blue = p_vout->tables.yuv.rgb16.p_blue;
616 i_chroma_width = i_width / 2;
617 i_chroma_eol = i_eol / 2;
618 CONVERT_YUV_RGB( 420 )
621 /*******************************************************************************
622 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
623 *******************************************************************************/
624 static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic,
625 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
626 int i_width, int i_height, int i_eol, int i_pic_eol,
627 int i_scale, int i_matrix_coefficients )
629 u16 * p_pic_src; /* source pointer in case of copy */
630 u16 * p_red; /* red table */
631 u16 * p_green; /* green table */
632 u16 * p_blue; /* blue table */
633 int i_uval, i_yval, i_vval; /* samples */
634 int i_x, i_y; /* picture coordinates */
635 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
636 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
638 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
639 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
640 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
641 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
642 p_red = p_vout->tables.yuv.rgb16.p_red;
643 p_green = p_vout->tables.yuv.rgb16.p_green;
644 p_blue = p_vout->tables.yuv.rgb16.p_blue;
645 i_chroma_width = i_width / 2;
646 i_chroma_eol = i_eol / 2;
647 CONVERT_YUV_RGB( 422 )
650 /*******************************************************************************
651 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
652 *******************************************************************************/
653 static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic,
654 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
655 int i_width, int i_height, int i_eol, int i_pic_eol,
656 int i_scale, int i_matrix_coefficients )
658 u16 * p_pic_src; /* source pointer in case of copy */
659 u16 * p_red; /* red table */
660 u16 * p_green; /* green table */
661 u16 * p_blue; /* blue table */
662 int i_uval, i_yval, i_vval; /* samples */
663 int i_x, i_y; /* picture coordinates */
664 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
665 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
667 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
668 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
669 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
670 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
671 p_red = p_vout->tables.yuv.rgb16.p_red;
672 p_green = p_vout->tables.yuv.rgb16.p_green;
673 p_blue = p_vout->tables.yuv.rgb16.p_blue;
674 i_chroma_width = i_width;
675 i_chroma_eol = i_eol;
676 CONVERT_YUV_RGB( 444 )
679 /*******************************************************************************
680 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
681 *******************************************************************************/
682 static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic,
683 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
684 int i_width, int i_height, int i_eol, int i_pic_eol,
685 int i_scale, int i_matrix_coefficients )
690 /*******************************************************************************
691 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
692 *******************************************************************************/
693 static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic,
694 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
695 int i_width, int i_height, int i_eol, int i_pic_eol,
696 int i_scale, int i_matrix_coefficients )
701 /*******************************************************************************
702 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
703 *******************************************************************************/
704 static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic,
705 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
706 int i_width, int i_height, int i_eol, int i_pic_eol,
707 int i_scale, int i_matrix_coefficients )
712 /*******************************************************************************
713 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
714 *******************************************************************************/
715 static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic,
716 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
717 int i_width, int i_height, int i_eol, int i_pic_eol,
718 int i_scale, int i_matrix_coefficients )
720 u32 * p_pic_src; /* source pointer in case of copy */
721 u32 * p_red; /* red table */
722 u32 * p_green; /* green table */
723 u32 * p_blue; /* blue table */
724 int i_uval, i_yval, i_vval; /* samples */
725 int i_x, i_y; /* picture coordinates */
726 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
727 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
729 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
730 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
731 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
732 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
733 p_red = p_vout->tables.yuv.rgb32.p_red;
734 p_green = p_vout->tables.yuv.rgb32.p_green;
735 p_blue = p_vout->tables.yuv.rgb32.p_blue;
736 i_chroma_width = i_width / 2;
737 i_chroma_eol = i_eol / 2;
738 CONVERT_YUV_RGB( 420 )
741 /*******************************************************************************
742 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
743 *******************************************************************************/
744 static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic,
745 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
746 int i_width, int i_height, int i_eol, int i_pic_eol,
747 int i_scale, int i_matrix_coefficients )
749 u32 * p_pic_src; /* source pointer in case of copy */
750 u32 * p_red; /* red table */
751 u32 * p_green; /* green table */
752 u32 * p_blue; /* blue table */
753 int i_uval, i_yval, i_vval; /* samples */
754 int i_x, i_y; /* picture coordinates */
755 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
756 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
758 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
759 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
760 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
761 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
762 p_red = p_vout->tables.yuv.rgb32.p_red;
763 p_green = p_vout->tables.yuv.rgb32.p_green;
764 p_blue = p_vout->tables.yuv.rgb32.p_blue;
765 i_chroma_width = i_width / 2;
766 i_chroma_eol = i_eol / 2;
767 CONVERT_YUV_RGB( 422 )
770 /*******************************************************************************
771 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
772 *******************************************************************************/
773 static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic,
774 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
775 int i_width, int i_height, int i_eol, int i_pic_eol,
776 int i_scale, int i_matrix_coefficients )
778 u32 * p_pic_src; /* source pointer in case of copy */
779 u32 * p_red; /* red table */
780 u32 * p_green; /* green table */
781 u32 * p_blue; /* blue table */
782 int i_uval, i_yval, i_vval; /* samples */
783 int i_x, i_y; /* picture coordinates */
784 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
785 int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
787 i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
788 i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
789 i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
790 i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
791 p_red = p_vout->tables.yuv.rgb32.p_red;
792 p_green = p_vout->tables.yuv.rgb32.p_green;
793 p_blue = p_vout->tables.yuv.rgb32.p_blue;
794 i_chroma_width = i_width;
795 i_chroma_eol = i_eol;
796 CONVERT_YUV_RGB( 444 )
799 /*******************************************************************************
800 * Scale16: 15 or 16 bpp picture scaling
801 *******************************************************************************/
802 static void Scale16( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
803 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
808 /*******************************************************************************
809 * Scale24: 24 bpp picture scaling
810 *******************************************************************************/
811 static void Scale24( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
812 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
817 /*******************************************************************************
818 * Scale32: 32 bpp picture scaling
819 *******************************************************************************/
820 static void Scale32( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
821 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
826 //-------------------------
828 /*******************************************************************************
829 * External prototypes
830 *******************************************************************************/
832 /* YUV transformations for MMX - in video_yuv_mmx.S
833 * p_y, p_u, p_v: Y U and V planes
834 * i_width, i_height: frames dimensions (pixels)
835 * i_ypitch, i_vpitch: Y and V lines sizes (bytes)
836 * i_aspect: vertical aspect factor
838 * i_dci_offset: ?? x offset for left image border
839 * i_offset_to_line_0: ?? x offset for left image border
840 * i_pitch: RGB line size (bytes)
841 * i_colortype: 0 for 565, 1 for 555 */
842 static YUV420_16_MMX( u8* p_y, u8* p_u, u8 *p_v,
843 unsigned int i_width, unsigned int i_height,
844 unsigned int i_ypitch, unsigned int i_vpitch,
845 unsigned int i_aspect, u8 *p_pic,
846 u32 i_dci_offset, u32 i_offset_to_line_0,
847 int CCOPitch, int i_colortype );
850 //-------------------- walken code follow --------------------------------
856 * YUV to RGB routines.
858 * these routines calculate r, g and b values from each pixel's y, u and v.
859 * these r, g an b values are then passed thru a table lookup to take the
860 * gamma curve into account and find the corresponding pixel value.
862 * the table must store more than 3*256 values because of the possibility
863 * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
864 * values are in the following intervals :
865 * -176 to 255+176 for red
866 * -133 to 255+133 for green
867 * -222 to 255+222 for blue
869 * If the input y,u,v values are right, the r,g,b results are not expected
870 * to move out of the 0 to 255 interval but who knows what will happen in
873 * the red, green and blue conversion tables are stored in a single 1935-entry
874 * array. The respective positions of each component in the array have been
875 * calculated to minimize the cache interactions of the 3 tables.
878 int rgbTable16 (short table [1935],
879 int redMask, int greenMask, int blueMask,
880 unsigned char gamma[256])
894 MaskToShift (&redRight, &redLeft, redMask);
895 MaskToShift (&greenRight, &greenLeft, greenMask);
896 MaskToShift (&blueRight, &blueLeft, blueMask);
899 * green blue red +- 2 just to be sure
900 * green = 0-525 [151-370]
901 * blue = 594-1297 [834-1053] <834-29>
902 * red = 1323-1934 [1517-1736] <493-712>
905 redTable = table + 1501;
906 greenTable = table + 135;
907 blueTable = table + 818;
909 for (i = 0; i < 178; i++) {
911 redTable[i+256] = redMask;
913 for (i = 0; i < 135; i++) {
914 greenTable[i-135] = 0;
915 greenTable[i+256] = greenMask;
917 for (i = 0; i < 224; i++) {
918 blueTable[i-224] = 0;
919 blueTable[i+256] = blueMask;
922 for (i = 0; i < 256; i++) {
924 redTable[i] = ((y >> redRight) << redLeft);
925 greenTable[i] = ((y >> greenRight) << greenLeft);
926 blueTable[i] = ((y >> blueRight) << blueLeft);
932 static int rgbTable32 (int table [1935],
933 int redMask, int greenMask, int blueMask,
934 unsigned char gamma[256])
948 MaskToShift (&redRight, &redLeft, redMask);
949 MaskToShift (&greenRight, &greenLeft, greenMask);
950 MaskToShift (&blueRight, &blueLeft, blueMask);
954 * green blue red +- 2 just to be sure
955 * green = 0-525 [151-370]
956 * blue = 594-1297 [834-1053] <834-29>
957 * red = 1323-1934 [1517-1736] <493-712>
960 redTable = table + 1501;
961 greenTable = table + 135;
962 blueTable = table + 818;
964 for (i = 0; i < 178; i++) {
966 redTable[i+256] = redMask;
968 for (i = 0; i < 135; i++) {
969 greenTable[i-135] = 0;
970 greenTable[i+256] = greenMask;
972 for (i = 0; i < 224; i++) {
973 blueTable[i-224] = 0;
974 blueTable[i+256] = blueMask;
977 for (i = 0; i < 256; i++) {
979 redTable[i] = ((y >> redRight) << redLeft);
980 greenTable[i] = ((y >> greenRight) << greenLeft);
981 blueTable[i] = ((y >> blueRight) << blueLeft);
988 #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
989 #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
990 #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
991 #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
993 void yuvToRgb16 (unsigned char * Y,
994 unsigned char * U, unsigned char * V,
995 short * dest, short table[1935], int width)
1009 uvRed = (V_RED_COEF*v) >> SHIFT;
1010 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1011 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1013 tableY = table + *(Y++);
1014 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1015 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1017 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1019 tableY = table + *(Y++);
1020 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1021 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1023 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1027 uvRed = (V_RED_COEF*v) >> SHIFT;
1028 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1029 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1031 tableY = table + *(Y++);
1032 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1033 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1035 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1037 tableY = table + *(Y++);
1038 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1039 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1041 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1045 uvRed = (V_RED_COEF*v) >> SHIFT;
1046 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1047 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1049 tableY = table + *(Y++);
1050 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1051 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1053 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1055 tableY = table + *(Y++);
1056 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1057 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1059 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1063 uvRed = (V_RED_COEF*v) >> SHIFT;
1064 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1065 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1067 tableY = table + *(Y++);
1068 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1069 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1071 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1073 tableY = table + *(Y++);
1074 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1075 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1077 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1081 uvRed = (V_RED_COEF*v) >> SHIFT;
1082 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1083 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1085 tableY = table + *(Y++);
1086 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1087 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1089 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1091 tableY = table + *(Y++);
1092 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1093 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1095 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1099 uvRed = (V_RED_COEF*v) >> SHIFT;
1100 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1101 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1103 tableY = table + *(Y++);
1104 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1105 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1107 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1109 tableY = table + *(Y++);
1110 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1111 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1113 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1117 uvRed = (V_RED_COEF*v) >> SHIFT;
1118 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1119 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1121 tableY = table + *(Y++);
1122 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1123 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1125 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1127 tableY = table + *(Y++);
1128 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1129 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1131 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1135 uvRed = (V_RED_COEF*v) >> SHIFT;
1136 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1137 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1139 tableY = table + *(Y++);
1140 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1141 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1143 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1145 tableY = table + *(Y++);
1146 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1147 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1149 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1152 i = (width & 15) >> 1;
1156 uvRed = (V_RED_COEF*v) >> SHIFT;
1157 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1158 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1160 tableY = table + *(Y++);
1161 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1162 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1164 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1166 tableY = table + *(Y++);
1167 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1168 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1170 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1176 uvRed = (V_RED_COEF*v) >> SHIFT;
1177 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1178 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1180 tableY = table + *(Y++);
1181 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1182 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1184 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1188 static void yuvToRgb24 (unsigned char * Y,
1189 unsigned char * U, unsigned char * V,
1190 char * dest, int table[1935], int width)
1205 uvRed = (V_RED_COEF*v) >> SHIFT;
1206 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1207 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1209 tableY = table + *(Y++);
1210 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1211 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1213 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1215 *(dest++) = tmp24 >> 8;
1216 *(dest++) = tmp24 >> 16;
1218 tableY = table + *(Y++);
1219 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1220 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1222 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1224 *(dest++) = tmp24 >> 8;
1225 *(dest++) = tmp24 >> 16;
1229 uvRed = (V_RED_COEF*v) >> SHIFT;
1230 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1231 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1233 tableY = table + *(Y++);
1234 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1235 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1237 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1239 *(dest++) = tmp24 >> 8;
1240 *(dest++) = tmp24 >> 16;
1242 tableY = table + *(Y++);
1243 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1244 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1246 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1248 *(dest++) = tmp24 >> 8;
1249 *(dest++) = tmp24 >> 16;
1253 uvRed = (V_RED_COEF*v) >> SHIFT;
1254 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1255 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1257 tableY = table + *(Y++);
1258 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1259 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1261 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1263 *(dest++) = tmp24 >> 8;
1264 *(dest++) = tmp24 >> 16;
1266 tableY = table + *(Y++);
1267 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1268 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1270 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1272 *(dest++) = tmp24 >> 8;
1273 *(dest++) = tmp24 >> 16;
1277 uvRed = (V_RED_COEF*v) >> SHIFT;
1278 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1279 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1281 tableY = table + *(Y++);
1282 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1283 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1285 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1287 *(dest++) = tmp24 >> 8;
1288 *(dest++) = tmp24 >> 16;
1290 tableY = table + *(Y++);
1291 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1292 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1294 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1296 *(dest++) = tmp24 >> 8;
1297 *(dest++) = tmp24 >> 16;
1300 i = (width & 7) >> 1;
1304 uvRed = (V_RED_COEF*v) >> SHIFT;
1305 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1306 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1308 tableY = table + *(Y++);
1309 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1310 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1312 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1314 *(dest++) = tmp24 >> 8;
1315 *(dest++) = tmp24 >> 16;
1317 tableY = table + *(Y++);
1318 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1319 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1321 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1323 *(dest++) = tmp24 >> 8;
1324 *(dest++) = tmp24 >> 16;
1330 uvRed = (V_RED_COEF*v) >> SHIFT;
1331 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1332 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1334 tableY = table + *(Y++);
1335 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1336 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1338 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1340 *(dest++) = tmp24 >> 8;
1341 *(dest++) = tmp24 >> 16;
1345 static void yuvToRgb32 (unsigned char * Y,
1346 unsigned char * U, unsigned char * V,
1347 int * dest, int table[1935], int width)
1361 uvRed = (V_RED_COEF*v) >> SHIFT;
1362 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1363 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1365 tableY = table + *(Y++);
1366 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1367 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1369 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1371 tableY = table + *(Y++);
1372 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1373 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1375 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1379 uvRed = (V_RED_COEF*v) >> SHIFT;
1380 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1381 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1383 tableY = table + *(Y++);
1384 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1385 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1387 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1389 tableY = table + *(Y++);
1390 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1391 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1393 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1397 uvRed = (V_RED_COEF*v) >> SHIFT;
1398 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1399 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1401 tableY = table + *(Y++);
1402 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1403 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1405 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1407 tableY = table + *(Y++);
1408 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1409 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1411 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1415 uvRed = (V_RED_COEF*v) >> SHIFT;
1416 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1417 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1419 tableY = table + *(Y++);
1420 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1421 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1423 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1425 tableY = table + *(Y++);
1426 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1427 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1429 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1433 uvRed = (V_RED_COEF*v) >> SHIFT;
1434 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1435 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1437 tableY = table + *(Y++);
1438 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1439 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1441 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1443 tableY = table + *(Y++);
1444 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1445 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1447 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1451 uvRed = (V_RED_COEF*v) >> SHIFT;
1452 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1453 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1455 tableY = table + *(Y++);
1456 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1457 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1459 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1461 tableY = table + *(Y++);
1462 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1463 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1465 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1469 uvRed = (V_RED_COEF*v) >> SHIFT;
1470 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1471 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1473 tableY = table + *(Y++);
1474 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1475 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1477 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1479 tableY = table + *(Y++);
1480 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1481 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1483 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1487 uvRed = (V_RED_COEF*v) >> SHIFT;
1488 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1489 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1491 tableY = table + *(Y++);
1492 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1493 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1495 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1497 tableY = table + *(Y++);
1498 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1499 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1501 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1504 i = (width & 15) >> 1;
1508 uvRed = (V_RED_COEF*v) >> SHIFT;
1509 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1510 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1512 tableY = table + *(Y++);
1513 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1514 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1516 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1518 tableY = table + *(Y++);
1519 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1520 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1522 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1528 uvRed = (V_RED_COEF*v) >> SHIFT;
1529 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1530 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1532 tableY = table + *(Y++);
1533 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1534 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1536 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);