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 );
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 );
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 );
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 );
62 static void ConvertYUV422RGB16( p_vout_thread_t p_vout, void *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 );
64 static void ConvertYUV444RGB16( p_vout_thread_t p_vout, void *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 );
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 );
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 );
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 );
72 static void ConvertYUV420RGB32( p_vout_thread_t p_vout, void *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 );
74 static void ConvertYUV422RGB32( p_vout_thread_t p_vout, void *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 );
76 static void ConvertYUV444RGB32( p_vout_thread_t p_vout, void *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 );
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 /* Set scale factor to be ignored if it is 0 */ \
136 i_scale = i_height; \
140 for (i_y = 0; i_y < i_height ; i_y++) \
142 for (i_x = 0; i_x < i_width; i_x += 16) \
144 /* Convert 16 pixels (width is always multiple of 16 */ \
145 *p_pic++ = p_gray[ *p_y++ ]; \
146 *p_pic++ = p_gray[ *p_y++ ]; \
147 *p_pic++ = p_gray[ *p_y++ ]; \
148 *p_pic++ = p_gray[ *p_y++ ]; \
149 *p_pic++ = p_gray[ *p_y++ ]; \
150 *p_pic++ = p_gray[ *p_y++ ]; \
151 *p_pic++ = p_gray[ *p_y++ ]; \
152 *p_pic++ = p_gray[ *p_y++ ]; \
153 *p_pic++ = p_gray[ *p_y++ ]; \
154 *p_pic++ = p_gray[ *p_y++ ]; \
155 *p_pic++ = p_gray[ *p_y++ ]; \
156 *p_pic++ = p_gray[ *p_y++ ]; \
157 *p_pic++ = p_gray[ *p_y++ ]; \
158 *p_pic++ = p_gray[ *p_y++ ]; \
159 *p_pic++ = p_gray[ *p_y++ ]; \
160 *p_pic++ = p_gray[ *p_y++ ]; \
163 /* Handle scale factor */ \
164 if( ! (i_y % i_scale) ) \
168 /* Copy previous line */ \
169 p_pic_src = p_pic - i_width; \
170 p_pic += i_pic_eol; \
175 /* Ignore next line */ \
176 p_y += i_eol + i_width; \
181 /* Skip until beginning of next line */ \
182 p_pic += i_pic_eol; \
186 /*******************************************************************************
187 * CONVERT_YUV_RGB: color YUV convertion
188 *******************************************************************************
190 * CHROMA 420, 422 or 444
192 * ...see vout_convert_t
193 * i_x, i_y coordinates
194 * i_uval, i_yval, i_vval samples
195 * p_pic_src same type as p_pic
196 * i_chroma_width chroma width
197 * i_chroma_eol chroma eol
198 * p_red red translation table
199 * p_green green translation table
200 * p_blue blue translation table
201 *******************************************************************************/
202 #define CONVERT_YUV_RGB \
203 /* Set scale factor to be ignored if it is 0 */ \
206 i_scale = i_height; \
210 for (i_y = 0; i_y < i_height ; i_y++) \
212 for (i_x=0; i_x < i_width; i_x += 2 ) \
214 /* First sample (complete) */ \
215 i_yval = 76309 * *p_y++ - 1188177; \
216 i_uval = *p_u++ - 128; \
217 i_vval = *p_v++ - 128; \
219 p_red [(i_yval+i_crv*i_vval) >>16] | \
220 p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval) >>16] | \
221 p_blue [(i_yval+i_cbu*i_uval) >>16]; \
222 i_yval = 76309 * *p_y++ - 1188177; \
223 /* Second sample (partial) */ \
224 if( CHROMA == 444 ) \
226 i_uval = *p_u++ - 128; \
227 i_vval = *p_v++ - 128; \
230 p_red [(i_yval+i_crv*i_vval) >>16] | \
231 p_green[(i_yval-i_cgu*i_uval-i_cgv*i_vval) >>16] | \
232 p_blue [(i_yval+i_cbu*i_uval) >>16]; \
235 /* Handle scale factor */ \
236 if( ! (i_y % i_scale) ) \
240 /* Copy previous line */ \
241 p_pic_src = p_pic - i_width; \
242 p_pic += i_pic_eol; \
247 /* Ignore next line, rewind if in 4:2:0 */ \
248 p_y += i_eol + i_width; \
249 if( (CHROMA == 420) && !(i_y & 0x1) ) \
251 p_u -= i_chroma_width; \
252 p_v -= i_chroma_width; \
256 p_u += i_chroma_eol; \
257 p_v += i_chroma_eol; \
263 /* Rewind u and v values in 4:2:0, or skip until next line */ \
264 if( (CHROMA == 420) && !(i_y & 0x1) ) \
266 p_u -= i_chroma_width; \
267 p_v -= i_chroma_width; \
271 p_u += i_chroma_eol; \
272 p_v += i_chroma_eol; \
275 /* Skip until beginning of next line */ \
276 p_pic += i_pic_eol; \
280 /*******************************************************************************
281 * vout_InitTables: allocate and initialize translations tables
282 *******************************************************************************
283 * This function will allocate memory to store translation tables, depending
284 * of the screen depth.
285 *******************************************************************************/
286 int vout_InitTables( vout_thread_t *p_vout )
288 /* Allocate memory and set pointers */
289 p_vout->tables.p_base = malloc( ( 3 * 1024 ) *
290 ( p_vout->i_bytes_per_pixel != 3 ?
291 p_vout->i_bytes_per_pixel : 4 ));
292 if( p_vout->tables.p_base == NULL )
294 intf_ErrMsg("error: %s\n", strerror(ENOMEM));
298 /* Initialize tables */
303 /*******************************************************************************
304 * vout_ResetTables: re-initialize translations tables
305 *******************************************************************************
306 * This function will initialize the tables allocated by vout_CreateTables and
307 * set functions pointers.
308 *******************************************************************************/
309 int vout_ResetTables( vout_thread_t *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., 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;
513 p_vout->p_Scale = (vout_scale_t *) Scale16;
516 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
517 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
518 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
519 p_vout->p_Scale = (vout_scale_t *) Scale24;
522 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
523 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
524 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
525 p_vout->p_Scale = (vout_scale_t *) Scale32;
532 switch( p_vout->i_screen_depth )
536 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB16;
537 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB16;
538 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB16;
539 p_vout->p_Scale = (vout_scale_t *) Scale16;
542 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB24;
543 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB24;
544 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB24;
545 p_vout->p_Scale = (vout_scale_t *) Scale24;
548 p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB32;
549 p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB32;
550 p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB32;
551 p_vout->p_Scale = (vout_scale_t *) Scale32;
557 /*******************************************************************************
558 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
559 *******************************************************************************/
560 static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic,
561 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
562 int i_width, int i_height, int i_eol, int i_pic_eol,
565 u16 * p_pic_src; /* source pointer in case of copy */
566 u16 * p_gray; /* gray table */
567 int i_x, i_y; /* picture coordinates */
569 p_gray = p_vout->tables.yuv.gray16.p_gray;
573 /*******************************************************************************
574 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
575 *******************************************************************************/
576 static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic,
577 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
578 int i_width, int i_height, int i_eol, int i_pic_eol,
584 /*******************************************************************************
585 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
586 *******************************************************************************/
587 static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic,
588 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
589 int i_width, int i_height, int i_eol, int i_pic_eol,
592 u32 * p_pic_src; /* source pointer in case of copy */
593 u32 * p_gray; /* gray table */
594 int i_x, i_y; /* picture coordinates */
596 p_gray = p_vout->tables.yuv.gray32.p_gray;
600 /*******************************************************************************
601 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
602 *******************************************************************************/
603 static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic,
604 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
605 int i_width, int i_height, int i_eol, int i_pic_eol,
608 u16 * p_pic_src; /* source pointer in case of copy */
609 u16 * p_red; /* red table */
610 u16 * p_green; /* green table */
611 u16 * p_blue; /* blue table */
612 int i_uval, i_yval, i_vval; /* samples */
613 int i_x, i_y; /* picture coordinates */
614 int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
617 /* p_red = p_vout->tables.yuv.rgb16.p_red;
618 p_green = p_vout->tables.yuv.rgb16.p_green;
619 p_blue = p_vout->tables.yuv.rgb16.p_blue;
620 i_chroma_width = i_width / 4;
621 i_chroma_eol = i_eol / 4;
625 /*******************************************************************************
626 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
627 *******************************************************************************/
628 static void ConvertYUV422RGB16( p_vout_thread_t p_vout, void *p_pic,
629 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
630 int i_width, int i_height, int i_eol, int i_pic_eol,
636 /*******************************************************************************
637 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
638 *******************************************************************************/
639 static void ConvertYUV444RGB16( p_vout_thread_t p_vout, void *p_pic,
640 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
641 int i_width, int i_height, int i_eol, int i_pic_eol,
647 /*******************************************************************************
648 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
649 *******************************************************************************/
650 static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic,
651 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
652 int i_width, int i_height, int i_eol, int i_pic_eol,
658 /*******************************************************************************
659 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
660 *******************************************************************************/
661 static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic,
662 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
663 int i_width, int i_height, int i_eol, int i_pic_eol,
669 /*******************************************************************************
670 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
671 *******************************************************************************/
672 static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic,
673 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
674 int i_width, int i_height, int i_eol, int i_pic_eol,
680 /*******************************************************************************
681 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
682 *******************************************************************************/
683 static void ConvertYUV420RGB32( p_vout_thread_t p_vout, void *p_pic,
684 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
685 int i_width, int i_height, int i_eol, int i_pic_eol,
691 /*******************************************************************************
692 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
693 *******************************************************************************/
694 static void ConvertYUV422RGB32( p_vout_thread_t p_vout, void *p_pic,
695 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
696 int i_width, int i_height, int i_eol, int i_pic_eol,
702 /*******************************************************************************
703 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
704 *******************************************************************************/
705 static void ConvertYUV444RGB32( p_vout_thread_t p_vout, void *p_pic,
706 yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
707 int i_width, int i_height, int i_eol, int i_pic_eol,
713 /*******************************************************************************
714 * Scale16: 15 or 16 bpp picture scaling
715 *******************************************************************************/
716 static void Scale16( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
717 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
722 /*******************************************************************************
723 * Scale24: 24 bpp picture scaling
724 *******************************************************************************/
725 static void Scale24( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
726 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
731 /*******************************************************************************
732 * Scale32: 32 bpp picture scaling
733 *******************************************************************************/
734 static void Scale32( p_vout_thread_t p_vout, void *p_pic, void *p_buffer,
735 int i_width, int i_height, int i_eol, int i_pic_eol, float f_alpha, float f_beta )
740 //-------------------------
742 /*******************************************************************************
743 * External prototypes
744 *******************************************************************************/
746 /* YUV transformations for MMX - in video_yuv_mmx.S
747 * p_y, p_u, p_v: Y U and V planes
748 * i_width, i_height: frames dimensions (pixels)
749 * i_ypitch, i_vpitch: Y and V lines sizes (bytes)
750 * i_aspect: vertical aspect factor
752 * i_dci_offset: ?? x offset for left image border
753 * i_offset_to_line_0: ?? x offset for left image border
754 * i_pitch: RGB line size (bytes)
755 * i_colortype: 0 for 565, 1 for 555 */
756 static YUV420_16_MMX( u8* p_y, u8* p_u, u8 *p_v,
757 unsigned int i_width, unsigned int i_height,
758 unsigned int i_ypitch, unsigned int i_vpitch,
759 unsigned int i_aspect, u8 *p_pic,
760 u32 i_dci_offset, u32 i_offset_to_line_0,
761 int CCOPitch, int i_colortype );
764 //-------------------- walken code follow --------------------------------
770 * YUV to RGB routines.
772 * these routines calculate r, g and b values from each pixel's y, u and v.
773 * these r, g an b values are then passed thru a table lookup to take the
774 * gamma curve into account and find the corresponding pixel value.
776 * the table must store more than 3*256 values because of the possibility
777 * of overflow in the yuv->rgb calculation. actually the calculated r,g,b
778 * values are in the following intervals :
779 * -176 to 255+176 for red
780 * -133 to 255+133 for green
781 * -222 to 255+222 for blue
783 * If the input y,u,v values are right, the r,g,b results are not expected
784 * to move out of the 0 to 255 interval but who knows what will happen in
787 * the red, green and blue conversion tables are stored in a single 1935-entry
788 * array. The respective positions of each component in the array have been
789 * calculated to minimize the cache interactions of the 3 tables.
792 int rgbTable16 (short table [1935],
793 int redMask, int greenMask, int blueMask,
794 unsigned char gamma[256])
808 MaskToShift (&redRight, &redLeft, redMask);
809 MaskToShift (&greenRight, &greenLeft, greenMask);
810 MaskToShift (&blueRight, &blueLeft, blueMask);
813 * green blue red +- 2 just to be sure
814 * green = 0-525 [151-370]
815 * blue = 594-1297 [834-1053] <834-29>
816 * red = 1323-1934 [1517-1736] <493-712>
819 redTable = table + 1501;
820 greenTable = table + 135;
821 blueTable = table + 818;
823 for (i = 0; i < 178; i++) {
825 redTable[i+256] = redMask;
827 for (i = 0; i < 135; i++) {
828 greenTable[i-135] = 0;
829 greenTable[i+256] = greenMask;
831 for (i = 0; i < 224; i++) {
832 blueTable[i-224] = 0;
833 blueTable[i+256] = blueMask;
836 for (i = 0; i < 256; i++) {
838 redTable[i] = ((y >> redRight) << redLeft);
839 greenTable[i] = ((y >> greenRight) << greenLeft);
840 blueTable[i] = ((y >> blueRight) << blueLeft);
846 static int rgbTable32 (int table [1935],
847 int redMask, int greenMask, int blueMask,
848 unsigned char gamma[256])
862 MaskToShift (&redRight, &redLeft, redMask);
863 MaskToShift (&greenRight, &greenLeft, greenMask);
864 MaskToShift (&blueRight, &blueLeft, blueMask);
868 * green blue red +- 2 just to be sure
869 * green = 0-525 [151-370]
870 * blue = 594-1297 [834-1053] <834-29>
871 * red = 1323-1934 [1517-1736] <493-712>
874 redTable = table + 1501;
875 greenTable = table + 135;
876 blueTable = table + 818;
878 for (i = 0; i < 178; i++) {
880 redTable[i+256] = redMask;
882 for (i = 0; i < 135; i++) {
883 greenTable[i-135] = 0;
884 greenTable[i+256] = greenMask;
886 for (i = 0; i < 224; i++) {
887 blueTable[i-224] = 0;
888 blueTable[i+256] = blueMask;
891 for (i = 0; i < 256; i++) {
893 redTable[i] = ((y >> redRight) << redLeft);
894 greenTable[i] = ((y >> greenRight) << greenLeft);
895 blueTable[i] = ((y >> blueRight) << blueLeft);
902 #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
903 #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
904 #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
905 #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
907 void yuvToRgb16 (unsigned char * Y,
908 unsigned char * U, unsigned char * V,
909 short * dest, short table[1935], int width)
923 uvRed = (V_RED_COEF*v) >> SHIFT;
924 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
925 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
927 tableY = table + *(Y++);
928 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
929 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
931 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
933 tableY = table + *(Y++);
934 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
935 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
937 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
941 uvRed = (V_RED_COEF*v) >> SHIFT;
942 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
943 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
945 tableY = table + *(Y++);
946 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
947 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
949 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
951 tableY = table + *(Y++);
952 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
953 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
955 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
959 uvRed = (V_RED_COEF*v) >> SHIFT;
960 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
961 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
963 tableY = table + *(Y++);
964 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
965 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
967 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
969 tableY = table + *(Y++);
970 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
971 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
973 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
977 uvRed = (V_RED_COEF*v) >> SHIFT;
978 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
979 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
981 tableY = table + *(Y++);
982 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
983 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
985 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
987 tableY = table + *(Y++);
988 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
989 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
991 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
995 uvRed = (V_RED_COEF*v) >> SHIFT;
996 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
997 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
999 tableY = table + *(Y++);
1000 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1001 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1003 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1005 tableY = table + *(Y++);
1006 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1007 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1009 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1013 uvRed = (V_RED_COEF*v) >> SHIFT;
1014 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1015 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1017 tableY = table + *(Y++);
1018 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1019 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1021 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1023 tableY = table + *(Y++);
1024 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1025 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1027 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1031 uvRed = (V_RED_COEF*v) >> SHIFT;
1032 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1033 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1035 tableY = table + *(Y++);
1036 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1037 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1039 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1041 tableY = table + *(Y++);
1042 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1043 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1045 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1049 uvRed = (V_RED_COEF*v) >> SHIFT;
1050 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1051 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1053 tableY = table + *(Y++);
1054 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1055 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1057 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1059 tableY = table + *(Y++);
1060 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1061 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1063 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1066 i = (width & 15) >> 1;
1070 uvRed = (V_RED_COEF*v) >> SHIFT;
1071 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1072 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1074 tableY = table + *(Y++);
1075 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1076 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1078 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1080 tableY = table + *(Y++);
1081 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1082 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1084 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1090 uvRed = (V_RED_COEF*v) >> SHIFT;
1091 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1092 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1094 tableY = table + *(Y++);
1095 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1096 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1098 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1102 static void yuvToRgb24 (unsigned char * Y,
1103 unsigned char * U, unsigned char * V,
1104 char * dest, int table[1935], int width)
1119 uvRed = (V_RED_COEF*v) >> SHIFT;
1120 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1121 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1123 tableY = table + *(Y++);
1124 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1125 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1127 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1129 *(dest++) = tmp24 >> 8;
1130 *(dest++) = tmp24 >> 16;
1132 tableY = table + *(Y++);
1133 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1134 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1136 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1138 *(dest++) = tmp24 >> 8;
1139 *(dest++) = tmp24 >> 16;
1143 uvRed = (V_RED_COEF*v) >> SHIFT;
1144 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1145 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1147 tableY = table + *(Y++);
1148 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1149 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1151 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1153 *(dest++) = tmp24 >> 8;
1154 *(dest++) = tmp24 >> 16;
1156 tableY = table + *(Y++);
1157 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1158 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1160 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1162 *(dest++) = tmp24 >> 8;
1163 *(dest++) = tmp24 >> 16;
1167 uvRed = (V_RED_COEF*v) >> SHIFT;
1168 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1169 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1171 tableY = table + *(Y++);
1172 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1173 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1175 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1177 *(dest++) = tmp24 >> 8;
1178 *(dest++) = tmp24 >> 16;
1180 tableY = table + *(Y++);
1181 tmp24 = (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]);
1186 *(dest++) = tmp24 >> 8;
1187 *(dest++) = tmp24 >> 16;
1191 uvRed = (V_RED_COEF*v) >> SHIFT;
1192 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1193 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1195 tableY = table + *(Y++);
1196 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1197 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1199 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1201 *(dest++) = tmp24 >> 8;
1202 *(dest++) = tmp24 >> 16;
1204 tableY = table + *(Y++);
1205 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1206 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1208 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1210 *(dest++) = tmp24 >> 8;
1211 *(dest++) = tmp24 >> 16;
1214 i = (width & 7) >> 1;
1218 uvRed = (V_RED_COEF*v) >> SHIFT;
1219 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1220 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1222 tableY = table + *(Y++);
1223 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1224 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1226 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1228 *(dest++) = tmp24 >> 8;
1229 *(dest++) = tmp24 >> 16;
1231 tableY = table + *(Y++);
1232 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1233 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1235 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1237 *(dest++) = tmp24 >> 8;
1238 *(dest++) = tmp24 >> 16;
1244 uvRed = (V_RED_COEF*v) >> SHIFT;
1245 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1246 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1248 tableY = table + *(Y++);
1249 tmp24 = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1250 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1252 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1254 *(dest++) = tmp24 >> 8;
1255 *(dest++) = tmp24 >> 16;
1259 static void yuvToRgb32 (unsigned char * Y,
1260 unsigned char * U, unsigned char * V,
1261 int * dest, int table[1935], int width)
1275 uvRed = (V_RED_COEF*v) >> SHIFT;
1276 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1277 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1279 tableY = table + *(Y++);
1280 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1281 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1283 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1285 tableY = table + *(Y++);
1286 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1287 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1289 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1293 uvRed = (V_RED_COEF*v) >> SHIFT;
1294 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1295 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1297 tableY = table + *(Y++);
1298 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1299 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1301 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1303 tableY = table + *(Y++);
1304 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1305 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1307 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1311 uvRed = (V_RED_COEF*v) >> SHIFT;
1312 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1313 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1315 tableY = table + *(Y++);
1316 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1317 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1319 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1321 tableY = table + *(Y++);
1322 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1323 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1325 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1329 uvRed = (V_RED_COEF*v) >> SHIFT;
1330 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1331 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1333 tableY = table + *(Y++);
1334 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1335 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1337 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1339 tableY = table + *(Y++);
1340 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1341 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1343 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1347 uvRed = (V_RED_COEF*v) >> SHIFT;
1348 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1349 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1351 tableY = table + *(Y++);
1352 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1353 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1355 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1357 tableY = table + *(Y++);
1358 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1359 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1361 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1365 uvRed = (V_RED_COEF*v) >> SHIFT;
1366 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1367 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1369 tableY = table + *(Y++);
1370 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1371 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1373 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1375 tableY = table + *(Y++);
1376 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1377 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1379 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1383 uvRed = (V_RED_COEF*v) >> SHIFT;
1384 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1385 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1387 tableY = table + *(Y++);
1388 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1389 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1391 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1393 tableY = table + *(Y++);
1394 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1395 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1397 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1401 uvRed = (V_RED_COEF*v) >> SHIFT;
1402 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1403 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1405 tableY = table + *(Y++);
1406 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1407 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1409 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1411 tableY = table + *(Y++);
1412 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1413 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1415 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1418 i = (width & 15) >> 1;
1422 uvRed = (V_RED_COEF*v) >> SHIFT;
1423 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1424 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1426 tableY = table + *(Y++);
1427 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1428 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1430 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1432 tableY = table + *(Y++);
1433 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1434 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1436 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);
1442 uvRed = (V_RED_COEF*v) >> SHIFT;
1443 uvGreen = (U_GREEN_COEF*u + V_GREEN_COEF*v) >> SHIFT;
1444 uvBlue = (U_BLUE_COEF*u) >> SHIFT;
1446 tableY = table + *(Y++);
1447 *(dest++) = (tableY [1501 - ((V_RED_COEF*128)>>SHIFT) + uvRed] |
1448 tableY [135 - (((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) +
1450 tableY [818 - ((U_BLUE_COEF*128)>>SHIFT) + uvBlue]);