1 /*****************************************************************************
2 * transforms_common.h: YUV transformation macros for truecolor
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 * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel conversion blocks
26 *****************************************************************************
27 * These conversion routines are used by YUV conversion functions.
28 * conversion are made from p_y, p_u, p_v, which are modified, to p_buffer,
29 * which is also modified.
30 *****************************************************************************/
31 #define CONVERT_Y_PIXEL( BPP ) \
32 /* Only Y sample is present */ \
33 p_ybase = p_yuv + *p_y++; \
34 *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] | \
35 p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) \
36 + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
38 #define CONVERT_YUV_PIXEL( BPP ) \
39 /* Y, U and V samples are present */ \
42 i_red = (V_RED_COEF * i_vval) >> SHIFT; \
43 i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
44 i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
45 CONVERT_Y_PIXEL( BPP ) \
47 /*****************************************************************************
48 * SCALE_WIDTH: scale a line horizontally
49 *****************************************************************************
50 * This macro scales a line using rendering buffer and offset array. It works
52 *****************************************************************************/
54 if( b_horizontal_scaling ) \
56 /* Horizontal scaling, conversion has been done to buffer. \
57 * Rewind buffer and offset, then copy and scale line */ \
58 p_buffer = p_buffer_start; \
59 p_offset = p_offset_start; \
60 for( i_x = i_pic_width / 16; i_x--; ) \
62 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
63 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
64 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
65 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
66 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
67 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
68 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
69 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
70 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
71 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
72 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
73 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
74 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
75 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
76 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
77 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
79 p_pic += i_pic_line_width; \
83 /* No scaling, conversion has been done directly in picture memory. \
84 * Increment of picture pointer to end of line is still needed */ \
85 p_pic += i_pic_width + i_pic_line_width; \
88 /*****************************************************************************
89 * SCALE_HEIGHT: handle vertical scaling
90 *****************************************************************************
91 * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
92 * 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
94 *****************************************************************************/
95 #define SCALE_HEIGHT( CHROMA, BPP ) \
96 /* If line is odd, rewind 4:2:0 U and V samples */ \
97 if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
99 p_u -= i_chroma_width; \
100 p_v -= i_chroma_width; \
104 * Handle vertical scaling. The current line can be copied or next one \
107 switch( i_vertical_scaling ) \
109 case -1: /* vertical scaling factor is < 1 */ \
110 while( (i_scale_count -= i_pic_height) > 0 ) \
112 /* Height reduction: skip next source line */ \
115 if( (CHROMA == 420) || (CHROMA == 422) ) \
119 p_u += i_chroma_width; \
120 p_v += i_chroma_width; \
123 else if( CHROMA == 444 ) \
129 i_scale_count += i_height; \
131 case 1: /* vertical scaling factor is > 1 */ \
132 while( (i_scale_count -= i_height) > 0 ) \
134 /* Height increment: copy previous picture line */ \
135 for( i_x = i_pic_width / 16; i_x--; ) \
137 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
138 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
139 if( BPP > 1 ) /* 2, 3, 4 Bpp */ \
141 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
142 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
144 if( BPP > 2 ) /* 3, 4 Bpp */ \
146 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
147 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
149 if( BPP > 3 ) /* 4 Bpp */ \
151 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
152 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
155 p_pic += i_pic_line_width; \
156 p_pic_start += i_pic_line_width; \
158 i_scale_count += i_pic_height; \