1 /*****************************************************************************
2 * transforms_yuv.h: C specific YUV transformation macros
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
5 * $Id: transforms_yuv.h,v 1.2 2001/03/21 13:42:34 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
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_4YUV_PIXELS: dither 4 pixels in 8 bpp
27 *****************************************************************************
28 * These macros dither 4 pixels in 8 bpp
29 *****************************************************************************/
30 #define CONVERT_4YUV_PIXELS( CHROMA ) \
31 *p_pic++ = p_lookup[ \
32 (((*p_y++ + dither10[i_real_y]) >> 4) << 7) \
33 + ((*p_u + dither20[i_real_y]) >> 5) * 9 \
34 + ((*p_v + dither20[i_real_y]) >> 5) ]; \
35 *p_pic++ = p_lookup[ \
36 (((*p_y++ + dither11[i_real_y]) >> 4) << 7) \
37 + ((*p_u++ + dither21[i_real_y]) >> 5) * 9 \
38 + ((*p_v++ + dither21[i_real_y]) >> 5) ]; \
39 *p_pic++ = p_lookup[ \
40 (((*p_y++ + dither12[i_real_y]) >> 4) << 7) \
41 + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
42 + ((*p_v + dither22[i_real_y]) >> 5) ]; \
43 *p_pic++ = p_lookup[ \
44 (((*p_y++ + dither13[i_real_y]) >> 4) << 7) \
45 + ((*p_u++ + dither23[i_real_y]) >> 5) * 9 \
46 + ((*p_v++ + dither23[i_real_y]) >> 5) ]; \
48 /*****************************************************************************
49 * CONVERT_4YUV_PIXELS_SCALE: dither and scale 4 pixels in 8 bpp
50 *****************************************************************************
51 * These macros dither 4 pixels in 8 bpp, with horizontal scaling
52 *****************************************************************************/
53 #define CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
54 *p_pic++ = p_lookup[ \
55 ( ((*p_y + dither10[i_real_y]) >> 4) << 7) \
56 + ((*p_u + dither20[i_real_y]) >> 5) * 9 \
57 + ((*p_v + dither20[i_real_y]) >> 5) ]; \
61 *p_pic++ = p_lookup[ \
62 ( ((*p_y + dither11[i_real_y]) >> 4) << 7) \
63 + ((*p_u + dither21[i_real_y]) >> 5) * 9 \
64 + ((*p_v + dither21[i_real_y]) >> 5) ]; \
68 *p_pic++ = p_lookup[ \
69 ( ((*p_y + dither12[i_real_y]) >> 4) << 7) \
70 + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
71 + ((*p_v + dither22[i_real_y]) >> 5) ]; \
75 *p_pic++ = p_lookup[ \
76 ( ((*p_y + dither13[i_real_y]) >> 4) << 7) \
77 + ((*p_u + dither23[i_real_y]) >> 5) * 9 \
78 + ((*p_v + dither23[i_real_y]) >> 5) ]; \
83 /*****************************************************************************
84 * SCALE_WIDTH_DITHER: scale a line horizontally for dithered 8 bpp
85 *****************************************************************************
86 * This macro scales a line using an offset array.
87 *****************************************************************************/
88 #define SCALE_WIDTH_DITHER( CHROMA ) \
89 if( b_horizontal_scaling ) \
91 /* Horizontal scaling - we can't use a buffer due to dithering */ \
92 p_offset = p_offset_start; \
93 for( i_x = i_pic_width / 16; i_x--; ) \
95 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
96 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
97 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
98 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
103 for( i_x = i_width / 16; i_x--; ) \
105 CONVERT_4YUV_PIXELS( CHROMA ) \
106 CONVERT_4YUV_PIXELS( CHROMA ) \
107 CONVERT_4YUV_PIXELS( CHROMA ) \
108 CONVERT_4YUV_PIXELS( CHROMA ) \
111 /* Increment of picture pointer to end of line is still needed */ \
112 p_pic += i_pic_line_width; \
114 /* Increment the Y coordinate in the matrix, modulo 4 */ \
115 i_real_y = (i_real_y + 1) & 0x3; \
117 /*****************************************************************************
118 * SCALE_HEIGHT_DITHER: handle vertical scaling for dithered 8 bpp
119 *****************************************************************************
120 * This macro handles vertical scaling for a picture. CHROMA may be 420,
121 * 422 or 444 for RGB conversion, or 400 for gray conversion.
122 *****************************************************************************/
123 #define SCALE_HEIGHT_DITHER( CHROMA ) \
125 /* If line is odd, rewind 4:2:0 U and V samples */ \
126 if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
128 p_u -= i_chroma_width; \
129 p_v -= i_chroma_width; \
133 * Handle vertical scaling. The current line can be copied or next one \
137 switch( i_vertical_scaling ) \
139 case -1: /* vertical scaling factor is < 1 */ \
140 while( (i_scale_count -= i_pic_height) > 0 ) \
142 /* Height reduction: skip next source line */ \
145 if( (CHROMA == 420) || (CHROMA == 422) ) \
149 p_u += i_chroma_width; \
150 p_v += i_chroma_width; \
153 else if( CHROMA == 444 ) \
159 i_scale_count += i_height; \
161 case 1: /* vertical scaling factor is > 1 */ \
162 while( (i_scale_count -= i_height) > 0 ) \
165 p_u -= i_chroma_width; \
166 p_v -= i_chroma_width; \
167 SCALE_WIDTH_DITHER( CHROMA ); \
169 i_scale_count += i_pic_height; \