1 /*****************************************************************************
2 * transforms_yuv.c: C YUV transformation functions
3 * Provides functions to perform the YUV conversion. The functions provided
4 * here are a complete and portable C implementation, and may be replaced in
5 * certain cases by optimized functions.
6 *****************************************************************************
7 * Copyright (C) 1999, 2000, 2001 VideoLAN
9 * Authors: Vincent Seguin <ptyx@via.ecp.fr>
10 * Samuel Hocevar <sam@zoy.org>
11 * Richard Shepherd <richard@rshepherd.demon.co.uk>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
23 * You should have received a copy of the GNU General Public
24 * License along with this program; if not, write to the
25 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 * Boston, MA 02111-1307, USA.
27 *****************************************************************************/
29 /*****************************************************************************
31 *****************************************************************************/
34 #include <math.h> /* exp(), pow() */
35 #include <errno.h> /* ENOMEM */
36 #include <stdlib.h> /* free() */
37 #include <string.h> /* strerror() */
45 #include "video_output.h"
47 #include "video_common.h"
48 #include "transforms_common.h"
49 #include "transforms_yuv.h"
53 /*****************************************************************************
54 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
55 *****************************************************************************/
56 void ConvertY4Gray8( YUV_ARGS_8BPP )
58 boolean_t b_horizontal_scaling; /* horizontal scaling type */
59 int i_vertical_scaling; /* vertical scaling type */
60 int i_x, i_y; /* horizontal and vertical indexes */
61 int i_scale_count; /* scale modulo counter */
62 int i_chroma_width; /* chroma width, not used */
63 u8 * p_gray; /* base conversion table */
64 u8 * p_pic_start; /* beginning of the current line for copy */
65 u8 * p_buffer_start; /* conversion buffer start */
66 u8 * p_buffer; /* conversion buffer pointer */
67 int * p_offset_start; /* offset array start */
68 int * p_offset; /* offset array pointer */
71 * Initialize some values - i_pic_line_width will store the line skip
73 i_pic_line_width -= i_pic_width;
74 p_gray = p_vout->yuv.yuv.p_gray8;
75 p_buffer_start = p_vout->yuv.p_buffer;
76 p_offset_start = p_vout->yuv.p_offset;
77 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
78 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
83 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
84 for( i_y = 0; i_y < i_height; i_y++ )
86 /* Mark beginnning of line for possible later line copy, and initialize
89 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
91 /* Do YUV conversion to buffer - YUV picture is always formed of 16
92 * pixels wide blocks */
93 for( i_x = i_width / 16; i_x--; )
95 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
96 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
97 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
98 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
99 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
100 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
101 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
102 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
105 /* Do horizontal and vertical scaling */
107 SCALE_HEIGHT(400, 1);
111 /*****************************************************************************
112 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
113 *****************************************************************************/
114 void ConvertYUV420RGB8( YUV_ARGS_8BPP )
116 boolean_t b_horizontal_scaling; /* horizontal scaling type */
117 int i_vertical_scaling; /* vertical scaling type */
118 int i_x, i_y; /* horizontal and vertical indexes */
119 int i_scale_count; /* scale modulo counter */
120 int i_real_y; /* y % 4 */
121 u8 * p_lookup; /* lookup table */
122 int i_chroma_width; /* chroma width */
123 int * p_offset_start; /* offset array start */
124 int * p_offset; /* offset array pointer */
127 * The dithering matrices
129 static int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
130 static int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
131 static int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
132 static int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
134 static int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
135 static int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
136 static int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
137 static int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
140 * Initialize some values - i_pic_line_width will store the line skip
142 i_pic_line_width -= i_pic_width;
143 i_chroma_width = i_width / 2;
144 p_offset_start = p_vout->yuv.p_offset;
145 p_lookup = p_vout->yuv.p_base;
146 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
147 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 1 );
152 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
154 for( i_y = 0; i_y < i_height; i_y++ )
156 /* Do horizontal and vertical scaling */
157 SCALE_WIDTH_DITHER( 420 );
158 SCALE_HEIGHT_DITHER( 420 );
162 /*****************************************************************************
163 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
164 *****************************************************************************/
165 void ConvertYUV422RGB8( YUV_ARGS_8BPP )
167 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 8" );
170 /*****************************************************************************
171 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
172 *****************************************************************************/
173 void ConvertYUV444RGB8( YUV_ARGS_8BPP )
175 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 8" );
178 /*****************************************************************************
179 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
180 *****************************************************************************/
181 void ConvertY4Gray16( YUV_ARGS_16BPP )
183 boolean_t b_horizontal_scaling; /* horizontal scaling type */
184 int i_vertical_scaling; /* vertical scaling type */
185 int i_x, i_y; /* horizontal and vertical indexes */
186 int i_scale_count; /* scale modulo counter */
187 int i_chroma_width; /* chroma width, not used */
188 u16 * p_gray; /* base conversion table */
189 u16 * p_pic_start; /* beginning of the current line for copy */
190 u16 * p_buffer_start; /* conversion buffer start */
191 u16 * p_buffer; /* conversion buffer pointer */
192 int * p_offset_start; /* offset array start */
193 int * p_offset; /* offset array pointer */
196 * Initialize some values - i_pic_line_width will store the line skip
198 i_pic_line_width -= i_pic_width;
199 p_gray = p_vout->yuv.yuv.p_gray16;
200 p_buffer_start = p_vout->yuv.p_buffer;
201 p_offset_start = p_vout->yuv.p_offset;
202 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
203 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
208 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
209 for( i_y = 0; i_y < i_height; i_y++ )
211 /* Mark beginnning of line for possible later line copy, and initialize
214 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
216 /* Do YUV conversion to buffer - YUV picture is always formed of 16
217 * pixels wide blocks */
218 for( i_x = i_width / 16; i_x--; )
220 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
221 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
222 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
223 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
224 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
225 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
226 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
227 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
230 /* Do horizontal and vertical scaling */
232 SCALE_HEIGHT(400, 2);
236 /*****************************************************************************
237 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
238 *****************************************************************************/
239 void ConvertYUV420RGB16( YUV_ARGS_16BPP )
241 boolean_t b_horizontal_scaling; /* horizontal scaling type */
242 int i_vertical_scaling; /* vertical scaling type */
243 int i_x, i_y; /* horizontal and vertical indexes */
244 int i_scale_count; /* scale modulo counter */
245 int i_uval, i_vval; /* U and V samples */
246 int i_red, i_green, i_blue; /* U and V modified samples */
247 int i_chroma_width; /* chroma width */
248 u16 * p_yuv; /* base conversion table */
249 u16 * p_ybase; /* Y dependant conversion table */
250 u16 * p_pic_start; /* beginning of the current line for copy */
251 u16 * p_buffer_start; /* conversion buffer start */
252 u16 * p_buffer; /* conversion buffer pointer */
253 int * p_offset_start; /* offset array start */
254 int * p_offset; /* offset array pointer */
257 * Initialize some values - i_pic_line_width will store the line skip
259 i_pic_line_width -= i_pic_width;
260 i_chroma_width = i_width / 2;
261 p_yuv = p_vout->yuv.yuv.p_rgb16;
262 p_buffer_start = p_vout->yuv.p_buffer;
263 p_offset_start = p_vout->yuv.p_offset;
264 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
265 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
270 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
271 for( i_y = 0; i_y < i_height; i_y++ )
273 /* Mark beginnning of line for possible later line copy, and initialize
276 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
278 /* Do YUV conversion to buffer - YUV picture is always formed of 16
279 * pixels wide blocks */
280 for( i_x = i_width / 16; i_x--; )
282 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
283 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
284 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
285 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
286 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
287 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
288 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
289 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
292 /* Do horizontal and vertical scaling */
294 SCALE_HEIGHT(420, 2);
298 /*****************************************************************************
299 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
300 *****************************************************************************/
301 void ConvertYUV422RGB16( YUV_ARGS_16BPP )
303 boolean_t b_horizontal_scaling; /* horizontal scaling type */
304 int i_vertical_scaling; /* vertical scaling type */
305 int i_x, i_y; /* horizontal and vertical indexes */
306 int i_scale_count; /* scale modulo counter */
307 int i_uval, i_vval; /* U and V samples */
308 int i_red, i_green, i_blue; /* U and V modified samples */
309 int i_chroma_width; /* chroma width */
310 u16 * p_yuv; /* base conversion table */
311 u16 * p_ybase; /* Y dependant conversion table */
312 u16 * p_pic_start; /* beginning of the current line for copy */
313 u16 * p_buffer_start; /* conversion buffer start */
314 u16 * p_buffer; /* conversion buffer pointer */
315 int * p_offset_start; /* offset array start */
316 int * p_offset; /* offset array pointer */
319 * Initialize some values - i_pic_line_width will store the line skip
321 i_pic_line_width -= i_pic_width;
322 i_chroma_width = i_width / 2;
323 p_yuv = p_vout->yuv.yuv.p_rgb16;
324 p_buffer_start = p_vout->yuv.p_buffer;
325 p_offset_start = p_vout->yuv.p_offset;
326 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
327 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
332 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
333 for( i_y = 0; i_y < i_height; i_y++ )
335 /* Mark beginnning of line for possible later line copy, and initialize
338 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
340 /* Do YUV conversion to buffer - YUV picture is always formed of 16
341 * pixels wide blocks */
342 for( i_x = i_width / 16; i_x--; )
344 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
345 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
346 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
347 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
348 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
349 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
350 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
351 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
354 /* Do horizontal and vertical scaling */
356 SCALE_HEIGHT(422, 2);
360 /*****************************************************************************
361 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
362 *****************************************************************************/
363 void ConvertYUV444RGB16( YUV_ARGS_16BPP )
365 boolean_t b_horizontal_scaling; /* horizontal scaling type */
366 int i_vertical_scaling; /* vertical scaling type */
367 int i_x, i_y; /* horizontal and vertical indexes */
368 int i_scale_count; /* scale modulo counter */
369 int i_uval, i_vval; /* U and V samples */
370 int i_red, i_green, i_blue; /* U and V modified samples */
371 int i_chroma_width; /* chroma width, not used */
372 u16 * p_yuv; /* base conversion table */
373 u16 * p_ybase; /* Y dependant conversion table */
374 u16 * p_pic_start; /* beginning of the current line for copy */
375 u16 * p_buffer_start; /* conversion buffer start */
376 u16 * p_buffer; /* conversion buffer pointer */
377 int * p_offset_start; /* offset array start */
378 int * p_offset; /* offset array pointer */
381 * Initialize some values - i_pic_line_width will store the line skip
383 i_pic_line_width -= i_pic_width;
384 p_yuv = p_vout->yuv.yuv.p_rgb16;
385 p_buffer_start = p_vout->yuv.p_buffer;
386 p_offset_start = p_vout->yuv.p_offset;
387 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
388 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
393 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
394 for( i_y = 0; i_y < i_height; i_y++ )
396 /* Mark beginnning of line for possible later line copy, and initialize
399 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
401 /* Do YUV conversion to buffer - YUV picture is always formed of 16
402 * pixels wide blocks */
403 for( i_x = i_width / 16; i_x--; )
405 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
406 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
407 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
408 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
409 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
410 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
411 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
412 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
415 /* Do horizontal and vertical scaling */
417 SCALE_HEIGHT(444, 2);
421 /*****************************************************************************
422 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
423 *****************************************************************************/
424 void ConvertY4Gray24( YUV_ARGS_24BPP )
426 intf_ErrMsg( "yuv error: unhandled function, grayscale, bpp = 24" );
429 /*****************************************************************************
430 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
431 *****************************************************************************/
432 void ConvertYUV420RGB24( YUV_ARGS_24BPP )
434 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, bpp = 24" );
437 /*****************************************************************************
438 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
439 *****************************************************************************/
440 void ConvertYUV422RGB24( YUV_ARGS_24BPP )
442 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 24" );
445 /*****************************************************************************
446 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
447 *****************************************************************************/
448 void ConvertYUV444RGB24( YUV_ARGS_24BPP )
450 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 24" );
453 /*****************************************************************************
454 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
455 *****************************************************************************/
456 void ConvertY4Gray32( YUV_ARGS_32BPP )
458 boolean_t b_horizontal_scaling; /* horizontal scaling type */
459 int i_vertical_scaling; /* vertical scaling type */
460 int i_x, i_y; /* horizontal and vertical indexes */
461 int i_scale_count; /* scale modulo counter */
462 int i_chroma_width; /* chroma width, not used */
463 u32 * p_gray; /* base conversion table */
464 u32 * p_pic_start; /* beginning of the current line for copy */
465 u32 * p_buffer_start; /* conversion buffer start */
466 u32 * p_buffer; /* conversion buffer pointer */
467 int * p_offset_start; /* offset array start */
468 int * p_offset; /* offset array pointer */
471 * Initialize some values - i_pic_line_width will store the line skip
473 i_pic_line_width -= i_pic_width;
474 p_gray = p_vout->yuv.yuv.p_gray32;
475 p_buffer_start = p_vout->yuv.p_buffer;
476 p_offset_start = p_vout->yuv.p_offset;
477 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
478 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
483 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
484 for( i_y = 0; i_y < i_height; i_y++ )
486 /* Mark beginnning of line for possible later line copy, and initialize
489 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
491 /* Do YUV conversion to buffer - YUV picture is always formed of 16
492 * pixels wide blocks */
493 for( i_x = i_width / 16; i_x--; )
495 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
496 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
497 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
498 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
499 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
500 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
501 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
502 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
505 /* Do horizontal and vertical scaling */
507 SCALE_HEIGHT(400, 4);
511 /*****************************************************************************
512 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
513 *****************************************************************************/
514 void ConvertYUV420RGB32( YUV_ARGS_32BPP )
516 boolean_t b_horizontal_scaling; /* horizontal scaling type */
517 int i_vertical_scaling; /* vertical scaling type */
518 int i_x, i_y; /* horizontal and vertical indexes */
519 int i_scale_count; /* scale modulo counter */
520 int i_uval, i_vval; /* U and V samples */
521 int i_red, i_green, i_blue; /* U and V modified samples */
522 int i_chroma_width; /* chroma width */
523 u32 * p_yuv; /* base conversion table */
524 u32 * p_ybase; /* Y dependant conversion table */
525 u32 * p_pic_start; /* beginning of the current line for copy */
526 u32 * p_buffer_start; /* conversion buffer start */
527 u32 * p_buffer; /* conversion buffer pointer */
528 int * p_offset_start; /* offset array start */
529 int * p_offset; /* offset array pointer */
532 * Initialize some values - i_pic_line_width will store the line skip
534 i_pic_line_width -= i_pic_width;
535 i_chroma_width = i_width / 2;
536 p_yuv = p_vout->yuv.yuv.p_rgb32;
537 p_buffer_start = p_vout->yuv.p_buffer;
538 p_offset_start = p_vout->yuv.p_offset;
539 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
540 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
545 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
546 for( i_y = 0; i_y < i_height; i_y++ )
548 /* Mark beginnning of line for possible later line copy, and initialize
551 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
553 /* Do YUV conversion to buffer - YUV picture is always formed of 16
554 * pixels wide blocks */
555 for( i_x = i_width / 16; i_x--; )
557 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
558 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
559 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
560 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
561 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
562 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
563 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
564 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
567 /* Do horizontal and vertical scaling */
569 SCALE_HEIGHT(420, 4);
573 /*****************************************************************************
574 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
575 *****************************************************************************/
576 void ConvertYUV422RGB32( YUV_ARGS_32BPP )
578 boolean_t b_horizontal_scaling; /* horizontal scaling type */
579 int i_vertical_scaling; /* vertical scaling type */
580 int i_x, i_y; /* horizontal and vertical indexes */
581 int i_scale_count; /* scale modulo counter */
582 int i_uval, i_vval; /* U and V samples */
583 int i_red, i_green, i_blue; /* U and V modified samples */
584 int i_chroma_width; /* chroma width */
585 u32 * p_yuv; /* base conversion table */
586 u32 * p_ybase; /* Y dependant conversion table */
587 u32 * p_pic_start; /* beginning of the current line for copy */
588 u32 * p_buffer_start; /* conversion buffer start */
589 u32 * p_buffer; /* conversion buffer pointer */
590 int * p_offset_start; /* offset array start */
591 int * p_offset; /* offset array pointer */
594 * Initialize some values - i_pic_line_width will store the line skip
596 i_pic_line_width -= i_pic_width;
597 i_chroma_width = i_width / 2;
598 p_yuv = p_vout->yuv.yuv.p_rgb32;
599 p_buffer_start = p_vout->yuv.p_buffer;
600 p_offset_start = p_vout->yuv.p_offset;
601 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
602 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
607 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
608 for( i_y = 0; i_y < i_height; i_y++ )
610 /* Mark beginnning of line for possible later line copy, and initialize
613 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
615 /* Do YUV conversion to buffer - YUV picture is always formed of 16
616 * pixels wide blocks */
617 for( i_x = i_width / 16; i_x--; )
619 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
620 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
621 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
622 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
623 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
624 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
625 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
626 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
629 /* Do horizontal and vertical scaling */
631 SCALE_HEIGHT(422, 4);
635 /*****************************************************************************
636 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
637 *****************************************************************************/
638 void ConvertYUV444RGB32( YUV_ARGS_32BPP )
640 boolean_t b_horizontal_scaling; /* horizontal scaling type */
641 int i_vertical_scaling; /* vertical scaling type */
642 int i_x, i_y; /* horizontal and vertical indexes */
643 int i_scale_count; /* scale modulo counter */
644 int i_uval, i_vval; /* U and V samples */
645 int i_red, i_green, i_blue; /* U and V modified samples */
646 int i_chroma_width; /* chroma width, not used */
647 u32 * p_yuv; /* base conversion table */
648 u32 * p_ybase; /* Y dependant conversion table */
649 u32 * p_pic_start; /* beginning of the current line for copy */
650 u32 * p_buffer_start; /* conversion buffer start */
651 u32 * p_buffer; /* conversion buffer pointer */
652 int * p_offset_start; /* offset array start */
653 int * p_offset; /* offset array pointer */
656 * Initialize some values - i_pic_line_width will store the line skip
658 i_pic_line_width -= i_pic_width;
659 p_yuv = p_vout->yuv.yuv.p_rgb32;
660 p_buffer_start = p_vout->yuv.p_buffer;
661 p_offset_start = p_vout->yuv.p_offset;
662 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
663 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
668 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
669 for( i_y = 0; i_y < i_height; i_y++ )
671 /* Mark beginnning of line for possible later line copy, and initialize
674 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
676 /* Do YUV conversion to buffer - YUV picture is always formed of 16
677 * pixels wide blocks */
678 for( i_x = i_width / 16; i_x--; )
680 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
681 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
682 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
683 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
684 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
685 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
686 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
687 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
690 /* Do horizontal and vertical scaling */
692 SCALE_HEIGHT(444, 4);
696 static __inline__ void yuv2YCbCr422_inner( u8 *p_y, u8 *p_u, u8 *p_v,
697 u8 *p_out, int i_width_by_4 )
701 for( i_x = 0 ; i_x < 4 * i_width_by_4 ; ++i_x )
703 *p_out++ = p_y[ 2 * i_x ];
704 *p_out++ = p_u[ i_x ];
705 *p_out++ = p_y[ 2 * i_x + 1 ];
706 *p_out++ = p_v[ i_x ];
710 void ConvertYUV420YCbr8 ( YUV_ARGS_8BPP )
712 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 8" );
715 void ConvertYUV422YCbr8 ( YUV_ARGS_8BPP )
717 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 8" );
720 void ConvertYUV444YCbr8 ( YUV_ARGS_8BPP )
722 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 8" );
726 /*****************************************************************************
727 * yuv2YCbCr422: color YUV 4:2:0 to color YCbCr 16bpp
728 *****************************************************************************/
729 void ConvertYUV420YCbr16 ( YUV_ARGS_16BPP )
733 for( i_y = 0 ; i_y < i_height ; ++i_y )
735 yuv2YCbCr422_inner( p_y, p_u, p_v, (u8 *)p_pic, i_width / 8 );
737 p_pic += i_width * 2;
749 void ConvertYUV422YCbr16 ( YUV_ARGS_16BPP )
751 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 16" );
754 void ConvertYUV444YCbr16 ( YUV_ARGS_16BPP )
756 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 16" );
760 void ConvertYUV420YCbr24 ( YUV_ARGS_24BPP )
762 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 24" );
766 void ConvertYUV422YCbr24 ( YUV_ARGS_24BPP )
768 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 24" );
772 void ConvertYUV444YCbr24 ( YUV_ARGS_24BPP )
774 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 24" );
778 void ConvertYUV420YCbr32 ( YUV_ARGS_32BPP )
780 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 32" );
784 void ConvertYUV422YCbr32 ( YUV_ARGS_32BPP )
786 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 32" );
789 void ConvertYUV444YCbr32 ( YUV_ARGS_32BPP )
791 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 32" );