]> git.sesse.net Git - vlc/blob - plugins/yuv/video_yuv_macros_8bpp.h
116f7ae71e6f087cfaa21630093b3cec9dc1f3b5
[vlc] / plugins / yuv / video_yuv_macros_8bpp.h
1 /*****************************************************************************
2  * video_yuv_macros_8bpp.h: YUV transformation macros for 8bpp
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  *
6  * Authors:
7  *
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.
12  *
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.
17  *
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  *****************************************************************************/
23
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) ];                               \
46
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;                                                   \
58     p_y += *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;                                                   \
66     p_y += *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;                                                   \
74     p_y += *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;                                                   \
82     p_y += *p_offset;                                                         \
83     p_u += *p_offset   & b_jump_uv;                                           \
84     p_v += *p_offset++ & b_jump_uv;                                           \
85
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 )                                                \
93     {                                                                         \
94         /* Horizontal scaling, but we can't use a buffer due to dither */     \
95         p_offset = p_offset_start;                                            \
96         b_jump_uv = 0;                                                        \
97         for( i_x = i_pic_width / 16; i_x--; )                                 \
98         {                                                                     \
99             CONVERT_4YUV_PIXELS_SCALE( CHROMA )                               \
100             CONVERT_4YUV_PIXELS_SCALE( CHROMA )                               \
101             CONVERT_4YUV_PIXELS_SCALE( CHROMA )                               \
102             CONVERT_4YUV_PIXELS_SCALE( CHROMA )                               \
103         }                                                                     \
104     }                                                                         \
105     else                                                                      \
106     {                                                                         \
107         for( i_x = i_width / 16; i_x--;  )                                    \
108         {                                                                     \
109             CONVERT_4YUV_PIXELS( CHROMA )                                     \
110             CONVERT_4YUV_PIXELS( CHROMA )                                     \
111             CONVERT_4YUV_PIXELS( CHROMA )                                     \
112             CONVERT_4YUV_PIXELS( CHROMA )                                     \
113         }                                                                     \
114     }                                                                         \
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;                                          \
118
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 )                                         \
126                                                                               \
127     /* If line is odd, rewind 4:2:0 U and V samples */                        \
128     if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) )                \
129     {                                                                         \
130         p_u -= i_chroma_width;                                                \
131         p_v -= i_chroma_width;                                                \
132     }                                                                         \
133                                                                               \
134     /*                                                                        \
135      * Handle vertical scaling. The current line can be copied or next one    \
136      * can be ignored.                                                        \
137      */                                                                       \
138                                                                               \
139     switch( i_vertical_scaling )                                              \
140     {                                                                         \
141     case -1:                             /* vertical scaling factor is < 1 */ \
142         while( (i_scale_count -= i_pic_height) >= 0 )                         \
143         {                                                                     \
144             /* Height reduction: skip next source line */                     \
145             p_y += i_width;                                                   \
146             i_y++;                                                            \
147             if( (CHROMA == 420) || (CHROMA == 422) )                          \
148             {                                                                 \
149                 if( i_y & 0x1 )                                               \
150                 {                                                             \
151                     p_u += i_chroma_width;                                    \
152                     p_v += i_chroma_width;                                    \
153                 }                                                             \
154             }                                                                 \
155             else if( CHROMA == 444 )                                          \
156             {                                                                 \
157                 p_u += i_width;                                               \
158                 p_v += i_width;                                               \
159             }                                                                 \
160         }                                                                     \
161         i_scale_count += i_height;                                            \
162         break;                                                                \
163     case 1:                              /* vertical scaling factor is > 1 */ \
164         while( (i_scale_count -= i_height) > 0 )                              \
165         {                                                                     \
166             SCALE_WIDTH_DITHER( CHROMA );                                     \
167             p_y -= i_width;                                                   \
168             p_u -= i_chroma_width;                                            \
169             p_v -= i_chroma_width;                                            \
170             p_pic +=        i_pic_line_width;                                 \
171         }                                                                     \
172         i_scale_count += i_pic_height;                                        \
173         break;                                                                \
174     }                                                                         \
175