1 /*****************************************************************************
2 * transforms_yuv.h: C specific 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 * CONVERT_4YUV_PIXELS: dither 4 pixels in 8 bpp
26 *****************************************************************************
27 * These macros dither 4 pixels in 8 bpp
28 *****************************************************************************/
29 #define CONVERT_4YUV_PIXELS( CHROMA ) \
30 *p_pic++ = p_lookup[ \
31 (((*p_y++ + dither10[i_real_y]) >> 4) << 7) \
32 + ((*p_u + dither20[i_real_y]) >> 5) * 9 \
33 + ((*p_v + dither20[i_real_y]) >> 5) ]; \
34 *p_pic++ = p_lookup[ \
35 (((*p_y++ + dither11[i_real_y]) >> 4) << 7) \
36 + ((*p_u++ + dither21[i_real_y]) >> 5) * 9 \
37 + ((*p_v++ + dither21[i_real_y]) >> 5) ]; \
38 *p_pic++ = p_lookup[ \
39 (((*p_y++ + dither12[i_real_y]) >> 4) << 7) \
40 + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
41 + ((*p_v + dither22[i_real_y]) >> 5) ]; \
42 *p_pic++ = p_lookup[ \
43 (((*p_y++ + dither13[i_real_y]) >> 4) << 7) \
44 + ((*p_u++ + dither23[i_real_y]) >> 5) * 9 \
45 + ((*p_v++ + dither23[i_real_y]) >> 5) ]; \
47 /*****************************************************************************
48 * CONVERT_4YUV_PIXELS_SCALE: dither and scale 4 pixels in 8 bpp
49 *****************************************************************************
50 * These macros dither 4 pixels in 8 bpp, with horizontal scaling
51 *****************************************************************************/
52 #define CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
53 *p_pic++ = p_lookup[ \
54 ( ((*p_y + dither10[i_real_y]) >> 4) << 7) \
55 + ((*p_u + dither20[i_real_y]) >> 5) * 9 \
56 + ((*p_v + dither20[i_real_y]) >> 5) ]; \
60 *p_pic++ = p_lookup[ \
61 ( ((*p_y + dither11[i_real_y]) >> 4) << 7) \
62 + ((*p_u + dither21[i_real_y]) >> 5) * 9 \
63 + ((*p_v + dither21[i_real_y]) >> 5) ]; \
67 *p_pic++ = p_lookup[ \
68 ( ((*p_y + dither12[i_real_y]) >> 4) << 7) \
69 + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
70 + ((*p_v + dither22[i_real_y]) >> 5) ]; \
74 *p_pic++ = p_lookup[ \
75 ( ((*p_y + dither13[i_real_y]) >> 4) << 7) \
76 + ((*p_u + dither23[i_real_y]) >> 5) * 9 \
77 + ((*p_v + dither23[i_real_y]) >> 5) ]; \
82 /*****************************************************************************
83 * SCALE_WIDTH_DITHER: scale a line horizontally for dithered 8 bpp
84 *****************************************************************************
85 * This macro scales a line using an offset array.
86 *****************************************************************************/
87 #define SCALE_WIDTH_DITHER( CHROMA ) \
88 if( b_horizontal_scaling ) \
90 /* Horizontal scaling - we can't use a buffer due to dithering */ \
91 p_offset = p_offset_start; \
92 for( i_x = i_pic_width / 16; i_x--; ) \
94 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
95 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
96 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
97 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
102 for( i_x = i_width / 16; i_x--; ) \
104 CONVERT_4YUV_PIXELS( CHROMA ) \
105 CONVERT_4YUV_PIXELS( CHROMA ) \
106 CONVERT_4YUV_PIXELS( CHROMA ) \
107 CONVERT_4YUV_PIXELS( CHROMA ) \
110 /* Increment of picture pointer to end of line is still needed */ \
111 p_pic += i_pic_line_width; \
113 /* Increment the Y coordinate in the matrix, modulo 4 */ \
114 i_real_y = (i_real_y + 1) & 0x3; \
116 /*****************************************************************************
117 * SCALE_HEIGHT_DITHER: handle vertical scaling for dithered 8 bpp
118 *****************************************************************************
119 * This macro handles vertical scaling for a picture. CHROMA may be 420,
120 * 422 or 444 for RGB conversion, or 400 for gray conversion.
121 *****************************************************************************/
122 #define SCALE_HEIGHT_DITHER( CHROMA ) \
124 /* If line is odd, rewind 4:2:0 U and V samples */ \
125 if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
127 p_u -= i_chroma_width; \
128 p_v -= i_chroma_width; \
132 * Handle vertical scaling. The current line can be copied or next one \
136 switch( i_vertical_scaling ) \
138 case -1: /* vertical scaling factor is < 1 */ \
139 while( (i_scale_count -= i_pic_height) > 0 ) \
141 /* Height reduction: skip next source line */ \
144 if( (CHROMA == 420) || (CHROMA == 422) ) \
148 p_u += i_chroma_width; \
149 p_v += i_chroma_width; \
152 else if( CHROMA == 444 ) \
158 i_scale_count += i_height; \
160 case 1: /* vertical scaling factor is > 1 */ \
161 while( (i_scale_count -= i_height) > 0 ) \
164 p_u -= i_chroma_width; \
165 p_v -= i_chroma_width; \
166 SCALE_WIDTH_DITHER( CHROMA ); \
168 i_scale_count += i_pic_height; \