Spelling Cleanup
[blender.git] / source / gameengine / VideoTexture / ImageBase.h
1 /*
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 /** \file ImageBase.h
24  *  \ingroup bgevideotex
25  */
26  
27 #if !defined IMAGEBASE_H
28 #define IMAGEBASE_H
29
30 #include "Common.h"
31
32 #include <vector>
33 #include <PyObjectPlus.h>
34
35 #include "PyTypeList.h"
36
37 #include "FilterBase.h"
38
39
40 // forward declarations
41 struct PyImage;
42 class ImageSource;
43
44
45 /// type for list of image sources
46 typedef std::vector<ImageSource*> ImageSourceList;
47
48
49 /// base class for image filters
50 class ImageBase
51 {
52 public:
53         /// constructor
54         ImageBase (bool staticSrc = false);
55         /// destructor
56         virtual ~ImageBase (void);
57         /// release contained objects, if returns true, object should be deleted
58         virtual bool release (void);
59
60         /// is an image available
61         bool isImageAvailable(void)
62         { return m_avail; }
63         /// get image
64         unsigned int * getImage (unsigned int texId = 0, double timestamp=-1.0);
65         /// get image size
66         short * getSize (void) { return m_size; }
67         /// get image buffer size
68         unsigned long getBuffSize (void)
69         { return m_size[0] * m_size[1] * sizeof(unsigned int); }
70         /// refresh image - invalidate its current content
71         virtual void refresh (void);
72
73         /// get scale
74         bool getScale (void) { return m_scale; }
75         /// set scale
76         void setScale (bool scale) { m_scale = scale; m_scaleChange = true; }
77         /// get vertical flip
78         bool getFlip (void) { return m_flip; }
79         /// set vertical flip
80         void setFlip (bool flip) { m_flip = flip; }
81
82         /// get source object
83         PyImage * getSource (const char * id);
84         /// set source object, return true, if source was set
85         bool setSource (const char * id, PyImage * source);
86
87         /// get pixel filter
88         PyFilter * getFilter (void) { return m_pyfilter; }
89         /// set pixel filter
90         void setFilter (PyFilter * filt);
91
92         /// calculate size (nearest power of 2)
93         static short calcSize (short size);
94
95         /// number of buffer pointing to m_image, public because not handled by this class
96         int m_exports;
97
98 protected:
99         /// image buffer
100         unsigned int * m_image;
101         /// image buffer size
102         unsigned int m_imgSize;
103         /// image size
104         short m_size[2];
105         /// image is available
106         bool m_avail;
107
108         /// scale image to power 2 sizes
109         bool m_scale;
110         /// scale was changed
111         bool m_scaleChange;
112         /// flip image vertically
113         bool m_flip;
114
115         /// source image list
116         ImageSourceList m_sources;
117         /// flag for disabling addition and deletion of sources
118         bool m_staticSources;
119
120         /// pixel filter
121         PyFilter * m_pyfilter;
122
123         /// initialize image data
124         void init (short width, short height);
125
126         /// find source
127         ImageSourceList::iterator findSource (const char * id);
128
129         /// create new source
130         virtual ImageSource * newSource (const char * id) { return NULL; }
131
132         /// check source sizes
133         bool checkSourceSizes (void);
134
135         /// calculate image from sources and set its availability
136         virtual void calcImage (unsigned int texId, double ts) {}
137
138         /// perform loop detection
139         bool loopDetect (ImageBase * img);
140
141         /// template for image conversion
142         template<class FLT, class SRC> void convImage (FLT & filter, SRC srcBuff,
143                 short * srcSize)
144         {
145                 // destination buffer
146                 unsigned int * dstBuff = m_image;
147                 // pixel size from filter
148                 unsigned int pixSize = filter.firstPixelSize();
149                 // if no scaling is needed
150                 if (srcSize[0] == m_size[0] && srcSize[1] == m_size[1])
151                         // if flipping isn't required
152                         if (!m_flip)
153                                 // copy bitmap
154                                 for (short y = 0; y < m_size[1]; ++y)
155                                         for (short x = 0; x < m_size[0]; ++x, ++dstBuff, srcBuff += pixSize)
156                                                 // copy pixel
157                                                 *dstBuff = filter.convert(srcBuff, x, y, srcSize, pixSize);
158                 // otherwise flip image top to bottom
159                         else
160                         {
161                                 // go to last row of image
162                                 srcBuff += srcSize[0] * (srcSize[1] - 1) * pixSize;
163                                 // copy bitmap
164                                 for (short y = m_size[1] - 1; y >= 0; --y, srcBuff -= 2 * srcSize[0] * pixSize)
165                                         for (short x = 0; x < m_size[0]; ++x, ++dstBuff, srcBuff += pixSize)
166                                                 // copy pixel
167                                                 *dstBuff = filter.convert(srcBuff, x, y, srcSize, pixSize);
168                         }
169                         // else scale picture (nearest neighbor)
170                 else
171                 {
172                         // interpolation accumulator
173                         int accHeight = srcSize[1] >> 1;
174                         // if flipping is required
175                         if (m_flip)
176                                 // go to last row of image
177                                 srcBuff += srcSize[0] * (srcSize[1] - 1) * pixSize;
178                         // process image rows
179                         for (int y = 0; y < srcSize[1]; ++y)
180                         {
181                                 // increase height accum
182                                 accHeight += m_size[1];
183                                 // if pixel row has to be drawn
184                                 if (accHeight >= srcSize[1])
185                                 {
186                                         // decrease accum
187                                         accHeight -= srcSize[1];
188                                         // width accum
189                                         int accWidth = srcSize[0] >> 1;
190                                         // process row
191                                         for (int x = 0; x < srcSize[0]; ++x)
192                                         {
193                                                 // increase width accum
194                                                 accWidth += m_size[0];
195                                                 // if pixel has to be drawn
196                                                 if (accWidth >= srcSize[0])
197                                                 {
198                                                         // decrease accum
199                                                         accWidth -= srcSize[0];
200                                                         // convert pixel
201                                                         *dstBuff = filter.convert(srcBuff, x, m_flip ? srcSize[1] - y - 1 : y,
202                                                                 srcSize, pixSize);
203                                                         // next pixel
204                                                         ++dstBuff;
205                                                 }
206                                                 // shift source pointer
207                                                 srcBuff += pixSize;
208                                         }
209                                 }
210                                 // if pixel row will not be drawn
211                                 else
212                                         // move source pointer to next row
213                                         srcBuff += pixSize * srcSize[0];
214                                 // if y flipping is required
215                                 if (m_flip)
216                                         // go to previous row of image
217                                         srcBuff -= 2 * pixSize * srcSize[0];
218                         }
219                 }
220         }
221
222         // template for specific filter preprocessing
223         template <class F, class SRC> void filterImage (F & filt, SRC srcBuff, short * srcSize)
224         {
225                 // find first filter in chain
226                 FilterBase * firstFilter = NULL;
227                 if (m_pyfilter != NULL) firstFilter = m_pyfilter->m_filter->findFirst();
228                 // if first filter is available
229                 if (firstFilter != NULL)
230                 {
231                         // python wrapper for filter
232                         PyFilter pyFilt;
233                         pyFilt.m_filter = &filt;
234                         // set specified filter as first in chain
235                         firstFilter->setPrevious(&pyFilt, false);
236                         // convert video image
237                         convImage(*(m_pyfilter->m_filter), srcBuff, srcSize);
238                         // delete added filter
239                         firstFilter->setPrevious(NULL, false);
240                 }
241                 // otherwise use given filter for conversion
242                 else convImage(filt, srcBuff, srcSize);
243                 // source was processed
244                 m_avail = true;
245         }
246 };
247
248
249 // python structure for image filter
250 struct PyImage
251 {
252         PyObject_HEAD
253         // source object
254         ImageBase * m_image;
255 };
256
257
258 // size of id
259 const int SourceIdSize = 32;
260
261
262 /// class for source of image
263 class ImageSource
264 {
265 public:
266         /// constructor
267         ImageSource (const char * id);
268         /// destructor
269         virtual ~ImageSource (void);
270
271         /// get id
272         const char * getId (void) { return m_id; }
273         /// compare id to argument
274         bool is (const char * id);
275
276         /// get source object
277         PyImage * getSource (void) { return m_source; }
278         /// set source object
279         void setSource (PyImage * source);
280
281         /// get image from source
282         unsigned int * getImage (double ts=-1.0);
283         /// get buffered image
284         unsigned int * getImageBuf (void) { return m_image; }
285         /// refresh source
286         void refresh (void);
287
288         /// get image size
289         short * getSize (void)
290         { 
291                 static short defSize [] = {0, 0};
292                 return m_source != NULL ? m_source->m_image->getSize() : defSize;
293         }
294
295 protected:
296         /// id of source
297         char m_id [SourceIdSize];
298         /// pointer to source structure
299         PyImage * m_source;
300         /// buffered image from source
301         unsigned int * m_image;
302
303 private:
304         /// default constructor is forbidden
305         ImageSource (void) {}
306 };
307
308 // list of python image types
309 extern PyTypeList pyImageTypes;
310
311
312 // functions for python interface
313
314 // object initialization
315 template <class T> static int Image_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
316 {
317         PyImage * self = reinterpret_cast<PyImage*>(pySelf);
318         // create source object
319         if (self->m_image != NULL) delete self->m_image;
320         self->m_image = new T();
321         // initialization succeded
322         return 0;
323 }
324
325 // object allocation
326 PyObject * Image_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds);
327 // object deallocation
328 void Image_dealloc (PyImage * self);
329
330 // get image data
331 PyObject * Image_getImage (PyImage * self, char * mode);
332 // get image size
333 PyObject * Image_getSize (PyImage * self, void * closure);
334 // refresh image - invalidate current content
335 PyObject * Image_refresh (PyImage * self);
336
337 // get scale
338 PyObject * Image_getScale (PyImage * self, void * closure);
339 // set scale
340 int Image_setScale (PyImage * self, PyObject * value, void * closure);
341 // get flip
342 PyObject * Image_getFlip (PyImage * self, void * closure);
343 // set flip
344 int Image_setFlip (PyImage * self, PyObject * value, void * closure);
345
346 // get filter source object
347 PyObject * Image_getSource (PyImage * self, PyObject * args);
348 // set filter source object
349 PyObject * Image_setSource (PyImage * self, PyObject * args);
350
351 // get pixel filter object
352 PyObject * Image_getFilter (PyImage * self, void * closure);
353 // set pixel filter object
354 int Image_setFilter (PyImage * self, PyObject * value, void * closure);
355 // check if a buffer can be extracted
356 PyObject * Image_valid(PyImage * self, void * closure);
357 // for buffer access to PyImage objects
358 extern PyBufferProcs imageBufferProcs;
359
360 #endif