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() */
43 #include "video_output.h"
45 #include "video_common.h"
46 #include "transforms_common.h"
47 #include "transforms_yuv.h"
51 /*****************************************************************************
52 * ConvertY4Gray8: grayscale YUV 4:x:x to RGB 8 bpp
53 *****************************************************************************/
54 void ConvertY4Gray8( YUV_ARGS_8BPP )
56 boolean_t b_horizontal_scaling; /* horizontal scaling type */
57 int i_vertical_scaling; /* vertical scaling type */
58 int i_x, i_y; /* horizontal and vertical indexes */
59 int i_scale_count; /* scale modulo counter */
60 int i_chroma_width; /* chroma width, not used */
61 u8 * p_gray; /* base conversion table */
62 u8 * p_pic_start; /* beginning of the current line for copy */
63 u8 * p_buffer_start; /* conversion buffer start */
64 u8 * p_buffer; /* conversion buffer pointer */
65 int * p_offset_start; /* offset array start */
66 int * p_offset; /* offset array pointer */
69 * Initialize some values - i_pic_line_width will store the line skip
71 i_pic_line_width -= i_pic_width;
72 p_gray = p_vout->yuv.yuv.p_gray8;
73 p_buffer_start = p_vout->yuv.p_buffer;
74 p_offset_start = p_vout->yuv.p_offset;
75 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
76 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
81 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
82 for( i_y = 0; i_y < i_height; i_y++ )
84 /* Mark beginnning of line for possible later line copy, and initialize
87 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
89 /* Do YUV conversion to buffer - YUV picture is always formed of 16
90 * pixels wide blocks */
91 for( i_x = i_width / 16; i_x--; )
93 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
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++ ];
103 /* Do horizontal and vertical scaling */
105 SCALE_HEIGHT(400, 1);
109 /*****************************************************************************
110 * ConvertYUV420RGB8: color YUV 4:2:0 to RGB 8 bpp
111 *****************************************************************************/
112 void ConvertYUV420RGB8( YUV_ARGS_8BPP )
114 boolean_t b_horizontal_scaling; /* horizontal scaling type */
115 int i_vertical_scaling; /* vertical scaling type */
116 int i_x, i_y; /* horizontal and vertical indexes */
117 int i_scale_count; /* scale modulo counter */
118 int i_real_y; /* y % 4 */
119 u8 * p_lookup; /* lookup table */
120 int i_chroma_width; /* chroma width */
121 int * p_offset_start; /* offset array start */
122 int * p_offset; /* offset array pointer */
125 * The dithering matrices
127 static int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
128 static int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
129 static int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
130 static int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
132 static int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
133 static int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
134 static int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
135 static int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
138 * Initialize some values - i_pic_line_width will store the line skip
140 i_pic_line_width -= i_pic_width;
141 i_chroma_width = i_width / 2;
142 p_offset_start = p_vout->yuv.p_offset;
143 p_lookup = p_vout->yuv.p_base;
144 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
145 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 1 );
150 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
152 for( i_y = 0; i_y < i_height; i_y++ )
154 /* Do horizontal and vertical scaling */
155 SCALE_WIDTH_DITHER( 420 );
156 SCALE_HEIGHT_DITHER( 420 );
160 /*****************************************************************************
161 * ConvertYUV422RGB8: color YUV 4:2:2 to RGB 8 bpp
162 *****************************************************************************/
163 void ConvertYUV422RGB8( YUV_ARGS_8BPP )
165 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 8" );
168 /*****************************************************************************
169 * ConvertYUV444RGB8: color YUV 4:4:4 to RGB 8 bpp
170 *****************************************************************************/
171 void ConvertYUV444RGB8( YUV_ARGS_8BPP )
173 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 8" );
176 /*****************************************************************************
177 * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
178 *****************************************************************************/
179 void ConvertY4Gray16( YUV_ARGS_16BPP )
181 boolean_t b_horizontal_scaling; /* horizontal scaling type */
182 int i_vertical_scaling; /* vertical scaling type */
183 int i_x, i_y; /* horizontal and vertical indexes */
184 int i_scale_count; /* scale modulo counter */
185 int i_chroma_width; /* chroma width, not used */
186 u16 * p_gray; /* base conversion table */
187 u16 * p_pic_start; /* beginning of the current line for copy */
188 u16 * p_buffer_start; /* conversion buffer start */
189 u16 * p_buffer; /* conversion buffer pointer */
190 int * p_offset_start; /* offset array start */
191 int * p_offset; /* offset array pointer */
194 * Initialize some values - i_pic_line_width will store the line skip
196 i_pic_line_width -= i_pic_width;
197 p_gray = p_vout->yuv.yuv.p_gray16;
198 p_buffer_start = p_vout->yuv.p_buffer;
199 p_offset_start = p_vout->yuv.p_offset;
200 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
201 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
206 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
207 for( i_y = 0; i_y < i_height; i_y++ )
209 /* Mark beginnning of line for possible later line copy, and initialize
212 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
214 /* Do YUV conversion to buffer - YUV picture is always formed of 16
215 * pixels wide blocks */
216 for( i_x = i_width / 16; i_x--; )
218 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
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++ ];
228 /* Do horizontal and vertical scaling */
230 SCALE_HEIGHT(400, 2);
234 /*****************************************************************************
235 * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
236 *****************************************************************************/
237 void ConvertYUV420RGB16( YUV_ARGS_16BPP )
239 boolean_t b_horizontal_scaling; /* horizontal scaling type */
240 int i_vertical_scaling; /* vertical scaling type */
241 int i_x, i_y; /* horizontal and vertical indexes */
242 int i_scale_count; /* scale modulo counter */
243 int i_uval, i_vval; /* U and V samples */
244 int i_red, i_green, i_blue; /* U and V modified samples */
245 int i_chroma_width; /* chroma width */
246 u16 * p_yuv; /* base conversion table */
247 u16 * p_ybase; /* Y dependant conversion table */
248 u16 * p_pic_start; /* beginning of the current line for copy */
249 u16 * p_buffer_start; /* conversion buffer start */
250 u16 * p_buffer; /* conversion buffer pointer */
251 int * p_offset_start; /* offset array start */
252 int * p_offset; /* offset array pointer */
255 * Initialize some values - i_pic_line_width will store the line skip
257 i_pic_line_width -= i_pic_width;
258 i_chroma_width = i_width / 2;
259 p_yuv = p_vout->yuv.yuv.p_rgb16;
260 p_buffer_start = p_vout->yuv.p_buffer;
261 p_offset_start = p_vout->yuv.p_offset;
262 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
263 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
268 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
269 for( i_y = 0; i_y < i_height; i_y++ )
271 /* Mark beginnning of line for possible later line copy, and initialize
274 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
276 /* Do YUV conversion to buffer - YUV picture is always formed of 16
277 * pixels wide blocks */
278 for( i_x = i_width / 16; i_x--; )
280 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
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);
290 /* Do horizontal and vertical scaling */
292 SCALE_HEIGHT(420, 2);
296 /*****************************************************************************
297 * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
298 *****************************************************************************/
299 void ConvertYUV422RGB16( YUV_ARGS_16BPP )
301 boolean_t b_horizontal_scaling; /* horizontal scaling type */
302 int i_vertical_scaling; /* vertical scaling type */
303 int i_x, i_y; /* horizontal and vertical indexes */
304 int i_scale_count; /* scale modulo counter */
305 int i_uval, i_vval; /* U and V samples */
306 int i_red, i_green, i_blue; /* U and V modified samples */
307 int i_chroma_width; /* chroma width */
308 u16 * p_yuv; /* base conversion table */
309 u16 * p_ybase; /* Y dependant conversion table */
310 u16 * p_pic_start; /* beginning of the current line for copy */
311 u16 * p_buffer_start; /* conversion buffer start */
312 u16 * p_buffer; /* conversion buffer pointer */
313 int * p_offset_start; /* offset array start */
314 int * p_offset; /* offset array pointer */
317 * Initialize some values - i_pic_line_width will store the line skip
319 i_pic_line_width -= i_pic_width;
320 i_chroma_width = i_width / 2;
321 p_yuv = p_vout->yuv.yuv.p_rgb16;
322 p_buffer_start = p_vout->yuv.p_buffer;
323 p_offset_start = p_vout->yuv.p_offset;
324 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
325 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
330 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
331 for( i_y = 0; i_y < i_height; i_y++ )
333 /* Mark beginnning of line for possible later line copy, and initialize
336 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
338 /* Do YUV conversion to buffer - YUV picture is always formed of 16
339 * pixels wide blocks */
340 for( i_x = i_width / 16; i_x--; )
342 CONVERT_YUV_PIXEL(2); CONVERT_Y_PIXEL(2);
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);
352 /* Do horizontal and vertical scaling */
354 SCALE_HEIGHT(422, 2);
358 /*****************************************************************************
359 * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
360 *****************************************************************************/
361 void ConvertYUV444RGB16( YUV_ARGS_16BPP )
363 boolean_t b_horizontal_scaling; /* horizontal scaling type */
364 int i_vertical_scaling; /* vertical scaling type */
365 int i_x, i_y; /* horizontal and vertical indexes */
366 int i_scale_count; /* scale modulo counter */
367 int i_uval, i_vval; /* U and V samples */
368 int i_red, i_green, i_blue; /* U and V modified samples */
369 int i_chroma_width; /* chroma width, not used */
370 u16 * p_yuv; /* base conversion table */
371 u16 * p_ybase; /* Y dependant conversion table */
372 u16 * p_pic_start; /* beginning of the current line for copy */
373 u16 * p_buffer_start; /* conversion buffer start */
374 u16 * p_buffer; /* conversion buffer pointer */
375 int * p_offset_start; /* offset array start */
376 int * p_offset; /* offset array pointer */
379 * Initialize some values - i_pic_line_width will store the line skip
381 i_pic_line_width -= i_pic_width;
382 p_yuv = p_vout->yuv.yuv.p_rgb16;
383 p_buffer_start = p_vout->yuv.p_buffer;
384 p_offset_start = p_vout->yuv.p_offset;
385 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
386 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
391 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
392 for( i_y = 0; i_y < i_height; i_y++ )
394 /* Mark beginnning of line for possible later line copy, and initialize
397 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
399 /* Do YUV conversion to buffer - YUV picture is always formed of 16
400 * pixels wide blocks */
401 for( i_x = i_width / 16; i_x--; )
403 CONVERT_YUV_PIXEL(2); CONVERT_YUV_PIXEL(2);
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);
413 /* Do horizontal and vertical scaling */
415 SCALE_HEIGHT(444, 2);
419 /*****************************************************************************
420 * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 2 Bpp
421 *****************************************************************************/
422 void ConvertY4Gray24( YUV_ARGS_24BPP )
424 intf_ErrMsg( "yuv error: unhandled function, grayscale, bpp = 24" );
427 /*****************************************************************************
428 * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 2 Bpp
429 *****************************************************************************/
430 void ConvertYUV420RGB24( YUV_ARGS_24BPP )
432 intf_ErrMsg( "yuv error: unhandled function, chroma = 420, bpp = 24" );
435 /*****************************************************************************
436 * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 2 Bpp
437 *****************************************************************************/
438 void ConvertYUV422RGB24( YUV_ARGS_24BPP )
440 intf_ErrMsg( "yuv error: unhandled function, chroma = 422, bpp = 24" );
443 /*****************************************************************************
444 * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 2 Bpp
445 *****************************************************************************/
446 void ConvertYUV444RGB24( YUV_ARGS_24BPP )
448 intf_ErrMsg( "yuv error: unhandled function, chroma = 444, bpp = 24" );
451 /*****************************************************************************
452 * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
453 *****************************************************************************/
454 void ConvertY4Gray32( YUV_ARGS_32BPP )
456 boolean_t b_horizontal_scaling; /* horizontal scaling type */
457 int i_vertical_scaling; /* vertical scaling type */
458 int i_x, i_y; /* horizontal and vertical indexes */
459 int i_scale_count; /* scale modulo counter */
460 int i_chroma_width; /* chroma width, not used */
461 u32 * p_gray; /* base conversion table */
462 u32 * p_pic_start; /* beginning of the current line for copy */
463 u32 * p_buffer_start; /* conversion buffer start */
464 u32 * p_buffer; /* conversion buffer pointer */
465 int * p_offset_start; /* offset array start */
466 int * p_offset; /* offset array pointer */
469 * Initialize some values - i_pic_line_width will store the line skip
471 i_pic_line_width -= i_pic_width;
472 p_gray = p_vout->yuv.yuv.p_gray32;
473 p_buffer_start = p_vout->yuv.p_buffer;
474 p_offset_start = p_vout->yuv.p_offset;
475 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
476 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
481 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
482 for( i_y = 0; i_y < i_height; i_y++ )
484 /* Mark beginnning of line for possible later line copy, and initialize
487 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
489 /* Do YUV conversion to buffer - YUV picture is always formed of 16
490 * pixels wide blocks */
491 for( i_x = i_width / 16; i_x--; )
493 *p_buffer++ = p_gray[ *p_y++ ]; *p_buffer++ = p_gray[ *p_y++ ];
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++ ];
503 /* Do horizontal and vertical scaling */
505 SCALE_HEIGHT(400, 4);
509 /*****************************************************************************
510 * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
511 *****************************************************************************/
512 void ConvertYUV420RGB32( YUV_ARGS_32BPP )
514 boolean_t b_horizontal_scaling; /* horizontal scaling type */
515 int i_vertical_scaling; /* vertical scaling type */
516 int i_x, i_y; /* horizontal and vertical indexes */
517 int i_scale_count; /* scale modulo counter */
518 int i_uval, i_vval; /* U and V samples */
519 int i_red, i_green, i_blue; /* U and V modified samples */
520 int i_chroma_width; /* chroma width */
521 u32 * p_yuv; /* base conversion table */
522 u32 * p_ybase; /* Y dependant conversion table */
523 u32 * p_pic_start; /* beginning of the current line for copy */
524 u32 * p_buffer_start; /* conversion buffer start */
525 u32 * p_buffer; /* conversion buffer pointer */
526 int * p_offset_start; /* offset array start */
527 int * p_offset; /* offset array pointer */
530 * Initialize some values - i_pic_line_width will store the line skip
532 i_pic_line_width -= i_pic_width;
533 i_chroma_width = i_width / 2;
534 p_yuv = p_vout->yuv.yuv.p_rgb32;
535 p_buffer_start = p_vout->yuv.p_buffer;
536 p_offset_start = p_vout->yuv.p_offset;
537 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
538 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
543 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
544 for( i_y = 0; i_y < i_height; i_y++ )
546 /* Mark beginnning of line for possible later line copy, and initialize
549 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
551 /* Do YUV conversion to buffer - YUV picture is always formed of 16
552 * pixels wide blocks */
553 for( i_x = i_width / 16; i_x--; )
555 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
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);
565 /* Do horizontal and vertical scaling */
567 SCALE_HEIGHT(420, 4);
571 /*****************************************************************************
572 * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
573 *****************************************************************************/
574 void ConvertYUV422RGB32( YUV_ARGS_32BPP )
576 boolean_t b_horizontal_scaling; /* horizontal scaling type */
577 int i_vertical_scaling; /* vertical scaling type */
578 int i_x, i_y; /* horizontal and vertical indexes */
579 int i_scale_count; /* scale modulo counter */
580 int i_uval, i_vval; /* U and V samples */
581 int i_red, i_green, i_blue; /* U and V modified samples */
582 int i_chroma_width; /* chroma width */
583 u32 * p_yuv; /* base conversion table */
584 u32 * p_ybase; /* Y dependant conversion table */
585 u32 * p_pic_start; /* beginning of the current line for copy */
586 u32 * p_buffer_start; /* conversion buffer start */
587 u32 * p_buffer; /* conversion buffer pointer */
588 int * p_offset_start; /* offset array start */
589 int * p_offset; /* offset array pointer */
592 * Initialize some values - i_pic_line_width will store the line skip
594 i_pic_line_width -= i_pic_width;
595 i_chroma_width = i_width / 2;
596 p_yuv = p_vout->yuv.yuv.p_rgb32;
597 p_buffer_start = p_vout->yuv.p_buffer;
598 p_offset_start = p_vout->yuv.p_offset;
599 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
600 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
605 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
606 for( i_y = 0; i_y < i_height; i_y++ )
608 /* Mark beginnning of line for possible later line copy, and initialize
611 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
613 /* Do YUV conversion to buffer - YUV picture is always formed of 16
614 * pixels wide blocks */
615 for( i_x = i_width / 16; i_x--; )
617 CONVERT_YUV_PIXEL(4); CONVERT_Y_PIXEL(4);
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);
627 /* Do horizontal and vertical scaling */
629 SCALE_HEIGHT(422, 4);
633 /*****************************************************************************
634 * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
635 *****************************************************************************/
636 void ConvertYUV444RGB32( YUV_ARGS_32BPP )
638 boolean_t b_horizontal_scaling; /* horizontal scaling type */
639 int i_vertical_scaling; /* vertical scaling type */
640 int i_x, i_y; /* horizontal and vertical indexes */
641 int i_scale_count; /* scale modulo counter */
642 int i_uval, i_vval; /* U and V samples */
643 int i_red, i_green, i_blue; /* U and V modified samples */
644 int i_chroma_width; /* chroma width, not used */
645 u32 * p_yuv; /* base conversion table */
646 u32 * p_ybase; /* Y dependant conversion table */
647 u32 * p_pic_start; /* beginning of the current line for copy */
648 u32 * p_buffer_start; /* conversion buffer start */
649 u32 * p_buffer; /* conversion buffer pointer */
650 int * p_offset_start; /* offset array start */
651 int * p_offset; /* offset array pointer */
654 * Initialize some values - i_pic_line_width will store the line skip
656 i_pic_line_width -= i_pic_width;
657 p_yuv = p_vout->yuv.yuv.p_rgb32;
658 p_buffer_start = p_vout->yuv.p_buffer;
659 p_offset_start = p_vout->yuv.p_offset;
660 SetOffset( i_width, i_height, i_pic_width, i_pic_height,
661 &b_horizontal_scaling, &i_vertical_scaling, p_offset_start, 0 );
666 i_scale_count = ( i_vertical_scaling == 1 ) ? i_pic_height : i_height;
667 for( i_y = 0; i_y < i_height; i_y++ )
669 /* Mark beginnning of line for possible later line copy, and initialize
672 p_buffer = b_horizontal_scaling ? p_buffer_start : p_pic;
674 /* Do YUV conversion to buffer - YUV picture is always formed of 16
675 * pixels wide blocks */
676 for( i_x = i_width / 16; i_x--; )
678 CONVERT_YUV_PIXEL(4); CONVERT_YUV_PIXEL(4);
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);
688 /* Do horizontal and vertical scaling */
690 SCALE_HEIGHT(444, 4);