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