]> git.sesse.net Git - vlc/blob - plugins/yuv/transforms_common.h
87c5a9e3afefb618291dbab6ba0bdbe8aaa554f6
[vlc] / plugins / yuv / transforms_common.h
1 /*****************************************************************************
2  * transforms_common.h: YUV transformation macros for truecolor
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_YUV_PIXEL, CONVERT_Y_PIXEL: pixel conversion blocks
26  *****************************************************************************
27  * These conversion routines are used by YUV conversion functions.
28  * conversion are made from p_y, p_u, p_v, which are modified, to p_buffer,
29  * which is also modified.
30  *****************************************************************************/
31 #define CONVERT_Y_PIXEL( BPP )                                                \
32     /* Only Y sample is present */                                            \
33     p_ybase = p_yuv + *p_y++;                                                 \
34     *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] |     \
35         p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT)       \
36         + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
37
38 #define CONVERT_YUV_PIXEL( BPP )                                              \
39     /* Y, U and V samples are present */                                      \
40     i_uval =    *p_u++;                                                       \
41     i_vval =    *p_v++;                                                       \
42     i_red =     (V_RED_COEF * i_vval) >> SHIFT;                               \
43     i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;     \
44     i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;                              \
45     CONVERT_Y_PIXEL( BPP )                                                    \
46
47 /*****************************************************************************
48  * SCALE_WIDTH: scale a line horizontally
49  *****************************************************************************
50  * This macro scales a line using rendering buffer and offset array. It works
51  * for 1, 2 and 4 Bpp.
52  *****************************************************************************/
53 #define SCALE_WIDTH                                                           \
54     if( b_horizontal_scaling )                                                \
55     {                                                                         \
56         /* Horizontal scaling, conversion has been done to buffer.            \
57          * Rewind buffer and offset, then copy and scale line */              \
58         p_buffer = p_buffer_start;                                            \
59         p_offset = p_offset_start;                                            \
60         for( i_x = i_pic_width / 16; i_x--; )                                 \
61         {                                                                     \
62             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
63             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
64             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
65             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
66             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
67             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
68             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
69             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
70             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
71             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
72             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
73             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
74             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
75             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
76             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
77             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  \
78         }                                                                     \
79         p_pic += i_pic_line_width;                                            \
80     }                                                                         \
81     else                                                                      \
82     {                                                                         \
83         /* No scaling, conversion has been done directly in picture memory.   \
84          * Increment of picture pointer to end of line is still needed */     \
85         p_pic += i_pic_width + i_pic_line_width;                              \
86     }                                                                         \
87
88 /*****************************************************************************
89  * SCALE_HEIGHT: handle vertical scaling
90  *****************************************************************************
91  * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
92  * 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
93  * and 4 Bpp.
94  *****************************************************************************/
95 #define SCALE_HEIGHT( CHROMA, BPP )                                           \
96     /* If line is odd, rewind 4:2:0 U and V samples */                        \
97     if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) )                \
98     {                                                                         \
99         p_u -= i_chroma_width;                                                \
100         p_v -= i_chroma_width;                                                \
101     }                                                                         \
102                                                                               \
103     /*                                                                        \
104      * Handle vertical scaling. The current line can be copied or next one    \
105      * can be ignored.                                                        \
106      */                                                                       \
107     switch( i_vertical_scaling )                                              \
108     {                                                                         \
109     case -1:                             /* vertical scaling factor is < 1 */ \
110         while( (i_scale_count -= i_pic_height) > 0 )                          \
111         {                                                                     \
112             /* Height reduction: skip next source line */                     \
113             p_y += i_width;                                                   \
114             i_y++;                                                            \
115             if( (CHROMA == 420) || (CHROMA == 422) )                          \
116             {                                                                 \
117                 if( i_y & 0x1 )                                               \
118                 {                                                             \
119                     p_u += i_chroma_width;                                    \
120                     p_v += i_chroma_width;                                    \
121                 }                                                             \
122             }                                                                 \
123             else if( CHROMA == 444 )                                          \
124             {                                                                 \
125                 p_u += i_width;                                               \
126                 p_v += i_width;                                               \
127             }                                                                 \
128         }                                                                     \
129         i_scale_count += i_height;                                            \
130         break;                                                                \
131     case 1:                              /* vertical scaling factor is > 1 */ \
132         while( (i_scale_count -= i_height) > 0 )                              \
133         {                                                                     \
134             /* Height increment: copy previous picture line */                \
135             for( i_x = i_pic_width / 16; i_x--; )                             \
136             {                                                                 \
137                 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );           \
138                 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );           \
139                 if( BPP > 1 )                               /* 2, 3, 4 Bpp */ \
140                 {                                                             \
141                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
142                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
143                 }                                                             \
144                 if( BPP > 2 )                                  /* 3, 4 Bpp */ \
145                 {                                                             \
146                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
147                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
148                 }                                                             \
149                 if( BPP > 3 )                                     /* 4 Bpp */ \
150                 {                                                             \
151                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
152                     *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
153                 }                                                             \
154             }                                                                 \
155             p_pic +=        i_pic_line_width;                                 \
156             p_pic_start +=  i_pic_line_width;                                 \
157         }                                                                     \
158         i_scale_count += i_pic_height;                                        \
159         break;                                                                \
160     }                                                                         \
161