|
Blender
V2.59
|
00001 00004 /* $Id: ImageBase.cpp 35176 2011-02-25 13:39:34Z jesterking $ 00005 ----------------------------------------------------------------------------- 00006 This source file is part of VideoTexture library 00007 00008 Copyright (c) 2007 The Zdeno Ash Miklas 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 00026 #include "ImageBase.h" 00027 extern "C" { 00028 #include "bgl.h" 00029 } 00030 #include "GL/glew.h" 00031 00032 #include <vector> 00033 #include <string.h> 00034 00035 #include <PyObjectPlus.h> 00036 #include <structmember.h> 00037 00038 #include "FilterBase.h" 00039 00040 #include "Exception.h" 00041 00042 #if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS) 00043 #define strcasecmp _stricmp 00044 #endif 00045 00046 // ImageBase class implementation 00047 00048 // constructor 00049 ImageBase::ImageBase (bool staticSrc) : m_image(NULL), m_imgSize(0), 00050 m_avail(false), m_scale(false), m_scaleChange(false), m_flip(false), 00051 m_staticSources(staticSrc), m_pyfilter(NULL) 00052 { 00053 m_size[0] = m_size[1] = 0; 00054 m_exports = 0; 00055 } 00056 00057 00058 // destructor 00059 ImageBase::~ImageBase (void) 00060 { 00061 // release image 00062 if (m_image) 00063 delete [] m_image; 00064 } 00065 00066 00067 // release python objects 00068 bool ImageBase::release (void) 00069 { 00070 // iterate sources 00071 for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it) 00072 { 00073 // release source object 00074 delete *it; 00075 *it = NULL; 00076 } 00077 // release filter object 00078 Py_XDECREF(m_pyfilter); 00079 m_pyfilter = NULL; 00080 return true; 00081 } 00082 00083 00084 // get image 00085 unsigned int * ImageBase::getImage (unsigned int texId, double ts) 00086 { 00087 // if image is not available 00088 if (!m_avail) 00089 { 00090 // if there are any sources 00091 if (!m_sources.empty()) 00092 { 00093 // get images from sources 00094 for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it) 00095 // get source image 00096 (*it)->getImage(ts); 00097 // init image 00098 init(m_sources[0]->getSize()[0], m_sources[0]->getSize()[1]); 00099 } 00100 // calculate new image 00101 calcImage(texId, ts); 00102 } 00103 // if image is available, return it, otherwise NULL 00104 return m_avail ? m_image : NULL; 00105 } 00106 00107 00108 // refresh image source 00109 void ImageBase::refresh (void) 00110 { 00111 // invalidate this image 00112 m_avail = false; 00113 // refresh all sources 00114 for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it) 00115 (*it)->refresh(); 00116 } 00117 00118 00119 // get source object 00120 PyImage * ImageBase::getSource (const char * id) 00121 { 00122 // find source 00123 ImageSourceList::iterator src = findSource(id); 00124 // return it, if found 00125 return src != m_sources.end() ? (*src)->getSource() : NULL; 00126 } 00127 00128 00129 // set source object 00130 bool ImageBase::setSource (const char * id, PyImage * source) 00131 { 00132 // find source 00133 ImageSourceList::iterator src = findSource(id); 00134 // check source loop 00135 if (source != NULL && source->m_image->loopDetect(this)) 00136 return false; 00137 // if found, set new object 00138 if (src != m_sources.end()) 00139 // if new object is not empty or sources are static 00140 if (source != NULL || m_staticSources) 00141 // replace previous source 00142 (*src)->setSource(source); 00143 // otherwise delete source 00144 else 00145 m_sources.erase(src); 00146 // if source is not found and adding is allowed 00147 else 00148 if (!m_staticSources) 00149 { 00150 // create new source 00151 ImageSource * newSrc = newSource(id); 00152 newSrc->setSource(source); 00153 // if source was created, add it to source list 00154 if (newSrc != NULL) m_sources.push_back(newSrc); 00155 } 00156 // otherwise source wasn't set 00157 else 00158 return false; 00159 // source was set 00160 return true; 00161 } 00162 00163 00164 // set pixel filter 00165 void ImageBase::setFilter (PyFilter * filt) 00166 { 00167 // reference new filter 00168 if (filt != NULL) Py_INCREF(filt); 00169 // release previous filter 00170 Py_XDECREF(m_pyfilter); 00171 // set new filter 00172 m_pyfilter = filt; 00173 } 00174 00175 ExceptionID ImageHasExports; 00176 ExceptionID InvalidColorChannel; 00177 00178 ExpDesc ImageHasExportsDesc (ImageHasExports, "Image has exported buffers, cannot resize"); 00179 ExpDesc InvalidColorChannelDesc (InvalidColorChannel, "Invalid or too many color channels specified. At most 4 values within R, G, B, A, 0, 1"); 00180 00181 // initialize image data 00182 void ImageBase::init (short width, short height) 00183 { 00184 // if image has to be scaled 00185 if (m_scale) 00186 { 00187 // recalc sizes of image 00188 width = calcSize(width); 00189 height = calcSize(height); 00190 } 00191 // if sizes differ 00192 if (width != m_size[0] || height != m_size[1]) 00193 { 00194 if (m_exports > 0) 00195 THRWEXCP(ImageHasExports,S_OK); 00196 00197 // new buffer size 00198 unsigned int newSize = width * height; 00199 // if new buffer is larger than previous 00200 if (newSize > m_imgSize) 00201 { 00202 // set new buffer size 00203 m_imgSize = newSize; 00204 // release previous and create new buffer 00205 if (m_image) 00206 delete [] m_image; 00207 m_image = new unsigned int[m_imgSize]; 00208 } 00209 // new image size 00210 m_size[0] = width; 00211 m_size[1] = height; 00212 // scale was processed 00213 m_scaleChange = false; 00214 } 00215 } 00216 00217 00218 // find source 00219 ImageSourceList::iterator ImageBase::findSource (const char * id) 00220 { 00221 // iterate sources 00222 ImageSourceList::iterator it; 00223 for (it = m_sources.begin(); it != m_sources.end(); ++it) 00224 // if id matches, return iterator 00225 if ((*it)->is(id)) return it; 00226 // source not found 00227 return it; 00228 } 00229 00230 00231 // check sources sizes 00232 bool ImageBase::checkSourceSizes (void) 00233 { 00234 // reference size 00235 short * refSize = NULL; 00236 // iterate sources 00237 for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it) 00238 { 00239 // get size of current source 00240 short * curSize = (*it)->getSize(); 00241 // if size is available and is not empty 00242 if (curSize[0] != 0 && curSize[1] != 0) { 00243 // if reference size is not set 00244 if (refSize == NULL) { 00245 // set current size as reference 00246 refSize = curSize; 00247 // otherwise check with current size 00248 } else if (curSize[0] != refSize[0] || curSize[1] != refSize[1]) { 00249 // if they don't match, report it 00250 return false; 00251 } 00252 } 00253 } 00254 // all sizes match 00255 return true; 00256 } 00257 00258 00259 // compute nearest power of 2 value 00260 short ImageBase::calcSize (short size) 00261 { 00262 // while there is more than 1 bit in size value 00263 while ((size & (size - 1)) != 0) 00264 // clear last bit 00265 size = size & (size - 1); 00266 // return result 00267 return size; 00268 } 00269 00270 00271 // perform loop detection 00272 bool ImageBase::loopDetect (ImageBase * img) 00273 { 00274 // if this object is the same as parameter, loop is detected 00275 if (this == img) return true; 00276 // check all sources 00277 for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it) 00278 // if source detected loop, return this result 00279 if ((*it)->getSource() != NULL && (*it)->getSource()->m_image->loopDetect(img)) 00280 return true; 00281 // no loop detected 00282 return false; 00283 } 00284 00285 00286 // ImageSource class implementation 00287 00288 // constructor 00289 ImageSource::ImageSource (const char * id) : m_source(NULL), m_image(NULL) 00290 { 00291 // copy id 00292 int idx; 00293 for (idx = 0; id[idx] != '\0' && idx < SourceIdSize - 1; ++idx) 00294 m_id[idx] = id[idx]; 00295 m_id[idx] = '\0'; 00296 } 00297 00298 // destructor 00299 ImageSource::~ImageSource (void) 00300 { 00301 // release source 00302 setSource(NULL); 00303 } 00304 00305 00306 // compare id 00307 bool ImageSource::is (const char * id) 00308 { 00309 for (char * myId = m_id; *myId != '\0'; ++myId, ++id) 00310 if (*myId != *id) return false; 00311 return *id == '\0'; 00312 } 00313 00314 00315 // set source object 00316 void ImageSource::setSource (PyImage * source) 00317 { 00318 // reference new source 00319 if (source != NULL) Py_INCREF(source); 00320 // release previous source 00321 Py_XDECREF(m_source); 00322 // set new source 00323 m_source = source; 00324 } 00325 00326 00327 // get image from source 00328 unsigned int * ImageSource::getImage (double ts) 00329 { 00330 // if source is available 00331 if (m_source != NULL) 00332 // get image from source 00333 m_image = m_source->m_image->getImage(0, ts); 00334 // otherwise reset buffer 00335 else 00336 m_image = NULL; 00337 // return image 00338 return m_image; 00339 } 00340 00341 00342 // refresh source 00343 void ImageSource::refresh (void) 00344 { 00345 // if source is available, refresh it 00346 if (m_source != NULL) m_source->m_image->refresh(); 00347 } 00348 00349 00350 00351 // list of image types 00352 PyTypeList pyImageTypes; 00353 00354 00355 00356 // functions for python interface 00357 00358 // object allocation 00359 PyObject * Image_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds) 00360 { 00361 // allocate object 00362 PyImage * self = reinterpret_cast<PyImage*>(type->tp_alloc(type, 0)); 00363 // initialize object structure 00364 self->m_image = NULL; 00365 // return allocated object 00366 return reinterpret_cast<PyObject*>(self); 00367 } 00368 00369 // object deallocation 00370 void Image_dealloc (PyImage * self) 00371 { 00372 // release object attributes 00373 if (self->m_image != NULL) 00374 { 00375 if (self->m_image->m_exports > 0) 00376 { 00377 PyErr_SetString(PyExc_SystemError, 00378 "deallocated Image object has exported buffers"); 00379 PyErr_Print(); 00380 } 00381 // if release requires deleting of object, do it 00382 if (self->m_image->release()) 00383 delete self->m_image; 00384 self->m_image = NULL; 00385 } 00386 } 00387 00388 // get image data 00389 PyObject * Image_getImage (PyImage * self, char * mode) 00390 { 00391 try 00392 { 00393 unsigned int * image = self->m_image->getImage(); 00394 if (image) 00395 { 00396 // build BGL buffer 00397 int dimensions = self->m_image->getBuffSize(); 00398 Buffer * buffer; 00399 if (mode == NULL || !strcasecmp(mode, "RGBA")) 00400 { 00401 buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, image); 00402 } 00403 else 00404 { 00405 int i, c, ncolor, pixels; 00406 int offset[4]; 00407 unsigned char *s, *d; 00408 // scan the mode to get the channels requested, no more than 4 00409 for (i=ncolor=0; mode[i] != 0 && ncolor < 4; i++) 00410 { 00411 switch (toupper(mode[i])) 00412 { 00413 case 'R': 00414 offset[ncolor++] = 0; 00415 break; 00416 case 'G': 00417 offset[ncolor++] = 1; 00418 break; 00419 case 'B': 00420 offset[ncolor++] = 2; 00421 break; 00422 case 'A': 00423 offset[ncolor++] = 3; 00424 break; 00425 case '0': 00426 offset[ncolor++] = -1; 00427 break; 00428 case '1': 00429 offset[ncolor++] = -2; 00430 break; 00431 // if you add more color code, change the switch further down 00432 default: 00433 THRWEXCP(InvalidColorChannel,S_OK); 00434 } 00435 } 00436 if (mode[i] != 0) { 00437 THRWEXCP(InvalidColorChannel,S_OK); 00438 } 00439 // first get the number of pixels 00440 pixels = dimensions / 4; 00441 // multiple by the number of channels, each is one byte 00442 dimensions = pixels * ncolor; 00443 // get an empty buffer 00444 buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, NULL); 00445 // and fill it 00446 for (i=0, d=(unsigned char*)buffer->buf.asbyte, s=(unsigned char*)image; 00447 i<pixels; 00448 ++i, d+=ncolor, s+=4) 00449 { 00450 for (c=0; c<ncolor; c++) 00451 { 00452 switch (offset[c]) 00453 { 00454 case 0: d[c] = s[0]; break; 00455 case 1: d[c] = s[1]; break; 00456 case 2: d[c] = s[2]; break; 00457 case 3: d[c] = s[3]; break; 00458 case -1: d[c] = 0; break; 00459 case -2: d[c] = 0xFF; break; 00460 } 00461 } 00462 } 00463 } 00464 return (PyObject*)buffer; 00465 } 00466 } 00467 catch (Exception & exp) 00468 { 00469 exp.report(); 00470 return NULL; 00471 } 00472 Py_RETURN_NONE; 00473 } 00474 00475 // get image size 00476 PyObject * Image_getSize (PyImage * self, void * closure) 00477 { 00478 return Py_BuildValue("(hh)", self->m_image->getSize()[0], 00479 self->m_image->getSize()[1]); 00480 } 00481 00482 // refresh image 00483 PyObject * Image_refresh (PyImage * self) 00484 { 00485 self->m_image->refresh(); 00486 Py_RETURN_NONE; 00487 } 00488 00489 // get scale 00490 PyObject * Image_getScale (PyImage * self, void * closure) 00491 { 00492 if (self->m_image != NULL && self->m_image->getScale()) Py_RETURN_TRUE; 00493 else Py_RETURN_FALSE; 00494 } 00495 00496 // set scale 00497 int Image_setScale (PyImage * self, PyObject * value, void * closure) 00498 { 00499 // check parameter, report failure 00500 if (value == NULL || !PyBool_Check(value)) 00501 { 00502 PyErr_SetString(PyExc_TypeError, "The value must be a bool"); 00503 return -1; 00504 } 00505 // set scale 00506 if (self->m_image != NULL) self->m_image->setScale(value == Py_True); 00507 // success 00508 return 0; 00509 } 00510 00511 // get flip 00512 PyObject * Image_getFlip (PyImage * self, void * closure) 00513 { 00514 if (self->m_image != NULL && self->m_image->getFlip()) Py_RETURN_TRUE; 00515 else Py_RETURN_FALSE; 00516 } 00517 00518 // set flip 00519 int Image_setFlip (PyImage * self, PyObject * value, void * closure) 00520 { 00521 // check parameter, report failure 00522 if (value == NULL || !PyBool_Check(value)) 00523 { 00524 PyErr_SetString(PyExc_TypeError, "The value must be a bool"); 00525 return -1; 00526 } 00527 // set scale 00528 if (self->m_image != NULL) self->m_image->setFlip(value == Py_True); 00529 // success 00530 return 0; 00531 } 00532 00533 00534 // get filter source object 00535 PyObject * Image_getSource (PyImage * self, PyObject * args) 00536 { 00537 // get arguments 00538 char * id; 00539 if (!PyArg_ParseTuple(args, "s:getSource", &id)) 00540 return NULL; 00541 if (self->m_image != NULL) 00542 { 00543 // get source object 00544 PyObject * src = reinterpret_cast<PyObject*>(self->m_image->getSource(id)); 00545 // if source is available 00546 if (src != NULL) 00547 { 00548 // return source 00549 Py_INCREF(src); 00550 return src; 00551 } 00552 } 00553 // source was not found 00554 Py_RETURN_NONE; 00555 } 00556 00557 00558 // set filter source object 00559 PyObject * Image_setSource (PyImage * self, PyObject * args) 00560 { 00561 // get arguments 00562 char * id; 00563 PyObject * obj; 00564 if (!PyArg_ParseTuple(args, "sO:setSource", &id, &obj)) 00565 return NULL; 00566 if (self->m_image != NULL) 00567 { 00568 // check type of object 00569 if (pyImageTypes.in(obj->ob_type)) 00570 { 00571 // convert to image struct 00572 PyImage * img = reinterpret_cast<PyImage*>(obj); 00573 // set source 00574 if (!self->m_image->setSource(id, img)) 00575 { 00576 // if not set, retport error 00577 PyErr_SetString(PyExc_RuntimeError, "Invalid source or id"); 00578 return NULL; 00579 } 00580 } 00581 // else report error 00582 else 00583 { 00584 PyErr_SetString(PyExc_RuntimeError, "Invalid type of object"); 00585 return NULL; 00586 } 00587 } 00588 // return none 00589 Py_RETURN_NONE; 00590 } 00591 00592 00593 // get pixel filter object 00594 PyObject * Image_getFilter (PyImage * self, void * closure) 00595 { 00596 // if image object is available 00597 if (self->m_image != NULL) 00598 { 00599 // pixel filter object 00600 PyObject * filt = reinterpret_cast<PyObject*>(self->m_image->getFilter()); 00601 // if filter is present 00602 if (filt != NULL) 00603 { 00604 // return it 00605 Py_INCREF(filt); 00606 return filt; 00607 } 00608 } 00609 // otherwise return none 00610 Py_RETURN_NONE; 00611 } 00612 00613 00614 // set pixel filter object 00615 int Image_setFilter (PyImage * self, PyObject * value, void * closure) 00616 { 00617 // if image object is available 00618 if (self->m_image != NULL) 00619 { 00620 // check new value 00621 if (value == NULL || !pyFilterTypes.in(value->ob_type)) 00622 { 00623 // report value error 00624 PyErr_SetString(PyExc_TypeError, "Invalid type of value"); 00625 return -1; 00626 } 00627 // set new value 00628 self->m_image->setFilter(reinterpret_cast<PyFilter*>(value)); 00629 } 00630 // return success 00631 return 0; 00632 } 00633 PyObject * Image_valid(PyImage * self, void * closure) 00634 { 00635 if (self->m_image->isImageAvailable()) 00636 { 00637 Py_RETURN_TRUE; 00638 } 00639 else 00640 { 00641 Py_RETURN_FALSE; 00642 } 00643 } 00644 00645 int Image_getbuffer(PyImage *self, Py_buffer *view, int flags) 00646 { 00647 unsigned int * image; 00648 int ret; 00649 00650 try 00651 { 00652 // can throw in case of resize 00653 image = self->m_image->getImage(); 00654 } 00655 catch (Exception & exp) 00656 { 00657 // cannot return -1, this creates a crash in Python, for now we will just return an empty buffer 00658 exp.report(); 00659 //return -1; 00660 goto error; 00661 } 00662 00663 if (!image) 00664 { 00665 // same remark, see above 00666 //PyErr_SetString(PyExc_BufferError, "Image buffer is not available"); 00667 //return -1; 00668 goto error; 00669 } 00670 if (view == NULL) 00671 { 00672 self->m_image->m_exports++; 00673 return 0; 00674 } 00675 ret = PyBuffer_FillInfo(view, (PyObject*)self, image, self->m_image->getBuffSize(), 0, flags); 00676 if (ret >= 0) 00677 self->m_image->m_exports++; 00678 return ret; 00679 00680 error: 00681 // Return a empty buffer to avoid a crash in Python 3.1 00682 // The bug is fixed in Python SVN 77916, as soon as the python revision used by Blender is 00683 // updated, you can simply return -1 and set the error 00684 static char* buf = (char *)""; 00685 ret = PyBuffer_FillInfo(view, (PyObject*)self, buf, 0, 0, flags); 00686 if (ret >= 0) 00687 self->m_image->m_exports++; 00688 return ret; 00689 00690 } 00691 00692 void Image_releaseBuffer(PyImage *self, Py_buffer *buffer) 00693 { 00694 self->m_image->m_exports--; 00695 } 00696 00697 PyBufferProcs imageBufferProcs = 00698 { 00699 (getbufferproc)Image_getbuffer, 00700 (releasebufferproc)Image_releaseBuffer 00701 }; 00702