1 /*****************************************************************************
2 * transforms_yuv.c: C YUV transformation functions
3 * Provides functions to perform the YUV conversion. The functions provided here
4 * are a complete and portable C implementation, and may be replaced in certain
5 * case by optimized functions.
6 *****************************************************************************
7 * Copyright (C) 1999, 2000 VideoLAN
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public
22 * License along with this program; if not, write to the
23 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 * Boston, MA 02111-1307, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
32 #include <math.h> /* exp(), pow() */
33 #include <errno.h> /* ENOMEM */
34 #include <stdlib.h> /* free() */
35 #include <string.h> /* strerror() */
44 #include "video_output.h"
46 #include "video_common.h"
47 #include "transforms_common.h"
48 #include "transforms_yuv.h"
52 /*****************************************************************************
53 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
54 *****************************************************************************/
55 void ConvertY4Gray8( YUV_ARGS_8BPP )
57 boolean_t b_horizontal_scaling; /* horizontal scaling type */
58 int i_vertical_scaling; /* vertical scaling type */
59 int i_x, i_y; /* horizontal and vertical indexes */
60 int i_scale_count; /* scale modulo counter */
61 int i_chroma_width; /* chroma width, not used */
62 u8 * p_gray; /* base conversion table */
63 u8 * p_pic_start; /* beginning of the current line for copy */
64 u8 * p_buffer_start; /* conversion buffer start */
65 u8 * p_buffer; /* conversion buffer pointer */
66 int * p_offset_start; /* offset array start */
67 int * p_offset; /* offset array pointer */
70 * Initialize some values - i_pic_line_width will store the line skip
72 i_pic_line_width -= i_pic_width;
73 p_gray = p_vout->yuv.yuv.p_gray8;
74 p_buffer_start = p_vout->yuv.p_buffer;
75 p_offset_start = p_vout->yuv.p_offset;
76 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
77 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
82 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
83 for( i_y = 0; i_y < i_height; i_y++ )
85 /* Mark beginnning of line for possible later line copy, and initialize
88 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
90 /* Do YUV conversion to buffer - YUV picture is always formed of 16
91 * pixels wide blocks */
92 for( i_x = i_width / 16; i_x--; )
94 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
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++ ];
104 /* Do horizontal and vertical scaling */
106 SCALE_HEIGHT(400, 1);
110 /*****************************************************************************
111 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
112 *****************************************************************************/
113 void ConvertYUV420RGB8( YUV_ARGS_8BPP )
115 boolean_t b_horizontal_scaling; /* horizontal scaling type */
116 int i_vertical_scaling; /* vertical scaling type */
117 int i_x, i_y; /* horizontal and vertical indexes */
118 int i_scale_count; /* scale modulo counter */
119 int i_real_y; /* y % 4 */
120 u8 * p_lookup; /* lookup table */
121 int i_chroma_width; /* chroma width */
122 int * p_offset_start; /* offset array start */
123 int * p_offset; /* offset array pointer */
126 * The dithering matrices
128 static int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
129 static int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
130 static int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
131 static int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
133 static int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
134 static int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
135 static int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
136 static int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
139 * Initialize some values - i_pic_line_width will store the line skip
141 i_pic_line_width -= i_pic_width;
142 i_chroma_width = i_width / 2;
143 p_offset_start = p_vout->yuv.p_offset;
144 p_lookup = p_vout->yuv.p_base;
145 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
146 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 1 );
151 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
153 for( i_y = 0; i_y < i_height; i_y++ )
155 /* Do horizontal and vertical scaling */
156 SCALE_WIDTH_DITHER( 420 );
157 SCALE_HEIGHT_DITHER( 420 );
161 /*****************************************************************************
162 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
163 *****************************************************************************/
164 void ConvertYUV422RGB8( YUV_ARGS_8BPP )
166 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 8" );
169 /*****************************************************************************
170 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
171 *****************************************************************************/
172 void ConvertYUV444RGB8( YUV_ARGS_8BPP )
174 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 8" );
177 /*****************************************************************************
178 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
179 *****************************************************************************/
180 void ConvertY4Gray16( YUV_ARGS_16BPP )
182 boolean_t b_horizontal_scaling; /* horizontal scaling type */
183 int i_vertical_scaling; /* vertical scaling type */
184 int i_x, i_y; /* horizontal and vertical indexes */
185 int i_scale_count; /* scale modulo counter */
186 int i_chroma_width; /* chroma width, not used */
187 u16 * p_gray; /* base conversion table */
188 u16 * p_pic_start; /* beginning of the current line for copy */
189 u16 * p_buffer_start; /* conversion buffer start */
190 u16 * p_buffer; /* conversion buffer pointer */
191 int * p_offset_start; /* offset array start */
192 int * p_offset; /* offset array pointer */
195 * Initialize some values - i_pic_line_width will store the line skip
197 i_pic_line_width -= i_pic_width;
198 p_gray = p_vout->yuv.yuv.p_gray16;
199 p_buffer_start = p_vout->yuv.p_buffer;
200 p_offset_start = p_vout->yuv.p_offset;
201 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
202 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
207 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
208 for( i_y = 0; i_y < i_height; i_y++ )
210 /* Mark beginnning of line for possible later line copy, and initialize
213 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
215 /* Do YUV conversion to buffer - YUV picture is always formed of 16
216 * pixels wide blocks */
217 for( i_x = i_width / 16; i_x--; )
219 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
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++ ];
229 /* Do horizontal and vertical scaling */
231 SCALE_HEIGHT(400, 2);
235 /*****************************************************************************
236 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
237 *****************************************************************************/
238 void ConvertYUV420RGB16( YUV_ARGS_16BPP )
240 boolean_t b_horizontal_scaling; /* horizontal scaling type */
241 int i_vertical_scaling; /* vertical scaling type */
242 int i_x, i_y; /* horizontal and vertical indexes */
243 int i_scale_count; /* scale modulo counter */
244 int i_uval, i_vval; /* U and V samples */
245 int i_red, i_green, i_blue; /* U and V modified samples */
246 int i_chroma_width; /* chroma width */
247 u16 * p_yuv; /* base conversion table */
248 u16 * p_ybase; /* Y dependant conversion table */
249 u16 * p_pic_start; /* beginning of the current line for copy */
250 u16 * p_buffer_start; /* conversion buffer start */
251 u16 * p_buffer; /* conversion buffer pointer */
252 int * p_offset_start; /* offset array start */
253 int * p_offset; /* offset array pointer */
256 * Initialize some values - i_pic_line_width will store the line skip
258 i_pic_line_width -= i_pic_width;
259 i_chroma_width = i_width / 2;
260 p_yuv = p_vout->yuv.yuv.p_rgb16;
261 p_buffer_start = p_vout->yuv.p_buffer;
262 p_offset_start = p_vout->yuv.p_offset;
263 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
264 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
269 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
270 for( i_y = 0; i_y < i_height; i_y++ )
272 /* Mark beginnning of line for possible later line copy, and initialize
275 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
277 /* Do YUV conversion to buffer - YUV picture is always formed of 16
278 * pixels wide blocks */
279 for( i_x = i_width / 16; i_x--; )
281 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
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);
291 /* Do horizontal and vertical scaling */
293 SCALE_HEIGHT(420, 2);
297 /*****************************************************************************
298 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
299 *****************************************************************************/
300 void ConvertYUV422RGB16( YUV_ARGS_16BPP )
302 boolean_t b_horizontal_scaling; /* horizontal scaling type */
303 int i_vertical_scaling; /* vertical scaling type */
304 int i_x, i_y; /* horizontal and vertical indexes */
305 int i_scale_count; /* scale modulo counter */
306 int i_uval, i_vval; /* U and V samples */
307 int i_red, i_green, i_blue; /* U and V modified samples */
308 int i_chroma_width; /* chroma width */
309 u16 * p_yuv; /* base conversion table */
310 u16 * p_ybase; /* Y dependant conversion table */
311 u16 * p_pic_start; /* beginning of the current line for copy */
312 u16 * p_buffer_start; /* conversion buffer start */
313 u16 * p_buffer; /* conversion buffer pointer */
314 int * p_offset_start; /* offset array start */
315 int * p_offset; /* offset array pointer */
318 * Initialize some values - i_pic_line_width will store the line skip
320 i_pic_line_width -= i_pic_width;
321 i_chroma_width = i_width / 2;
322 p_yuv = p_vout->yuv.yuv.p_rgb16;
323 p_buffer_start = p_vout->yuv.p_buffer;
324 p_offset_start = p_vout->yuv.p_offset;
325 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
326 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
331 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
332 for( i_y = 0; i_y < i_height; i_y++ )
334 /* Mark beginnning of line for possible later line copy, and initialize
337 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
339 /* Do YUV conversion to buffer - YUV picture is always formed of 16
340 * pixels wide blocks */
341 for( i_x = i_width / 16; i_x--; )
343 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
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);
353 /* Do horizontal and vertical scaling */
355 SCALE_HEIGHT(422, 2);
359 /*****************************************************************************
360 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
361 *****************************************************************************/
362 void ConvertYUV444RGB16( YUV_ARGS_16BPP )
364 boolean_t b_horizontal_scaling; /* horizontal scaling type */
365 int i_vertical_scaling; /* vertical scaling type */
366 int i_x, i_y; /* horizontal and vertical indexes */
367 int i_scale_count; /* scale modulo counter */
368 int i_uval, i_vval; /* U and V samples */
369 int i_red, i_green, i_blue; /* U and V modified samples */
370 int i_chroma_width; /* chroma width, not used */
371 u16 * p_yuv; /* base conversion table */
372 u16 * p_ybase; /* Y dependant conversion table */
373 u16 * p_pic_start; /* beginning of the current line for copy */
374 u16 * p_buffer_start; /* conversion buffer start */
375 u16 * p_buffer; /* conversion buffer pointer */
376 int * p_offset_start; /* offset array start */
377 int * p_offset; /* offset array pointer */
380 * Initialize some values - i_pic_line_width will store the line skip
382 i_pic_line_width -= i_pic_width;
383 p_yuv = p_vout->yuv.yuv.p_rgb16;
384 p_buffer_start = p_vout->yuv.p_buffer;
385 p_offset_start = p_vout->yuv.p_offset;
386 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
387 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
392 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
393 for( i_y = 0; i_y < i_height; i_y++ )
395 /* Mark beginnning of line for possible later line copy, and initialize
398 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
400 /* Do YUV conversion to buffer - YUV picture is always formed of 16
401 * pixels wide blocks */
402 for( i_x = i_width / 16; i_x--; )
404 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
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);
414 /* Do horizontal and vertical scaling */
416 SCALE_HEIGHT(444, 2);
420 /*****************************************************************************
421 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
422 *****************************************************************************/
423 void ConvertY4Gray24( YUV_ARGS_24BPP )
425 intf_ErrMsg( "yuv error: unhandled function, grayscale, bpp = 24" );
428 /*****************************************************************************
429 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
430 *****************************************************************************/
431 void ConvertYUV420RGB24( YUV_ARGS_24BPP )
433 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, bpp = 24" );
436 /*****************************************************************************
437 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
438 *****************************************************************************/
439 void ConvertYUV422RGB24( YUV_ARGS_24BPP )
441 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 24" );
444 /*****************************************************************************
445 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
446 *****************************************************************************/
447 void ConvertYUV444RGB24( YUV_ARGS_24BPP )
449 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 24" );
452 /*****************************************************************************
453 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
454 *****************************************************************************/
455 void ConvertY4Gray32( YUV_ARGS_32BPP )
457 boolean_t b_horizontal_scaling; /* horizontal scaling type */
458 int i_vertical_scaling; /* vertical scaling type */
459 int i_x, i_y; /* horizontal and vertical indexes */
460 int i_scale_count; /* scale modulo counter */
461 int i_chroma_width; /* chroma width, not used */
462 u32 * p_gray; /* base conversion table */
463 u32 * p_pic_start; /* beginning of the current line for copy */
464 u32 * p_buffer_start; /* conversion buffer start */
465 u32 * p_buffer; /* conversion buffer pointer */
466 int * p_offset_start; /* offset array start */
467 int * p_offset; /* offset array pointer */
470 * Initialize some values - i_pic_line_width will store the line skip
472 i_pic_line_width -= i_pic_width;
473 p_gray = p_vout->yuv.yuv.p_gray32;
474 p_buffer_start = p_vout->yuv.p_buffer;
475 p_offset_start = p_vout->yuv.p_offset;
476 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
477 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
482 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
483 for( i_y = 0; i_y < i_height; i_y++ )
485 /* Mark beginnning of line for possible later line copy, and initialize
488 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
490 /* Do YUV conversion to buffer - YUV picture is always formed of 16
491 * pixels wide blocks */
492 for( i_x = i_width / 16; i_x--; )
494 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
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++ ];
504 /* Do horizontal and vertical scaling */
506 SCALE_HEIGHT(400, 4);
510 /*****************************************************************************
511 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
512 *****************************************************************************/
513 void ConvertYUV420RGB32( YUV_ARGS_32BPP )
515 boolean_t b_horizontal_scaling; /* horizontal scaling type */
516 int i_vertical_scaling; /* vertical scaling type */
517 int i_x, i_y; /* horizontal and vertical indexes */
518 int i_scale_count; /* scale modulo counter */
519 int i_uval, i_vval; /* U and V samples */
520 int i_red, i_green, i_blue; /* U and V modified samples */
521 int i_chroma_width; /* chroma width */
522 u32 * p_yuv; /* base conversion table */
523 u32 * p_ybase; /* Y dependant conversion table */
524 u32 * p_pic_start; /* beginning of the current line for copy */
525 u32 * p_buffer_start; /* conversion buffer start */
526 u32 * p_buffer; /* conversion buffer pointer */
527 int * p_offset_start; /* offset array start */
528 int * p_offset; /* offset array pointer */
531 * Initialize some values - i_pic_line_width will store the line skip
533 i_pic_line_width -= i_pic_width;
534 i_chroma_width = i_width / 2;
535 p_yuv = p_vout->yuv.yuv.p_rgb32;
536 p_buffer_start = p_vout->yuv.p_buffer;
537 p_offset_start = p_vout->yuv.p_offset;
538 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
539 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
544 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
545 for( i_y = 0; i_y < i_height; i_y++ )
547 /* Mark beginnning of line for possible later line copy, and initialize
550 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
552 /* Do YUV conversion to buffer - YUV picture is always formed of 16
553 * pixels wide blocks */
554 for( i_x = i_width / 16; i_x--; )
556 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
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);
566 /* Do horizontal and vertical scaling */
568 SCALE_HEIGHT(420, 4);
572 /*****************************************************************************
573 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
574 *****************************************************************************/
575 void ConvertYUV422RGB32( YUV_ARGS_32BPP )
577 boolean_t b_horizontal_scaling; /* horizontal scaling type */
578 int i_vertical_scaling; /* vertical scaling type */
579 int i_x, i_y; /* horizontal and vertical indexes */
580 int i_scale_count; /* scale modulo counter */
581 int i_uval, i_vval; /* U and V samples */
582 int i_red, i_green, i_blue; /* U and V modified samples */
583 int i_chroma_width; /* chroma width */
584 u32 * p_yuv; /* base conversion table */
585 u32 * p_ybase; /* Y dependant conversion table */
586 u32 * p_pic_start; /* beginning of the current line for copy */
587 u32 * p_buffer_start; /* conversion buffer start */
588 u32 * p_buffer; /* conversion buffer pointer */
589 int * p_offset_start; /* offset array start */
590 int * p_offset; /* offset array pointer */
593 * Initialize some values - i_pic_line_width will store the line skip
595 i_pic_line_width -= i_pic_width;
596 i_chroma_width = i_width / 2;
597 p_yuv = p_vout->yuv.yuv.p_rgb32;
598 p_buffer_start = p_vout->yuv.p_buffer;
599 p_offset_start = p_vout->yuv.p_offset;
600 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
601 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
606 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
607 for( i_y = 0; i_y < i_height; i_y++ )
609 /* Mark beginnning of line for possible later line copy, and initialize
612 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
614 /* Do YUV conversion to buffer - YUV picture is always formed of 16
615 * pixels wide blocks */
616 for( i_x = i_width / 16; i_x--; )
618 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
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);
628 /* Do horizontal and vertical scaling */
630 SCALE_HEIGHT(422, 4);
634 /*****************************************************************************
635 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
636 *****************************************************************************/
637 void ConvertYUV444RGB32( YUV_ARGS_32BPP )
639 boolean_t b_horizontal_scaling; /* horizontal scaling type */
640 int i_vertical_scaling; /* vertical scaling type */
641 int i_x, i_y; /* horizontal and vertical indexes */
642 int i_scale_count; /* scale modulo counter */
643 int i_uval, i_vval; /* U and V samples */
644 int i_red, i_green, i_blue; /* U and V modified samples */
645 int i_chroma_width; /* chroma width, not used */
646 u32 * p_yuv; /* base conversion table */
647 u32 * p_ybase; /* Y dependant conversion table */
648 u32 * p_pic_start; /* beginning of the current line for copy */
649 u32 * p_buffer_start; /* conversion buffer start */
650 u32 * p_buffer; /* conversion buffer pointer */
651 int * p_offset_start; /* offset array start */
652 int * p_offset; /* offset array pointer */
655 * Initialize some values - i_pic_line_width will store the line skip
657 i_pic_line_width -= i_pic_width;
658 p_yuv = p_vout->yuv.yuv.p_rgb32;
659 p_buffer_start = p_vout->yuv.p_buffer;
660 p_offset_start = p_vout->yuv.p_offset;
661 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
662 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
667 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
668 for( i_y = 0; i_y < i_height; i_y++ )
670 /* Mark beginnning of line for possible later line copy, and initialize
673 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
675 /* Do YUV conversion to buffer - YUV picture is always formed of 16
676 * pixels wide blocks */
677 for( i_x = i_width / 16; i_x--; )
679 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
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);
689 /* Do horizontal and vertical scaling */
691 SCALE_HEIGHT(444, 4);