]> git.sesse.net Git - vlc/blob - plugins/yuv/transforms_yuv.h
* Header cleaning: filled all empty authors fields, added CVS $Id stuff.
[vlc] / plugins / yuv / transforms_yuv.h
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 $
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
24
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) ];                               \
47
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) ];                               \
58     p_y += *p_offset++;                                                       \
59     p_u += *p_offset;                                                         \
60     p_v += *p_offset++;                                                       \
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     p_y += *p_offset++;                                                       \
66     p_u += *p_offset;                                                         \
67     p_v += *p_offset++;                                                       \
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) ];                               \
72     p_y += *p_offset++;                                                       \
73     p_u += *p_offset;                                                         \
74     p_v += *p_offset++;                                                       \
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) ];                               \
79     p_y += *p_offset++;                                                       \
80     p_u += *p_offset;                                                         \
81     p_v += *p_offset++;                                                       \
82
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 )                                                \
90     {                                                                         \
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--; )                                 \
94         {                                                                     \
95             CONVERT_4YUV_PIXELS_SCALE( CHROMA )                               \
96             CONVERT_4YUV_PIXELS_SCALE( CHROMA )                               \
97             CONVERT_4YUV_PIXELS_SCALE( CHROMA )                               \
98             CONVERT_4YUV_PIXELS_SCALE( CHROMA )                               \
99         }                                                                     \
100     }                                                                         \
101     else                                                                      \
102     {                                                                         \
103         for( i_x = i_width / 16; i_x--;  )                                    \
104         {                                                                     \
105             CONVERT_4YUV_PIXELS( CHROMA )                                     \
106             CONVERT_4YUV_PIXELS( CHROMA )                                     \
107             CONVERT_4YUV_PIXELS( CHROMA )                                     \
108             CONVERT_4YUV_PIXELS( CHROMA )                                     \
109         }                                                                     \
110     }                                                                         \
111     /* Increment of picture pointer to end of line is still needed */         \
112     p_pic += i_pic_line_width;                                                \
113                                                                               \
114     /* Increment the Y coordinate in the matrix, modulo 4 */                  \
115     i_real_y = (i_real_y + 1) & 0x3;                                          \
116
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 )                                         \
124                                                                               \
125     /* If line is odd, rewind 4:2:0 U and V samples */                        \
126     if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) )                \
127     {                                                                         \
128         p_u -= i_chroma_width;                                                \
129         p_v -= i_chroma_width;                                                \
130     }                                                                         \
131                                                                               \
132     /*                                                                        \
133      * Handle vertical scaling. The current line can be copied or next one    \
134      * can be ignored.                                                        \
135      */                                                                       \
136                                                                               \
137     switch( i_vertical_scaling )                                              \
138     {                                                                         \
139     case -1:                             /* vertical scaling factor is < 1 */ \
140         while( (i_scale_count -= i_pic_height) > 0 )                          \
141         {                                                                     \
142             /* Height reduction: skip next source line */                     \
143             p_y += i_width;                                                   \
144             i_y++;                                                            \
145             if( (CHROMA == 420) || (CHROMA == 422) )                          \
146             {                                                                 \
147                 if( i_y & 0x1 )                                               \
148                 {                                                             \
149                     p_u += i_chroma_width;                                    \
150                     p_v += i_chroma_width;                                    \
151                 }                                                             \
152             }                                                                 \
153             else if( CHROMA == 444 )                                          \
154             {                                                                 \
155                 p_u += i_width;                                               \
156                 p_v += i_width;                                               \
157             }                                                                 \
158         }                                                                     \
159         i_scale_count += i_height;                                            \
160         break;                                                                \
161     case 1:                              /* vertical scaling factor is > 1 */ \
162         while( (i_scale_count -= i_height) > 0 )                              \
163         {                                                                     \
164             p_y -= i_width;                                                   \
165             p_u -= i_chroma_width;                                            \
166             p_v -= i_chroma_width;                                            \
167             SCALE_WIDTH_DITHER( CHROMA );                                     \
168         }                                                                     \
169         i_scale_count += i_pic_height;                                        \
170         break;                                                                \
171     }                                                                         \
172