1 /*****************************************************************************
2 * video_yuv_macros.h: YUV transformation macros
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * SCALE_WIDTH: scale a line horizontally
26 *****************************************************************************
27 * This macro scales a line using rendering buffer and offset array. It works
29 *****************************************************************************/
31 if( b_horizontal_scaling ) \
33 /* Horizontal scaling, conversion has been done to buffer. \
34 * Rewind buffer and offset, then copy and scale line */ \
35 p_buffer = p_buffer_start; \
36 p_offset = p_offset_start; \
37 for( i_x = i_pic_width / 16; i_x--; ) \
39 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
40 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
41 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
42 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
43 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
44 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
45 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
46 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
47 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
48 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
49 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
50 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
51 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
52 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
53 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
54 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
56 p_pic += i_pic_line_width; \
60 /* No scaling, conversion has been done directly in picture memory. \
61 * Increment of picture pointer to end of line is still needed */ \
62 p_pic += i_pic_width + i_pic_line_width; \
65 /*****************************************************************************
66 * SCALE_HEIGHT: handle vertical scaling
67 *****************************************************************************
68 * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
69 * 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
71 *****************************************************************************/
72 #define SCALE_HEIGHT( CHROMA, BPP ) \
73 /* If line is odd, rewind 4:2:0 U and V samples */ \
74 if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
76 p_u -= i_chroma_width; \
77 p_v -= i_chroma_width; \
81 * Handle vertical scaling. The current line can be copied or next one \
84 switch( i_vertical_scaling ) \
86 case -1: /* vertical scaling factor is < 1 */ \
87 while( (i_scale_count -= i_pic_height) >= 0 ) \
89 /* Height reduction: skip next source line */ \
92 if( (CHROMA == 420) || (CHROMA == 422) ) \
96 p_u += i_chroma_width; \
97 p_v += i_chroma_width; \
100 else if( CHROMA == 444 ) \
106 i_scale_count += i_height; \
108 case 1: /* vertical scaling factor is > 1 */ \
109 while( (i_scale_count -= i_height) > 0 ) \
111 /* Height increment: copy previous picture line */ \
112 for( i_x = i_pic_width / 16; i_x--; ) \
114 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
115 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
116 if( BPP > 1 ) /* 2, 3, 4 Bpp */ \
118 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
119 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
121 if( BPP > 2 ) /* 3, 4 Bpp */ \
123 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
124 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
126 if( BPP > 3 ) /* 4 Bpp */ \
128 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
129 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
132 p_pic += i_pic_line_width; \
133 p_pic_start += i_pic_line_width; \
135 i_scale_count += i_pic_height; \