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.6 2001/06/03 12:47:21 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"
58 #include "modules_export.h"
60 /*****************************************************************************
61 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
62 *****************************************************************************/
63 void _M( ConvertY4Gray8 )( YUV_ARGS_8BPP )
65 boolean_t b_horizontal_scaling; /* horizontal scaling type */
66 int i_vertical_scaling; /* vertical scaling type */
67 int i_x, i_y; /* horizontal and vertical indexes */
68 int i_scale_count; /* scale modulo counter */
69 int i_chroma_width; /* chroma width, not used */
70 u8 * p_gray; /* base conversion table */
71 u8 * p_pic_start; /* beginning of the current line for copy */
72 u8 * p_buffer_start; /* conversion buffer start */
73 u8 * p_buffer; /* conversion buffer pointer */
74 int * p_offset_start; /* offset array start */
75 int * p_offset; /* offset array pointer */
78 * Initialize some values - i_pic_line_width will store the line skip
80 i_pic_line_width -= i_pic_width;
81 p_gray = p_vout->yuv.yuv.p_gray8;
82 p_buffer_start = p_vout->yuv.p_buffer;
83 p_offset_start = p_vout->yuv.p_offset;
84 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
85 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
90 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
91 for( i_y = 0; i_y < i_height; i_y++ )
93 /* Mark beginnning of line for possible later line copy, and initialize
96 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
98 /* Do YUV conversion to buffer - YUV picture is always formed of 16
99 * pixels wide blocks */
100 for( i_x = i_width / 16; i_x--; )
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++ ];
109 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
112 /* Do horizontal and vertical scaling */
114 SCALE_HEIGHT(400, 1);
118 /*****************************************************************************
119 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
120 *****************************************************************************/
121 void _M( ConvertYUV420RGB8 )( YUV_ARGS_8BPP )
123 boolean_t b_horizontal_scaling; /* horizontal scaling type */
124 int i_vertical_scaling; /* vertical scaling type */
125 int i_x, i_y; /* horizontal and vertical indexes */
126 int i_scale_count; /* scale modulo counter */
127 int i_real_y; /* y % 4 */
128 u8 * p_lookup; /* lookup table */
129 int i_chroma_width; /* chroma width */
130 int * p_offset_start; /* offset array start */
131 int * p_offset; /* offset array pointer */
134 * The dithering matrices
136 static int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
137 static int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
138 static int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
139 static int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
141 static int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
142 static int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
143 static int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
144 static int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
147 * Initialize some values - i_pic_line_width will store the line skip
149 i_pic_line_width -= i_pic_width;
150 i_chroma_width = i_width / 2;
151 p_offset_start = p_vout->yuv.p_offset;
152 p_lookup = p_vout->yuv.p_base;
153 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
154 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 1 );
159 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
161 for( i_y = 0; i_y < i_height; i_y++ )
163 /* Do horizontal and vertical scaling */
164 SCALE_WIDTH_DITHER( 420 );
165 SCALE_HEIGHT_DITHER( 420 );
169 /*****************************************************************************
170 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
171 *****************************************************************************/
172 void _M( ConvertYUV422RGB8 )( YUV_ARGS_8BPP )
174 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 8" );
177 /*****************************************************************************
178 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
179 *****************************************************************************/
180 void _M( ConvertYUV444RGB8 )( YUV_ARGS_8BPP )
182 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 8" );
185 /*****************************************************************************
186 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
187 *****************************************************************************/
188 void _M( ConvertY4Gray16 )( YUV_ARGS_16BPP )
190 boolean_t b_horizontal_scaling; /* horizontal scaling type */
191 int i_vertical_scaling; /* vertical scaling type */
192 int i_x, i_y; /* horizontal and vertical indexes */
193 int i_scale_count; /* scale modulo counter */
194 int i_chroma_width; /* chroma width, not used */
195 u16 * p_gray; /* base conversion table */
196 u16 * p_pic_start; /* beginning of the current line for copy */
197 u16 * p_buffer_start; /* conversion buffer start */
198 u16 * p_buffer; /* conversion buffer pointer */
199 int * p_offset_start; /* offset array start */
200 int * p_offset; /* offset array pointer */
203 * Initialize some values - i_pic_line_width will store the line skip
205 i_pic_line_width -= i_pic_width;
206 p_gray = p_vout->yuv.yuv.p_gray16;
207 p_buffer_start = p_vout->yuv.p_buffer;
208 p_offset_start = p_vout->yuv.p_offset;
209 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
210 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
215 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
216 for( i_y = 0; i_y < i_height; i_y++ )
218 /* Mark beginnning of line for possible later line copy, and initialize
221 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
223 /* Do YUV conversion to buffer - YUV picture is always formed of 16
224 * pixels wide blocks */
225 for( i_x = i_width / 16; i_x--; )
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++ ];
234 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
237 /* Do horizontal and vertical scaling */
239 SCALE_HEIGHT(400, 2);
243 /*****************************************************************************
244 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
245 *****************************************************************************/
246 void _M( ConvertYUV420RGB16 )( YUV_ARGS_16BPP )
248 boolean_t b_horizontal_scaling; /* horizontal scaling type */
249 int i_vertical_scaling; /* vertical scaling type */
250 int i_x, i_y; /* horizontal and vertical indexes */
251 int i_scale_count; /* scale modulo counter */
252 int i_uval, i_vval; /* U and V samples */
253 int i_red, i_green, i_blue; /* U and V modified samples */
254 int i_chroma_width; /* chroma width */
255 u16 * p_yuv; /* base conversion table */
256 u16 * p_ybase; /* Y dependant conversion table */
257 u16 * p_pic_start; /* beginning of the current line for copy */
258 u16 * p_buffer_start; /* conversion buffer start */
259 u16 * p_buffer; /* conversion buffer pointer */
260 int * p_offset_start; /* offset array start */
261 int * p_offset; /* offset array pointer */
264 * Initialize some values - i_pic_line_width will store the line skip
266 i_pic_line_width -= i_pic_width;
267 i_chroma_width = i_width / 2;
268 p_yuv = p_vout->yuv.yuv.p_rgb16;
269 p_buffer_start = p_vout->yuv.p_buffer;
270 p_offset_start = p_vout->yuv.p_offset;
271 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
272 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
277 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
278 for( i_y = 0; i_y < i_height; i_y++ )
280 /* Mark beginnning of line for possible later line copy, and initialize
283 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
285 /* Do YUV conversion to buffer - YUV picture is always formed of 16
286 * pixels wide blocks */
287 for( i_x = i_width / 16; i_x--; )
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);
296 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
299 /* Do horizontal and vertical scaling */
301 SCALE_HEIGHT(420, 2);
305 /*****************************************************************************
306 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
307 *****************************************************************************/
308 void _M( ConvertYUV422RGB16 )( YUV_ARGS_16BPP )
310 boolean_t b_horizontal_scaling; /* horizontal scaling type */
311 int i_vertical_scaling; /* vertical scaling type */
312 int i_x, i_y; /* horizontal and vertical indexes */
313 int i_scale_count; /* scale modulo counter */
314 int i_uval, i_vval; /* U and V samples */
315 int i_red, i_green, i_blue; /* U and V modified samples */
316 int i_chroma_width; /* chroma width */
317 u16 * p_yuv; /* base conversion table */
318 u16 * p_ybase; /* Y dependant conversion table */
319 u16 * p_pic_start; /* beginning of the current line for copy */
320 u16 * p_buffer_start; /* conversion buffer start */
321 u16 * p_buffer; /* conversion buffer pointer */
322 int * p_offset_start; /* offset array start */
323 int * p_offset; /* offset array pointer */
326 * Initialize some values - i_pic_line_width will store the line skip
328 i_pic_line_width -= i_pic_width;
329 i_chroma_width = i_width / 2;
330 p_yuv = p_vout->yuv.yuv.p_rgb16;
331 p_buffer_start = p_vout->yuv.p_buffer;
332 p_offset_start = p_vout->yuv.p_offset;
333 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
334 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
339 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
340 for( i_y = 0; i_y < i_height; i_y++ )
342 /* Mark beginnning of line for possible later line copy, and initialize
345 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
347 /* Do YUV conversion to buffer - YUV picture is always formed of 16
348 * pixels wide blocks */
349 for( i_x = i_width / 16; i_x--; )
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);
358 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
361 /* Do horizontal and vertical scaling */
363 SCALE_HEIGHT(422, 2);
367 /*****************************************************************************
368 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
369 *****************************************************************************/
370 void _M( ConvertYUV444RGB16 )( YUV_ARGS_16BPP )
372 boolean_t b_horizontal_scaling; /* horizontal scaling type */
373 int i_vertical_scaling; /* vertical scaling type */
374 int i_x, i_y; /* horizontal and vertical indexes */
375 int i_scale_count; /* scale modulo counter */
376 int i_uval, i_vval; /* U and V samples */
377 int i_red, i_green, i_blue; /* U and V modified samples */
378 int i_chroma_width; /* chroma width, not used */
379 u16 * p_yuv; /* base conversion table */
380 u16 * p_ybase; /* Y dependant conversion table */
381 u16 * p_pic_start; /* beginning of the current line for copy */
382 u16 * p_buffer_start; /* conversion buffer start */
383 u16 * p_buffer; /* conversion buffer pointer */
384 int * p_offset_start; /* offset array start */
385 int * p_offset; /* offset array pointer */
388 * Initialize some values - i_pic_line_width will store the line skip
390 i_pic_line_width -= i_pic_width;
391 p_yuv = p_vout->yuv.yuv.p_rgb16;
392 p_buffer_start = p_vout->yuv.p_buffer;
393 p_offset_start = p_vout->yuv.p_offset;
394 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
395 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
400 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
401 for( i_y = 0; i_y < i_height; i_y++ )
403 /* Mark beginnning of line for possible later line copy, and initialize
406 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
408 /* Do YUV conversion to buffer - YUV picture is always formed of 16
409 * pixels wide blocks */
410 for( i_x = i_width / 16; i_x--; )
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);
419 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
422 /* Do horizontal and vertical scaling */
424 SCALE_HEIGHT(444, 2);
428 /*****************************************************************************
429 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
430 *****************************************************************************/
431 void _M( ConvertY4Gray24 )( YUV_ARGS_24BPP )
433 intf_ErrMsg( "yuv error: unhandled function, grayscale, bpp = 24" );
436 /*****************************************************************************
437 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
438 *****************************************************************************/
439 void _M( ConvertYUV420RGB24 )( YUV_ARGS_24BPP )
441 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, bpp = 24" );
444 /*****************************************************************************
445 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
446 *****************************************************************************/
447 void _M( ConvertYUV422RGB24 )( YUV_ARGS_24BPP )
449 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 24" );
452 /*****************************************************************************
453 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
454 *****************************************************************************/
455 void _M( ConvertYUV444RGB24 )( YUV_ARGS_24BPP )
457 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 24" );
460 /*****************************************************************************
461 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
462 *****************************************************************************/
463 void _M( ConvertY4Gray32 )( YUV_ARGS_32BPP )
465 boolean_t b_horizontal_scaling; /* horizontal scaling type */
466 int i_vertical_scaling; /* vertical scaling type */
467 int i_x, i_y; /* horizontal and vertical indexes */
468 int i_scale_count; /* scale modulo counter */
469 int i_chroma_width; /* chroma width, not used */
470 u32 * p_gray; /* base conversion table */
471 u32 * p_pic_start; /* beginning of the current line for copy */
472 u32 * p_buffer_start; /* conversion buffer start */
473 u32 * p_buffer; /* conversion buffer pointer */
474 int * p_offset_start; /* offset array start */
475 int * p_offset; /* offset array pointer */
478 * Initialize some values - i_pic_line_width will store the line skip
480 i_pic_line_width -= i_pic_width;
481 p_gray = p_vout->yuv.yuv.p_gray32;
482 p_buffer_start = p_vout->yuv.p_buffer;
483 p_offset_start = p_vout->yuv.p_offset;
484 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
485 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
490 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
491 for( i_y = 0; i_y < i_height; i_y++ )
493 /* Mark beginnning of line for possible later line copy, and initialize
496 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
498 /* Do YUV conversion to buffer - YUV picture is always formed of 16
499 * pixels wide blocks */
500 for( i_x = i_width / 16; i_x--; )
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++ ];
509 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
512 /* Do horizontal and vertical scaling */
514 SCALE_HEIGHT(400, 4);
518 /*****************************************************************************
519 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
520 *****************************************************************************/
521 void _M( ConvertYUV420RGB32 )( YUV_ARGS_32BPP )
523 boolean_t b_horizontal_scaling; /* horizontal scaling type */
524 int i_vertical_scaling; /* vertical scaling type */
525 int i_x, i_y; /* horizontal and vertical indexes */
526 int i_scale_count; /* scale modulo counter */
527 int i_uval, i_vval; /* U and V samples */
528 int i_red, i_green, i_blue; /* U and V modified samples */
529 int i_chroma_width; /* chroma width */
530 u32 * p_yuv; /* base conversion table */
531 u32 * p_ybase; /* Y dependant conversion table */
532 u32 * p_pic_start; /* beginning of the current line for copy */
533 u32 * p_buffer_start; /* conversion buffer start */
534 u32 * p_buffer; /* conversion buffer pointer */
535 int * p_offset_start; /* offset array start */
536 int * p_offset; /* offset array pointer */
539 * Initialize some values - i_pic_line_width will store the line skip
541 i_pic_line_width -= i_pic_width;
542 i_chroma_width = i_width / 2;
543 p_yuv = p_vout->yuv.yuv.p_rgb32;
544 p_buffer_start = p_vout->yuv.p_buffer;
545 p_offset_start = p_vout->yuv.p_offset;
546 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
547 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
552 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
553 for( i_y = 0; i_y < i_height; i_y++ )
555 /* Mark beginnning of line for possible later line copy, and initialize
558 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
560 /* Do YUV conversion to buffer - YUV picture is always formed of 16
561 * pixels wide blocks */
562 for( i_x = i_width / 16; i_x--; )
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);
571 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
574 /* Do horizontal and vertical scaling */
576 SCALE_HEIGHT(420, 4);
580 /*****************************************************************************
581 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
582 *****************************************************************************/
583 void _M( ConvertYUV422RGB32 )( YUV_ARGS_32BPP )
585 boolean_t b_horizontal_scaling; /* horizontal scaling type */
586 int i_vertical_scaling; /* vertical scaling type */
587 int i_x, i_y; /* horizontal and vertical indexes */
588 int i_scale_count; /* scale modulo counter */
589 int i_uval, i_vval; /* U and V samples */
590 int i_red, i_green, i_blue; /* U and V modified samples */
591 int i_chroma_width; /* chroma width */
592 u32 * p_yuv; /* base conversion table */
593 u32 * p_ybase; /* Y dependant conversion table */
594 u32 * p_pic_start; /* beginning of the current line for copy */
595 u32 * p_buffer_start; /* conversion buffer start */
596 u32 * p_buffer; /* conversion buffer pointer */
597 int * p_offset_start; /* offset array start */
598 int * p_offset; /* offset array pointer */
601 * Initialize some values - i_pic_line_width will store the line skip
603 i_pic_line_width -= i_pic_width;
604 i_chroma_width = i_width / 2;
605 p_yuv = p_vout->yuv.yuv.p_rgb32;
606 p_buffer_start = p_vout->yuv.p_buffer;
607 p_offset_start = p_vout->yuv.p_offset;
608 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
609 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
614 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
615 for( i_y = 0; i_y < i_height; i_y++ )
617 /* Mark beginnning of line for possible later line copy, and initialize
620 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
622 /* Do YUV conversion to buffer - YUV picture is always formed of 16
623 * pixels wide blocks */
624 for( i_x = i_width / 16; i_x--; )
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);
633 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
636 /* Do horizontal and vertical scaling */
638 SCALE_HEIGHT(422, 4);
642 /*****************************************************************************
643 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
644 *****************************************************************************/
645 void _M( ConvertYUV444RGB32 )( YUV_ARGS_32BPP )
647 boolean_t b_horizontal_scaling; /* horizontal scaling type */
648 int i_vertical_scaling; /* vertical scaling type */
649 int i_x, i_y; /* horizontal and vertical indexes */
650 int i_scale_count; /* scale modulo counter */
651 int i_uval, i_vval; /* U and V samples */
652 int i_red, i_green, i_blue; /* U and V modified samples */
653 int i_chroma_width; /* chroma width, not used */
654 u32 * p_yuv; /* base conversion table */
655 u32 * p_ybase; /* Y dependant conversion table */
656 u32 * p_pic_start; /* beginning of the current line for copy */
657 u32 * p_buffer_start; /* conversion buffer start */
658 u32 * p_buffer; /* conversion buffer pointer */
659 int * p_offset_start; /* offset array start */
660 int * p_offset; /* offset array pointer */
663 * Initialize some values - i_pic_line_width will store the line skip
665 i_pic_line_width -= i_pic_width;
666 p_yuv = p_vout->yuv.yuv.p_rgb32;
667 p_buffer_start = p_vout->yuv.p_buffer;
668 p_offset_start = p_vout->yuv.p_offset;
669 _M( SetOffset )( i_width, i_height, i_pic_width, i_pic_height,
670 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
675 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
676 for( i_y = 0; i_y < i_height; i_y++ )
678 /* Mark beginnning of line for possible later line copy, and initialize
681 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
683 /* Do YUV conversion to buffer - YUV picture is always formed of 16
684 * pixels wide blocks */
685 for( i_x = i_width / 16; i_x--; )
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);
694 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
697 /* Do horizontal and vertical scaling */
699 SCALE_HEIGHT(444, 4);
703 static __inline__ void yuv2YCbCr422_inner( u8 *p_y, u8 *p_u, u8 *p_v,
704 u8 *p_out, int i_width_by_4 )
708 for( i_x = 0 ; i_x < 4 * i_width_by_4 ; ++i_x )
710 *p_out++ = p_y[ 2 * i_x ];
711 *p_out++ = p_u[ i_x ];
712 *p_out++ = p_y[ 2 * i_x + 1 ];
713 *p_out++ = p_v[ i_x ];
717 void _M( ConvertYUV420YCbr8 )( YUV_ARGS_8BPP )
719 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 8" );
722 void _M( ConvertYUV422YCbr8 )( YUV_ARGS_8BPP )
724 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 8" );
728 void _M( ConvertYUV444YCbr8 )( YUV_ARGS_8BPP )
730 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 8" );
734 /*****************************************************************************
735 * yuv2YCbCr422: color YUV 4:2:0 to color YCbCr 16bpp
736 *****************************************************************************/
737 void _M( ConvertYUV420YCbr16 )( YUV_ARGS_16BPP )
741 for( i_y = 0 ; i_y < i_height ; ++i_y )
743 yuv2YCbCr422_inner( p_y, p_u, p_v, (u8 *)p_pic, i_width / 8 );
745 p_pic += i_width * 2;
757 void _M( ConvertYUV422YCbr16 )( YUV_ARGS_16BPP )
759 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 16" );
762 void _M( ConvertYUV444YCbr16 )( YUV_ARGS_16BPP )
764 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 16" );
768 void _M( ConvertYUV420YCbr24 )( YUV_ARGS_24BPP )
770 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 24" );
774 void _M( ConvertYUV422YCbr24 )( YUV_ARGS_24BPP )
776 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 24" );
780 void _M( ConvertYUV444YCbr24 )( YUV_ARGS_24BPP )
782 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 24" );
786 void _M( ConvertYUV420YCbr32 )( YUV_ARGS_32BPP )
788 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, YCbr = 32" );
792 void _M( ConvertYUV422YCbr32 )( YUV_ARGS_32BPP )
794 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, YCbr = 32" );
797 void _M( ConvertYUV444YCbr32 )( YUV_ARGS_32BPP )
799 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, YCbr = 32" );