Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/VideoTexture/ImageBase.cpp')
-rw-r--r--source/gameengine/VideoTexture/ImageBase.cpp834
1 files changed, 0 insertions, 834 deletions
diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp
deleted file mode 100644
index a547d2a7a85..00000000000
--- a/source/gameengine/VideoTexture/ImageBase.cpp
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (c) 2007 The Zdeno Ash Miklas
- *
- * This source file is part of VideoTexture library
- *
- * Contributor(s):
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/VideoTexture/ImageBase.cpp
- * \ingroup bgevideotex
- */
-
-#include "ImageBase.h"
-extern "C" {
-#include "bgl.h"
-}
-
-#include <vector>
-#include <string.h>
-
-#include "EXP_PyObjectPlus.h"
-#include <structmember.h>
-
-#include "FilterBase.h"
-
-#include "Exception.h"
-
-#if (defined(WIN32) || defined(WIN64))
-#define strcasecmp _stricmp
-#endif
-
-// ImageBase class implementation
-
-ExceptionID ImageHasExports;
-ExceptionID InvalidColorChannel;
-ExceptionID InvalidImageMode;
-
-ExpDesc ImageHasExportsDesc(ImageHasExports, "Image has exported buffers, cannot resize");
-ExpDesc InvalidColorChannelDesc(InvalidColorChannel, "Invalid or too many color channels specified. At most 4 values within R, G, B, A, 0, 1");
-ExpDesc InvalidImageModeDesc(InvalidImageMode, "Invalid image mode, only RGBA and BGRA are supported");
-
-// constructor
-ImageBase::ImageBase (bool staticSrc) : m_image(NULL), m_imgSize(0),
-m_avail(false), m_scale(false), m_scaleChange(false), m_flip(false),
-m_zbuff(false),
-m_depth(false),
-m_staticSources(staticSrc), m_pyfilter(NULL)
-{
- m_size[0] = m_size[1] = 0;
- m_exports = 0;
-}
-
-
-// destructor
-ImageBase::~ImageBase (void)
-{
- // release image
- if (m_image)
- delete [] m_image;
-}
-
-
-// release python objects
-bool ImageBase::release (void)
-{
- // iterate sources
- for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
- {
- // release source object
- delete *it;
- *it = NULL;
- }
- // release filter object
- Py_XDECREF(m_pyfilter);
- m_pyfilter = NULL;
- return true;
-}
-
-
-// get image
-unsigned int * ImageBase::getImage (unsigned int texId, double ts)
-{
- // if image is not available
- if (!m_avail)
- {
- // if there are any sources
- if (!m_sources.empty())
- {
- // get images from sources
- for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
- // get source image
- (*it)->getImage(ts);
- // init image
- init(m_sources[0]->getSize()[0], m_sources[0]->getSize()[1]);
- }
- // calculate new image
- calcImage(texId, ts);
- }
- // if image is available, return it, otherwise NULL
- return m_avail ? m_image : NULL;
-}
-
-bool ImageBase::loadImage(unsigned int *buffer, unsigned int size, unsigned int format, double ts)
-{
- unsigned int *d, *s, v, len;
- if (getImage(0, ts) != NULL && size >= getBuffSize()) {
- switch (format) {
- case GL_RGBA:
- memcpy(buffer, m_image, getBuffSize());
- break;
- case GL_BGRA:
- len = (unsigned int)m_size[0] * m_size[1];
- for (s=m_image, d=buffer; len; len--) {
- v = *s++;
- *d++ = VT_SWAPBR(v);
- }
- break;
- default:
- THRWEXCP(InvalidImageMode,S_OK);
- }
- return true;
- }
- return false;
-}
-
-// refresh image source
-void ImageBase::refresh (void)
-{
- // invalidate this image
- m_avail = false;
- // refresh all sources
- for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
- (*it)->refresh();
-}
-
-
-// get source object
-PyImage * ImageBase::getSource (const char *id)
-{
- // find source
- ImageSourceList::iterator src = findSource(id);
- // return it, if found
- return src != m_sources.end() ? (*src)->getSource() : NULL;
-}
-
-
-// set source object
-bool ImageBase::setSource (const char *id, PyImage *source)
-{
- // find source
- ImageSourceList::iterator src = findSource(id);
- // check source loop
- if (source != NULL && source->m_image->loopDetect(this))
- return false;
- // if found, set new object
- if (src != m_sources.end())
- // if new object is not empty or sources are static
- if (source != NULL || m_staticSources)
- // replace previous source
- (*src)->setSource(source);
- // otherwise delete source
- else
- m_sources.erase(src);
- // if source is not found and adding is allowed
- else
- if (!m_staticSources)
- {
- // create new source
- ImageSource * newSrc = newSource(id);
- newSrc->setSource(source);
- // if source was created, add it to source list
- if (newSrc != NULL) m_sources.push_back(newSrc);
- }
- // otherwise source wasn't set
- else
- return false;
- // source was set
- return true;
-}
-
-
-// set pixel filter
-void ImageBase::setFilter (PyFilter * filt)
-{
- // reference new filter
- if (filt != NULL) Py_INCREF(filt);
- // release previous filter
- Py_XDECREF(m_pyfilter);
- // set new filter
- m_pyfilter = filt;
-}
-
-void ImageBase::swapImageBR()
-{
- unsigned int size, v, *s;
-
- if (m_avail) {
- size = 1 * m_size[0] * m_size[1];
- for (s=m_image; size; size--) {
- v = *s;
- *s++ = VT_SWAPBR(v);
- }
- }
-}
-
-// initialize image data
-void ImageBase::init (short width, short height)
-{
- // if image has to be scaled
- if (m_scale)
- {
- // recalc sizes of image
- width = calcSize(width);
- height = calcSize(height);
- }
- // if sizes differ
- if (width != m_size[0] || height != m_size[1])
- {
- if (m_exports > 0)
- THRWEXCP(ImageHasExports,S_OK);
-
- // new buffer size
- unsigned int newSize = width * height;
- // if new buffer is larger than previous
- if (newSize > m_imgSize)
- {
- // set new buffer size
- m_imgSize = newSize;
- // release previous and create new buffer
- if (m_image)
- delete [] m_image;
- m_image = new unsigned int[m_imgSize];
- }
- // new image size
- m_size[0] = width;
- m_size[1] = height;
- // scale was processed
- m_scaleChange = false;
- }
-}
-
-
-// find source
-ImageSourceList::iterator ImageBase::findSource (const char *id)
-{
- // iterate sources
- ImageSourceList::iterator it;
- for (it = m_sources.begin(); it != m_sources.end(); ++it)
- // if id matches, return iterator
- if ((*it)->is(id)) return it;
- // source not found
- return it;
-}
-
-
-// check sources sizes
-bool ImageBase::checkSourceSizes (void)
-{
- // reference size
- short * refSize = NULL;
- // iterate sources
- for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
- {
- // get size of current source
- short * curSize = (*it)->getSize();
- // if size is available and is not empty
- if (curSize[0] != 0 && curSize[1] != 0) {
- // if reference size is not set
- if (refSize == NULL) {
- // set current size as reference
- refSize = curSize;
- // otherwise check with current size
- }
- else if (curSize[0] != refSize[0] || curSize[1] != refSize[1]) {
- // if they don't match, report it
- return false;
- }
- }
- }
- // all sizes match
- return true;
-}
-
-
-// compute nearest power of 2 value
-short ImageBase::calcSize (short size)
-{
- // while there is more than 1 bit in size value
- while ((size & (size - 1)) != 0)
- // clear last bit
- size = size & (size - 1);
- // return result
- return size;
-}
-
-
-// perform loop detection
-bool ImageBase::loopDetect (ImageBase * img)
-{
- // if this object is the same as parameter, loop is detected
- if (this == img) return true;
- // check all sources
- for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
- // if source detected loop, return this result
- if ((*it)->getSource() != NULL && (*it)->getSource()->m_image->loopDetect(img))
- return true;
- // no loop detected
- return false;
-}
-
-
-// ImageSource class implementation
-
-// constructor
-ImageSource::ImageSource (const char *id) : m_source(NULL), m_image(NULL)
-{
- // copy id
- int idx;
- for (idx = 0; id[idx] != '\0' && idx < SourceIdSize - 1; ++idx)
- m_id[idx] = id[idx];
- m_id[idx] = '\0';
-}
-
-// destructor
-ImageSource::~ImageSource (void)
-{
- // release source
- setSource(NULL);
-}
-
-
-// compare id
-bool ImageSource::is (const char *id)
-{
- for (char *myId = m_id; *myId != '\0'; ++myId, ++id)
- if (*myId != *id) return false;
- return *id == '\0';
-}
-
-
-// set source object
-void ImageSource::setSource (PyImage *source)
-{
- // reference new source
- if (source != NULL) Py_INCREF(source);
- // release previous source
- Py_XDECREF(m_source);
- // set new source
- m_source = source;
-}
-
-
-// get image from source
-unsigned int * ImageSource::getImage (double ts)
-{
- // if source is available
- if (m_source != NULL)
- // get image from source
- m_image = m_source->m_image->getImage(0, ts);
- // otherwise reset buffer
- else
- m_image = NULL;
- // return image
- return m_image;
-}
-
-
-// refresh source
-void ImageSource::refresh (void)
-{
- // if source is available, refresh it
- if (m_source != NULL) m_source->m_image->refresh();
-}
-
-
-
-// list of image types
-PyTypeList pyImageTypes;
-
-
-
-// functions for python interface
-
-// object allocation
-PyObject *Image_allocNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- // allocate object
- PyImage *self = reinterpret_cast<PyImage*>(type->tp_alloc(type, 0));
- // initialize object structure
- self->m_image = NULL;
- // return allocated object
- return reinterpret_cast<PyObject*>(self);
-}
-
-// object deallocation
-void Image_dealloc(PyImage *self)
-{
- // release object attributes
- if (self->m_image != NULL)
- {
- if (self->m_image->m_exports > 0)
- {
- PyErr_SetString(PyExc_SystemError,
- "deallocated Image object has exported buffers");
- PyErr_Print();
- }
- // if release requires deleting of object, do it
- if (self->m_image->release())
- delete self->m_image;
- self->m_image = NULL;
- }
- Py_TYPE((PyObject *)self)->tp_free((PyObject *)self);
-}
-
-// get image data
-PyObject *Image_getImage(PyImage *self, char *mode)
-{
- try
- {
- unsigned int * image = self->m_image->getImage();
- if (image)
- {
- // build BGL buffer
- int dimensions = self->m_image->getBuffSize();
- Buffer * buffer;
- if (mode == NULL || !strcasecmp(mode, "RGBA"))
- {
- buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, image);
- }
- else if (!strcasecmp(mode, "F"))
- {
- // this mode returns the image as an array of float.
- // This makes sense ONLY for the depth buffer:
- // source = VideoTexture.ImageViewport()
- // source.depth = True
- // depth = VideoTexture.imageToArray(source, 'F')
-
- // adapt dimension from byte to float
- dimensions /= sizeof(float);
- buffer = BGL_MakeBuffer( GL_FLOAT, 1, &dimensions, image);
- }
- else
- {
- int i, c, ncolor, pixels;
- int offset[4];
- unsigned char *s, *d;
- // scan the mode to get the channels requested, no more than 4
- for (i=ncolor=0; mode[i] != 0 && ncolor < 4; i++)
- {
- switch (toupper(mode[i]))
- {
- case 'R':
- offset[ncolor++] = 0;
- break;
- case 'G':
- offset[ncolor++] = 1;
- break;
- case 'B':
- offset[ncolor++] = 2;
- break;
- case 'A':
- offset[ncolor++] = 3;
- break;
- case '0':
- offset[ncolor++] = -1;
- break;
- case '1':
- offset[ncolor++] = -2;
- break;
- // if you add more color code, change the switch further down
- default:
- THRWEXCP(InvalidColorChannel,S_OK);
- }
- }
- if (mode[i] != 0) {
- THRWEXCP(InvalidColorChannel,S_OK);
- }
- // first get the number of pixels
- pixels = dimensions / 4;
- // multiple by the number of channels, each is one byte
- dimensions = pixels * ncolor;
- // get an empty buffer
- buffer = BGL_MakeBuffer( GL_BYTE, 1, &dimensions, NULL);
- // and fill it
- for (i = 0, d = (unsigned char *)buffer->buf.asbyte, s = (unsigned char *)image;
- i < pixels;
- i++, d += ncolor, s += 4)
- {
- for (c=0; c<ncolor; c++)
- {
- switch (offset[c])
- {
- case 0: d[c] = s[0]; break;
- case 1: d[c] = s[1]; break;
- case 2: d[c] = s[2]; break;
- case 3: d[c] = s[3]; break;
- case -1: d[c] = 0; break;
- case -2: d[c] = 0xFF; break;
- }
- }
- }
- }
- return (PyObject *)buffer;
- }
- }
- catch (Exception & exp)
- {
- exp.report();
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-// get image size
-PyObject *Image_getSize (PyImage *self, void *closure)
-{
- return Py_BuildValue("(hh)", self->m_image->getSize()[0],
- self->m_image->getSize()[1]);
-}
-
-// refresh image
-PyObject *Image_refresh (PyImage *self, PyObject *args)
-{
- Py_buffer buffer;
- bool done = true;
- char *mode = NULL;
- double ts = -1.0;
- unsigned int format;
-
- memset(&buffer, 0, sizeof(buffer));
- if (PyArg_ParseTuple(args, "|s*sd:refresh", &buffer, &mode, &ts)) {
- if (buffer.buf) {
- // a target buffer is provided, verify its format
- if (buffer.readonly) {
- PyErr_SetString(PyExc_TypeError, "Buffers passed in argument must be writable");
- }
- else if (!PyBuffer_IsContiguous(&buffer, 'C')) {
- PyErr_SetString(PyExc_TypeError, "Buffers passed in argument must be contiguous in memory");
- }
- else if (((intptr_t)buffer.buf & 3) != 0) {
- PyErr_SetString(PyExc_TypeError, "Buffers passed in argument must be aligned to 4 bytes boundary");
- }
- else {
- // ready to get the image into our buffer
- try {
- if (mode == NULL || !strcmp(mode, "RGBA"))
- format = GL_RGBA;
- else if (!strcmp(mode, "BGRA"))
- format = GL_BGRA;
- else
- THRWEXCP(InvalidImageMode,S_OK);
-
- done = self->m_image->loadImage((unsigned int *)buffer.buf, buffer.len, format, ts);
- }
- catch (Exception & exp) {
- exp.report();
- }
- }
- PyBuffer_Release(&buffer);
- if (PyErr_Occurred()) {
- return NULL;
- }
- }
- }
- else {
- return NULL;
- }
-
- self->m_image->refresh();
- if (done)
- Py_RETURN_TRUE;
- Py_RETURN_FALSE;
-}
-
-// get scale
-PyObject *Image_getScale (PyImage *self, void *closure)
-{
- if (self->m_image != NULL && self->m_image->getScale()) Py_RETURN_TRUE;
- else Py_RETURN_FALSE;
-}
-
-// set scale
-int Image_setScale(PyImage *self, PyObject *value, void *closure)
-{
- // check parameter, report failure
- if (value == NULL || !PyBool_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, "The value must be a bool");
- return -1;
- }
- // set scale
- if (self->m_image != NULL) self->m_image->setScale(value == Py_True);
- // success
- return 0;
-}
-
-// get flip
-PyObject *Image_getFlip (PyImage *self, void *closure)
-{
- if (self->m_image != NULL && self->m_image->getFlip()) Py_RETURN_TRUE;
- else Py_RETURN_FALSE;
-}
-
-// set flip
-int Image_setFlip(PyImage *self, PyObject *value, void *closure)
-{
- // check parameter, report failure
- if (value == NULL || !PyBool_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, "The value must be a bool");
- return -1;
- }
- // set scale
- if (self->m_image != NULL) self->m_image->setFlip(value == Py_True);
- // success
- return 0;
-}
-
-// get zbuff
-PyObject *Image_getZbuff(PyImage *self, void *closure)
-{
- if (self->m_image != NULL && self->m_image->getZbuff()) Py_RETURN_TRUE;
- else Py_RETURN_FALSE;
-}
-
-// set zbuff
-int Image_setZbuff(PyImage *self, PyObject *value, void *closure)
-{
- // check parameter, report failure
- if (value == NULL || !PyBool_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, "The value must be a bool");
- return -1;
- }
- // set scale
- if (self->m_image != NULL) self->m_image->setZbuff(value == Py_True);
- // success
- return 0;
-}
-
-// get depth
-PyObject *Image_getDepth(PyImage *self, void *closure)
-{
- if (self->m_image != NULL && self->m_image->getDepth()) Py_RETURN_TRUE;
- else Py_RETURN_FALSE;
-}
-
-// set depth
-int Image_setDepth(PyImage *self, PyObject *value, void *closure)
-{
- // check parameter, report failure
- if (value == NULL || !PyBool_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, "The value must be a bool");
- return -1;
- }
- // set scale
- if (self->m_image != NULL) self->m_image->setDepth(value == Py_True);
- // success
- return 0;
-}
-
-
-
-
-// get filter source object
-PyObject *Image_getSource(PyImage *self, PyObject *args)
-{
- // get arguments
- char *id;
- if (!PyArg_ParseTuple(args, "s:getSource", &id))
- return NULL;
- if (self->m_image != NULL)
- {
- // get source object
- PyObject *src = reinterpret_cast<PyObject*>(self->m_image->getSource(id));
- // if source is available
- if (src != NULL)
- {
- // return source
- Py_INCREF(src);
- return src;
- }
- }
- // source was not found
- Py_RETURN_NONE;
-}
-
-
-// set filter source object
-PyObject *Image_setSource(PyImage *self, PyObject *args)
-{
- // get arguments
- char *id;
- PyObject *obj;
- if (!PyArg_ParseTuple(args, "sO:setSource", &id, &obj))
- return NULL;
- if (self->m_image != NULL)
- {
- // check type of object
- if (pyImageTypes.in(Py_TYPE(obj)))
- {
- // convert to image struct
- PyImage * img = reinterpret_cast<PyImage*>(obj);
- // set source
- if (!self->m_image->setSource(id, img))
- {
- // if not set, retport error
- PyErr_SetString(PyExc_RuntimeError, "Invalid source or id");
- return NULL;
- }
- }
- // else report error
- else
- {
- PyErr_SetString(PyExc_RuntimeError, "Invalid type of object");
- return NULL;
- }
- }
- // return none
- Py_RETURN_NONE;
-}
-
-
-// get pixel filter object
-PyObject *Image_getFilter(PyImage *self, void *closure)
-{
- // if image object is available
- if (self->m_image != NULL)
- {
- // pixel filter object
- PyObject *filt = reinterpret_cast<PyObject*>(self->m_image->getFilter());
- // if filter is present
- if (filt != NULL)
- {
- // return it
- Py_INCREF(filt);
- return filt;
- }
- }
- // otherwise return none
- Py_RETURN_NONE;
-}
-
-
-// set pixel filter object
-int Image_setFilter(PyImage *self, PyObject *value, void *closure)
-{
- // if image object is available
- if (self->m_image != NULL)
- {
- // check new value
- if (value == NULL || !pyFilterTypes.in(Py_TYPE(value)))
- {
- // report value error
- PyErr_SetString(PyExc_TypeError, "Invalid type of value");
- return -1;
- }
- // set new value
- self->m_image->setFilter(reinterpret_cast<PyFilter*>(value));
- }
- // return success
- return 0;
-}
-PyObject *Image_valid(PyImage *self, void *closure)
-{
- if (self->m_image->isImageAvailable())
- {
- Py_RETURN_TRUE;
- }
- else
- {
- Py_RETURN_FALSE;
- }
-}
-
-static int Image_getbuffer(PyImage *self, Py_buffer *view, int flags)
-{
- unsigned int * image;
- int ret;
-
- try {
- // can throw in case of resize
- image = self->m_image->getImage();
- }
- catch (Exception & exp) {
- exp.report();
- return -1;
- }
-
- if (!image) {
- PyErr_SetString(PyExc_BufferError, "Image buffer is not available");
- return -1;
- }
- if (view == NULL)
- {
- self->m_image->m_exports++;
- return 0;
- }
- ret = PyBuffer_FillInfo(view, (PyObject *)self, image, self->m_image->getBuffSize(), 0, flags);
- if (ret >= 0)
- self->m_image->m_exports++;
- return ret;
-}
-
-static void Image_releaseBuffer(PyImage *self, Py_buffer *buffer)
-{
- self->m_image->m_exports--;
-}
-
-PyBufferProcs imageBufferProcs =
-{
- (getbufferproc)Image_getbuffer,
- (releasebufferproc)Image_releaseBuffer
-};
-