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:
-rw-r--r--projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj2
-rw-r--r--source/blender/python/generic/BGL.c65
-rw-r--r--source/blender/python/generic/BGL.h37
-rw-r--r--source/gameengine/VideoTexture/CMakeLists.txt1
-rw-r--r--source/gameengine/VideoTexture/Exception.cpp2
-rw-r--r--source/gameengine/VideoTexture/Exception.h2
-rw-r--r--source/gameengine/VideoTexture/ImageBase.cpp170
-rw-r--r--source/gameengine/VideoTexture/ImageBase.h15
-rw-r--r--source/gameengine/VideoTexture/ImageBuff.cpp102
-rw-r--r--source/gameengine/VideoTexture/ImageMix.cpp3
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp6
-rw-r--r--source/gameengine/VideoTexture/ImageViewport.cpp26
-rw-r--r--source/gameengine/VideoTexture/Makefile1
-rw-r--r--source/gameengine/VideoTexture/SConscript2
-rw-r--r--source/gameengine/VideoTexture/Texture.cpp2
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.cpp14
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.h3
-rw-r--r--source/gameengine/VideoTexture/blendVideoTex.cpp16
18 files changed, 366 insertions, 103 deletions
diff --git a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
index 4eb37259785..ccbc6c15004 100644
--- a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
+++ b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
@@ -42,7 +42,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\GameLogic;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\Rasterizer;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\gpu;..\..\..\source\kernel\gen_system;..\..\..\intern\string;..\..\..\intern\moto\include;..\..\..\intern\guardedalloc;..\..\..\intern\SoundSystem;..\..\..\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python3.1;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\GameLogic;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\Rasterizer;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\python\generic;..\..\..\source\blender\gpu;..\..\..\source\kernel\gen_system;..\..\..\intern\string;..\..\..\intern\moto\include;..\..\..\intern\guardedalloc;..\..\..\intern\SoundSystem;..\..\..\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;WITH_FFMPEG;__STDC_CONSTANT_MACROS"
StringPooling="false"
BasicRuntimeChecks="3"
diff --git a/source/blender/python/generic/BGL.c b/source/blender/python/generic/BGL.c
index 2318549f2ec..340ebbe3dcd 100644
--- a/source/blender/python/generic/BGL.c
+++ b/source/blender/python/generic/BGL.c
@@ -36,9 +36,6 @@
#include <GL/glew.h>
#include "MEM_guardedalloc.h"
-static int type_size( int type );
-static Buffer *make_buffer( int type, int ndimensions, int *dimensions );
-
static char Method_Buffer_doc[] =
"(type, dimensions, [template]) - Create a new Buffer object\n\n\
(type) - The format to store data in\n\
@@ -82,7 +79,7 @@ static PyObject *Buffer_dimensions( PyObject * self );
static PyObject *Buffer_getattr( PyObject * self, char *name );
static PyObject *Buffer_repr( PyObject * self );
-PyTypeObject buffer_Type = {
+PyTypeObject BGL_bufferType = {
PyVarObject_HEAD_INIT(NULL, 0)
"buffer", /*tp_name */
sizeof( Buffer ), /*tp_basicsize */
@@ -120,7 +117,7 @@ static PyObject *Method_##funcname (PyObject *self, PyObject *args) {\
/* #endif */
/********/
-static int type_size(int type)
+int BGL_typeSize(int type)
{
switch (type) {
case GL_BYTE:
@@ -137,7 +134,7 @@ static int type_size(int type)
return -1;
}
-static Buffer *make_buffer(int type, int ndimensions, int *dimensions)
+Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuffer)
{
Buffer *buffer;
void *buf= NULL;
@@ -147,39 +144,49 @@ static Buffer *make_buffer(int type, int ndimensions, int *dimensions)
for (i=0; i<ndimensions; i++)
length*= dimensions[i];
- size= type_size(type);
+ size= BGL_typeSize(type);
buf= MEM_mallocN(length*size, "Buffer buffer");
-
- buffer= (Buffer *) PyObject_NEW(Buffer, &buffer_Type);
+
+ buffer= (Buffer *) PyObject_NEW(Buffer, &BGL_bufferType);
buffer->parent= NULL;
buffer->ndimensions= ndimensions;
- buffer->dimensions= dimensions;
+ buffer->dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
+ memcpy(buffer->dimensions, dimensions, ndimensions*sizeof(int));
buffer->type= type;
buffer->buf.asvoid= buf;
- for (i= 0; i<length; i++) {
- if (type==GL_BYTE)
- buffer->buf.asbyte[i]= 0;
- else if (type==GL_SHORT)
- buffer->buf.asshort[i]= 0;
- else if (type==GL_INT)
- buffer->buf.asint[i]= 0;
- else if (type==GL_FLOAT)
- buffer->buf.asfloat[i]= 0.0f;
- else if (type==GL_DOUBLE)
- buffer->buf.asdouble[i]= 0.0;
+ if (initbuffer) {
+ memcpy(buffer->buf.asvoid, initbuffer, length*size);
+ } else {
+ memset(buffer->buf.asvoid, 0, length*size);
+ /*
+ for (i= 0; i<length; i++) {
+ if (type==GL_BYTE)
+ buffer->buf.asbyte[i]= 0;
+ else if (type==GL_SHORT)
+ buffer->buf.asshort[i]= 0;
+ else if (type==GL_INT)
+ buffer->buf.asint[i]= 0;
+ else if (type==GL_FLOAT)
+ buffer->buf.asfloat[i]= 0.0f;
+ else if (type==GL_DOUBLE)
+ buffer->buf.asdouble[i]= 0.0;
+ }
+ */
}
return buffer;
}
+#define MAX_DIMENSIONS 256
static PyObject *Method_Buffer (PyObject *self, PyObject *args)
{
PyObject *length_ob= NULL, *template= NULL;
Buffer *buffer;
+ int dimensions[MAX_DIMENSIONS];
int i, type;
- int *dimensions = 0, ndimensions = 0;
+ int ndimensions = 0;
if (!PyArg_ParseTuple(args, "iO|O", &type, &length_ob, &template)) {
PyErr_SetString(PyExc_AttributeError, "expected an int and one or two PyObjects");
@@ -192,11 +199,13 @@ static PyObject *Method_Buffer (PyObject *self, PyObject *args)
if (PyNumber_Check(length_ob)) {
ndimensions= 1;
- dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
dimensions[0]= PyLong_AsLong(length_ob);
} else if (PySequence_Check(length_ob)) {
ndimensions= PySequence_Length(length_ob);
- dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
+ if (ndimensions > MAX_DIMENSIONS) {
+ PyErr_SetString(PyExc_AttributeError, "too many dimensions, max is 256");
+ return NULL;
+ }
for (i=0; i<ndimensions; i++) {
PyObject *ob= PySequence_GetItem(length_ob, i);
@@ -206,7 +215,7 @@ static PyObject *Method_Buffer (PyObject *self, PyObject *args)
}
}
- buffer= make_buffer(type, ndimensions, dimensions);
+ buffer= BGL_MakeBuffer(type, ndimensions, dimensions, NULL);
if (template && ndimensions) {
if (Buffer_ass_slice((PyObject *) buffer, 0, dimensions[0], template)) {
Py_DECREF(buffer);
@@ -250,9 +259,9 @@ static PyObject *Buffer_item(PyObject *self, int i)
for (j=1; j<buf->ndimensions; j++) {
length*= buf->dimensions[j];
}
- size= type_size(buf->type);
+ size= BGL_typeSize(buf->type);
- newbuf= (Buffer *) PyObject_NEW(Buffer, &buffer_Type);
+ newbuf= (Buffer *) PyObject_NEW(Buffer, &BGL_bufferType);
Py_INCREF(self);
newbuf->parent= self;
@@ -1104,7 +1113,7 @@ PyObject *BGL_Init(void)
PyDict_SetItemString(PySys_GetObject("modules"), BGL_module_def.m_name, mod);
dict= PyModule_GetDict(mod);
- if( PyType_Ready( &buffer_Type) < 0)
+ if( PyType_Ready( &BGL_bufferType) < 0)
return NULL; /* should never happen */
#define EXPP_ADDCONST(x) PyDict_SetItemString(dict, #x, item=PyLong_FromLong((int)x)); Py_DECREF(item)
diff --git a/source/blender/python/generic/BGL.h b/source/blender/python/generic/BGL.h
index 32076f4fba8..89bade930ce 100644
--- a/source/blender/python/generic/BGL.h
+++ b/source/blender/python/generic/BGL.h
@@ -44,9 +44,16 @@
PyObject *BGL_Init(void);
+/*@ Create a buffer object */
+/*@ dimensions is an array of ndimensions integers representing the size of each dimension */
+/*@ initbuffer if not NULL holds a contiguous buffer with the correct format from which the buffer will be initialized */
+struct _Buffer *BGL_MakeBuffer( int type, int ndimensions, int *dimensions, void *initbuffer );
+/*@ Return the size of buffer element, type must be one of GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT or GL_DOUBLE */
+/*@ returns -1 otherwise */
+int BGL_typeSize( int type );
+
/*@ Buffer Object */
/*@ For Python access to OpenGL functions requiring a pointer. */
-
typedef struct _Buffer {
PyObject_VAR_HEAD
PyObject * parent;
@@ -66,6 +73,8 @@ typedef struct _Buffer {
} buf;
} Buffer;
+/*@ The type object */
+extern PyTypeObject BGL_bufferType;
/*@ By golly George! It looks like fancy pants macro time!!! */
@@ -93,7 +102,7 @@ typedef struct _Buffer {
#define buffer_str "O!"
#define buffer_var(number) (bgl_buffer##number)->buf.asvoid
-#define buffer_ref(number) &buffer_Type, &bgl_buffer##number
+#define buffer_ref(number) &BGL_bufferType, &bgl_buffer##number
#define buffer_def(number) Buffer *bgl_buffer##number
/* GL Pointer fields, handled by buffer type */
@@ -101,62 +110,62 @@ typedef struct _Buffer {
#define GLbooleanP_str "O!"
#define GLbooleanP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLbooleanP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLbooleanP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLbooleanP_def(number) Buffer *bgl_buffer##number
#define GLbyteP_str "O!"
#define GLbyteP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLbyteP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLbyteP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLbyteP_def(number) Buffer *bgl_buffer##number
#define GLubyteP_str "O!"
#define GLubyteP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLubyteP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLubyteP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLubyteP_def(number) Buffer *bgl_buffer##number
#define GLintP_str "O!"
#define GLintP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLintP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLintP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLintP_def(number) Buffer *bgl_buffer##number
#define GLuintP_str "O!"
#define GLuintP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLuintP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLuintP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLuintP_def(number) Buffer *bgl_buffer##number
#define GLshortP_str "O!"
#define GLshortP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLshortP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLshortP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLshortP_def(number) Buffer *bgl_buffer##number
#define GLushortP_str "O!"
#define GLushortP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLushortP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLushortP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLushortP_def(number) Buffer *bgl_buffer##number
#define GLfloatP_str "O!"
#define GLfloatP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLfloatP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLfloatP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLfloatP_def(number) Buffer *bgl_buffer##number
#define GLdoubleP_str "O!"
#define GLdoubleP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLdoubleP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLdoubleP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLdoubleP_def(number) Buffer *bgl_buffer##number
#define GLclampfP_str "O!"
#define GLclampfP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLclampfP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLclampfP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLclampfP_def(number) Buffer *bgl_buffer##number
#define GLvoidP_str "O!"
#define GLvoidP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLvoidP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLvoidP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLvoidP_def(number) Buffer *bgl_buffer##number
#define buffer_str "O!"
#define buffer_var(number) (bgl_buffer##number)->buf.asvoid
-#define buffer_ref(number) &buffer_Type, &bgl_buffer##number
+#define buffer_ref(number) &BGL_bufferType, &bgl_buffer##number
#define buffer_def(number) Buffer *bgl_buffer##number
/*@The standard GL typedefs are used as prototypes, we can't
diff --git a/source/gameengine/VideoTexture/CMakeLists.txt b/source/gameengine/VideoTexture/CMakeLists.txt
index 1268d887eee..eaee00753ff 100644
--- a/source/gameengine/VideoTexture/CMakeLists.txt
+++ b/source/gameengine/VideoTexture/CMakeLists.txt
@@ -42,6 +42,7 @@ SET(INC
../../../source/blender/editors/include
../../../source/blender/imbuf
../../../source/blender/python
+ ../../../source/blender/python/generic
../../../source/blender/gpu
../../../source/kernel/gen_system
../../../intern/string
diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp
index 8b4808ffbe9..124c8ae27d8 100644
--- a/source/gameengine/VideoTexture/Exception.cpp
+++ b/source/gameengine/VideoTexture/Exception.cpp
@@ -202,6 +202,8 @@ void registerAllExceptions(void)
errNFoundDesc.registerDesc();
MaterialNotAvailDesc.registerDesc();
ImageSizesNotMatchDesc.registerDesc();
+ ImageHasExportsDesc.registerDesc();
+ InvalidColorChannelDesc.registerDesc();
SceneInvalidDesc.registerDesc();
CameraInvalidDesc.registerDesc();
ObserverInvalidDesc.registerDesc();
diff --git a/source/gameengine/VideoTexture/Exception.h b/source/gameengine/VideoTexture/Exception.h
index 4a57a7f20e4..74dc444c0a9 100644
--- a/source/gameengine/VideoTexture/Exception.h
+++ b/source/gameengine/VideoTexture/Exception.h
@@ -200,6 +200,8 @@ protected:
extern ExpDesc MaterialNotAvailDesc;
extern ExpDesc ImageSizesNotMatchDesc;
+extern ExpDesc ImageHasExportsDesc;
+extern ExpDesc InvalidColorChannelDesc;
extern ExpDesc SceneInvalidDesc;
extern ExpDesc CameraInvalidDesc;
extern ExpDesc ObserverInvalidDesc;
diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp
index 1c5425c932c..908aa5ddd5e 100644
--- a/source/gameengine/VideoTexture/ImageBase.cpp
+++ b/source/gameengine/VideoTexture/ImageBase.cpp
@@ -21,6 +21,10 @@ http://www.gnu.org/copyleft/lesser.txt.
*/
#include "ImageBase.h"
+extern "C" {
+#include "BGL.h"
+}
+#include "GL/glew.h"
#include <vector>
#include <string.h>
@@ -32,7 +36,9 @@ http://www.gnu.org/copyleft/lesser.txt.
#include "Exception.h"
-
+#if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS)
+#define strcasecmp _stricmp
+#endif
// ImageBase class implementation
@@ -42,6 +48,7 @@ m_avail(false), m_scale(false), m_scaleChange(false), m_flip(false),
m_staticSources(staticSrc), m_pyfilter(NULL)
{
m_size[0] = m_size[1] = 0;
+ m_exports = 0;
}
@@ -161,6 +168,11 @@ void ImageBase::setFilter (PyFilter * filt)
m_pyfilter = filt;
}
+ExceptionID ImageHasExports;
+ExceptionID InvalidColorChannel;
+
+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");
// initialize image data
void ImageBase::init (short width, short height)
@@ -175,6 +187,9 @@ void ImageBase::init (short width, short 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
@@ -352,6 +367,12 @@ 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;
@@ -360,17 +381,88 @@ void Image_dealloc (PyImage * self)
}
// get image data
-PyObject * Image_getImage (PyImage * self, void * closure)
+PyObject * Image_getImage (PyImage * self, char * mode)
{
try
{
- // get image
unsigned int * image = self->m_image->getImage();
- return Py_BuildValue("s#", image, self->m_image->getBuffSize());
+ 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
+ {
+ 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;
}
@@ -533,3 +625,73 @@ int Image_setFilter (PyImage * self, PyObject * value, void * closure)
// return success
return 0;
}
+PyObject * Image_valid(PyImage * self, void * closure)
+{
+ if (self->m_image->isImageAvailable())
+ {
+ Py_RETURN_TRUE;
+ }
+ else
+ {
+ Py_RETURN_FALSE;
+ }
+}
+
+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)
+ {
+ // cannot return -1, this creates a crash in Python, for now we will just return an empty buffer
+ //exp.report();
+ //return -1;
+ goto error;
+ }
+
+ if (!image)
+ {
+ // same remark, see above
+ //PyErr_SetString(PyExc_BufferError, "Image buffer is not available");
+ //return -1;
+ goto error;
+ }
+ 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;
+
+error:
+ // Return a empty buffer to avoid a crash in Python 3.1
+ // The bug is fixed in Python SVN 77916, as soon as the python revision used by Blender is
+ // updated, you can simply return -1 and set the error
+ static char* buf = "";
+ ret = PyBuffer_FillInfo(view, (PyObject*)self, buf, 0, 0, flags);
+ if (ret >= 0)
+ self->m_image->m_exports++;
+ return ret;
+
+}
+
+void Image_releaseBuffer(PyImage *self, Py_buffer *buffer)
+{
+ self->m_image->m_exports--;
+}
+
+PyBufferProcs imageBufferProcs =
+{
+ (getbufferproc)Image_getbuffer,
+ (releasebufferproc)Image_releaseBuffer
+};
+
diff --git a/source/gameengine/VideoTexture/ImageBase.h b/source/gameengine/VideoTexture/ImageBase.h
index 70b1929b91d..43a56290bee 100644
--- a/source/gameengine/VideoTexture/ImageBase.h
+++ b/source/gameengine/VideoTexture/ImageBase.h
@@ -53,6 +53,9 @@ public:
/// release contained objects, if returns true, object should be deleted
virtual bool release (void);
+ /// is an image available
+ bool isImageAvailable(void)
+ { return m_avail; }
/// get image
unsigned int * getImage (unsigned int texId = 0, double timestamp=-1.0);
/// get image size
@@ -85,6 +88,9 @@ public:
/// calculate size (nearest power of 2)
static short calcSize (short size);
+ /// number of buffer pointing to m_image, public because not handled by this class
+ int m_exports;
+
protected:
/// image buffer
unsigned int * m_image;
@@ -295,8 +301,6 @@ private:
ImageSource (void) {}
};
-
-
// list of python image types
extern PyTypeList pyImageTypes;
@@ -320,7 +324,7 @@ PyObject * Image_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds
void Image_dealloc (PyImage * self);
// get image data
-PyObject * Image_getImage (PyImage * self, void * closure);
+PyObject * Image_getImage (PyImage * self, char * mode);
// get image size
PyObject * Image_getSize (PyImage * self, void * closure);
// refresh image - invalidate current content
@@ -344,6 +348,9 @@ PyObject * Image_setSource (PyImage * self, PyObject * args);
PyObject * Image_getFilter (PyImage * self, void * closure);
// set pixel filter object
int Image_setFilter (PyImage * self, PyObject * value, void * closure);
-
+// check if a buffer can be extracted
+PyObject * Image_valid(PyImage * self, void * closure);
+// for buffer access to PyImage objects
+extern PyBufferProcs imageBufferProcs;
#endif
diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp
index eccac9d9f89..474a34b2f43 100644
--- a/source/gameengine/VideoTexture/ImageBuff.cpp
+++ b/source/gameengine/VideoTexture/ImageBuff.cpp
@@ -26,7 +26,7 @@ http://www.gnu.org/copyleft/lesser.txt.
#include <structmember.h>
#include "ImageBuff.h"
-
+#include "Exception.h"
#include "ImageBase.h"
#include "FilterSource.h"
@@ -34,6 +34,7 @@ http://www.gnu.org/copyleft/lesser.txt.
extern "C" {
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "BGL.h"
};
// default filter
@@ -137,7 +138,7 @@ static bool testPyBuffer(Py_buffer* buffer, int width, int height, unsigned int
}
if (buffer->len != width*height*pixsize)
{
- PyErr_SetString(PyExc_ValueError, "Buffer hasn't correct size");
+ PyErr_SetString(PyExc_ValueError, "Buffer hasn't the correct size");
return false;
}
// multi dimension are ok as long as there is no hole in the memory
@@ -160,43 +161,91 @@ static bool testPyBuffer(Py_buffer* buffer, int width, int height, unsigned int
return true;
}
+static bool testBGLBuffer(Buffer* buffer, int width, int height, unsigned int pixsize)
+{
+ unsigned int size = BGL_typeSize(buffer->type);
+ for (int i=0; i<buffer->ndimensions; i++)
+ {
+ size *= buffer->dimensions[i];
+ }
+ if (size != width*height*pixsize)
+ {
+ PyErr_SetString(PyExc_ValueError, "Buffer hasn't the correct size");
+ return false;
+ }
+ return true;
+}
+
+
// load image
static PyObject * load (PyImage * self, PyObject * args)
{
// parameters: string image buffer, its size, width, height
Py_buffer buffer;
+ Buffer *bglBuffer;
short width;
short height;
+ unsigned int pixSize;
+
+ // calc proper buffer size
+ // use pixel size from filter
+ if (self->m_image->getFilter() != NULL)
+ pixSize = self->m_image->getFilter()->m_filter->firstPixelSize();
+ else
+ pixSize = defFilter.firstPixelSize();
+
// parse parameters
if (!PyArg_ParseTuple(args, "s*hh:load", &buffer, &width, &height))
{
- // report error
- return NULL;
+ PyErr_Clear();
+ // check if it is BGL buffer
+ if (!PyArg_ParseTuple(args, "O!hh:load", &BGL_bufferType, &bglBuffer, &width, &height))
+ {
+ // report error
+ return NULL;
+ }
+ else
+ {
+ if (testBGLBuffer(bglBuffer, width, height, pixSize))
+ {
+ try
+ {
+ // if correct, load image
+ getImageBuff(self)->load((unsigned char*)bglBuffer->buf.asvoid, width, height);
+ }
+ catch (Exception & exp)
+ {
+ exp.report();
+ }
+ }
+ }
}
- // else check buffer size
else
{
- // calc proper buffer size
- unsigned int pixSize;
- // use pixel size from filter
- if (self->m_image->getFilter() != NULL)
- pixSize = self->m_image->getFilter()->m_filter->firstPixelSize();
- else
- pixSize = defFilter.firstPixelSize();
// check if buffer size is correct
if (testPyBuffer(&buffer, width, height, pixSize))
{
- // if correct, load image
- getImageBuff(self)->load((unsigned char*)buffer.buf, width, height);
+ try
+ {
+ // if correct, load image
+ getImageBuff(self)->load((unsigned char*)buffer.buf, width, height);
+ }
+ catch (Exception & exp)
+ {
+ exp.report();
+ }
}
PyBuffer_Release(&buffer);
}
+ if (PyErr_Occurred())
+ return NULL;
Py_RETURN_NONE;
}
static PyObject * plot (PyImage * self, PyObject * args)
{
PyImage * other;
+ Buffer* bglBuffer;
Py_buffer buffer;
//unsigned char * buff;
//unsigned int buffSize;
@@ -214,17 +263,31 @@ static PyObject * plot (PyImage * self, PyObject * args)
getImageBuff(self)->plot((unsigned char*)buffer.buf, width, height, x, y, mode);
}
PyBuffer_Release(&buffer);
+ if (PyErr_Occurred())
+ return NULL;
Py_RETURN_NONE;
}
PyErr_Clear();
// try the other format
- if (!PyArg_ParseTuple(args, "O!hh|h:plot", &ImageBuffType, &other, &x, &y, &mode))
+ if (PyArg_ParseTuple(args, "O!hh|h:plot", &ImageBuffType, &other, &x, &y, &mode))
{
- PyErr_SetString(PyExc_TypeError, "Expecting ImageBuff or string,width,height as first arguments, postion x, y and mode and last arguments");
+ getImageBuff(self)->plot(getImageBuff(other), x, y, mode);
+ Py_RETURN_NONE;
+ }
+ PyErr_Clear();
+ // try the last format (BGL buffer)
+ if (!PyArg_ParseTuple(args, "O!hhhh|h:plot", &BGL_bufferType, &bglBuffer, &width, &height, &x, &y, &mode))
+ {
+ PyErr_SetString(PyExc_TypeError, "Expecting ImageBuff or Py buffer or BGL buffer as first argument; width, height next; postion x, y and mode as last arguments");
return NULL;
}
- getImageBuff(self)->plot(getImageBuff(other), x, y, mode);
- Py_RETURN_NONE;
+ if (testBGLBuffer(bglBuffer, width, height, 4))
+ {
+ getImageBuff(self)->plot((unsigned char*)bglBuffer->buf.asvoid, width, height, x, y, mode);
+ }
+ if (PyErr_Occurred)
+ return NULL;
+ Py_RETURN_NONE;
}
// methods structure
@@ -237,6 +300,7 @@ static PyMethodDef imageBuffMethods[] =
// attributes structure
static PyGetSetDef imageBuffGetSets[] =
{ // attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -267,7 +331,7 @@ PyTypeObject ImageBuffType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from image buffer", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp
index a4a61e7f55a..7b304dda3ce 100644
--- a/source/gameengine/VideoTexture/ImageMix.cpp
+++ b/source/gameengine/VideoTexture/ImageMix.cpp
@@ -154,6 +154,7 @@ static PyMethodDef imageMixMethods[] =
// attributes structure
static PyGetSetDef imageMixGetSets[] =
{ // attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -184,7 +185,7 @@ PyTypeObject ImageMixType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image mixer", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index 0a01ce11a0e..d654bc14114 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -365,6 +365,7 @@ static PyGetSetDef imageRenderGetSets[] =
{(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
{(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL},
// attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -395,7 +396,7 @@ PyTypeObject ImageRenderType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from render", /* tp_doc */
0, /* tp_traverse */
@@ -526,6 +527,7 @@ static PyGetSetDef imageMirrorGetSets[] =
{(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
{(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL},
// attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -729,7 +731,7 @@ PyTypeObject ImageMirrorType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from mirror", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp
index c39173a96f9..5a4e8af1b0c 100644
--- a/source/gameengine/VideoTexture/ImageViewport.cpp
+++ b/source/gameengine/VideoTexture/ImageViewport.cpp
@@ -177,8 +177,16 @@ int ImageViewport_setWhole (PyImage * self, PyObject * value, void * closure)
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
return -1;
}
- // set whole
- if (self->m_image != NULL) getImageViewport(self)->setWhole(value == Py_True);
+ try
+ {
+ // set whole, can throw in case of resize and buffer exports
+ if (self->m_image != NULL) getImageViewport(self)->setWhole(value == Py_True);
+ }
+ catch (Exception & exp)
+ {
+ exp.report();
+ return -1;
+ }
// success
return 0;
}
@@ -257,7 +265,16 @@ int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closu
short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 0))),
short(PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value, 1)))
};
- getImageViewport(self)->setCaptureSize(size);
+ try
+ {
+ // can throw in case of resize and buffer exports
+ getImageViewport(self)->setCaptureSize(size);
+ }
+ catch (Exception & exp)
+ {
+ exp.report();
+ return -1;
+ }
// success
return 0;
}
@@ -277,6 +294,7 @@ static PyGetSetDef imageViewportGetSets[] =
{(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of viewport area being captured", NULL},
{(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL},
// attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -307,7 +325,7 @@ PyTypeObject ImageViewportType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Image source from viewport", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/Makefile b/source/gameengine/VideoTexture/Makefile
index 90457df720f..1cb147860cd 100644
--- a/source/gameengine/VideoTexture/Makefile
+++ b/source/gameengine/VideoTexture/Makefile
@@ -41,6 +41,7 @@ CPPFLAGS += -I$(NAN_GLEW)/include
CPPFLAGS += -I$(OPENGL_HEADERS)
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
CPPFLAGS += -I../../blender/python
+CPPFLAGS += -I../../blender/python/generic
CPPFLAGS += -I$(NAN_STRING)/include
CPPFLAGS += -I$(NAN_MOTO)/include
CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer
diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript
index 59c311d5240..70c7dfc6d3a 100644
--- a/source/gameengine/VideoTexture/SConscript
+++ b/source/gameengine/VideoTexture/SConscript
@@ -10,7 +10,7 @@ incs += ' #source/gameengine/GameLogic #source/gameengine/SceneGraph #source/gam
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer'
incs += ' #source/gameengine/BlenderRoutines'
incs += ' #source/blender/editors/include #source/blender/blenlib #source/blender/blenkernel'
-incs += ' #source/blender/makesdna #source/blender/imbuf #source/blender/python'
+incs += ' #source/blender/makesdna #source/blender/imbuf #source/blender/python #source/blender/python/generic'
incs += ' #source/blender/gpu #source/kernel/gen_system #intern/string #intern/moto/include'
incs += ' #intern/guardedalloc #extern/glew/include'
diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp
index f59b92409f5..b8ed38c435d 100644
--- a/source/gameengine/VideoTexture/Texture.cpp
+++ b/source/gameengine/VideoTexture/Texture.cpp
@@ -455,7 +455,7 @@ PyTypeObject TextureType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"Texture objects", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
index 4c87b1764d6..c33cb9a671d 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
@@ -723,14 +723,8 @@ void VideoFFmpeg::setFrameRate (float rate)
// image calculation
-void VideoFFmpeg::calcImage (unsigned int texId, double ts)
-{
- loadFrame(ts);
-}
-
-
// load frame from video
-void VideoFFmpeg::loadFrame (double ts)
+void VideoFFmpeg::calcImage (unsigned int texId, double ts)
{
if (m_status == SourcePlaying)
{
@@ -1162,6 +1156,7 @@ static PyGetSetDef videoGetSets[] =
{(char*)"repeat", (getter)Video_getRepeat, (setter)Video_setRepeat, (char*)"repeat count, -1 for infinite repeat", NULL},
{(char*)"framerate", (getter)Video_getFrameRate, (setter)Video_setFrameRate, (char*)"frame rate", NULL},
// attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -1193,7 +1188,7 @@ PyTypeObject VideoFFmpegType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"FFmpeg video source", /* tp_doc */
0, /* tp_traverse */
@@ -1282,6 +1277,7 @@ static PyGetSetDef imageGetSets[] =
{ // methods from VideoBase class
{(char*)"status", (getter)Video_getStatus, NULL, (char*)"video status", NULL},
// attributes from ImageBase class
+ {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL},
{(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL},
{(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL},
{(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL},
@@ -1311,7 +1307,7 @@ PyTypeObject ImageFFmpegType =
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
+ &imageBufferProcs, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"FFmpeg image source", /* tp_doc */
0, /* tp_traverse */
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h
index 355c58c496b..b9bf69039c7 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.h
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.h
@@ -159,9 +159,6 @@ protected:
/// image calculation
virtual void calcImage (unsigned int texId, double ts);
- /// load frame from video
- void loadFrame (double ts);
-
/// set actual position
void setPositions (void);
diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp
index 998d63506b0..01e783edc10 100644
--- a/source/gameengine/VideoTexture/blendVideoTex.cpp
+++ b/source/gameengine/VideoTexture/blendVideoTex.cpp
@@ -86,7 +86,8 @@ static PyObject * imageToArray (PyObject * self, PyObject *args)
{
// parameter is Image object
PyObject * pyImg;
- if (!PyArg_ParseTuple(args, "O:imageToArray", &pyImg) || !pyImageTypes.in(pyImg->ob_type))
+ char *mode = NULL;
+ if (!PyArg_ParseTuple(args, "O|s:imageToArray", &pyImg, &mode) || !pyImageTypes.in(pyImg->ob_type))
{
// if object is incorect, report error
PyErr_SetString(PyExc_TypeError, "VideoTexture.imageToArray(image): The value must be a image source object");
@@ -94,16 +95,7 @@ static PyObject * imageToArray (PyObject * self, PyObject *args)
}
// get image structure
PyImage * img = reinterpret_cast<PyImage*>(pyImg);
- // create array object
- unsigned int * imgBuff = img->m_image->getImage();
- // if image is available, convert it to array
- if (imgBuff != NULL)
- // Nasty problem here: the image buffer is an array of integers
- // in the processor endian format. The user must take care of that in the script.
- // Need to find an elegant solution to this problem
- return Py_BuildValue("s#", imgBuff, img->m_image->getBuffSize());
- // otherwise return None
- Py_RETURN_NONE;
+ return Image_getImage(img, mode);
}
@@ -113,7 +105,7 @@ static PyMethodDef moduleMethods[] =
{"materialID", getMaterialID, METH_VARARGS, "Gets object's Blender Material ID"},
{"getLastError", getLastError, METH_NOARGS, "Gets last error description"},
{"setLogFile", setLogFile, METH_VARARGS, "Sets log file name"},
- {"imageToArray", imageToArray, METH_VARARGS, "get array from image source"},
+ {"imageToArray", imageToArray, METH_VARARGS, "get buffer from image source, color channels are selectable"},
{NULL} /* Sentinel */
};