VideoTexture: use PyObjectPlus.h instead of Python.h for compatibility with Python2.3
[blender.git] / source / gameengine / VideoTexture / FilterSource.h
1 /* $Id$
2 -----------------------------------------------------------------------------
3 This source file is part of blendTex library
4
5 Copyright (c) 2007 The Zdeno Ash Miklas
6
7 This program is free software; you can redistribute it and/or modify it under
8 the terms of the GNU Lesser General Public License as published by the Free Software
9 Foundation; either version 2 of the License, or (at your option) any later
10 version.
11
12 This program is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
19 http://www.gnu.org/copyleft/lesser.txt.
20 -----------------------------------------------------------------------------
21 */
22
23 #if !defined FILTERSOURCE_H
24 #define FILTERSOURCE_H
25
26 #include "Common.h"
27
28 #include "FilterBase.h"
29
30
31 /// class for RGB24 conversion
32 class FilterRGB24 : public FilterBase
33 {
34 public:
35         /// constructor
36         FilterRGB24 (void) {}
37         /// destructor
38         virtual ~FilterRGB24 (void) {}
39
40         /// get source pixel size
41         virtual unsigned int getPixelSize (void) { return 3; }
42
43 protected:
44         /// filter pixel, source byte buffer
45         virtual unsigned int filter (unsigned char * src, short x, short y,
46                 short * size, unsigned int pixSize, unsigned int val)
47         { return 0xFF000000 | src[0] << 16 | src[1] << 8 | src[2]; }
48 };
49
50 /// class for BGR24 conversion
51 class FilterBGR24 : public FilterBase
52 {
53 public:
54         /// constructor
55         FilterBGR24 (void) {}
56         /// destructor
57         virtual ~FilterBGR24 (void) {}
58
59         /// get source pixel size
60         virtual unsigned int getPixelSize (void) { return 3; }
61
62 protected:
63         /// filter pixel, source byte buffer
64         virtual unsigned int filter (unsigned char * src, short x, short y,
65                 short * size, unsigned int pixSize, unsigned int val)
66         { return 0xFF000000 | src[2] << 16 | src[1] << 8 | src[0]; }
67 };
68
69 /// class for YV12 conversion
70 class FilterYV12 : public FilterBase
71 {
72 public:
73         /// constructor
74         FilterYV12 (void) {}
75         /// destructor
76         virtual ~FilterYV12 (void) {}
77
78         /// get source pixel size
79         virtual unsigned int getPixelSize (void) { return 1; }
80
81         /// set pointers to color buffers
82         void setBuffs (unsigned char * buff, short * size)
83         {
84                 unsigned int buffSize = size[0] * size[1];
85                 m_buffV = buff + buffSize;
86                 m_buffU = m_buffV + (buffSize >> 2);
87                 m_pitchUV = size[0] >> 1;
88         }
89
90 protected:
91         /// begin of V buffer
92         unsigned char * m_buffV;
93         /// begin of U buffer
94         unsigned char * m_buffU;
95         /// pitch for V & U buffers
96         short m_pitchUV;
97
98         /// interpolation function
99         int interpol (int a, int b, int c, int d)
100         { return (9 * (b + c) - a - d + 8) >> 4; }
101
102         /// common horizontal interpolation
103         int interpolH (unsigned char * src)
104         { return interpol(*(src-1), *src, *(src+1), *(src+2)); }
105
106         /// common vertical interpolation
107         int interpolV (unsigned char * src)
108         { return interpol(*(src-m_pitchUV), *src, *(src+m_pitchUV), *(src+2*m_pitchUV)); }
109
110         /// common joined vertical and horizontal interpolation
111         int interpolVH (unsigned char * src)
112         {
113                 return interpol(interpolV(src-1), interpolV(src), interpolV(src+1),
114                         interpolV(src+2));
115         }
116
117         /// is pixel on edge
118         bool isEdge (short x, short y, short * size)
119         { return x <= 1 || x >= size[0] - 4 || y <= 1 || y >= size[1] - 4; }
120
121         /// get the first parameter on the low edge
122         unsigned char * interParA (unsigned char * src, short x, short size, short shift)
123         { return x > 1 ? src - shift : src; }
124         /// get the third parameter on the high edge
125         unsigned char * interParC (unsigned char * src, short x, short size, short shift)
126         { return x < size - 2 ? src + shift : src; }
127         /// get the fourth parameter on the high edge
128         unsigned char * interParD (unsigned char * src, short x, short size, short shift)
129         { return x < size - 4 ? src + 2 * shift : x < size - 2 ? src + shift : src; }
130
131         /// horizontal interpolation on edges
132         int interpolEH (unsigned char * src, short x, short size)
133         { 
134                 return interpol(*interParA(src, x, size, 1), *src,
135                         *interParC(src, x, size, 1), *interParD(src, x, size, 1));
136         }
137
138         /// vertical interpolation on edges
139         int interpolEV (unsigned char * src, short y, short size)
140         { 
141                 return interpol(*interParA(src, y, size, m_pitchUV), *src,
142                         *interParC(src, y, size, m_pitchUV), *interParD(src, y, size, m_pitchUV));
143         }
144
145         /// joined vertical and horizontal interpolation on edges
146         int interpolEVH (unsigned char * src, short x, short y, short * size)
147         {
148                 return interpol(interpolEV(interParA(src, x, size[0], 1), y, size[1]),
149                         interpolEV(src, y, size[1]), interpolEV(interParC(src, x, size[0], 1), y, size[1]),
150                         interpolEV(interParD(src, x, size[0], 1), y, size[1]));
151         }
152
153
154         /// filter pixel, source byte buffer
155         virtual unsigned int filter (unsigned char * src, short x, short y,
156                 short * size, unsigned int pixSize, unsigned int val)
157         {
158                 // V & U offset
159                 long offset = (x >> 1) + m_pitchUV * (y >> 1);
160                 // get modified YUV -> CDE: C = Y - 16; D = U - 128; E = V - 128
161                 int c = *src - 16;
162                 int d = m_buffU[offset] - 128;
163                 int e = m_buffV[offset] - 128;
164                 // if horizontal interpolation is needed
165                 if ((x & 1) == 1)
166                         // if vertical interpolation is needed too
167                         if ((y & 1) == 1)
168                                 // if this pixel is on the edge
169                                 if (isEdge(x, y, size))
170                                 {
171                                         // get U & V from edge
172                                         d = interpolEVH(m_buffU + offset, x, y, size) - 128;
173                                         e = interpolEVH(m_buffV + offset, x, y, size) - 128;
174                                 }
175                                 // otherwise get U & V from inner range
176                                 else
177                                 {
178                                         d = interpolVH(m_buffU + offset) - 128;
179                                         e = interpolVH(m_buffV + offset) - 128;
180                                 }
181                                 // otherwise use horizontal interpolation only
182                         else
183                                 // if this pixel is on the edge
184                                 if (isEdge(x, y, size))
185                                 {
186                                         // get U & V from edge
187                                         d = interpolEH(m_buffU + offset, x, size[0]) - 128;
188                                         e = interpolEH(m_buffV + offset, x, size[0]) - 128;
189                                 }
190                                 // otherwise get U & V from inner range
191                                 else
192                                 {
193                                         d = interpolH(m_buffU + offset) - 128;
194                                         e = interpolH(m_buffV + offset) - 128;
195                                 }
196                                 // otherwise if only vertical interpolation is needed
197                 else if ((y & 1) == 1)
198                         // if this pixel is on the edge
199                         if (isEdge(x, y, size))
200                         {
201                                 // get U & V from edge
202                                 d = interpolEV(m_buffU + offset, y, size[1]) - 128;
203                                 e = interpolEV(m_buffV + offset, y, size[1]) - 128;
204                         }
205                         // otherwise get U & V from inner range
206                         else
207                         {
208                                 d = interpolV(m_buffU + offset) - 128;
209                                 e = interpolV(m_buffV + offset) - 128;
210                         }
211                 // convert to RGB
212                 // R = clip(( 298 * C           + 409 * E + 128) >> 8)
213                 // G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
214                 // B = clip(( 298 * C + 516 * D           + 128) >> 8)
215                 int red = (298 * c + 409 * e + 128) >> 8;
216                 if (red >= 0x100) red = 0xFF;
217                 else if (red < 0) red = 0;
218                 int green = 298 * c - 100 * d - 208 * e;
219                 if (green > 0x10000) green = 0xFF00;
220                 else if (green < 0) green = 0;
221                 int blue = (298 * c + 516 * d + 128) << 8;
222                 if (blue > 0x1000000) blue = 0xFF0000;
223                 else if (blue < 0) blue = 0;
224                 // return result
225                 return 0xFF000000 | blue & 0xFF0000 | green & 0xFF00
226                         | red & 0xFF;
227         }
228 };
229
230
231 #endif