3b6dec21e5232a49a3a14c8111587f6b1267119d
[blender.git] / source / gameengine / VideoTexture / ImageBase.cpp
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 VideoTexture library
21  *
22  * Contributor(s):
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file gameengine/VideoTexture/ImageBase.cpp
28  *  \ingroup bgevideotex
29  */
30
31 #include "ImageBase.h"
32 extern "C" {
33 #include "bgl.h"
34 }
35 #include "GL/glew.h"
36
37 #include <vector>
38 #include <string.h>
39
40 #include "PyObjectPlus.h"
41 #include <structmember.h>
42
43 #include "FilterBase.h"
44
45 #include "Exception.h"
46
47 #if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS)
48 #define strcasecmp      _stricmp
49 #endif
50
51 // ImageBase class implementation
52
53 // constructor
54 ImageBase::ImageBase (bool staticSrc) : m_image(NULL), m_imgSize(0),
55 m_avail(false), m_scale(false), m_scaleChange(false), m_flip(false),
56 m_zbuff(false),
57 m_depth(false),
58 m_staticSources(staticSrc), m_pyfilter(NULL)
59 {
60         m_size[0] = m_size[1] = 0;
61         m_exports = 0;
62 }
63
64
65 // destructor
66 ImageBase::~ImageBase (void)
67 {
68         // release image
69         if (m_image)
70                 delete [] m_image;
71 }
72
73
74 // release python objects
75 bool ImageBase::release (void)
76 {
77         // iterate sources
78         for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
79         {
80                 // release source object
81                 delete *it;
82                 *it = NULL;
83         }
84         // release filter object
85         Py_XDECREF(m_pyfilter);
86         m_pyfilter = NULL;
87         return true;
88 }
89
90
91 // get image
92 unsigned int * ImageBase::getImage (unsigned int texId, double ts)
93 {
94         // if image is not available
95         if (!m_avail)
96         {
97                 // if there are any sources
98                 if (!m_sources.empty())
99                 {
100                         // get images from sources
101                         for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
102                                 // get source image
103                                 (*it)->getImage(ts);
104                         // init image
105                         init(m_sources[0]->getSize()[0], m_sources[0]->getSize()[1]);
106                 }
107                 // calculate new image
108                 calcImage(texId, ts);
109         }
110         // if image is available, return it, otherwise NULL
111         return m_avail ? m_image : NULL;
112 }
113
114
115 // refresh image source
116 void ImageBase::refresh (void)
117 {
118         // invalidate this image
119         m_avail = false;
120         // refresh all sources
121         for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
122                 (*it)->refresh();
123 }
124
125
126 // get source object
127 PyImage * ImageBase::getSource (const char * id)
128 {
129         // find source
130         ImageSourceList::iterator src = findSource(id);
131         // return it, if found
132         return src != m_sources.end() ? (*src)->getSource() : NULL;
133 }
134
135
136 // set source object
137 bool ImageBase::setSource (const char * id, PyImage *source)
138 {
139         // find source
140         ImageSourceList::iterator src = findSource(id);
141         // check source loop
142         if (source != NULL && source->m_image->loopDetect(this))
143                 return false;
144         // if found, set new object
145         if (src != m_sources.end())
146                 // if new object is not empty or sources are static
147                 if (source != NULL || m_staticSources)
148                         // replace previous source
149                         (*src)->setSource(source);
150                 // otherwise delete source
151                 else
152                         m_sources.erase(src);
153         // if source is not found and adding is allowed
154         else
155                 if (!m_staticSources)
156                 {
157                         // create new source
158                         ImageSource * newSrc = newSource(id);
159                         newSrc->setSource(source);
160                         // if source was created, add it to source list
161                         if (newSrc != NULL) m_sources.push_back(newSrc);
162                 }
163                 // otherwise source wasn't set
164                 else 
165                         return false;
166         // source was set
167         return true;
168 }
169
170
171 // set pixel filter
172 void ImageBase::setFilter (PyFilter * filt)
173 {
174         // reference new filter
175         if (filt != NULL) Py_INCREF(filt);
176         // release previous filter
177         Py_XDECREF(m_pyfilter);
178         // set new filter
179         m_pyfilter = filt;
180 }
181
182 ExceptionID ImageHasExports;
183 ExceptionID InvalidColorChannel;
184
185 ExpDesc ImageHasExportsDesc (ImageHasExports, "Image has exported buffers, cannot resize");
186 ExpDesc InvalidColorChannelDesc (InvalidColorChannel, "Invalid or too many color channels specified. At most 4 values within R, G, B, A, 0, 1");
187
188 // initialize image data
189 void ImageBase::init (short width, short height)
190 {
191         // if image has to be scaled
192         if (m_scale)
193         {
194                 // recalc sizes of image
195                 width = calcSize(width);
196                 height = calcSize(height);
197         }
198         // if sizes differ
199         if (width != m_size[0] || height != m_size[1])
200         {
201                 if (m_exports > 0)
202                         THRWEXCP(ImageHasExports,S_OK);
203
204                 // new buffer size
205                 unsigned int newSize = width * height;
206                 // if new buffer is larger than previous
207                 if (newSize > m_imgSize)
208                 {
209                         // set new buffer size
210                         m_imgSize = newSize;
211                         // release previous and create new buffer
212                         if (m_image)
213                                 delete [] m_image;
214                         m_image = new unsigned int[m_imgSize];
215                 }
216                 // new image size
217                 m_size[0] = width;
218                 m_size[1] = height;
219                 // scale was processed
220                 m_scaleChange = false;
221         }
222 }
223
224
225 // find source
226 ImageSourceList::iterator ImageBase::findSource (const char * id)
227 {
228         // iterate sources
229         ImageSourceList::iterator it;
230         for (it = m_sources.begin(); it != m_sources.end(); ++it)
231                 // if id matches, return iterator
232                 if ((*it)->is(id)) return it;
233         // source not found
234         return it;
235 }
236
237
238 // check sources sizes
239 bool ImageBase::checkSourceSizes (void)
240 {
241         // reference size
242         short * refSize = NULL;
243         // iterate sources
244         for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
245         {
246                 // get size of current source
247                 short * curSize = (*it)->getSize();
248                 // if size is available and is not empty
249                 if (curSize[0] != 0 && curSize[1] != 0) {
250                         // if reference size is not set
251                         if (refSize == NULL) {
252                                 // set current size as reference
253                                 refSize = curSize;
254                 // otherwise check with current size
255                         }
256                         else if (curSize[0] != refSize[0] || curSize[1] != refSize[1]) {
257                                 // if they don't match, report it
258                                 return false;
259                         }
260                 }
261         }
262         // all sizes match
263         return true;
264 }
265
266
267 // compute nearest power of 2 value
268 short ImageBase::calcSize (short size)
269 {
270         // while there is more than 1 bit in size value
271         while ((size & (size - 1)) != 0)
272                 // clear last bit
273                 size = size & (size - 1);
274         // return result
275         return size;
276 }
277
278
279 // perform loop detection
280 bool ImageBase::loopDetect (ImageBase * img)
281 {
282         // if this object is the same as parameter, loop is detected
283         if (this == img) return true;
284         // check all sources
285         for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
286                 // if source detected loop, return this result
287                 if ((*it)->getSource() != NULL && (*it)->getSource()->m_image->loopDetect(img))
288                         return true;
289         // no loop detected
290         return false;
291 }
292
293
294 // ImageSource class implementation
295
296 // constructor
297 ImageSource::ImageSource (const char * id) : m_source(NULL), m_image(NULL)
298 {
299         // copy id
300         int idx;
301         for (idx = 0; id[idx] != '\0' && idx < SourceIdSize - 1; ++idx)
302                 m_id[idx] = id[idx];
303         m_id[idx] = '\0';
304 }
305
306 // destructor
307 ImageSource::~ImageSource (void)
308 {
309         // release source
310         setSource(NULL);
311 }
312
313
314 // compare id
315 bool ImageSource::is (const char * id)
316 {
317         for (char * myId = m_id; *myId != '\0'; ++myId, ++id)
318                 if (*myId != *id) return false;
319         return *id == '\0';
320 }
321
322
323 // set source object
324 void ImageSource::setSource (PyImage *source)
325 {
326         // reference new source
327         if (source != NULL) Py_INCREF(source);
328         // release previous source
329         Py_XDECREF(m_source);
330         // set new source
331         m_source = source;
332 }
333
334
335 // get image from source
336 unsigned int * ImageSource::getImage (double ts)
337 {
338         // if source is available
339         if (m_source != NULL)
340                 // get image from source
341                 m_image = m_source->m_image->getImage(0, ts);
342         // otherwise reset buffer
343         else
344                 m_image = NULL;
345         // return image
346         return m_image;
347 }
348
349
350 // refresh source
351 void ImageSource::refresh (void)
352 {
353         // if source is available, refresh it
354         if (m_source != NULL) m_source->m_image->refresh();
355 }
356
357
358
359 // list of image types
360 PyTypeList pyImageTypes;
361
362
363
364 // functions for python interface
365
366 // object allocation
367 PyObject *Image_allocNew (PyTypeObject *type, PyObject *args, PyObject *kwds)
368 {
369         // allocate object
370         PyImage *self = reinterpret_cast<PyImage*>(type->tp_alloc(type, 0));
371         // initialize object structure
372         self->m_image = NULL;
373         // return allocated object
374         return reinterpret_cast<PyObject*>(self);
375 }
376
377 // object deallocation
378 void Image_dealloc (PyImage *self)
379 {
380         // release object attributes
381         if (self->m_image != NULL)
382         {
383                 if (self->m_image->m_exports > 0)
384                 {
385                         PyErr_SetString(PyExc_SystemError,
386                                         "deallocated Image object has exported buffers");
387                         PyErr_Print();
388                 }
389                 // if release requires deleting of object, do it
390                 if (self->m_image->release())
391                         delete self->m_image;
392                 self->m_image = NULL;
393         }
394 }
395
396 // get image data
397 PyObject *Image_getImage (PyImage *self, char * mode)
398 {
399         try
400         {
401                 unsigned int * image = self->m_image->getImage();
402                 if (image) 
403                 {
404                         // build BGL buffer
405                         int dimensions = self->m_image->getBuffSize();
406                         Buffer * buffer;
407                         if (mode == NULL || !strcasecmp(mode, "RGBA"))
408                         {
409                                 buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, image);
410                         }
411                         else if (!strcasecmp(mode, "F"))
412                         {
413                                 // this mode returns the image as an array of float.
414                                 // This makes sense ONLY for the depth buffer:
415                                 //   source = VideoTexture.ImageViewport()
416                                 //   source.depth = True
417                                 //   depth = VideoTexture.imageToArray(source, 'F')
418
419                                 // adapt dimension from byte to float
420                                 dimensions /= sizeof(float);
421                                 buffer = BGL_MakeBuffer( GL_FLOAT, 1, &dimensions, image);
422                         }
423                         else 
424                         {
425                                 int i, c, ncolor, pixels;
426                                 int offset[4];
427                                 unsigned char *s, *d;
428                                 // scan the mode to get the channels requested, no more than 4
429                                 for (i=ncolor=0; mode[i] != 0 && ncolor < 4; i++)
430                                 {
431                                         switch (toupper(mode[i]))
432                                         {
433                                         case 'R':
434                                                 offset[ncolor++] = 0;
435                                                 break;
436                                         case 'G':
437                                                 offset[ncolor++] = 1;
438                                                 break;
439                                         case 'B':
440                                                 offset[ncolor++] = 2;
441                                                 break;
442                                         case 'A':
443                                                 offset[ncolor++] = 3;
444                                                 break;
445                                         case '0':
446                                                 offset[ncolor++] = -1;
447                                                 break;
448                                         case '1':
449                                                 offset[ncolor++] = -2;
450                                                 break;
451                                         // if you add more color code, change the switch further down
452                                         default:
453                                                 THRWEXCP(InvalidColorChannel,S_OK);
454                                         }
455                                 }
456                                 if (mode[i] != 0) {
457                                         THRWEXCP(InvalidColorChannel,S_OK);
458                                 }
459                                 // first get the number of pixels
460                                 pixels = dimensions / 4;
461                                 // multiple by the number of channels, each is one byte
462                                 dimensions = pixels * ncolor;
463                                 // get an empty buffer
464                                 buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, NULL);
465                                 // and fill it
466                                 for (i = 0, d = (unsigned char *)buffer->buf.asbyte, s = (unsigned char *)image;
467                                      i < pixels;
468                                      i++, d += ncolor, s += 4)
469                                 {
470                                         for (c=0; c<ncolor; c++)
471                                         {
472                                                 switch (offset[c])
473                                                 {
474                                                 case 0: d[c] = s[0]; break;
475                                                 case 1: d[c] = s[1]; break;
476                                                 case 2: d[c] = s[2]; break;
477                                                 case 3: d[c] = s[3]; break;
478                                                 case -1: d[c] = 0; break;
479                                                 case -2: d[c] = 0xFF; break;
480                                                 }
481                                         }
482                                 }
483                         }
484                         return (PyObject *)buffer;
485                 }
486         }
487         catch (Exception & exp)
488         {
489                 exp.report();
490                 return NULL;
491         }
492         Py_RETURN_NONE;
493 }
494
495 // get image size
496 PyObject *Image_getSize (PyImage *self, void *closure)
497 {
498         return Py_BuildValue("(hh)", self->m_image->getSize()[0],
499                 self->m_image->getSize()[1]);
500 }
501
502 // refresh image
503 PyObject *Image_refresh (PyImage *self)
504 {
505         self->m_image->refresh();
506         Py_RETURN_NONE;
507 }
508
509 // get scale
510 PyObject *Image_getScale (PyImage *self, void *closure)
511 {
512         if (self->m_image != NULL && self->m_image->getScale()) Py_RETURN_TRUE;
513         else Py_RETURN_FALSE;
514 }
515
516 // set scale
517 int Image_setScale (PyImage *self, PyObject *value, void *closure)
518 {
519         // check parameter, report failure
520         if (value == NULL || !PyBool_Check(value))
521         {
522                 PyErr_SetString(PyExc_TypeError, "The value must be a bool");
523                 return -1;
524         }
525         // set scale
526         if (self->m_image != NULL) self->m_image->setScale(value == Py_True);
527         // success
528         return 0;
529 }
530
531 // get flip
532 PyObject *Image_getFlip (PyImage *self, void *closure)
533 {
534         if (self->m_image != NULL && self->m_image->getFlip()) Py_RETURN_TRUE;
535         else Py_RETURN_FALSE;
536 }
537
538 // set flip
539 int Image_setFlip (PyImage *self, PyObject *value, void *closure)
540 {
541         // check parameter, report failure
542         if (value == NULL || !PyBool_Check(value))
543         {
544                 PyErr_SetString(PyExc_TypeError, "The value must be a bool");
545                 return -1;
546         }
547         // set scale
548         if (self->m_image != NULL) self->m_image->setFlip(value == Py_True);
549         // success
550         return 0;
551 }
552
553 // get zbuff
554 PyObject * Image_getZbuff (PyImage * self, void * closure)
555 {
556         if (self->m_image != NULL && self->m_image->getZbuff()) Py_RETURN_TRUE;
557         else Py_RETURN_FALSE;
558 }
559
560 // set zbuff
561 int Image_setZbuff (PyImage * self, PyObject * value, void * closure)
562 {
563         // check parameter, report failure
564         if (value == NULL || !PyBool_Check(value))
565         {
566                 PyErr_SetString(PyExc_TypeError, "The value must be a bool");
567                 return -1;
568         }
569         // set scale
570         if (self->m_image != NULL) self->m_image->setZbuff(value == Py_True);
571         // success
572         return 0;
573 }
574
575 // get depth
576 PyObject * Image_getDepth (PyImage * self, void * closure)
577 {
578         if (self->m_image != NULL && self->m_image->getDepth()) Py_RETURN_TRUE;
579         else Py_RETURN_FALSE;
580 }
581
582 // set depth
583 int Image_setDepth (PyImage * self, PyObject * value, void * closure)
584 {
585         // check parameter, report failure
586         if (value == NULL || !PyBool_Check(value))
587         {
588                 PyErr_SetString(PyExc_TypeError, "The value must be a bool");
589                 return -1;
590         }
591         // set scale
592         if (self->m_image != NULL) self->m_image->setDepth(value == Py_True);
593         // success
594         return 0;
595 }
596
597
598
599
600 // get filter source object
601 PyObject *Image_getSource (PyImage *self, PyObject *args)
602 {
603         // get arguments
604         char * id;
605         if (!PyArg_ParseTuple(args, "s:getSource", &id))
606                 return NULL;
607         if (self->m_image != NULL)
608         {
609                 // get source object
610                 PyObject *src = reinterpret_cast<PyObject*>(self->m_image->getSource(id));
611                 // if source is available
612                 if (src != NULL)
613                 {
614                         // return source
615                         Py_INCREF(src);
616                         return src;
617                 }
618         }
619         // source was not found
620         Py_RETURN_NONE;
621 }
622
623
624 // set filter source object
625 PyObject *Image_setSource (PyImage *self, PyObject *args)
626 {
627         // get arguments
628         char * id;
629         PyObject *obj;
630         if (!PyArg_ParseTuple(args, "sO:setSource", &id, &obj))
631                 return NULL;
632         if (self->m_image != NULL)
633         {
634                 // check type of object
635                 if (pyImageTypes.in(Py_TYPE(obj)))
636                 {
637                         // convert to image struct
638                         PyImage * img = reinterpret_cast<PyImage*>(obj);
639                         // set source
640                         if (!self->m_image->setSource(id, img))
641                         {
642                                 // if not set, retport error
643                                 PyErr_SetString(PyExc_RuntimeError, "Invalid source or id");
644                                 return NULL;
645                         }
646                 }
647                 // else report error
648                 else
649                 {
650                         PyErr_SetString(PyExc_RuntimeError, "Invalid type of object");
651                         return NULL;
652                 }
653         }
654         // return none
655         Py_RETURN_NONE;
656 }
657
658
659 // get pixel filter object
660 PyObject *Image_getFilter (PyImage *self, void *closure)
661 {
662         // if image object is available
663         if (self->m_image != NULL)
664         {
665                 // pixel filter object
666                 PyObject * filt = reinterpret_cast<PyObject*>(self->m_image->getFilter());
667                 // if filter is present
668                 if (filt != NULL)
669                 {
670                         // return it
671                         Py_INCREF(filt);
672                         return filt;
673                 }
674         }
675         // otherwise return none
676         Py_RETURN_NONE;
677 }
678
679
680 // set pixel filter object
681 int Image_setFilter (PyImage *self, PyObject *value, void *closure)
682 {
683         // if image object is available
684         if (self->m_image != NULL)
685         {
686                 // check new value
687                 if (value == NULL || !pyFilterTypes.in(Py_TYPE(value)))
688                 {
689                         // report value error
690                         PyErr_SetString(PyExc_TypeError, "Invalid type of value");
691                         return -1;
692                 }
693                 // set new value
694                 self->m_image->setFilter(reinterpret_cast<PyFilter*>(value));
695         }
696         // return success
697         return 0;
698 }
699 PyObject *Image_valid(PyImage *self, void *closure)
700 {
701         if (self->m_image->isImageAvailable())
702         {
703                 Py_RETURN_TRUE;
704         }
705         else
706         {
707                 Py_RETURN_FALSE;
708         }
709 }
710
711 static int Image_getbuffer(PyImage *self, Py_buffer *view, int flags)
712 {
713         unsigned int * image;
714         int ret;
715
716         try
717         {
718                 // can throw in case of resize
719                 image = self->m_image->getImage();
720         }
721         catch (Exception & exp)
722         {
723                 // cannot return -1, this creates a crash in Python, for now we will just return an empty buffer
724                 exp.report();
725                 //return -1;
726                 goto error;
727         }
728
729         if (!image)
730         {
731                 // same remark, see above
732                 //PyErr_SetString(PyExc_BufferError, "Image buffer is not available");
733                 //return -1;
734                 goto error;
735         }
736         if (view == NULL)
737         {
738                 self->m_image->m_exports++;
739                 return 0;
740         }
741         ret = PyBuffer_FillInfo(view, (PyObject *)self, image, self->m_image->getBuffSize(), 0, flags);
742         if (ret >= 0)
743                 self->m_image->m_exports++;
744         return ret;
745
746 error:
747         // Return a empty buffer to avoid a crash in Python 3.1
748         // The bug is fixed in Python SVN 77916, as soon as the python revision used by Blender is
749         // updated, you can simply return -1 and set the error
750         static char* buf = (char *)"";
751         ret = PyBuffer_FillInfo(view, (PyObject *)self, buf, 0, 0, flags);
752         if (ret >= 0)
753                 self->m_image->m_exports++;
754         return ret;
755         
756 }
757
758 static void Image_releaseBuffer(PyImage *self, Py_buffer *buffer)
759 {
760         self->m_image->m_exports--;
761 }
762
763 PyBufferProcs imageBufferProcs = 
764 {
765         (getbufferproc)Image_getbuffer,
766         (releasebufferproc)Image_releaseBuffer
767 };
768