4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License. See http://www.blender.org/BL/ for information
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * This is a new part of Blender.
28 * Contributor(s): Willian P. Germano, Campbell Barton, Joilnen B. Leite,
31 * ***** END GPL/BL DUAL LICENSE BLOCK *****
33 #include "Image.h" /*This must come first */
35 #include "BDR_drawmesh.h" /* free_realtime_image */
37 #include "BKE_global.h"
38 #include "BKE_library.h"
39 #include "BKE_image.h"
40 #include "BIF_drawimage.h"
41 #include "BLI_blenlib.h"
42 #include "DNA_space_types.h" /* FILE_MAXDIR = 160 */
43 #include "IMB_imbuf_types.h" /* for the IB_rect define */
45 #include "gen_utils.h"
49 this belongs in a header
52 short IMB_saveiff( struct ImBuf *ibuf, char *naam, int flags );
54 /*****************************************************************************/
55 /* Python BPy_Image defaults: */
56 /*****************************************************************************/
57 #define EXPP_IMAGE_REP 1
58 #define EXPP_IMAGE_REP_MIN 1
59 #define EXPP_IMAGE_REP_MAX 16
62 /************************/
63 /*** The Image Module ***/
64 /************************/
66 /*****************************************************************************/
67 /* Python API function prototypes for the Image module. */
68 /*****************************************************************************/
69 static PyObject *M_Image_New( PyObject * self, PyObject * args );
70 static PyObject *M_Image_Get( PyObject * self, PyObject * args );
71 static PyObject *M_Image_GetCurrent( PyObject * self );
72 static PyObject *M_Image_Load( PyObject * self, PyObject * args );
74 /*****************************************************************************/
75 /* The following string definitions are used for documentation strings. */
76 /* In Python these will be written to the console when doing a */
77 /* Blender.Image.__doc__ */
78 /*****************************************************************************/
79 static char M_Image_doc[] = "The Blender Image module\n\n";
81 static char M_Image_New_doc[] =
82 "() - return a new Image object";
84 static char M_Image_Get_doc[] =
85 "(name) - return the image with the name 'name', \
86 returns None if not found.\n If 'name' is not specified, \
87 it returns a list of all images in the\ncurrent scene.";
89 static char M_Image_GetCurrent_doc[] =
90 "() - return the current image, from last active the uv/image view, \
91 returns None no image is in the view.\n";
93 static char M_Image_Load_doc[] =
94 "(filename) - return image from file filename as Image Object, \
95 returns None if not found.\n";
97 /*****************************************************************************/
98 /* Python method structure definition for Blender.Image module: */
99 /*****************************************************************************/
100 struct PyMethodDef M_Image_methods[] = {
101 {"New", M_Image_New, METH_VARARGS, M_Image_New_doc},
102 {"Get", M_Image_Get, METH_VARARGS, M_Image_Get_doc},
103 {"GetCurrent", ( PyCFunction ) M_Image_GetCurrent, METH_NOARGS, M_Image_GetCurrent_doc},
104 {"get", M_Image_Get, METH_VARARGS, M_Image_Get_doc},
105 {"Load", M_Image_Load, METH_VARARGS, M_Image_Load_doc},
106 {NULL, NULL, 0, NULL}
110 /*****************************************************************************/
111 /* Function: M_Image_New */
112 /* Python equivalent: Blender.Image.New */
113 /*****************************************************************************/
114 static PyObject *M_Image_New( PyObject * self, PyObject * args)
116 int width, height, depth;
119 if( !PyArg_ParseTuple( args, "siii", &name, &width, &height, &depth ) )
120 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
121 "expected 1 string and 3 ints" ) );
122 if (width > 5000 || height > 5000 || width < 1 || height < 1)
123 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
124 "Image width and height must be between 1 and 5000" ) );
125 img = new_image(width, height, name, 0);
127 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
128 "couldn't create PyObject Image_Type" ) );
130 return Image_CreatePyObject( img );
135 /*****************************************************************************/
136 /* Function: M_Image_Get */
137 /* Python equivalent: Blender.Image.Get */
138 /* Description: Receives a string and returns the image object */
139 /* whose name matches the string. If no argument is */
140 /* passed in, a list of all image names in the */
141 /* current scene is returned. */
142 /*****************************************************************************/
143 static PyObject *M_Image_Get( PyObject * self, PyObject * args )
148 if( !PyArg_ParseTuple( args, "|s", &name ) )
149 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
150 "expected string argument (or nothing)" ) );
152 img_iter = G.main->image.first;
154 if( name ) { /* (name) - Search image by name */
156 BPy_Image *wanted_image = NULL;
158 while( ( img_iter ) && ( wanted_image == NULL ) ) {
159 if( strcmp( name, img_iter->id.name + 2 ) == 0 ) {
160 wanted_image = ( BPy_Image * )
161 PyObject_NEW( BPy_Image, &Image_Type );
163 wanted_image->image = img_iter;
165 img_iter = img_iter->id.next;
168 if( wanted_image == NULL ) { /* Requested image doesn't exist */
170 PyOS_snprintf( error_msg, sizeof( error_msg ),
171 "Image \"%s\" not found", name );
172 return ( EXPP_ReturnPyObjError
173 ( PyExc_NameError, error_msg ) );
176 return ( PyObject * ) wanted_image;
179 else { /* () - return a list of all images in the scene */
181 PyObject *img_list, *pyobj;
183 img_list = PyList_New( BLI_countlist( &( G.main->image ) ) );
185 if( img_list == NULL )
186 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
187 "couldn't create PyList" ) );
190 pyobj = Image_CreatePyObject( img_iter );
192 PyList_SET_ITEM( img_list, index, pyobj );
194 img_iter = img_iter->id.next;
204 /*****************************************************************************/
205 /* Function: M_Image_GetCurrent*/
206 /* Python equivalent: Blender.Image.GetCurrent */
207 /* Description: Returns the active current (G.sima) */
208 /* This will be the image last under the mouse cursor */
209 /* None if there is no Image. */
210 /*****************************************************************************/
211 static PyObject *M_Image_GetCurrent( PyObject * self )
213 if (!G.sima || !G.sima->image) {
216 return Image_CreatePyObject( G.sima->image );
221 /*****************************************************************************/
222 /* Function: M_Image_Load */
223 /* Python equivalent: Blender.Image.Load */
224 /* Description: Receives a string and returns the image object */
225 /* whose filename matches the string. */
226 /*****************************************************************************/
227 static PyObject *M_Image_Load( PyObject * self, PyObject * args )
233 if( !PyArg_ParseTuple( args, "s", &fname ) )
234 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
235 "expected string argument" ) );
237 img = ( BPy_Image * ) PyObject_NEW( BPy_Image, &Image_Type );
240 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
241 "couldn't create PyObject Image_Type" ) );
243 img_ptr = add_image( fname );
245 return ( EXPP_ReturnPyObjError( PyExc_IOError,
246 "couldn't load image" ) );
248 img->image = img_ptr;
250 return ( PyObject * ) img;
256 * returns float list of pixel colors in rgba order.
257 * returned values are floats normalized to 0.0 - 1.0.
258 * blender images are all 4x8 bit at the moment apr-2005
261 static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
265 Image *image = self->image;
266 char *pixel; /* image data */
267 int index; /* offset into image data */
270 int pixel_size = 4; /* each pixel is 4 x 8-bits packed in unsigned int */
272 if( !PyArg_ParseTuple( args, "ii", &x, &y ) )
273 return EXPP_ReturnPyObjError( PyExc_TypeError,
274 "expected 2 integers" );
276 if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
277 load_image( image, IB_rect, "", 0 ); /* loading it */
279 if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
280 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
281 "couldn't load image data in Blender" );
283 if( image->ibuf->type == 1 ) /* bitplane image */
284 return EXPP_ReturnPyObjError( PyExc_TypeError,
285 "unsupported bitplane image format" );
287 if( x > ( image->ibuf->x - 1 )
288 || y > ( image->ibuf->y - 1 )
289 || x < image->ibuf->xorig || y < image->ibuf->yorig )
290 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
291 "x or y is out of range" );
294 assumption: from looking at source, skipx is often not set,
298 index = ( x + y * image->ibuf->x ) * pixel_size;
300 pixel = ( char * ) image->ibuf->rect;
301 attr = Py_BuildValue( "[f,f,f,f]",
302 ( ( float ) pixel[index] ) / 255.0,
303 ( ( float ) pixel[index + 1] ) / 255.0,
304 ( ( float ) pixel[index + 2] ) / 255.0,
305 ( ( float ) pixel[index + 3] / 255.0 ) );
307 if( attr ) /* normal return */
310 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
311 "couldn't get pixel colors" );
317 * returns integer list of pixel colors in rgba order.
318 * returned values are ints normalized to 0-255.
319 * blender images are all 4x8 bit at the moment apr-2005
322 static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
325 Image *image = self->image;
326 char *pixel; /* image data */
327 int index; /* offset into image data */
330 int pixel_size = 4; /* each pixel is 4 x 8-bits packed in unsigned int */
332 if( !PyArg_ParseTuple( args, "ii", &x, &y ) )
333 return EXPP_ReturnPyObjError( PyExc_TypeError,
334 "expected 2 integers" );
336 if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
337 load_image( image, IB_rect, "", 0 ); /* loading it */
339 if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
340 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
341 "couldn't load image data in Blender" );
343 if( image->ibuf->type == 1 ) /* bitplane image */
344 return EXPP_ReturnPyObjError( PyExc_TypeError,
345 "unsupported bitplane image format" );
347 if( x > ( image->ibuf->x - 1 )
348 || y > ( image->ibuf->y - 1 )
349 || x < image->ibuf->xorig || y < image->ibuf->yorig )
350 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
351 "x or y is out of range" );
354 assumption: from looking at source, skipx is often not set,
358 index = ( x + y * image->ibuf->x ) * pixel_size;
360 pixel = ( char * ) image->ibuf->rect;
361 attr = Py_BuildValue( "[i,i,i,i]",
364 pixel[index + 2], pixel[index + 3] );
366 if( attr ) /* normal return */
369 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
370 "couldn't get pixel colors" );
374 /* set pixel as floats */
376 static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
378 Image *image = self->image;
379 char *pixel; /* image data */
380 int index; /* offset into image data */
384 int pixel_size = 4; /* each pixel is 4 x 8-bits packed in unsigned int */
387 if( !PyArg_ParseTuple
388 ( args, "ii(ffff)", &x, &y, &p[0], &p[1], &p[2], &p[3] ) )
389 return EXPP_ReturnPyObjError( PyExc_TypeError,
390 "expected 2 integers and an array of 4 floats" );
392 if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
393 load_image( image, IB_rect, "", 0 ); /* loading it */
395 if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
396 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
397 "couldn't load image data in Blender" );
399 if( image->ibuf->type == 1 ) /* bitplane image */
400 return EXPP_ReturnPyObjError( PyExc_TypeError,
401 "unsupported bitplane image format" );
403 if( x > ( image->ibuf->x - 1 )
404 || y > ( image->ibuf->y - 1 )
405 || x < image->ibuf->xorig || y < image->ibuf->yorig )
406 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
407 "x or y is out of range" );
409 for( a = 0; a < 4; a++ ) {
410 if( p[a] > 1.0 || p[a] < 0.0 )
411 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
412 "r, g, b, or a is out of range" );
417 assumption: from looking at source, skipx is often not set,
421 index = ( x + y * image->ibuf->x ) * pixel_size;
423 pixel = ( char * ) image->ibuf->rect;
425 pixel[index] = ( char ) ( p[0] * 255.0 );
426 pixel[index + 1] = ( char ) ( p[1] * 255.0 );
427 pixel[index + 2] = ( char ) ( p[2] * 255.0 );
428 pixel[index + 3] = ( char ) ( p[3] * 255.0 );
434 /* set pixel as ints */
436 static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
438 Image *image = self->image;
439 char *pixel; /* image data */
440 int index; /* offset into image data */
444 int pixel_size = 4; /* each pixel is 4 x 8-bits packed in unsigned int */
447 if( !PyArg_ParseTuple
448 ( args, "ii(iiii)", &x, &y, &p[0], &p[1], &p[2], &p[3] ) )
449 return EXPP_ReturnPyObjError( PyExc_TypeError,
450 "expected 2 integers and an list of 4 ints" );
452 if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
453 load_image( image, IB_rect, "", 0 ); /* loading it */
455 if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
456 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
457 "couldn't load image data in Blender" );
459 if( image->ibuf->type == 1 ) /* bitplane image */
460 return EXPP_ReturnPyObjError( PyExc_TypeError,
461 "unsupported bitplane image format" );
463 if( x > ( image->ibuf->x - 1 )
464 || y > ( image->ibuf->y - 1 )
465 || x < image->ibuf->xorig || y < image->ibuf->yorig )
466 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
467 "x or y is out of range" );
469 for( a = 0; a < 4; a++ ) {
470 if( p[a] > 255 || p[a] < 0 )
471 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
472 "r, g, b, or a is out of range" );
476 assumption: from looking at source, skipx is often not set,
480 index = ( x + y * image->ibuf->x ) * pixel_size;
482 pixel = ( char * ) image->ibuf->rect;
484 pixel[index] = ( char ) p[0];
485 pixel[index + 1] = ( char ) p[1];
486 pixel[index + 2] = ( char ) p[2];
487 pixel[index + 3] = ( char ) p[3];
493 /* get max extent of image */
495 static PyObject *Image_getMaxXY( BPy_Image * self )
497 Image *image = self->image;
500 if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
501 load_image( image, IB_rect, "", 0 ); /* loading it */
503 if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
504 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
505 "couldn't load image data in Blender" );
507 attr = Py_BuildValue( "[i,i]", image->ibuf->x, image->ibuf->y );
512 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
513 "could not determine max x or y" );
517 /* get min extent of image */
519 static PyObject *Image_getMinXY( BPy_Image * self )
521 Image *image = self->image;
524 if( !image->ibuf || !image->ibuf->rect ) /* if no image data available */
525 load_image( image, IB_rect, "", 0 ); /* loading it */
527 if( !image->ibuf || !image->ibuf->rect ) /* didn't work */
528 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
529 "couldn't load image data in Blender" );
531 attr = Py_BuildValue( "[i,i]", image->ibuf->xorig,
532 image->ibuf->yorig );
537 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
538 "could not determine min x or y" );
542 /* save image to file */
544 static PyObject *Image_save( BPy_Image * self )
546 Py_INCREF( Py_None );
549 ( self->image->ibuf, self->image->name,
550 self->image->ibuf->flags ) )
551 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
552 "could not save image" );
554 Py_RETURN_NONE; /* normal return, image saved */
557 /*****************************************************************************/
558 /* Function: Image_Init */
559 /*****************************************************************************/
560 PyObject *Image_Init( void )
564 Image_Type.ob_type = &PyType_Type;
567 Py_InitModule3( "Blender.Image", M_Image_methods,
570 return ( submodule );
573 /************************/
574 /*** The Image PyType ***/
575 /************************/
577 /*****************************************************************************/
578 /* Python BPy_Image methods declarations: */
579 /*****************************************************************************/
580 static PyObject *Image_getName( BPy_Image * self );
581 static PyObject *Image_getFilename( BPy_Image * self );
582 static PyObject *Image_getSize( BPy_Image * self );
583 static PyObject *Image_getDepth( BPy_Image * self );
584 static PyObject *Image_getXRep( BPy_Image * self );
585 static PyObject *Image_getYRep( BPy_Image * self );
586 static PyObject *Image_getBindCode( BPy_Image * self );
587 static PyObject *Image_getStart( BPy_Image * self );
588 static PyObject *Image_getEnd( BPy_Image * self );
589 static PyObject *Image_getSpeed( BPy_Image * self );
590 static PyObject *Image_setName( BPy_Image * self, PyObject * args );
591 static PyObject *Image_setFilename( BPy_Image * self, PyObject * args );
592 static PyObject *Image_setXRep( BPy_Image * self, PyObject * args );
593 static PyObject *Image_setYRep( BPy_Image * self, PyObject * args );
594 static PyObject *Image_setStart( BPy_Image * self, PyObject * args );
595 static PyObject *Image_setEnd( BPy_Image * self, PyObject * args );
596 static PyObject *Image_setSpeed( BPy_Image * self, PyObject * args );
597 static PyObject *Image_reload( BPy_Image * self );
598 static PyObject *Image_glLoad( BPy_Image * self );
599 static PyObject *Image_glFree( BPy_Image * self );
600 static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args );
601 static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args );
602 static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args );
603 static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args );
604 static PyObject *Image_getMaxXY( BPy_Image * self );
605 static PyObject *Image_getMinXY( BPy_Image * self );
606 static PyObject *Image_save( BPy_Image * self );
609 /*****************************************************************************/
610 /* Python BPy_Image methods table: */
611 /*****************************************************************************/
612 static PyMethodDef BPy_Image_methods[] = {
613 /* name, method, flags, doc */
614 {"getPixelF", ( PyCFunction ) Image_getPixelF, METH_VARARGS,
615 "(int, int) - Get pixel color as floats 0.0-1.0 returns [r,g,b,a]"},
616 {"getPixelI", ( PyCFunction ) Image_getPixelI, METH_VARARGS,
617 "(int, int) - Get pixel color as ints 0-255 returns [r,g,b,a]"},
618 {"setPixelF", ( PyCFunction ) Image_setPixelF, METH_VARARGS,
619 "(int, int, [f r,f g,f b,f a]) - Set pixel color using floats 0.0-1.0"},
620 {"setPixelI", ( PyCFunction ) Image_setPixelI, METH_VARARGS,
621 "(int, int, [i r, i g, i b, i a]) - Set pixel color using ints 0-255"},
622 {"getMaxXY", ( PyCFunction ) Image_getMaxXY, METH_NOARGS,
623 "() - Get maximum x & y coordinates of current image as [x, y]"},
624 {"getMinXY", ( PyCFunction ) Image_getMinXY, METH_NOARGS,
625 "() - Get minimun x & y coordinates of image as [x, y]"},
626 {"getName", ( PyCFunction ) Image_getName, METH_NOARGS,
627 "() - Return Image object name"},
628 {"getFilename", ( PyCFunction ) Image_getFilename, METH_NOARGS,
629 "() - Return Image object filename"},
630 {"getSize", ( PyCFunction ) Image_getSize, METH_NOARGS,
631 "() - Return Image object [width, height] dimension in pixels"},
632 {"getDepth", ( PyCFunction ) Image_getDepth, METH_NOARGS,
633 "() - Return Image object pixel depth"},
634 {"getXRep", ( PyCFunction ) Image_getXRep, METH_NOARGS,
635 "() - Return Image object x repetition value"},
636 {"getYRep", ( PyCFunction ) Image_getYRep, METH_NOARGS,
637 "() - Return Image object y repetition value"},
638 {"getStart", ( PyCFunction ) Image_getStart, METH_NOARGS,
639 "() - Return Image object start frame."},
640 {"getEnd", ( PyCFunction ) Image_getEnd, METH_NOARGS,
641 "() - Return Image object end frame."},
642 {"getSpeed", ( PyCFunction ) Image_getSpeed, METH_NOARGS,
643 "() - Return Image object speed (fps)."},
644 {"getBindCode", ( PyCFunction ) Image_getBindCode, METH_NOARGS,
645 "() - Return Image object's bind code value"},
646 {"reload", ( PyCFunction ) Image_reload, METH_NOARGS,
647 "() - Reload the image from the filesystem"},
648 {"glLoad", ( PyCFunction ) Image_glLoad, METH_NOARGS,
649 "() - Load the image data in OpenGL texture memory.\n\
650 The bindcode (int) is returned."},
651 {"glFree", ( PyCFunction ) Image_glFree, METH_NOARGS,
652 "() - Free the image data from OpenGL texture memory only,\n\
653 see also image.glLoad()."},
654 {"setName", ( PyCFunction ) Image_setName, METH_VARARGS,
655 "(str) - Change Image object name"},
656 {"setFilename", ( PyCFunction ) Image_setFilename, METH_VARARGS,
657 "(str) - Change Image file name"},
658 {"setXRep", ( PyCFunction ) Image_setXRep, METH_VARARGS,
659 "(int) - Change Image object x repetition value"},
660 {"setYRep", ( PyCFunction ) Image_setYRep, METH_VARARGS,
661 "(int) - Change Image object y repetition value"},
662 {"setStart", ( PyCFunction ) Image_setStart, METH_VARARGS,
663 "(int) - Change Image object animation start value"},
664 {"setEnd", ( PyCFunction ) Image_setEnd, METH_VARARGS,
665 "(int) - Change Image object animation end value"},
666 {"setSpeed", ( PyCFunction ) Image_setSpeed, METH_VARARGS,
667 "(int) - Change Image object animation speed (fps)"},
668 {"save", ( PyCFunction ) Image_save, METH_NOARGS,
669 "() - Write image buffer to file"},
670 {NULL, NULL, 0, NULL}
673 /*****************************************************************************/
674 /* Python Image_Type callback function prototypes: */
675 /*****************************************************************************/
676 static void Image_dealloc( BPy_Image * self );
677 static int Image_setAttr( BPy_Image * self, char *name, PyObject * v );
678 static int Image_compare( BPy_Image * a, BPy_Image * b );
679 static PyObject *Image_getAttr( BPy_Image * self, char *name );
680 static PyObject *Image_repr( BPy_Image * self );
682 /*****************************************************************************/
683 /* Python Image_Type structure definition: */
684 /*****************************************************************************/
685 PyTypeObject Image_Type = {
686 PyObject_HEAD_INIT( NULL ) /* required macro. ( no comma needed ) */
688 "Blender Image", /* tp_name */
689 sizeof( BPy_Image ), /* tp_basicsize */
692 ( destructor ) Image_dealloc, /* tp_dealloc */
694 ( getattrfunc ) Image_getAttr, /* tp_getattr */
695 ( setattrfunc ) Image_setAttr, /* tp_setattr */
696 ( cmpfunc ) Image_compare, /* tp_compare */
697 ( reprfunc ) Image_repr, /* tp_repr */
698 0, /* tp_as_number */
699 0, /* tp_as_sequence */
700 0, /* tp_as_mapping */
705 BPy_Image_methods, /* tp_methods */
707 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* up to tp_del, to avoid a warning */
710 /*****************************************************************************/
711 /* Function: Image_dealloc */
712 /* Description: This is a callback function for the BPy_Image type. It is */
713 /* the destructor function. */
714 /*****************************************************************************/
715 static void Image_dealloc( BPy_Image * self )
717 PyObject_DEL( self );
720 /*****************************************************************************/
721 /* Function: Image_CreatePyObject */
722 /* Description: This function will create a new BPy_Image from an existing */
723 /* Blender image structure. */
724 /*****************************************************************************/
725 PyObject *Image_CreatePyObject( Image * image )
728 py_img = ( BPy_Image * ) PyObject_NEW( BPy_Image, &Image_Type );
731 return EXPP_ReturnPyObjError( PyExc_MemoryError,
732 "couldn't create BPy_Image object" );
734 py_img->image = image;
735 return ( PyObject * ) py_img;
738 /*****************************************************************************/
739 /* Function: Image_CheckPyObject */
740 /* Description: This function returns true when the given PyObject is of the */
741 /* type Image. Otherwise it will return false. */
742 /*****************************************************************************/
743 int Image_CheckPyObject( PyObject * pyobj )
745 return ( pyobj->ob_type == &Image_Type );
748 /*****************************************************************************/
749 /* Function: Image_FromPyObject */
750 /* Description: Returns the Blender Image associated with this object */
751 /*****************************************************************************/
752 Image *Image_FromPyObject( PyObject * pyobj )
754 return ( ( BPy_Image * ) pyobj )->image;
757 /*****************************************************************************/
758 /* Python BPy_Image methods: */
759 /*****************************************************************************/
760 static PyObject *Image_getName( BPy_Image * self )
762 PyObject *attr = PyString_FromString( self->image->id.name + 2 );
767 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
768 "couldn't get Image.name attribute" ) );
771 static PyObject *Image_getFilename( BPy_Image * self )
773 PyObject *attr = PyString_FromString( self->image->name );
778 return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
779 "couldn't get Image.filename attribute" ) );
782 static PyObject *Image_getSize( BPy_Image * self )
785 Image *image = self->image;
787 if( !image->ibuf ) /* if no image data available */
788 load_image( image, IB_rect, "", 0 ); /* loading it */
790 if( !image->ibuf ) /* didn't work */
791 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
792 "couldn't load image data in Blender" );
794 attr = Py_BuildValue( "[hh]", image->ibuf->x, image->ibuf->y );
799 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
800 "couldn't get Image.size attribute" );
803 static PyObject *Image_getDepth( BPy_Image * self )
806 Image *image = self->image;
808 if( !image->ibuf ) /* if no image data available */
809 load_image( image, IB_rect, "", 0 ); /* loading it */
811 if( !image->ibuf ) /* didn't work */
812 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
813 "couldn't load image data in Blender" );
815 attr = Py_BuildValue( "h", image->ibuf->depth );
820 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
821 "couldn't get Image.depth attribute" );
825 static PyObject *Image_getXRep( BPy_Image * self )
827 PyObject *attr = PyInt_FromLong( self->image->xrep );
832 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
833 "couldn't get Image.xrep attribute" );
836 static PyObject *Image_getYRep( BPy_Image * self )
838 PyObject *attr = PyInt_FromLong( self->image->yrep );
843 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
844 "couldn't get Image.yrep attribute" );
847 static PyObject *Image_getStart( BPy_Image * self )
849 PyObject *attr = PyInt_FromLong( self->image->twsta );
854 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
855 "couldn't get Image.start attribute" );
858 static PyObject *Image_getEnd( BPy_Image * self )
860 PyObject *attr = PyInt_FromLong( self->image->twend );
865 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
866 "couldn't get Image.end attribute" );
869 static PyObject *Image_getSpeed( BPy_Image * self )
871 PyObject *attr = PyInt_FromLong( self->image->animspeed );
876 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
877 "couldn't get Image.speed attribute" );
880 static PyObject *Image_getBindCode( BPy_Image * self )
882 PyObject *attr = PyLong_FromUnsignedLong( self->image->bindcode );
887 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
888 "couldn't get Image.bindcode attribute" );
891 static PyObject *Image_reload( BPy_Image * self )
893 Image *img = self->image;
895 free_image_buffers( img ); /* force read again */
900 static PyObject *Image_glFree( BPy_Image * self )
902 Image *img = self->image;
904 free_realtime_image( img );
905 /* remove the nocollect flag, image is available for garbage collection again */
906 img->flag &= ~IMA_NOCOLLECT;
910 static PyObject *Image_glLoad( BPy_Image * self )
912 Image *img = self->image;
913 unsigned int *bind = &img->bindcode;
917 if( !img->ibuf ) /* if no image data is available */
918 load_image( img, IB_rect, "", 0 ); /* loading it */
920 if( !img->ibuf ) /* didn't work */
921 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
922 "couldn't load image data in Blender" );
924 glGenTextures( 1, ( GLuint * ) bind );
925 glBindTexture( GL_TEXTURE_2D, *bind );
927 gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, img->ibuf->x,
928 img->ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
930 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
931 GL_LINEAR_MIPMAP_NEAREST );
932 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
934 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
936 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, img->ibuf->x,
937 img->ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE,
940 /* raise the nocollect flag,
941 image is not available for garbage collection
942 (python GL might use it directly)
944 img->flag |= IMA_NOCOLLECT;
947 return PyLong_FromUnsignedLong( img->bindcode );
950 static PyObject *Image_setName( BPy_Image * self, PyObject * args )
955 if( !PyArg_ParseTuple( args, "s", &name ) )
956 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
957 "expected string argument" ) );
959 PyOS_snprintf( buf, sizeof( buf ), "%s", name );
961 rename_id( &self->image->id, buf );
966 static PyObject *Image_setFilename( BPy_Image * self, PyObject * args )
971 /* max len is FILE_MAXDIR = 160 chars like done in DNA_image_types.h */
973 if( !PyArg_ParseTuple( args, "s#", &name, &namelen ) )
974 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
975 "expected a string argument" ) );
977 if( namelen >= FILE_MAXDIR )
978 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
979 "string argument is limited to 160 chars at most" ) );
981 PyOS_snprintf( self->image->name, FILE_MAXDIR * sizeof( char ), "%s",
987 static PyObject *Image_setXRep( BPy_Image * self, PyObject * args )
991 if( !PyArg_ParseTuple( args, "h", &value ) )
992 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
993 "expected int argument in [1,16]" ) );
995 if( value >= EXPP_IMAGE_REP_MIN && value <= EXPP_IMAGE_REP_MAX )
996 self->image->xrep = value;
998 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
999 "expected int argument in [1,16]" ) );
1004 static PyObject *Image_setYRep( BPy_Image * self, PyObject * args )
1008 if( !PyArg_ParseTuple( args, "h", &value ) )
1009 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1010 "expected int argument in [1,16]" ) );
1012 if( value >= EXPP_IMAGE_REP_MIN && value <= EXPP_IMAGE_REP_MAX )
1013 self->image->yrep = value;
1015 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
1016 "expected int argument in [1,16]" ) );
1022 static PyObject *Image_setStart( BPy_Image * self, PyObject * args )
1026 if( !PyArg_ParseTuple( args, "h", &value ) )
1027 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1028 "expected int argument in [0,128]" ) );
1030 if( value >= 0 && value <= 128 )
1031 self->image->twsta = value;
1033 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
1034 "expected int argument in [0,128]" ) );
1040 static PyObject *Image_setEnd( BPy_Image * self, PyObject * args )
1044 if( !PyArg_ParseTuple( args, "h", &value ) )
1045 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1046 "expected int argument in [0,128]" ) );
1048 if( value >= 0 && value <= 128 )
1049 self->image->twend = value;
1051 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
1052 "expected int argument in [0,128]" ) );
1057 static PyObject *Image_setSpeed( BPy_Image * self, PyObject * args )
1061 if( !PyArg_ParseTuple( args, "h", &value ) )
1062 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1063 "expected int argument in [0,128]" ) );
1065 if( value >= 1 && value <= 100 )
1066 self->image->animspeed = value;
1068 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
1069 "expected int argument in [0,128]" ) );
1074 /*****************************************************************************/
1075 /* Function: Image_getAttr */
1076 /* Description: This is a callback function for the BPy_Image type. It is */
1077 /* the function that accesses BPy_Image member variables and */
1079 /*****************************************************************************/
1080 static PyObject *Image_getAttr( BPy_Image * self, char *name )
1082 PyObject *attr = Py_None;
1084 if( strcmp( name, "name" ) == 0 )
1085 attr = PyString_FromString( self->image->id.name + 2 );
1086 else if( strcmp( name, "filename" ) == 0 )
1087 attr = PyString_FromString( self->image->name );
1088 else if( strcmp( name, "size" ) == 0 )
1089 attr = Image_getSize( self );
1090 else if( strcmp( name, "depth" ) == 0 )
1091 attr = Image_getDepth( self );
1092 else if( strcmp( name, "xrep" ) == 0 )
1093 attr = PyInt_FromLong( self->image->xrep );
1094 else if( strcmp( name, "yrep" ) == 0 )
1095 attr = PyInt_FromLong( self->image->yrep );
1096 else if( strcmp( name, "start" ) == 0 )
1097 attr = PyInt_FromLong( self->image->twsta );
1098 else if( strcmp( name, "end" ) == 0 )
1099 attr = PyInt_FromLong( self->image->twend );
1100 else if( strcmp( name, "speed" ) == 0 )
1101 attr = PyInt_FromLong( self->image->animspeed );
1102 else if( strcmp( name, "packed" ) == 0 ) {
1103 if (self->image->packedfile) {
1104 attr = EXPP_incr_ret_True();
1106 attr = EXPP_incr_ret_False();
1108 } else if( strcmp( name, "bindcode" ) == 0 )
1109 attr = PyInt_FromLong( self->image->bindcode );
1110 else if( strcmp( name, "users" ) == 0 )
1111 attr = PyInt_FromLong( self->image->id.us );
1112 else if( strcmp( name, "__members__" ) == 0 )
1113 attr = Py_BuildValue( "[s,s,s,s,s,s,s,s,s,s,s]",
1114 "name", "filename", "size", "depth",
1115 "xrep", "yrep", "start", "end",
1117 "bindcode", "users" );
1120 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
1121 "couldn't create PyObject" ) );
1123 if( attr != Py_None )
1124 return attr; /* attribute found, return its value */
1126 /* not an attribute, search the methods table */
1127 return Py_FindMethod( BPy_Image_methods, ( PyObject * ) self, name );
1130 /*****************************************************************************/
1131 /* Function: Image_setAttr */
1132 /* Description: This is a callback function for the BPy_Image type. It is the*/
1133 /* function that changes Image object members values. If this */
1134 /* data is linked to a Blender Image, it also gets updated. */
1135 /*****************************************************************************/
1136 static int Image_setAttr( BPy_Image * self, char *name, PyObject * value )
1139 PyObject *error = NULL;
1141 /* We're playing a trick on the Python API users here. Even if they use
1142 * Image.member = val instead of Image.setMember(value), we end up using the
1143 * function anyway, since it already has error checking, clamps to the right
1144 * interval and updates the Blender Image structure when necessary. */
1146 valtuple = Py_BuildValue( "(O)", value ); /*the set* functions expect a tuple */
1149 return EXPP_ReturnIntError( PyExc_MemoryError,
1150 "ImageSetAttr: couldn't create PyTuple" );
1152 if( strcmp( name, "name" ) == 0 )
1153 error = Image_setName( self, valtuple );
1154 if( strcmp( name, "filename" ) == 0 )
1155 error = Image_setFilename( self, valtuple );
1156 else if( strcmp( name, "xrep" ) == 0 )
1157 error = Image_setXRep( self, valtuple );
1158 else if( strcmp( name, "yrep" ) == 0 )
1159 error = Image_setYRep( self, valtuple );
1160 else if( strcmp( name, "start" ) == 0 )
1161 error = Image_setStart( self, valtuple );
1162 else if( strcmp( name, "end" ) == 0 )
1163 error = Image_setEnd( self, valtuple );
1164 else if( strcmp( name, "speed" ) == 0 )
1165 error = Image_setSpeed( self, valtuple );
1166 else { /* Error: no such member in the Image object structure */
1167 /*Py_DECREF( value ); borrowed ref, no need to decref */
1168 Py_DECREF( valtuple );
1169 return ( EXPP_ReturnIntError( PyExc_KeyError,
1170 "attribute not found or immutable" ) );
1173 Py_DECREF( valtuple );
1175 if( error != Py_None )
1178 Py_DECREF( Py_None ); /* incref'ed by the called set* function */
1179 return 0; /* normal exit */
1182 /*****************************************************************************/
1183 /* Function: Image_compare */
1184 /* Description: This is a callback function for the BPy_Image type. It */
1185 /* compares two Image_Type objects. Only the "==" and "!=" */
1186 /* comparisons are meaninful. Returns 0 for equality and -1 if */
1187 /* they don't point to the same Blender Image struct. */
1188 /* In Python it becomes 1 if they are equal, 0 otherwise. */
1189 /*****************************************************************************/
1190 static int Image_compare( BPy_Image * a, BPy_Image * b )
1192 Image *pa = a->image, *pb = b->image;
1193 return ( pa == pb ) ? 0 : -1;
1196 /*****************************************************************************/
1197 /* Function: Image_repr */
1198 /* Description: This is a callback function for the BPy_Image type. It */
1199 /* builds a meaninful string to represent image objects. */
1200 /*****************************************************************************/
1201 static PyObject *Image_repr( BPy_Image * self )
1203 return PyString_FromFormat( "[Image \"%s\"]",
1204 self->image->id.name + 2 );