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
8 * $Id: transforms_yuv.c,v 1.5 2001/04/15 04:19:58 sam Exp $
10 * Authors: Vincent Seguin <ptyx@via.ecp.fr>
11 * Samuel Hocevar <sam@zoy.org>
12 * Richard Shepherd <richard@rshepherd.demon.co.uk>
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
24 * You should have received a copy of the GNU General Public
25 * License along with this program; if not, write to the
26 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
27 * Boston, MA 02111-1307, USA.
28 *****************************************************************************/
30 #define MODULE_NAME yuv
31 #include "modules_inner.h"
33 /*****************************************************************************
35 *****************************************************************************/
38 #include <math.h> /* exp(), pow() */
39 #include <errno.h> /* ENOMEM */
40 #include <stdlib.h> /* free() */
41 #include <string.h> /* strerror() */
49 #include "video_output.h"
51 #include "video_common.h"
52 #include "transforms_common.h"
53 #include "transforms_yuv.h"
57 /*****************************************************************************
58 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
59 *****************************************************************************/
60 void _M( ConvertY4Gray8 )( YUV_ARGS_8BPP )
62 boolean_t b_horizontal_scaling; /* horizontal scaling type */
63 int i_vertical_scaling; /* vertical scaling type */
64 int i_x, i_y; /* horizontal and vertical indexes */
65 int i_scale_count; /* scale modulo counter */
66 int i_chroma_width; /* chroma width, not used */
67 u8 * p_gray; /* base conversion table */
68 u8 * p_pic_start; /* beginning of the current line for copy */
69 u8 * p_buffer_start; /* conversion buffer start */
70 u8 * p_buffer; /* conversion buffer pointer */
71 int * p_offset_start; /* offset array start */
72 int * p_offset; /* offset array pointer */
75 * Initialize some values - i_pic_line_width will store the line skip
77 i_pic_line_width -= i_pic_width;
78 p_gray = p_vout->yuv.yuv.p_gray8;
79 p_buffer_start = p_vout->yuv.p_buffer;
80 p_offset_start = p_vout->yuv.p_offset;
81 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
82 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
87 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
88 for( i_y = 0; i_y < i_height; i_y++ )
90 /* Mark beginnning of line for possible later line copy, and initialize
93 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
95 /* Do YUV conversion to buffer - YUV picture is always formed of 16
96 * pixels wide blocks */
97 for( i_x = i_width / 16; i_x--; )
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++ ];
103 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
104 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
105 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
106 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
109 /* Do horizontal and vertical scaling */
111 SCALE_HEIGHT(400, 1);
115 /*****************************************************************************
116 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
117 *****************************************************************************/
118 void _M( ConvertYUV420RGB8 )( YUV_ARGS_8BPP )
120 boolean_t b_horizontal_scaling; /* horizontal scaling type */
121 int i_vertical_scaling; /* vertical scaling type */
122 int i_x, i_y; /* horizontal and vertical indexes */
123 int i_scale_count; /* scale modulo counter */
124 int i_real_y; /* y % 4 */
125 u8 * p_lookup; /* lookup table */
126 int i_chroma_width; /* chroma width */
127 int * p_offset_start; /* offset array start */
128 int * p_offset; /* offset array pointer */
131 * The dithering matrices
133 static int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
134 static int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
135 static int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
136 static int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
138 static int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
139 static int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
140 static int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
141 static int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
144 * Initialize some values - i_pic_line_width will store the line skip
146 i_pic_line_width -= i_pic_width;
147 i_chroma_width = i_width / 2;
148 p_offset_start = p_vout->yuv.p_offset;
149 p_lookup = p_vout->yuv.p_base;
150 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
151 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 1 );
156 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
158 for( i_y = 0; i_y < i_height; i_y++ )
160 /* Do horizontal and vertical scaling */
161 SCALE_WIDTH_DITHER( 420 );
162 SCALE_HEIGHT_DITHER( 420 );
166 /*****************************************************************************
167 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
168 *****************************************************************************/
169 void _M( ConvertYUV422RGB8 )( YUV_ARGS_8BPP )
171 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 8" );
174 /*****************************************************************************
175 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
176 *****************************************************************************/
177 void _M( ConvertYUV444RGB8 )( YUV_ARGS_8BPP )
179 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 8" );
182 /*****************************************************************************
183 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
184 *****************************************************************************/
185 void _M( ConvertY4Gray16 )( YUV_ARGS_16BPP )
187 boolean_t b_horizontal_scaling; /* horizontal scaling type */
188 int i_vertical_scaling; /* vertical scaling type */
189 int i_x, i_y; /* horizontal and vertical indexes */
190 int i_scale_count; /* scale modulo counter */
191 int i_chroma_width; /* chroma width, not used */
192 u16 * p_gray; /* base conversion table */
193 u16 * p_pic_start; /* beginning of the current line for copy */
194 u16 * p_buffer_start; /* conversion buffer start */
195 u16 * p_buffer; /* conversion buffer pointer */
196 int * p_offset_start; /* offset array start */
197 int * p_offset; /* offset array pointer */
200 * Initialize some values - i_pic_line_width will store the line skip
202 i_pic_line_width -= i_pic_width;
203 p_gray = p_vout->yuv.yuv.p_gray16;
204 p_buffer_start = p_vout->yuv.p_buffer;
205 p_offset_start = p_vout->yuv.p_offset;
206 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
207 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
212 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
213 for( i_y = 0; i_y < i_height; i_y++ )
215 /* Mark beginnning of line for possible later line copy, and initialize
218 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
220 /* Do YUV conversion to buffer - YUV picture is always formed of 16
221 * pixels wide blocks */
222 for( i_x = i_width / 16; i_x--; )
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++ ];
228 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
229 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
230 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
231 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
234 /* Do horizontal and vertical scaling */
236 SCALE_HEIGHT(400, 2);
240 /*****************************************************************************
241 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
242 *****************************************************************************/
243 void _M( ConvertYUV420RGB16 )( YUV_ARGS_16BPP )
245 boolean_t b_horizontal_scaling; /* horizontal scaling type */
246 int i_vertical_scaling; /* vertical scaling type */
247 int i_x, i_y; /* horizontal and vertical indexes */
248 int i_scale_count; /* scale modulo counter */
249 int i_uval, i_vval; /* U and V samples */
250 int i_red, i_green, i_blue; /* U and V modified samples */
251 int i_chroma_width; /* chroma width */
252 u16 * p_yuv; /* base conversion table */
253 u16 * p_ybase; /* Y dependant conversion table */
254 u16 * p_pic_start; /* beginning of the current line for copy */
255 u16 * p_buffer_start; /* conversion buffer start */
256 u16 * p_buffer; /* conversion buffer pointer */
257 int * p_offset_start; /* offset array start */
258 int * p_offset; /* offset array pointer */
261 * Initialize some values - i_pic_line_width will store the line skip
263 i_pic_line_width -= i_pic_width;
264 i_chroma_width = i_width / 2;
265 p_yuv = p_vout->yuv.yuv.p_rgb16;
266 p_buffer_start = p_vout->yuv.p_buffer;
267 p_offset_start = p_vout->yuv.p_offset;
268 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
269 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
274 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
275 for( i_y = 0; i_y < i_height; i_y++ )
277 /* Mark beginnning of line for possible later line copy, and initialize
280 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
282 /* Do YUV conversion to buffer - YUV picture is always formed of 16
283 * pixels wide blocks */
284 for( i_x = i_width / 16; i_x--; )
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);
290 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
291 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
292 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
293 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
296 /* Do horizontal and vertical scaling */
298 SCALE_HEIGHT(420, 2);
302 /*****************************************************************************
303 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
304 *****************************************************************************/
305 void _M( ConvertYUV422RGB16 )( YUV_ARGS_16BPP )
307 boolean_t b_horizontal_scaling; /* horizontal scaling type */
308 int i_vertical_scaling; /* vertical scaling type */
309 int i_x, i_y; /* horizontal and vertical indexes */
310 int i_scale_count; /* scale modulo counter */
311 int i_uval, i_vval; /* U and V samples */
312 int i_red, i_green, i_blue; /* U and V modified samples */
313 int i_chroma_width; /* chroma width */
314 u16 * p_yuv; /* base conversion table */
315 u16 * p_ybase; /* Y dependant conversion table */
316 u16 * p_pic_start; /* beginning of the current line for copy */
317 u16 * p_buffer_start; /* conversion buffer start */
318 u16 * p_buffer; /* conversion buffer pointer */
319 int * p_offset_start; /* offset array start */
320 int * p_offset; /* offset array pointer */
323 * Initialize some values - i_pic_line_width will store the line skip
325 i_pic_line_width -= i_pic_width;
326 i_chroma_width = i_width / 2;
327 p_yuv = p_vout->yuv.yuv.p_rgb16;
328 p_buffer_start = p_vout->yuv.p_buffer;
329 p_offset_start = p_vout->yuv.p_offset;
330 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
331 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
336 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
337 for( i_y = 0; i_y < i_height; i_y++ )
339 /* Mark beginnning of line for possible later line copy, and initialize
342 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
344 /* Do YUV conversion to buffer - YUV picture is always formed of 16
345 * pixels wide blocks */
346 for( i_x = i_width / 16; i_x--; )
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);
352 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
353 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
354 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
355 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
358 /* Do horizontal and vertical scaling */
360 SCALE_HEIGHT(422, 2);
364 /*****************************************************************************
365 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
366 *****************************************************************************/
367 void _M( ConvertYUV444RGB16 )( YUV_ARGS_16BPP )
369 boolean_t b_horizontal_scaling; /* horizontal scaling type */
370 int i_vertical_scaling; /* vertical scaling type */
371 int i_x, i_y; /* horizontal and vertical indexes */
372 int i_scale_count; /* scale modulo counter */
373 int i_uval, i_vval; /* U and V samples */
374 int i_red, i_green, i_blue; /* U and V modified samples */
375 int i_chroma_width; /* chroma width, not used */
376 u16 * p_yuv; /* base conversion table */
377 u16 * p_ybase; /* Y dependant conversion table */
378 u16 * p_pic_start; /* beginning of the current line for copy */
379 u16 * p_buffer_start; /* conversion buffer start */
380 u16 * p_buffer; /* conversion buffer pointer */
381 int * p_offset_start; /* offset array start */
382 int * p_offset; /* offset array pointer */
385 * Initialize some values - i_pic_line_width will store the line skip
387 i_pic_line_width -= i_pic_width;
388 p_yuv = p_vout->yuv.yuv.p_rgb16;
389 p_buffer_start = p_vout->yuv.p_buffer;
390 p_offset_start = p_vout->yuv.p_offset;
391 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
392 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
397 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
398 for( i_y = 0; i_y < i_height; i_y++ )
400 /* Mark beginnning of line for possible later line copy, and initialize
403 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
405 /* Do YUV conversion to buffer - YUV picture is always formed of 16
406 * pixels wide blocks */
407 for( i_x = i_width / 16; i_x--; )
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);
413 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
414 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
415 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
416 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
419 /* Do horizontal and vertical scaling */
421 SCALE_HEIGHT(444, 2);
425 /*****************************************************************************
426 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
427 *****************************************************************************/
428 void _M( ConvertY4Gray24 )( YUV_ARGS_24BPP )
430 intf_ErrMsg( "yuv error: unhandled function, grayscale, bpp = 24" );
433 /*****************************************************************************
434 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
435 *****************************************************************************/
436 void _M( ConvertYUV420RGB24 )( YUV_ARGS_24BPP )
438 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, bpp = 24" );
441 /*****************************************************************************
442 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
443 *****************************************************************************/
444 void _M( ConvertYUV422RGB24 )( YUV_ARGS_24BPP )
446 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 24" );
449 /*****************************************************************************
450 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
451 *****************************************************************************/
452 void _M( ConvertYUV444RGB24 )( YUV_ARGS_24BPP )
454 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 24" );
457 /*****************************************************************************
458 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
459 *****************************************************************************/
460 void _M( ConvertY4Gray32 )( YUV_ARGS_32BPP )
462 boolean_t b_horizontal_scaling; /* horizontal scaling type */
463 int i_vertical_scaling; /* vertical scaling type */
464 int i_x, i_y; /* horizontal and vertical indexes */
465 int i_scale_count; /* scale modulo counter */
466 int i_chroma_width; /* chroma width, not used */
467 u32 * p_gray; /* base conversion table */
468 u32 * p_pic_start; /* beginning of the current line for copy */
469 u32 * p_buffer_start; /* conversion buffer start */
470 u32 * p_buffer; /* conversion buffer pointer */
471 int * p_offset_start; /* offset array start */
472 int * p_offset; /* offset array pointer */
475 * Initialize some values - i_pic_line_width will store the line skip
477 i_pic_line_width -= i_pic_width;
478 p_gray = p_vout->yuv.yuv.p_gray32;
479 p_buffer_start = p_vout->yuv.p_buffer;
480 p_offset_start = p_vout->yuv.p_offset;
481 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
482 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
487 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
488 for( i_y = 0; i_y < i_height; i_y++ )
490 /* Mark beginnning of line for possible later line copy, and initialize
493 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
495 /* Do YUV conversion to buffer - YUV picture is always formed of 16
496 * pixels wide blocks */
497 for( i_x = i_width / 16; i_x--; )
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++ ];
503 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
504 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
505 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
506 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
509 /* Do horizontal and vertical scaling */
511 SCALE_HEIGHT(400, 4);
515 /*****************************************************************************
516 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
517 *****************************************************************************/
518 void _M( ConvertYUV420RGB32 )( YUV_ARGS_32BPP )
520 boolean_t b_horizontal_scaling; /* horizontal scaling type */
521 int i_vertical_scaling; /* vertical scaling type */
522 int i_x, i_y; /* horizontal and vertical indexes */
523 int i_scale_count; /* scale modulo counter */
524 int i_uval, i_vval; /* U and V samples */
525 int i_red, i_green, i_blue; /* U and V modified samples */
526 int i_chroma_width; /* chroma width */
527 u32 * p_yuv; /* base conversion table */
528 u32 * p_ybase; /* Y dependant conversion table */
529 u32 * p_pic_start; /* beginning of the current line for copy */
530 u32 * p_buffer_start; /* conversion buffer start */
531 u32 * p_buffer; /* conversion buffer pointer */
532 int * p_offset_start; /* offset array start */
533 int * p_offset; /* offset array pointer */
536 * Initialize some values - i_pic_line_width will store the line skip
538 i_pic_line_width -= i_pic_width;
539 i_chroma_width = i_width / 2;
540 p_yuv = p_vout->yuv.yuv.p_rgb32;
541 p_buffer_start = p_vout->yuv.p_buffer;
542 p_offset_start = p_vout->yuv.p_offset;
543 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
544 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
549 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
550 for( i_y = 0; i_y < i_height; i_y++ )
552 /* Mark beginnning of line for possible later line copy, and initialize
555 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
557 /* Do YUV conversion to buffer - YUV picture is always formed of 16
558 * pixels wide blocks */
559 for( i_x = i_width / 16; i_x--; )
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);
565 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
566 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
567 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
568 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
571 /* Do horizontal and vertical scaling */
573 SCALE_HEIGHT(420, 4);
577 /*****************************************************************************
578 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
579 *****************************************************************************/
580 void _M( ConvertYUV422RGB32 )( YUV_ARGS_32BPP )
582 boolean_t b_horizontal_scaling; /* horizontal scaling type */
583 int i_vertical_scaling; /* vertical scaling type */
584 int i_x, i_y; /* horizontal and vertical indexes */
585 int i_scale_count; /* scale modulo counter */
586 int i_uval, i_vval; /* U and V samples */
587 int i_red, i_green, i_blue; /* U and V modified samples */
588 int i_chroma_width; /* chroma width */
589 u32 * p_yuv; /* base conversion table */
590 u32 * p_ybase; /* Y dependant conversion table */
591 u32 * p_pic_start; /* beginning of the current line for copy */
592 u32 * p_buffer_start; /* conversion buffer start */
593 u32 * p_buffer; /* conversion buffer pointer */
594 int * p_offset_start; /* offset array start */
595 int * p_offset; /* offset array pointer */
598 * Initialize some values - i_pic_line_width will store the line skip
600 i_pic_line_width -= i_pic_width;
601 i_chroma_width = i_width / 2;
602 p_yuv = p_vout->yuv.yuv.p_rgb32;
603 p_buffer_start = p_vout->yuv.p_buffer;
604 p_offset_start = p_vout->yuv.p_offset;
605 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
606 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
611 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
612 for( i_y = 0; i_y < i_height; i_y++ )
614 /* Mark beginnning of line for possible later line copy, and initialize
617 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
619 /* Do YUV conversion to buffer - YUV picture is always formed of 16
620 * pixels wide blocks */
621 for( i_x = i_width / 16; i_x--; )
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);
627 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
628 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
629 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
630 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
633 /* Do horizontal and vertical scaling */
635 SCALE_HEIGHT(422, 4);
639 /*****************************************************************************
640 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
641 *****************************************************************************/
642 void _M( ConvertYUV444RGB32 )( YUV_ARGS_32BPP )
644 boolean_t b_horizontal_scaling; /* horizontal scaling type */
645 int i_vertical_scaling; /* vertical scaling type */
646 int i_x, i_y; /* horizontal and vertical indexes */
647 int i_scale_count; /* scale modulo counter */
648 int i_uval, i_vval; /* U and V samples */
649 int i_red, i_green, i_blue; /* U and V modified samples */
650 int i_chroma_width; /* chroma width, not used */
651 u32 * p_yuv; /* base conversion table */
652 u32 * p_ybase; /* Y dependant conversion table */
653 u32 * p_pic_start; /* beginning of the current line for copy */
654 u32 * p_buffer_start; /* conversion buffer start */
655 u32 * p_buffer; /* conversion buffer pointer */
656 int * p_offset_start; /* offset array start */
657 int * p_offset; /* offset array pointer */
660 * Initialize some values - i_pic_line_width will store the line skip
662 i_pic_line_width -= i_pic_width;
663 p_yuv = p_vout->yuv.yuv.p_rgb32;
664 p_buffer_start = p_vout->yuv.p_buffer;
665 p_offset_start = p_vout->yuv.p_offset;
666 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
667 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
672 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
673 for( i_y = 0; i_y < i_height; i_y++ )
675 /* Mark beginnning of line for possible later line copy, and initialize
678 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
680 /* Do YUV conversion to buffer - YUV picture is always formed of 16
681 * pixels wide blocks */
682 for( i_x = i_width / 16; i_x--; )
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);
688 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
689 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
690 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
691 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
694 /* Do horizontal and vertical scaling */
696 SCALE_HEIGHT(444, 4);
700 static __inline__ void yuv2YCbCr422_inner( u8 *p_y, u8 *p_u, u8 *p_v,
701 u8 *p_out, int i_width_by_4 )
705 for( i_x = 0 ; i_x < 4 * i_width_by_4 ; ++i_x )
707 *p_out++ = p_y[ 2 * i_x ];
708 *p_out++ = p_u[ i_x ];
709 *p_out++ = p_y[ 2 * i_x + 1 ];
710 *p_out++ = p_v[ i_x ];
714 void _M( ConvertYUV420YCbr8 )( YUV_ARGS_8BPP )
716 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 8" );
719 void _M( ConvertYUV422YCbr8 )( YUV_ARGS_8BPP )
721 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 8" );
725 void _M( ConvertYUV444YCbr8 )( YUV_ARGS_8BPP )
727 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 8" );
731 /*****************************************************************************
732 * yuv2YCbCr422: color YUV 4:2:0 to color YCbCr 16bpp
733 *****************************************************************************/
734 void _M( ConvertYUV420YCbr16 )( YUV_ARGS_16BPP )
738 for( i_y = 0 ; i_y < i_height ; ++i_y )
740 yuv2YCbCr422_inner( p_y, p_u, p_v, (u8 *)p_pic, i_width / 8 );
742 p_pic += i_width * 2;
754 void _M( ConvertYUV422YCbr16 )( YUV_ARGS_16BPP )
756 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 16" );
759 void _M( ConvertYUV444YCbr16 )( YUV_ARGS_16BPP )
761 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 16" );
765 void _M( ConvertYUV420YCbr24 )( YUV_ARGS_24BPP )
767 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 24" );
771 void _M( ConvertYUV422YCbr24 )( YUV_ARGS_24BPP )
773 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 24" );
777 void _M( ConvertYUV444YCbr24 )( YUV_ARGS_24BPP )
779 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 24" );
783 void _M( ConvertYUV420YCbr32 )( YUV_ARGS_32BPP )
785 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 32" );
789 void _M( ConvertYUV422YCbr32 )( YUV_ARGS_32BPP )
791 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 32" );
794 void _M( ConvertYUV444YCbr32 )( YUV_ARGS_32BPP )
796 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 32" );