code cleanup: gpl header update (formatting)
[blender.git] / source / gameengine / VideoTexture / FilterSource.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Copyright (c) 2007 The Zdeno Ash Miklas
19  *
20  * This source file is part of blendTex library
21  *
22  * Contributor(s):
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file FilterSource.h
28  *  \ingroup bgevideotex
29  */
30
31 #ifndef __FILTERSOURCE_H__
32 #define __FILTERSOURCE_H__
33
34 #include "Common.h"
35
36 #include "FilterBase.h"
37
38 /// class for RGB24 conversion
39 class FilterRGB24 : public FilterBase
40 {
41 public:
42         /// constructor
43         FilterRGB24 (void) {}
44         /// destructor
45         virtual ~FilterRGB24 (void) {}
46
47         /// get source pixel size
48         virtual unsigned int getPixelSize (void) { return 3; }
49
50 protected:
51         /// filter pixel, source byte buffer
52         virtual unsigned int filter (unsigned char * src, short x, short y,
53                 short * size, unsigned int pixSize, unsigned int val)
54         { VT_RGBA(val,src[0],src[1],src[2],0xFF); return val; }
55 };
56
57 /// class for RGBA32 conversion
58 class FilterRGBA32 : public FilterBase
59 {
60 public:
61         /// constructor
62         FilterRGBA32 (void) {}
63         /// destructor
64         virtual ~FilterRGBA32 (void) {}
65
66         /// get source pixel size
67         virtual unsigned int getPixelSize (void) { return 4; }
68
69 protected:
70         /// filter pixel, source byte buffer
71         virtual unsigned int filter (unsigned char * src, short x, short y,
72                 short * size, unsigned int pixSize, unsigned int val)
73         { 
74                 if ((intptr_t(src)&0x3) == 0) 
75                         return *(unsigned int*)src;
76                 else 
77                 {
78                         VT_RGBA(val,src[0],src[1],src[2],src[3]); 
79                         return val; 
80                 }
81         }
82 };
83
84 /// class for BGR24 conversion
85 class FilterBGR24 : public FilterBase
86 {
87 public:
88         /// constructor
89         FilterBGR24 (void) {}
90         /// destructor
91         virtual ~FilterBGR24 (void) {}
92
93         /// get source pixel size
94         virtual unsigned int getPixelSize (void) { return 3; }
95
96 protected:
97         /// filter pixel, source byte buffer
98         virtual unsigned int filter (unsigned char * src, short x, short y,
99                 short * size, unsigned int pixSize, unsigned int val)
100         { VT_RGBA(val,src[2],src[1],src[0],0xFF); return val; }
101 };
102
103 /// class for Z_buffer conversion
104 class FilterZZZA : public FilterBase
105 {
106 public:
107         /// constructor
108         FilterZZZA (void) {}
109         /// destructor
110         virtual ~FilterZZZA (void) {}
111
112         /// get source pixel size
113         virtual unsigned int getPixelSize (void) { return 1; }
114
115 protected:
116         /// filter pixel, source float buffer
117         virtual unsigned int filter (float * src, short x, short y,
118                 short * size, unsigned int pixSize, unsigned int val)
119         {
120                 // calculate gray value
121         // convert float to unsigned char
122                 unsigned int depth = int(src[0] * 255);
123                 // return depth scale value
124                 VT_R(val) = depth;
125                 VT_G(val) = depth;
126                 VT_B(val) = depth;
127                 VT_A(val) = 0xFF;
128
129                 return val;
130         }
131 };
132
133
134 /// class for Z_buffer conversion
135 class FilterDEPTH : public FilterBase
136 {
137 public:
138         /// constructor
139         FilterDEPTH (void) {}
140         /// destructor
141         virtual ~FilterDEPTH (void) {}
142
143         /// get source pixel size
144         virtual unsigned int getPixelSize (void) { return 1; }
145
146 protected:
147         /// filter pixel, source float buffer
148         virtual unsigned int filter (float * src, short x, short y,
149                                      short * size, unsigned int pixSize, unsigned int val)
150         {
151                 /* Copy the float value straight away
152                  * The user can retrieve the original float value by using
153                  * 'F' mode in BGL buffer */
154                 memcpy(&val, src, sizeof (unsigned int));
155                 return val;
156         }
157 };
158
159
160
161
162 /// class for YV12 conversion
163 class FilterYV12 : public FilterBase
164 {
165 public:
166         /// constructor
167         FilterYV12 (void) {}
168         /// destructor
169         virtual ~FilterYV12 (void) {}
170
171         /// get source pixel size
172         virtual unsigned int getPixelSize (void) { return 1; }
173
174         /// set pointers to color buffers
175         void setBuffs (unsigned char * buff, short * size)
176         {
177                 unsigned int buffSize = size[0] * size[1];
178                 m_buffV = buff + buffSize;
179                 m_buffU = m_buffV + (buffSize >> 2);
180                 m_pitchUV = size[0] >> 1;
181         }
182
183 protected:
184         /// begin of V buffer
185         unsigned char * m_buffV;
186         /// begin of U buffer
187         unsigned char * m_buffU;
188         /// pitch for V & U buffers
189         short m_pitchUV;
190
191         /// interpolation function
192         int interpol (int a, int b, int c, int d)
193         { return (9 * (b + c) - a - d + 8) >> 4; }
194
195         /// common horizontal interpolation
196         int interpolH (unsigned char * src)
197         { return interpol(*(src-1), *src, *(src+1), *(src+2)); }
198
199         /// common vertical interpolation
200         int interpolV (unsigned char * src)
201         { return interpol(*(src-m_pitchUV), *src, *(src+m_pitchUV), *(src+2*m_pitchUV)); }
202
203         /// common joined vertical and horizontal interpolation
204         int interpolVH (unsigned char * src)
205         {
206                 return interpol(interpolV(src-1), interpolV(src), interpolV(src+1),
207                         interpolV(src+2));
208         }
209
210         /// is pixel on edge
211         bool isEdge (short x, short y, short * size)
212         { return x <= 1 || x >= size[0] - 4 || y <= 1 || y >= size[1] - 4; }
213
214         /// get the first parameter on the low edge
215         unsigned char * interParA (unsigned char * src, short x, short size, short shift)
216         { return x > 1 ? src - shift : src; }
217         /// get the third parameter on the high edge
218         unsigned char * interParC (unsigned char * src, short x, short size, short shift)
219         { return x < size - 2 ? src + shift : src; }
220         /// get the fourth parameter on the high edge
221         unsigned char * interParD (unsigned char * src, short x, short size, short shift)
222         { return x < size - 4 ? src + 2 * shift : x < size - 2 ? src + shift : src; }
223
224         /// horizontal interpolation on edges
225         int interpolEH (unsigned char * src, short x, short size)
226         { 
227                 return interpol(*interParA(src, x, size, 1), *src,
228                         *interParC(src, x, size, 1), *interParD(src, x, size, 1));
229         }
230
231         /// vertical interpolation on edges
232         int interpolEV (unsigned char * src, short y, short size)
233         { 
234                 return interpol(*interParA(src, y, size, m_pitchUV), *src,
235                         *interParC(src, y, size, m_pitchUV), *interParD(src, y, size, m_pitchUV));
236         }
237
238         /// joined vertical and horizontal interpolation on edges
239         int interpolEVH (unsigned char * src, short x, short y, short * size)
240         {
241                 return interpol(interpolEV(interParA(src, x, size[0], 1), y, size[1]),
242                         interpolEV(src, y, size[1]), interpolEV(interParC(src, x, size[0], 1), y, size[1]),
243                         interpolEV(interParD(src, x, size[0], 1), y, size[1]));
244         }
245
246
247         /// filter pixel, source byte buffer
248         virtual unsigned int filter (unsigned char * src, short x, short y,
249                 short * size, unsigned int pixSize, unsigned int val)
250         {
251                 // V & U offset
252                 long offset = (x >> 1) + m_pitchUV * (y >> 1);
253                 // get modified YUV -> CDE: C = Y - 16; D = U - 128; E = V - 128
254                 int c = *src - 16;
255                 int d = m_buffU[offset] - 128;
256                 int e = m_buffV[offset] - 128;
257                 // if horizontal interpolation is needed
258                 if ((x & 1) == 1) {
259                         // if vertical interpolation is needed too
260                         if ((y & 1) == 1)
261                         {
262                                 // if this pixel is on the edge
263                                 if (isEdge(x, y, size))
264                                 {
265                                         // get U & V from edge
266                                         d = interpolEVH(m_buffU + offset, x, y, size) - 128;
267                                         e = interpolEVH(m_buffV + offset, x, y, size) - 128;
268                                 }
269                                 // otherwise get U & V from inner range
270                                 else
271                                 {
272                                         d = interpolVH(m_buffU + offset) - 128;
273                                         e = interpolVH(m_buffV + offset) - 128;
274                                 }
275                                 // otherwise use horizontal interpolation only
276                         }
277                         else {
278                                 // if this pixel is on the edge
279                                 if (isEdge(x, y, size))
280                                 {
281                                         // get U & V from edge
282                                         d = interpolEH(m_buffU + offset, x, size[0]) - 128;
283                                         e = interpolEH(m_buffV + offset, x, size[0]) - 128;
284                                 }
285                                 // otherwise get U & V from inner range
286                                 else
287                                 {
288                                         d = interpolH(m_buffU + offset) - 128;
289                                         e = interpolH(m_buffV + offset) - 128;
290                                 }
291                                 // otherwise if only vertical interpolation is needed
292                         }
293                 }
294                 else if ((y & 1) == 1) {
295                         // if this pixel is on the edge
296                         if (isEdge(x, y, size))
297                         {
298                                 // get U & V from edge
299                                 d = interpolEV(m_buffU + offset, y, size[1]) - 128;
300                                 e = interpolEV(m_buffV + offset, y, size[1]) - 128;
301                         }
302                         // otherwise get U & V from inner range
303                         else
304                         {
305                                 d = interpolV(m_buffU + offset) - 128;
306                                 e = interpolV(m_buffV + offset) - 128;
307                         }
308                 }
309                 // convert to RGB
310                 // R = clip(( 298 * C           + 409 * E + 128) >> 8)
311                 // G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
312                 // B = clip(( 298 * C + 516 * D           + 128) >> 8)
313                 int red = (298 * c + 409 * e + 128) >> 8;
314                 if (red >= 0x100) red = 0xFF;
315                 else if (red < 0) red = 0;
316                 int green = (298 * c - 100 * d - 208 * e) >> 8;
317                 if (green >= 0x100) green = 0xFF;
318                 else if (green < 0) green = 0;
319                 int blue = (298 * c + 516 * d + 128) >> 8;
320                 if (blue >= 0x100) blue = 0xFF;
321                 else if (blue < 0) blue = 0;
322                 // return result
323                 VT_RGBA(val, red, green, blue, 0xFF);
324                 return val;
325         }
326 };
327
328
329 #endif