1 /*****************************************************************************
2 * transforms_common.h: YUV transformation macros for truecolor
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
5 * $Id: transforms_common.h,v 1.2 2001/03/21 13:42:34 sam Exp $
7 * Authors: Vincent Seguin <seguin@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * CONVERT_YUV_PIXEL, CONVERT_Y_PIXEL: pixel conversion blocks
27 *****************************************************************************
28 * These conversion routines are used by YUV conversion functions.
29 * conversion are made from p_y, p_u, p_v, which are modified, to p_buffer,
30 * which is also modified.
31 *****************************************************************************/
32 #define CONVERT_Y_PIXEL( BPP ) \
33 /* Only Y sample is present */ \
34 p_ybase = p_yuv + *p_y++; \
35 *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] | \
36 p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT) \
37 + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
39 #define CONVERT_YUV_PIXEL( BPP ) \
40 /* Y, U and V samples are present */ \
43 i_red = (V_RED_COEF * i_vval) >> SHIFT; \
44 i_green = (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT; \
45 i_blue = (U_BLUE_COEF * i_uval) >> SHIFT; \
46 CONVERT_Y_PIXEL( BPP ) \
48 /*****************************************************************************
49 * SCALE_WIDTH: scale a line horizontally
50 *****************************************************************************
51 * This macro scales a line using rendering buffer and offset array. It works
53 *****************************************************************************/
55 if( b_horizontal_scaling ) \
57 /* Horizontal scaling, conversion has been done to buffer. \
58 * Rewind buffer and offset, then copy and scale line */ \
59 p_buffer = p_buffer_start; \
60 p_offset = p_offset_start; \
61 for( i_x = i_pic_width / 16; i_x--; ) \
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++; \
78 *p_pic++ = *p_buffer; p_buffer += *p_offset++; \
80 p_pic += i_pic_line_width; \
84 /* No scaling, conversion has been done directly in picture memory. \
85 * Increment of picture pointer to end of line is still needed */ \
86 p_pic += i_pic_width + i_pic_line_width; \
89 /*****************************************************************************
90 * SCALE_HEIGHT: handle vertical scaling
91 *****************************************************************************
92 * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
93 * 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
95 *****************************************************************************/
96 #define SCALE_HEIGHT( CHROMA, BPP ) \
97 /* If line is odd, rewind 4:2:0 U and V samples */ \
98 if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
100 p_u -= i_chroma_width; \
101 p_v -= i_chroma_width; \
105 * Handle vertical scaling. The current line can be copied or next one \
108 switch( i_vertical_scaling ) \
110 case -1: /* vertical scaling factor is < 1 */ \
111 while( (i_scale_count -= i_pic_height) > 0 ) \
113 /* Height reduction: skip next source line */ \
116 if( (CHROMA == 420) || (CHROMA == 422) ) \
120 p_u += i_chroma_width; \
121 p_v += i_chroma_width; \
124 else if( CHROMA == 444 ) \
130 i_scale_count += i_height; \
132 case 1: /* vertical scaling factor is > 1 */ \
133 while( (i_scale_count -= i_height) > 0 ) \
135 /* Height increment: copy previous picture line */ \
136 for( i_x = i_pic_width / 16; i_x--; ) \
138 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
139 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
140 if( BPP > 1 ) /* 2, 3, 4 Bpp */ \
142 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
143 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
145 if( BPP > 2 ) /* 3, 4 Bpp */ \
147 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
148 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
150 if( BPP > 3 ) /* 4 Bpp */ \
152 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
153 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ ); \
156 p_pic += i_pic_line_width; \
157 p_pic_start += i_pic_line_width; \
159 i_scale_count += i_pic_height; \