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-2001 VideoLAN
8 * $Id: transforms_yuv.c,v 1.7 2001/11/28 15:08:06 massiot 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() */
50 #include "video_output.h"
52 #include "video_common.h"
53 #include "transforms_common.h"
54 #include "transforms_yuv.h"
57 #include "modules_export.h"
59 /*****************************************************************************
60 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
61 *****************************************************************************/
62 void _M( ConvertY4Gray8 )( YUV_ARGS_8BPP )
64 boolean_t b_horizontal_scaling; /* horizontal scaling type */
65 int i_vertical_scaling; /* vertical scaling type */
66 int i_x, i_y; /* horizontal and vertical indexes */
67 int i_scale_count; /* scale modulo counter */
68 int i_chroma_width; /* chroma width, not used */
69 u8 * p_gray; /* base conversion table */
70 u8 * p_pic_start; /* beginning of the current line for copy */
71 u8 * p_buffer_start; /* conversion buffer start */
72 u8 * p_buffer; /* conversion buffer pointer */
73 int * p_offset_start; /* offset array start */
74 int * p_offset; /* offset array pointer */
77 * Initialize some values - i_pic_line_width will store the line skip
79 i_pic_line_width -= i_pic_width;
80 p_gray = p_vout->yuv.yuv.p_gray8;
81 p_buffer_start = p_vout->yuv.p_buffer;
82 p_offset_start = p_vout->yuv.p_offset;
83 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
84 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
89 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
90 for( i_y = 0; i_y < i_height; i_y++ )
92 /* Mark beginnning of line for possible later line copy, and initialize
95 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
97 /* Do YUV conversion to buffer - YUV picture is always formed of 16
98 * pixels wide blocks */
99 for( i_x = i_width / 16; i_x--; )
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++ ];
107 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
108 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
111 /* Do horizontal and vertical scaling */
113 SCALE_HEIGHT(400, 1);
117 /*****************************************************************************
118 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
119 *****************************************************************************/
120 void _M( ConvertYUV420RGB8 )( YUV_ARGS_8BPP )
122 boolean_t b_horizontal_scaling; /* horizontal scaling type */
123 int i_vertical_scaling; /* vertical scaling type */
124 int i_x, i_y; /* horizontal and vertical indexes */
125 int i_scale_count; /* scale modulo counter */
126 int i_real_y; /* y % 4 */
127 u8 * p_lookup; /* lookup table */
128 int i_chroma_width; /* chroma width */
129 int * p_offset_start; /* offset array start */
130 int * p_offset; /* offset array pointer */
133 * The dithering matrices
135 static int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
136 static int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
137 static int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
138 static int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
140 static int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
141 static int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
142 static int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
143 static int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
146 * Initialize some values - i_pic_line_width will store the line skip
148 i_pic_line_width -= i_pic_width;
149 i_chroma_width = i_width / 2;
150 p_offset_start = p_vout->yuv.p_offset;
151 p_lookup = p_vout->yuv.p_base;
152 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
153 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 1 );
158 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
160 for( i_y = 0; i_y < i_height; i_y++ )
162 /* Do horizontal and vertical scaling */
163 SCALE_WIDTH_DITHER( 420 );
164 SCALE_HEIGHT_DITHER( 420 );
168 /*****************************************************************************
169 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
170 *****************************************************************************/
171 void _M( ConvertYUV422RGB8 )( YUV_ARGS_8BPP )
173 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 8" );
176 /*****************************************************************************
177 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
178 *****************************************************************************/
179 void _M( ConvertYUV444RGB8 )( YUV_ARGS_8BPP )
181 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 8" );
184 /*****************************************************************************
185 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
186 *****************************************************************************/
187 void _M( ConvertY4Gray16 )( YUV_ARGS_16BPP )
189 boolean_t b_horizontal_scaling; /* horizontal scaling type */
190 int i_vertical_scaling; /* vertical scaling type */
191 int i_x, i_y; /* horizontal and vertical indexes */
192 int i_scale_count; /* scale modulo counter */
193 int i_chroma_width; /* chroma width, not used */
194 u16 * p_gray; /* base conversion table */
195 u16 * p_pic_start; /* beginning of the current line for copy */
196 u16 * p_buffer_start; /* conversion buffer start */
197 u16 * p_buffer; /* conversion buffer pointer */
198 int * p_offset_start; /* offset array start */
199 int * p_offset; /* offset array pointer */
202 * Initialize some values - i_pic_line_width will store the line skip
204 i_pic_line_width -= i_pic_width;
205 p_gray = p_vout->yuv.yuv.p_gray16;
206 p_buffer_start = p_vout->yuv.p_buffer;
207 p_offset_start = p_vout->yuv.p_offset;
208 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
209 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
214 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
215 for( i_y = 0; i_y < i_height; i_y++ )
217 /* Mark beginnning of line for possible later line copy, and initialize
220 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
222 /* Do YUV conversion to buffer - YUV picture is always formed of 16
223 * pixels wide blocks */
224 for( i_x = i_width / 16; i_x--; )
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++ ];
232 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
233 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
236 /* Do horizontal and vertical scaling */
238 SCALE_HEIGHT(400, 2);
242 /*****************************************************************************
243 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
244 *****************************************************************************/
245 void _M( ConvertYUV420RGB16 )( YUV_ARGS_16BPP )
247 boolean_t b_horizontal_scaling; /* horizontal scaling type */
248 int i_vertical_scaling; /* vertical scaling type */
249 int i_x, i_y; /* horizontal and vertical indexes */
250 int i_scale_count; /* scale modulo counter */
251 int i_uval, i_vval; /* U and V samples */
252 int i_red, i_green, i_blue; /* U and V modified samples */
253 int i_chroma_width; /* chroma width */
254 u16 * p_yuv; /* base conversion table */
255 u16 * p_ybase; /* Y dependant conversion table */
256 u16 * p_pic_start; /* beginning of the current line for copy */
257 u16 * p_buffer_start; /* conversion buffer start */
258 u16 * p_buffer; /* conversion buffer pointer */
259 int * p_offset_start; /* offset array start */
260 int * p_offset; /* offset array pointer */
263 * Initialize some values - i_pic_line_width will store the line skip
265 i_pic_line_width -= i_pic_width;
266 i_chroma_width = i_width / 2;
267 p_yuv = p_vout->yuv.yuv.p_rgb16;
268 p_buffer_start = p_vout->yuv.p_buffer;
269 p_offset_start = p_vout->yuv.p_offset;
270 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
271 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
276 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
277 for( i_y = 0; i_y < i_height; i_y++ )
279 /* Mark beginnning of line for possible later line copy, and initialize
282 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
284 /* Do YUV conversion to buffer - YUV picture is always formed of 16
285 * pixels wide blocks */
286 for( i_x = i_width / 16; i_x--; )
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);
294 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
295 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
298 /* Do horizontal and vertical scaling */
300 SCALE_HEIGHT(420, 2);
304 /*****************************************************************************
305 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
306 *****************************************************************************/
307 void _M( ConvertYUV422RGB16 )( YUV_ARGS_16BPP )
309 boolean_t b_horizontal_scaling; /* horizontal scaling type */
310 int i_vertical_scaling; /* vertical scaling type */
311 int i_x, i_y; /* horizontal and vertical indexes */
312 int i_scale_count; /* scale modulo counter */
313 int i_uval, i_vval; /* U and V samples */
314 int i_red, i_green, i_blue; /* U and V modified samples */
315 int i_chroma_width; /* chroma width */
316 u16 * p_yuv; /* base conversion table */
317 u16 * p_ybase; /* Y dependant conversion table */
318 u16 * p_pic_start; /* beginning of the current line for copy */
319 u16 * p_buffer_start; /* conversion buffer start */
320 u16 * p_buffer; /* conversion buffer pointer */
321 int * p_offset_start; /* offset array start */
322 int * p_offset; /* offset array pointer */
325 * Initialize some values - i_pic_line_width will store the line skip
327 i_pic_line_width -= i_pic_width;
328 i_chroma_width = i_width / 2;
329 p_yuv = p_vout->yuv.yuv.p_rgb16;
330 p_buffer_start = p_vout->yuv.p_buffer;
331 p_offset_start = p_vout->yuv.p_offset;
332 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
333 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
338 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
339 for( i_y = 0; i_y < i_height; i_y++ )
341 /* Mark beginnning of line for possible later line copy, and initialize
344 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
346 /* Do YUV conversion to buffer - YUV picture is always formed of 16
347 * pixels wide blocks */
348 for( i_x = i_width / 16; i_x--; )
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);
356 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
357 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
360 /* Do horizontal and vertical scaling */
362 SCALE_HEIGHT(422, 2);
366 /*****************************************************************************
367 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
368 *****************************************************************************/
369 void _M( ConvertYUV444RGB16 )( YUV_ARGS_16BPP )
371 boolean_t b_horizontal_scaling; /* horizontal scaling type */
372 int i_vertical_scaling; /* vertical scaling type */
373 int i_x, i_y; /* horizontal and vertical indexes */
374 int i_scale_count; /* scale modulo counter */
375 int i_uval, i_vval; /* U and V samples */
376 int i_red, i_green, i_blue; /* U and V modified samples */
377 int i_chroma_width; /* chroma width, not used */
378 u16 * p_yuv; /* base conversion table */
379 u16 * p_ybase; /* Y dependant conversion table */
380 u16 * p_pic_start; /* beginning of the current line for copy */
381 u16 * p_buffer_start; /* conversion buffer start */
382 u16 * p_buffer; /* conversion buffer pointer */
383 int * p_offset_start; /* offset array start */
384 int * p_offset; /* offset array pointer */
387 * Initialize some values - i_pic_line_width will store the line skip
389 i_pic_line_width -= i_pic_width;
390 p_yuv = p_vout->yuv.yuv.p_rgb16;
391 p_buffer_start = p_vout->yuv.p_buffer;
392 p_offset_start = p_vout->yuv.p_offset;
393 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
394 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
399 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
400 for( i_y = 0; i_y < i_height; i_y++ )
402 /* Mark beginnning of line for possible later line copy, and initialize
405 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
407 /* Do YUV conversion to buffer - YUV picture is always formed of 16
408 * pixels wide blocks */
409 for( i_x = i_width / 16; i_x--; )
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);
417 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
418 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
421 /* Do horizontal and vertical scaling */
423 SCALE_HEIGHT(444, 2);
427 /*****************************************************************************
428 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
429 *****************************************************************************/
430 void _M( ConvertY4Gray24 )( YUV_ARGS_24BPP )
432 intf_ErrMsg( "yuv error: unhandled function, grayscale, bpp = 24" );
435 /*****************************************************************************
436 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
437 *****************************************************************************/
438 void _M( ConvertYUV420RGB24 )( YUV_ARGS_24BPP )
440 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, bpp = 24" );
443 /*****************************************************************************
444 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
445 *****************************************************************************/
446 void _M( ConvertYUV422RGB24 )( YUV_ARGS_24BPP )
448 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 24" );
451 /*****************************************************************************
452 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
453 *****************************************************************************/
454 void _M( ConvertYUV444RGB24 )( YUV_ARGS_24BPP )
456 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 24" );
459 /*****************************************************************************
460 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
461 *****************************************************************************/
462 void _M( ConvertY4Gray32 )( YUV_ARGS_32BPP )
464 boolean_t b_horizontal_scaling; /* horizontal scaling type */
465 int i_vertical_scaling; /* vertical scaling type */
466 int i_x, i_y; /* horizontal and vertical indexes */
467 int i_scale_count; /* scale modulo counter */
468 int i_chroma_width; /* chroma width, not used */
469 u32 * p_gray; /* base conversion table */
470 u32 * p_pic_start; /* beginning of the current line for copy */
471 u32 * p_buffer_start; /* conversion buffer start */
472 u32 * p_buffer; /* conversion buffer pointer */
473 int * p_offset_start; /* offset array start */
474 int * p_offset; /* offset array pointer */
477 * Initialize some values - i_pic_line_width will store the line skip
479 i_pic_line_width -= i_pic_width;
480 p_gray = p_vout->yuv.yuv.p_gray32;
481 p_buffer_start = p_vout->yuv.p_buffer;
482 p_offset_start = p_vout->yuv.p_offset;
483 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
484 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
489 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
490 for( i_y = 0; i_y < i_height; i_y++ )
492 /* Mark beginnning of line for possible later line copy, and initialize
495 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
497 /* Do YUV conversion to buffer - YUV picture is always formed of 16
498 * pixels wide blocks */
499 for( i_x = i_width / 16; i_x--; )
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++ ];
507 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
508 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
511 /* Do horizontal and vertical scaling */
513 SCALE_HEIGHT(400, 4);
517 /*****************************************************************************
518 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
519 *****************************************************************************/
520 void _M( ConvertYUV420RGB32 )( YUV_ARGS_32BPP )
522 boolean_t b_horizontal_scaling; /* horizontal scaling type */
523 int i_vertical_scaling; /* vertical scaling type */
524 int i_x, i_y; /* horizontal and vertical indexes */
525 int i_scale_count; /* scale modulo counter */
526 int i_uval, i_vval; /* U and V samples */
527 int i_red, i_green, i_blue; /* U and V modified samples */
528 int i_chroma_width; /* chroma width */
529 u32 * p_yuv; /* base conversion table */
530 u32 * p_ybase; /* Y dependant conversion table */
531 u32 * p_pic_start; /* beginning of the current line for copy */
532 u32 * p_buffer_start; /* conversion buffer start */
533 u32 * p_buffer; /* conversion buffer pointer */
534 int * p_offset_start; /* offset array start */
535 int * p_offset; /* offset array pointer */
538 * Initialize some values - i_pic_line_width will store the line skip
540 i_pic_line_width -= i_pic_width;
541 i_chroma_width = i_width / 2;
542 p_yuv = p_vout->yuv.yuv.p_rgb32;
543 p_buffer_start = p_vout->yuv.p_buffer;
544 p_offset_start = p_vout->yuv.p_offset;
545 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
546 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
551 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
552 for( i_y = 0; i_y < i_height; i_y++ )
554 /* Mark beginnning of line for possible later line copy, and initialize
557 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
559 /* Do YUV conversion to buffer - YUV picture is always formed of 16
560 * pixels wide blocks */
561 for( i_x = i_width / 16; i_x--; )
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);
569 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
570 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
573 /* Do horizontal and vertical scaling */
575 SCALE_HEIGHT(420, 4);
579 /*****************************************************************************
580 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
581 *****************************************************************************/
582 void _M( ConvertYUV422RGB32 )( YUV_ARGS_32BPP )
584 boolean_t b_horizontal_scaling; /* horizontal scaling type */
585 int i_vertical_scaling; /* vertical scaling type */
586 int i_x, i_y; /* horizontal and vertical indexes */
587 int i_scale_count; /* scale modulo counter */
588 int i_uval, i_vval; /* U and V samples */
589 int i_red, i_green, i_blue; /* U and V modified samples */
590 int i_chroma_width; /* chroma width */
591 u32 * p_yuv; /* base conversion table */
592 u32 * p_ybase; /* Y dependant conversion table */
593 u32 * p_pic_start; /* beginning of the current line for copy */
594 u32 * p_buffer_start; /* conversion buffer start */
595 u32 * p_buffer; /* conversion buffer pointer */
596 int * p_offset_start; /* offset array start */
597 int * p_offset; /* offset array pointer */
600 * Initialize some values - i_pic_line_width will store the line skip
602 i_pic_line_width -= i_pic_width;
603 i_chroma_width = i_width / 2;
604 p_yuv = p_vout->yuv.yuv.p_rgb32;
605 p_buffer_start = p_vout->yuv.p_buffer;
606 p_offset_start = p_vout->yuv.p_offset;
607 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
608 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
613 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
614 for( i_y = 0; i_y < i_height; i_y++ )
616 /* Mark beginnning of line for possible later line copy, and initialize
619 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
621 /* Do YUV conversion to buffer - YUV picture is always formed of 16
622 * pixels wide blocks */
623 for( i_x = i_width / 16; i_x--; )
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);
631 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
632 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
635 /* Do horizontal and vertical scaling */
637 SCALE_HEIGHT(422, 4);
641 /*****************************************************************************
642 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
643 *****************************************************************************/
644 void _M( ConvertYUV444RGB32 )( YUV_ARGS_32BPP )
646 boolean_t b_horizontal_scaling; /* horizontal scaling type */
647 int i_vertical_scaling; /* vertical scaling type */
648 int i_x, i_y; /* horizontal and vertical indexes */
649 int i_scale_count; /* scale modulo counter */
650 int i_uval, i_vval; /* U and V samples */
651 int i_red, i_green, i_blue; /* U and V modified samples */
652 int i_chroma_width; /* chroma width, not used */
653 u32 * p_yuv; /* base conversion table */
654 u32 * p_ybase; /* Y dependant conversion table */
655 u32 * p_pic_start; /* beginning of the current line for copy */
656 u32 * p_buffer_start; /* conversion buffer start */
657 u32 * p_buffer; /* conversion buffer pointer */
658 int * p_offset_start; /* offset array start */
659 int * p_offset; /* offset array pointer */
662 * Initialize some values - i_pic_line_width will store the line skip
664 i_pic_line_width -= i_pic_width;
665 p_yuv = p_vout->yuv.yuv.p_rgb32;
666 p_buffer_start = p_vout->yuv.p_buffer;
667 p_offset_start = p_vout->yuv.p_offset;
668 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
669 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
674 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
675 for( i_y = 0; i_y < i_height; i_y++ )
677 /* Mark beginnning of line for possible later line copy, and initialize
680 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
682 /* Do YUV conversion to buffer - YUV picture is always formed of 16
683 * pixels wide blocks */
684 for( i_x = i_width / 16; i_x--; )
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);
692 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
693 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
696 /* Do horizontal and vertical scaling */
698 SCALE_HEIGHT(444, 4);
702 static __inline__ void yuv2YCbCr422_inner( u8 *p_y, u8 *p_u, u8 *p_v,
703 u8 *p_out, int i_width_by_4 )
707 for( i_x = 0 ; i_x < 4 * i_width_by_4 ; ++i_x )
709 *p_out++ = p_y[ 2 * i_x ];
710 *p_out++ = p_u[ i_x ];
711 *p_out++ = p_y[ 2 * i_x + 1 ];
712 *p_out++ = p_v[ i_x ];
716 void _M( ConvertYUV420YCbr8 )( YUV_ARGS_8BPP )
718 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 8" );
721 void _M( ConvertYUV422YCbr8 )( YUV_ARGS_8BPP )
723 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 8" );
727 void _M( ConvertYUV444YCbr8 )( YUV_ARGS_8BPP )
729 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 8" );
733 /*****************************************************************************
734 * yuv2YCbCr422: color YUV 4:2:0 to color YCbCr 16bpp
735 *****************************************************************************/
736 void _M( ConvertYUV420YCbr16 )( YUV_ARGS_16BPP )
740 for( i_y = 0 ; i_y < i_height ; ++i_y )
742 yuv2YCbCr422_inner( p_y, p_u, p_v, (u8 *)p_pic, i_width / 8 );
744 p_pic += i_width * 2;
756 void _M( ConvertYUV422YCbr16 )( YUV_ARGS_16BPP )
758 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 16" );
761 void _M( ConvertYUV444YCbr16 )( YUV_ARGS_16BPP )
763 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 16" );
767 void _M( ConvertYUV420YCbr24 )( YUV_ARGS_24BPP )
769 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 24" );
773 void _M( ConvertYUV422YCbr24 )( YUV_ARGS_24BPP )
775 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 24" );
779 void _M( ConvertYUV444YCbr24 )( YUV_ARGS_24BPP )
781 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 24" );
785 void _M( ConvertYUV420YCbr32 )( YUV_ARGS_32BPP )
787 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 32" );
791 void _M( ConvertYUV422YCbr32 )( YUV_ARGS_32BPP )
793 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 32" );
796 void _M( ConvertYUV444YCbr32 )( YUV_ARGS_32BPP )
798 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 32" );