Blender  V2.59
ImageBase.h
Go to the documentation of this file.
00001 /* $Id: ImageBase.h 35082 2011-02-22 19:30:37Z jesterking $
00002 -----------------------------------------------------------------------------
00003 This source file is part of blendTex library
00004 
00005 Copyright (c) 2007 The Zdeno Ash Miklas
00006 
00007 This program is free software; you can redistribute it and/or modify it under
00008 the terms of the GNU Lesser General Public License as published by the Free Software
00009 Foundation; either version 2 of the License, or (at your option) any later
00010 version.
00011 
00012 This program is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00015 
00016 You should have received a copy of the GNU Lesser General Public License along with
00017 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00018 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00019 http://www.gnu.org/copyleft/lesser.txt.
00020 -----------------------------------------------------------------------------
00021 */
00022 
00027 #if !defined IMAGEBASE_H
00028 #define IMAGEBASE_H
00029 
00030 #include "Common.h"
00031 
00032 #include <vector>
00033 #include <PyObjectPlus.h>
00034 
00035 #include "PyTypeList.h"
00036 
00037 #include "FilterBase.h"
00038 
00039 
00040 // forward declarations
00041 struct PyImage;
00042 class ImageSource;
00043 
00044 
00046 typedef std::vector<ImageSource*> ImageSourceList;
00047 
00048 
00050 class ImageBase
00051 {
00052 public:
00054         ImageBase (bool staticSrc = false);
00056         virtual ~ImageBase (void);
00058         virtual bool release (void);
00059 
00061         bool isImageAvailable(void)
00062         { return m_avail; }
00064         unsigned int * getImage (unsigned int texId = 0, double timestamp=-1.0);
00066         short * getSize (void) { return m_size; }
00068         unsigned long getBuffSize (void)
00069         { return m_size[0] * m_size[1] * sizeof(unsigned int); }
00071         virtual void refresh (void);
00072 
00074         bool getScale (void) { return m_scale; }
00076         void setScale (bool scale) { m_scale = scale; m_scaleChange = true; }
00078         bool getFlip (void) { return m_flip; }
00080         void setFlip (bool flip) { m_flip = flip; }
00081 
00083         PyImage * getSource (const char * id);
00085         bool setSource (const char * id, PyImage * source);
00086 
00088         PyFilter * getFilter (void) { return m_pyfilter; }
00090         void setFilter (PyFilter * filt);
00091 
00093         static short calcSize (short size);
00094 
00096         int m_exports;
00097 
00098 protected:
00100         unsigned int * m_image;
00102         unsigned int m_imgSize;
00104         short m_size[2];
00106         bool m_avail;
00107 
00109         bool m_scale;
00111         bool m_scaleChange;
00113         bool m_flip;
00114 
00116         ImageSourceList m_sources;
00118         bool m_staticSources;
00119 
00121         PyFilter * m_pyfilter;
00122 
00124         void init (short width, short height);
00125 
00127         ImageSourceList::iterator findSource (const char * id);
00128 
00130         virtual ImageSource * newSource (const char * id) { return NULL; }
00131 
00133         bool checkSourceSizes (void);
00134 
00136         virtual void calcImage (unsigned int texId, double ts) {}
00137 
00139         bool loopDetect (ImageBase * img);
00140 
00142         template<class FLT, class SRC> void convImage (FLT & filter, SRC srcBuff,
00143                 short * srcSize)
00144         {
00145                 // destination buffer
00146                 unsigned int * dstBuff = m_image;
00147                 // pixel size from filter
00148                 unsigned int pixSize = filter.firstPixelSize();
00149                 // if no scaling is needed
00150                 if (srcSize[0] == m_size[0] && srcSize[1] == m_size[1])
00151                         // if flipping isn't required
00152                         if (!m_flip)
00153                                 // copy bitmap
00154                                 for (short y = 0; y < m_size[1]; ++y)
00155                                         for (short x = 0; x < m_size[0]; ++x, ++dstBuff, srcBuff += pixSize)
00156                                                 // copy pixel
00157                                                 *dstBuff = filter.convert(srcBuff, x, y, srcSize, pixSize);
00158                 // otherwise flip image top to bottom
00159                         else
00160                         {
00161                                 // go to last row of image
00162                                 srcBuff += srcSize[0] * (srcSize[1] - 1) * pixSize;
00163                                 // copy bitmap
00164                                 for (short y = m_size[1] - 1; y >= 0; --y, srcBuff -= 2 * srcSize[0] * pixSize)
00165                                         for (short x = 0; x < m_size[0]; ++x, ++dstBuff, srcBuff += pixSize)
00166                                                 // copy pixel
00167                                                 *dstBuff = filter.convert(srcBuff, x, y, srcSize, pixSize);
00168                         }
00169                         // else scale picture (nearest neighbour)
00170                 else
00171                 {
00172                         // interpolation accumulator
00173                         int accHeight = srcSize[1] >> 1;
00174                         // if flipping is required
00175                         if (m_flip)
00176                                 // go to last row of image
00177                                 srcBuff += srcSize[0] * (srcSize[1] - 1) * pixSize;
00178                         // process image rows
00179                         for (int y = 0; y < srcSize[1]; ++y)
00180                         {
00181                                 // increase height accum
00182                                 accHeight += m_size[1];
00183                                 // if pixel row has to be drawn
00184                                 if (accHeight >= srcSize[1])
00185                                 {
00186                                         // decrease accum
00187                                         accHeight -= srcSize[1];
00188                                         // width accum
00189                                         int accWidth = srcSize[0] >> 1;
00190                                         // process row
00191                                         for (int x = 0; x < srcSize[0]; ++x)
00192                                         {
00193                                                 // increase width accum
00194                                                 accWidth += m_size[0];
00195                                                 // if pixel has to be drawn
00196                                                 if (accWidth >= srcSize[0])
00197                                                 {
00198                                                         // decrease accum
00199                                                         accWidth -= srcSize[0];
00200                                                         // convert pixel
00201                                                         *dstBuff = filter.convert(srcBuff, x, m_flip ? srcSize[1] - y - 1 : y,
00202                                                                 srcSize, pixSize);
00203                                                         // next pixel
00204                                                         ++dstBuff;
00205                                                 }
00206                                                 // shift source pointer
00207                                                 srcBuff += pixSize;
00208                                         }
00209                                 }
00210                                 // if pixel row will not be drawn
00211                                 else
00212                                         // move source pointer to next row
00213                                         srcBuff += pixSize * srcSize[0];
00214                                 // if y flipping is required
00215                                 if (m_flip)
00216                                         // go to previous row of image
00217                                         srcBuff -= 2 * pixSize * srcSize[0];
00218                         }
00219                 }
00220         }
00221 
00222         // template for specific filter preprocessing
00223         template <class F, class SRC> void filterImage (F & filt, SRC srcBuff, short * srcSize)
00224         {
00225                 // find first filter in chain
00226                 FilterBase * firstFilter = NULL;
00227                 if (m_pyfilter != NULL) firstFilter = m_pyfilter->m_filter->findFirst();
00228                 // if first filter is available
00229                 if (firstFilter != NULL)
00230                 {
00231                         // python wrapper for filter
00232                         PyFilter pyFilt;
00233                         pyFilt.m_filter = &filt;
00234                         // set specified filter as first in chain
00235                         firstFilter->setPrevious(&pyFilt, false);
00236                         // convert video image
00237                         convImage(*(m_pyfilter->m_filter), srcBuff, srcSize);
00238                         // delete added filter
00239                         firstFilter->setPrevious(NULL, false);
00240                 }
00241                 // otherwise use given filter for conversion
00242                 else convImage(filt, srcBuff, srcSize);
00243                 // source was processed
00244                 m_avail = true;
00245         }
00246 };
00247 
00248 
00249 // python structure for image filter
00250 struct PyImage
00251 {
00252         PyObject_HEAD
00253         // source object
00254         ImageBase * m_image;
00255 };
00256 
00257 
00258 // size of id
00259 const int SourceIdSize = 32;
00260 
00261 
00263 class ImageSource
00264 {
00265 public:
00267         ImageSource (const char * id);
00269         virtual ~ImageSource (void);
00270 
00272         const char * getId (void) { return m_id; }
00274         bool is (const char * id);
00275 
00277         PyImage * getSource (void) { return m_source; }
00279         void setSource (PyImage * source);
00280 
00282         unsigned int * getImage (double ts=-1.0);
00284         unsigned int * getImageBuf (void) { return m_image; }
00286         void refresh (void);
00287 
00289         short * getSize (void)
00290         { 
00291                 static short defSize [] = {0, 0};
00292                 return m_source != NULL ? m_source->m_image->getSize() : defSize;
00293         }
00294 
00295 protected:
00297         char m_id [SourceIdSize];
00299         PyImage * m_source;
00301         unsigned int * m_image;
00302 
00303 private:
00305         ImageSource (void) {}
00306 };
00307 
00308 // list of python image types
00309 extern PyTypeList pyImageTypes;
00310 
00311 
00312 // functions for python interface
00313 
00314 // object initialization
00315 template <class T> static int Image_init (PyObject * pySelf, PyObject * args, PyObject * kwds)
00316 {
00317         PyImage * self = reinterpret_cast<PyImage*>(pySelf);
00318         // create source object
00319         if (self->m_image != NULL) delete self->m_image;
00320         self->m_image = new T();
00321         // initialization succeded
00322         return 0;
00323 }
00324 
00325 // object allocation
00326 PyObject * Image_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds);
00327 // object deallocation
00328 void Image_dealloc (PyImage * self);
00329 
00330 // get image data
00331 PyObject * Image_getImage (PyImage * self, char * mode);
00332 // get image size
00333 PyObject * Image_getSize (PyImage * self, void * closure);
00334 // refresh image - invalidate current content
00335 PyObject * Image_refresh (PyImage * self);
00336 
00337 // get scale
00338 PyObject * Image_getScale (PyImage * self, void * closure);
00339 // set scale
00340 int Image_setScale (PyImage * self, PyObject * value, void * closure);
00341 // get flip
00342 PyObject * Image_getFlip (PyImage * self, void * closure);
00343 // set flip
00344 int Image_setFlip (PyImage * self, PyObject * value, void * closure);
00345 
00346 // get filter source object
00347 PyObject * Image_getSource (PyImage * self, PyObject * args);
00348 // set filter source object
00349 PyObject * Image_setSource (PyImage * self, PyObject * args);
00350 
00351 // get pixel filter object
00352 PyObject * Image_getFilter (PyImage * self, void * closure);
00353 // set pixel filter object
00354 int Image_setFilter (PyImage * self, PyObject * value, void * closure);
00355 // check if a buffer can be extracted
00356 PyObject * Image_valid(PyImage * self, void * closure);
00357 // for buffer access to PyImage objects
00358 extern PyBufferProcs imageBufferProcs;
00359 
00360 #endif