1 /*****************************************************************************
2 * video_yuv_macros_8bpp.h: YUV transformation macros for 8bpp
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) ]; \
57 b_jump_uv += *p_offset; \
59 p_u += *p_offset & b_jump_uv; \
60 p_v += *p_offset++ & b_jump_uv; \
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) ]; \
65 b_jump_uv += *p_offset; \
67 p_u += *p_offset & b_jump_uv; \
68 p_v += *p_offset++ & b_jump_uv; \
69 *p_pic++ = p_lookup[ \
70 ( ((*p_y + dither12[i_real_y]) >> 4) << 7) \
71 + ((*p_u + dither22[i_real_y]) >> 5) * 9 \
72 + ((*p_v + dither22[i_real_y]) >> 5) ]; \
73 b_jump_uv += *p_offset; \
75 p_u += *p_offset & b_jump_uv; \
76 p_v += *p_offset++ & b_jump_uv; \
77 *p_pic++ = p_lookup[ \
78 ( ((*p_y + dither13[i_real_y]) >> 4) << 7) \
79 + ((*p_u + dither23[i_real_y]) >> 5) * 9 \
80 + ((*p_v + dither23[i_real_y]) >> 5) ]; \
81 b_jump_uv += *p_offset; \
83 p_u += *p_offset & b_jump_uv; \
84 p_v += *p_offset++ & b_jump_uv; \
86 /*****************************************************************************
87 * SCALE_WIDTH_DITHER: scale a line horizontally for dithered 8 bpp
88 *****************************************************************************
89 * This macro scales a line using an offset array.
90 *****************************************************************************/
91 #define SCALE_WIDTH_DITHER( CHROMA ) \
92 if( b_horizontal_scaling ) \
94 /* Horizontal scaling, but we can't use a buffer due to dither */ \
95 p_offset = p_offset_start; \
97 for( i_x = i_pic_width / 16; i_x--; ) \
99 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
100 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
101 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
102 CONVERT_4YUV_PIXELS_SCALE( CHROMA ) \
107 for( i_x = i_width / 16; i_x--; ) \
109 CONVERT_4YUV_PIXELS( CHROMA ) \
110 CONVERT_4YUV_PIXELS( CHROMA ) \
111 CONVERT_4YUV_PIXELS( CHROMA ) \
112 CONVERT_4YUV_PIXELS( CHROMA ) \
115 /* Increment of picture pointer to end of line is still needed */ \
116 p_pic += i_pic_line_width; \
117 i_real_y = (i_real_y + 1) & 0x3; \
119 /*****************************************************************************
120 * SCALE_HEIGHT_DITHER: handle vertical scaling for dithered 8 bpp
121 *****************************************************************************
122 * This macro handles vertical scaling for a picture. CHROMA may be 420, 422 or
123 * 444 for RGB conversion, or 400 for gray conversion.
124 *****************************************************************************/
125 #define SCALE_HEIGHT_DITHER( CHROMA ) \
127 /* If line is odd, rewind 4:2:0 U and V samples */ \
128 if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
130 p_u -= i_chroma_width; \
131 p_v -= i_chroma_width; \
135 * Handle vertical scaling. The current line can be copied or next one \
139 switch( i_vertical_scaling ) \
141 case -1: /* vertical scaling factor is < 1 */ \
142 while( (i_scale_count -= i_pic_height) >= 0 ) \
144 /* Height reduction: skip next source line */ \
147 if( (CHROMA == 420) || (CHROMA == 422) ) \
151 p_u += i_chroma_width; \
152 p_v += i_chroma_width; \
155 else if( CHROMA == 444 ) \
161 i_scale_count += i_height; \
163 case 1: /* vertical scaling factor is > 1 */ \
164 while( (i_scale_count -= i_height) > 0 ) \
166 SCALE_WIDTH_DITHER( CHROMA ); \
168 p_u -= i_chroma_width; \
169 p_v -= i_chroma_width; \
170 p_pic += i_pic_line_width; \
172 i_scale_count += i_pic_height; \