f7d135fe7b3c8ba633d082c3ca5410d88be898ec
[blender.git] / source / blender / python / api2_2x / Image.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
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
12  * about this.
13  *
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.
18  *
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.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): Willian P. Germano, Campbell Barton, Joilnen B. Leite,
29  * Austin Benesh
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32 */
33 #include "Image.h"              /*This must come first */
34
35 #include "BDR_drawmesh.h"       /* free_realtime_image */
36 #include "BKE_main.h"
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 */
44 #include "BIF_gl.h"
45 #include "gen_utils.h"
46
47 /* 
48    fixme
49    this belongs in a header
50    sswaney 10-aug-2005
51 */
52 short IMB_saveiff( struct ImBuf *ibuf, char *naam, int flags );
53
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
60
61
62 /************************/
63 /*** The Image Module ***/
64 /************************/
65
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 );
73
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";
80
81 static char M_Image_New_doc[] =
82         "() - return a new Image object";
83
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.";
88
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";
92
93 static char M_Image_Load_doc[] =
94         "(filename) - return image from file filename as Image Object, \
95 returns None if not found.\n";
96
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}
107 };
108
109
110 /*****************************************************************************/
111 /* Function:    M_Image_New     */
112 /* Python equivalent:        Blender.Image.New    */
113 /*****************************************************************************/
114 static PyObject *M_Image_New( PyObject * self, PyObject * args)
115 {
116         int width, height, depth;
117         char *name;
118         Image *img;
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);
126         if( !img )
127                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
128                                                 "couldn't create PyObject Image_Type" ) );
129         // image_changed(img, 0);
130         return Image_CreatePyObject( img );
131 }
132
133
134
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 )
144 {
145         char *name = NULL;
146         Image *img_iter;
147
148         if( !PyArg_ParseTuple( args, "|s", &name ) )
149                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
150                                                 "expected string argument (or nothing)" ) );
151
152         img_iter = G.main->image.first;
153
154         if( name ) {            /* (name) - Search image by name */
155
156                 BPy_Image *wanted_image = NULL;
157
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 );
162                                 if( wanted_image )
163                                         wanted_image->image = img_iter;
164                         }
165                         img_iter = img_iter->id.next;
166                 }
167
168                 if( wanted_image == NULL ) {    /* Requested image doesn't exist */
169                         char error_msg[64];
170                         PyOS_snprintf( error_msg, sizeof( error_msg ),
171                                        "Image \"%s\" not found", name );
172                         return ( EXPP_ReturnPyObjError
173                                  ( PyExc_NameError, error_msg ) );
174                 }
175
176                 return ( PyObject * ) wanted_image;
177         }
178
179         else {                  /* () - return a list of all images in the scene */
180                 int index = 0;
181                 PyObject *img_list, *pyobj;
182
183                 img_list = PyList_New( BLI_countlist( &( G.main->image ) ) );
184
185                 if( img_list == NULL )
186                         return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
187                                                         "couldn't create PyList" ) );
188
189                 while( img_iter ) {
190                         pyobj = Image_CreatePyObject( img_iter );
191
192                         PyList_SET_ITEM( img_list, index, pyobj );
193
194                         img_iter = img_iter->id.next;
195                         index++;
196                 }
197
198                 return ( img_list );
199         }
200 }
201
202
203
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 )
212 {
213         if (!G.sima || !G.sima->image) {
214                 Py_RETURN_NONE;
215         }
216         return Image_CreatePyObject( G.sima->image );
217 }
218
219
220
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 )
228 {
229         char *fname;
230         Image *img_ptr;
231         BPy_Image *img;
232
233         if( !PyArg_ParseTuple( args, "s", &fname ) )
234                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
235                                                 "expected string argument" ) );
236
237         img = ( BPy_Image * ) PyObject_NEW( BPy_Image, &Image_Type );
238
239         if( !img )
240                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
241                                                 "couldn't create PyObject Image_Type" ) );
242
243         img_ptr = add_image( fname );
244         if( !img_ptr )
245                 return ( EXPP_ReturnPyObjError( PyExc_IOError,
246                                                 "couldn't load image" ) );
247
248         img->image = img_ptr;
249
250         return ( PyObject * ) img;
251 }
252
253
254 /**
255  * getPixelF( x, y )
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
259  */
260
261 static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
262 {
263
264         PyObject *attr;
265         Image *image = self->image;
266         char *pixel;            /* image data */
267         int index;              /* offset into image data */
268         int x = 0;
269         int y = 0;
270         int pixel_size = 4;     /* each pixel is 4 x 8-bits packed in unsigned int */
271
272         if( !PyArg_ParseTuple( args, "ii", &x, &y ) )
273                 return EXPP_ReturnPyObjError( PyExc_TypeError,
274                                               "expected 2 integers" );
275
276         if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
277                 load_image( image, IB_rect, "", 0 );    /* loading it */
278
279         if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
280                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
281                                               "couldn't load image data in Blender" );
282
283         if( image->ibuf->type == 1 )    /* bitplane image */
284                 return EXPP_ReturnPyObjError( PyExc_TypeError,
285                                               "unsupported bitplane image format" );
286
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" );
292
293         /* 
294            assumption: from looking at source, skipx is often not set,
295            so we calc ourselves
296          */
297
298         index = ( x + y * image->ibuf->x ) * pixel_size;
299
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 ) );
306
307         if( attr )              /* normal return */
308                 return attr;
309
310         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
311                                       "couldn't get pixel colors" );
312 }
313
314
315 /**
316  * getPixelI( x, y )
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
320  */
321
322 static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
323 {
324         PyObject *attr;
325         Image *image = self->image;
326         char *pixel;            /* image data */
327         int index;              /* offset into image data */
328         int x = 0;
329         int y = 0;
330         int pixel_size = 4;     /* each pixel is 4 x 8-bits packed in unsigned int */
331
332         if( !PyArg_ParseTuple( args, "ii", &x, &y ) )
333                 return EXPP_ReturnPyObjError( PyExc_TypeError,
334                                               "expected 2 integers" );
335
336         if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
337                 load_image( image, IB_rect, "", 0 );    /* loading it */
338
339         if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
340                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
341                                               "couldn't load image data in Blender" );
342
343         if( image->ibuf->type == 1 )    /* bitplane image */
344                 return EXPP_ReturnPyObjError( PyExc_TypeError,
345                                               "unsupported bitplane image format" );
346
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" );
352
353         /* 
354            assumption: from looking at source, skipx is often not set,
355            so we calc ourselves
356          */
357
358         index = ( x + y * image->ibuf->x ) * pixel_size;
359
360         pixel = ( char * ) image->ibuf->rect;
361         attr = Py_BuildValue( "[i,i,i,i]",
362                               pixel[index],
363                               pixel[index + 1],
364                               pixel[index + 2], pixel[index + 3] );
365
366         if( attr )              /* normal return */
367                 return attr;
368
369         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
370                                       "couldn't get pixel colors" );
371 }
372
373
374 /* set pixel as floats */
375
376 static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
377 {
378         Image *image = self->image;
379         char *pixel;            /* image data */
380         int index;              /* offset into image data */
381         int x = 0;
382         int y = 0;
383         int a = 0;
384         int pixel_size = 4;     /* each pixel is 4 x 8-bits packed in unsigned int */
385         float p[4];
386
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" );
391
392         if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
393                 load_image( image, IB_rect, "", 0 );    /* loading it */
394
395         if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
396                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
397                                               "couldn't load image data in Blender" );
398
399         if( image->ibuf->type == 1 )    /* bitplane image */
400                 return EXPP_ReturnPyObjError( PyExc_TypeError,
401                                               "unsupported bitplane image format" );
402
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" );
408
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" );
413         }
414
415
416         /* 
417            assumption: from looking at source, skipx is often not set,
418            so we calc ourselves
419          */
420
421         index = ( x + y * image->ibuf->x ) * pixel_size;
422
423         pixel = ( char * ) image->ibuf->rect;
424
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 );
429
430         Py_RETURN_NONE;
431 }
432
433
434 /* set pixel as ints */
435
436 static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
437 {
438         Image *image = self->image;
439         char *pixel;            /* image data */
440         int index;              /* offset into image data */
441         int x = 0;
442         int y = 0;
443         int a = 0;
444         int pixel_size = 4;     /* each pixel is 4 x 8-bits packed in unsigned int */
445         int p[4];
446
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" );
451
452         if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
453                 load_image( image, IB_rect, "", 0 );    /* loading it */
454
455         if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
456                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
457                                               "couldn't load image data in Blender" );
458
459         if( image->ibuf->type == 1 )    /* bitplane image */
460                 return EXPP_ReturnPyObjError( PyExc_TypeError,
461                                               "unsupported bitplane image format" );
462
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" );
468
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" );
473         }
474
475         /* 
476            assumption: from looking at source, skipx is often not set,
477            so we calc ourselves
478          */
479
480         index = ( x + y * image->ibuf->x ) * pixel_size;
481
482         pixel = ( char * ) image->ibuf->rect;
483
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];
488
489         Py_RETURN_NONE;
490 }
491
492
493 /* get max extent of image */
494
495 static PyObject *Image_getMaxXY( BPy_Image * self )
496 {
497         Image *image = self->image;
498         PyObject *attr;
499
500         if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
501                 load_image( image, IB_rect, "", 0 );    /* loading it */
502
503         if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
504                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
505                                               "couldn't load image data in Blender" );
506
507         attr = Py_BuildValue( "[i,i]", image->ibuf->x, image->ibuf->y );
508
509         if( attr )
510                 return attr;
511
512         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
513                                       "could not determine max x or y" );
514 }
515
516
517 /* get min extent of image */
518
519 static PyObject *Image_getMinXY( BPy_Image * self )
520 {
521         Image *image = self->image;
522         PyObject *attr;
523
524         if( !image->ibuf || !image->ibuf->rect )        /* if no image data available */
525                 load_image( image, IB_rect, "", 0 );    /* loading it */
526
527         if( !image->ibuf || !image->ibuf->rect )        /* didn't work */
528                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
529                                               "couldn't load image data in Blender" );
530
531         attr = Py_BuildValue( "[i,i]", image->ibuf->xorig,
532                               image->ibuf->yorig );
533
534         if( attr )
535                 return attr;
536
537         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
538                                       "could not determine min x or y" );
539 }
540
541
542 /* save image to file */
543
544 static PyObject *Image_save( BPy_Image * self )
545 {
546         Py_INCREF( Py_None );
547
548         if( !IMB_saveiff
549             ( self->image->ibuf, self->image->name,
550               self->image->ibuf->flags ) )
551                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
552                                               "could not save image" );
553
554         Py_RETURN_NONE;         /*  normal return, image saved */
555 }
556
557 /*****************************************************************************/
558 /* Function:            Image_Init       */
559 /*****************************************************************************/
560 PyObject *Image_Init( void )
561 {
562         PyObject *submodule;
563
564         Image_Type.ob_type = &PyType_Type;
565
566         submodule =
567                 Py_InitModule3( "Blender.Image", M_Image_methods,
568                                 M_Image_doc );
569
570         return ( submodule );
571 }
572
573 /************************/
574 /*** The Image PyType ***/
575 /************************/
576
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 );
607
608
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}
671 };
672
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 );
681
682 /*****************************************************************************/
683 /* Python Image_Type structure definition:   */
684 /*****************************************************************************/
685 PyTypeObject Image_Type = {
686         PyObject_HEAD_INIT( NULL ) /*     required macro. ( no comma needed )  */ 
687         0,      /* ob_size */
688         "Blender Image",        /* tp_name */
689         sizeof( BPy_Image ),    /* tp_basicsize */
690         0,                      /* tp_itemsize */
691         /* methods */
692         ( destructor ) Image_dealloc,   /* tp_dealloc */
693         0,                      /* tp_print */
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 */
701         0,                      /* tp_as_hash */
702         0, 0, 0, 0, 0, 0,
703         0,                      /* tp_doc */
704         0, 0, 0, 0, 0, 0,
705         BPy_Image_methods,      /* tp_methods */
706         0,                      /* tp_members */
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 */
708 };
709
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 )
716 {
717         PyObject_DEL( self );
718 }
719
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 )
726 {
727         BPy_Image *py_img;
728         py_img = ( BPy_Image * ) PyObject_NEW( BPy_Image, &Image_Type );
729         
730         if( !py_img )
731                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
732                                               "couldn't create BPy_Image object" );
733         
734         py_img->image = image;
735         return ( PyObject * ) py_img;
736 }
737
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 )
744 {
745         return ( pyobj->ob_type == &Image_Type );
746 }
747
748 /*****************************************************************************/
749 /* Function:    Image_FromPyObject       */
750 /* Description: Returns the Blender Image associated with this object    */
751 /*****************************************************************************/
752 Image *Image_FromPyObject( PyObject * pyobj )
753 {
754         return ( ( BPy_Image * ) pyobj )->image;
755 }
756
757 /*****************************************************************************/
758 /* Python BPy_Image methods:             */
759 /*****************************************************************************/
760 static PyObject *Image_getName( BPy_Image * self )
761 {
762         PyObject *attr = PyString_FromString( self->image->id.name + 2 );
763
764         if( attr )
765                 return attr;
766
767         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
768                                         "couldn't get Image.name attribute" ) );
769 }
770
771 static PyObject *Image_getFilename( BPy_Image * self )
772 {
773         PyObject *attr = PyString_FromString( self->image->name );
774
775         if( attr )
776                 return attr;
777
778         return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
779                                         "couldn't get Image.filename attribute" ) );
780 }
781
782 static PyObject *Image_getSize( BPy_Image * self )
783 {
784         PyObject *attr;
785         Image *image = self->image;
786
787         if( !image->ibuf )      /* if no image data available */
788                 load_image( image, IB_rect, "", 0 );    /* loading it */
789
790         if( !image->ibuf )      /* didn't work */
791                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
792                                               "couldn't load image data in Blender" );
793
794         attr = Py_BuildValue( "[hh]", image->ibuf->x, image->ibuf->y );
795
796         if( attr )
797                 return attr;
798
799         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
800                                       "couldn't get Image.size attribute" );
801 }
802
803 static PyObject *Image_getDepth( BPy_Image * self )
804 {
805         PyObject *attr;
806         Image *image = self->image;
807
808         if( !image->ibuf )      /* if no image data available */
809                 load_image( image, IB_rect, "", 0 );    /* loading it */
810
811         if( !image->ibuf )      /* didn't work */
812                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
813                                               "couldn't load image data in Blender" );
814
815         attr = Py_BuildValue( "h", image->ibuf->depth );
816
817         if( attr )
818                 return attr;
819
820         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
821                                       "couldn't get Image.depth attribute" );
822 }
823
824
825 static PyObject *Image_getXRep( BPy_Image * self )
826 {
827         PyObject *attr = PyInt_FromLong( self->image->xrep );
828
829         if( attr )
830                 return attr;
831
832         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
833                                       "couldn't get Image.xrep attribute" );
834 }
835
836 static PyObject *Image_getYRep( BPy_Image * self )
837 {
838         PyObject *attr = PyInt_FromLong( self->image->yrep );
839
840         if( attr )
841                 return attr;
842
843         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
844                                       "couldn't get Image.yrep attribute" );
845 }
846
847 static PyObject *Image_getStart( BPy_Image * self )
848 {
849         PyObject *attr = PyInt_FromLong( self->image->twsta );
850
851         if( attr )
852                 return attr;
853
854         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
855                                       "couldn't get Image.start attribute" );
856 }
857
858 static PyObject *Image_getEnd( BPy_Image * self )
859 {
860         PyObject *attr = PyInt_FromLong( self->image->twend );
861
862         if( attr )
863                 return attr;
864
865         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
866                                       "couldn't get Image.end attribute" );
867 }
868
869 static PyObject *Image_getSpeed( BPy_Image * self )
870 {
871         PyObject *attr = PyInt_FromLong( self->image->animspeed );
872
873         if( attr )
874                 return attr;
875
876         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
877                                       "couldn't get Image.speed attribute" );
878 }
879
880 static PyObject *Image_getBindCode( BPy_Image * self )
881 {
882         PyObject *attr = PyLong_FromUnsignedLong( self->image->bindcode );
883
884         if( attr )
885                 return attr;
886
887         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
888                                       "couldn't get Image.bindcode attribute" );
889 }
890
891 static PyObject *Image_reload( BPy_Image * self )
892 {
893         Image *img = self->image;
894
895         free_image_buffers( img );      /* force read again */
896         img->ok = 1;
897         if( G.sima )
898                 image_changed( G.sima, 0 );
899
900         Py_RETURN_NONE;
901 }
902
903 static PyObject *Image_glFree( BPy_Image * self )
904 {
905         Image *img = self->image;
906
907         free_realtime_image( img );
908         /* remove the nocollect flag, image is available for garbage collection again */
909         img->flag &= ~IMA_NOCOLLECT;
910         Py_RETURN_NONE;
911 }
912
913 static PyObject *Image_glLoad( BPy_Image * self )
914 {
915         Image *img = self->image;
916         unsigned int *bind = &img->bindcode;
917
918         if( *bind == 0 ) {
919
920                 if( !img->ibuf )        /* if no image data is available */
921                         load_image( img, IB_rect, "", 0 );      /* loading it */
922
923                 if( !img->ibuf )        /* didn't work */
924                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
925                                                       "couldn't load image data in Blender" );
926
927                 glGenTextures( 1, ( GLuint * ) bind );
928                 glBindTexture( GL_TEXTURE_2D, *bind );
929
930                 gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, img->ibuf->x,
931                                    img->ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
932                                    img->ibuf->rect );
933                 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
934                                  GL_LINEAR_MIPMAP_NEAREST );
935                 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
936                                  GL_LINEAR );
937                 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
938
939                 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, img->ibuf->x,
940                               img->ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE,
941                               img->ibuf->rect );
942
943                 /* raise the nocollect flag, 
944                    image is not available for garbage collection 
945                    (python GL might use it directly)
946                  */
947                 img->flag |= IMA_NOCOLLECT;
948         }
949
950         return PyLong_FromUnsignedLong( img->bindcode );
951 }
952
953 static PyObject *Image_setName( BPy_Image * self, PyObject * args )
954 {
955         char *name;
956         char buf[21];
957
958         if( !PyArg_ParseTuple( args, "s", &name ) )
959                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
960                                                 "expected string argument" ) );
961
962         PyOS_snprintf( buf, sizeof( buf ), "%s", name );
963
964         rename_id( &self->image->id, buf );
965
966         Py_RETURN_NONE;
967 }
968
969 static PyObject *Image_setFilename( BPy_Image * self, PyObject * args )
970 {
971         char *name;
972         int namelen = 0;
973
974         /* max len is FILE_MAXDIR = 160 chars like done in DNA_image_types.h */
975
976         if( !PyArg_ParseTuple( args, "s#", &name, &namelen ) )
977                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
978                                                 "expected a string argument" ) );
979
980         if( namelen >= FILE_MAXDIR )
981                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
982                                                 "string argument is limited to 160 chars at most" ) );
983
984         PyOS_snprintf( self->image->name, FILE_MAXDIR * sizeof( char ), "%s",
985                        name );
986
987         Py_RETURN_NONE;
988 }
989
990 static PyObject *Image_setXRep( BPy_Image * self, PyObject * args )
991 {
992         short value;
993
994         if( !PyArg_ParseTuple( args, "h", &value ) )
995                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
996                                                 "expected int argument in [1,16]" ) );
997
998         if( value >= EXPP_IMAGE_REP_MIN && value <= EXPP_IMAGE_REP_MAX )
999                 self->image->xrep = value;
1000         else
1001                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
1002                                                 "expected int argument in [1,16]" ) );
1003
1004         Py_RETURN_NONE;
1005 }
1006
1007 static PyObject *Image_setYRep( BPy_Image * self, PyObject * args )
1008 {
1009         short value;
1010
1011         if( !PyArg_ParseTuple( args, "h", &value ) )
1012                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1013                                                 "expected int argument in [1,16]" ) );
1014
1015         if( value >= EXPP_IMAGE_REP_MIN && value <= EXPP_IMAGE_REP_MAX )
1016                 self->image->yrep = value;
1017         else
1018                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
1019                                                 "expected int argument in [1,16]" ) );
1020
1021         Py_RETURN_NONE;
1022 }
1023
1024
1025 static PyObject *Image_setStart( BPy_Image * self, PyObject * args )
1026 {
1027         short value;
1028
1029         if( !PyArg_ParseTuple( args, "h", &value ) )
1030                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1031                                                 "expected int argument in [0,128]" ) );
1032
1033         if( value >= 0 && value <= 128 )
1034                 self->image->twsta = value;
1035         else
1036                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
1037                                                 "expected int argument in [0,128]" ) );
1038
1039         Py_RETURN_NONE;
1040 }
1041
1042
1043 static PyObject *Image_setEnd( BPy_Image * self, PyObject * args )
1044 {
1045         short value;
1046
1047         if( !PyArg_ParseTuple( args, "h", &value ) )
1048                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1049                                                 "expected int argument in [0,128]" ) );
1050
1051         if( value >= 0 && value <= 128 )
1052                 self->image->twend = value;
1053         else
1054                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
1055                                                 "expected int argument in [0,128]" ) );
1056
1057         Py_RETURN_NONE;
1058 }
1059
1060 static PyObject *Image_setSpeed( BPy_Image * self, PyObject * args )
1061 {
1062         short value;
1063
1064         if( !PyArg_ParseTuple( args, "h", &value ) )
1065                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
1066                                                 "expected int argument in [0,128]" ) );
1067
1068         if( value >= 1 && value <= 100 )
1069                 self->image->animspeed = value;
1070         else
1071                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
1072                                                 "expected int argument in [0,128]" ) );
1073
1074         Py_RETURN_NONE;
1075 }
1076
1077 /*****************************************************************************/
1078 /* Function:            Image_getAttr            */
1079 /* Description: This is a callback function for the BPy_Image type. It is */
1080 /*              the function that accesses BPy_Image member variables and   */
1081 /*              methods.         */
1082 /*****************************************************************************/
1083 static PyObject *Image_getAttr( BPy_Image * self, char *name )
1084 {
1085         PyObject *attr = Py_None;
1086
1087         if( strcmp( name, "name" ) == 0 )
1088                 attr = PyString_FromString( self->image->id.name + 2 );
1089         else if( strcmp( name, "filename" ) == 0 )
1090                 attr = PyString_FromString( self->image->name );
1091         else if( strcmp( name, "size" ) == 0 )
1092                 attr = Image_getSize( self );
1093         else if( strcmp( name, "depth" ) == 0 )
1094                 attr = Image_getDepth( self );
1095         else if( strcmp( name, "xrep" ) == 0 )
1096                 attr = PyInt_FromLong( self->image->xrep );
1097         else if( strcmp( name, "yrep" ) == 0 )
1098                 attr = PyInt_FromLong( self->image->yrep );
1099         else if( strcmp( name, "start" ) == 0 )
1100                 attr = PyInt_FromLong( self->image->twsta );
1101         else if( strcmp( name, "end" ) == 0 )
1102                 attr = PyInt_FromLong( self->image->twend );
1103         else if( strcmp( name, "speed" ) == 0 )
1104                 attr = PyInt_FromLong( self->image->animspeed );
1105         else if( strcmp( name, "packed" ) == 0 ) {
1106                 if (self->image->packedfile)  {
1107                         attr = Py_True;
1108                 } else {
1109                         attr = Py_False;
1110                 }
1111                 Py_INCREF(attr);
1112                 
1113         } else if( strcmp( name, "bindcode" ) == 0 )
1114                 attr = PyInt_FromLong( self->image->bindcode );
1115         else if( strcmp( name, "users" ) == 0 )
1116                 attr = PyInt_FromLong( self->image->id.us );
1117         else if( strcmp( name, "__members__" ) == 0 )
1118                 attr = Py_BuildValue( "[s,s,s,s,s,s,s,s,s,s,s]",
1119                                       "name", "filename", "size", "depth",
1120                                       "xrep", "yrep", "start", "end",
1121                                       "speed", "packed",
1122                                       "bindcode", "users" );
1123
1124         if( !attr )
1125                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
1126                                                 "couldn't create PyObject" ) );
1127
1128         if( attr != Py_None )
1129                 return attr;    /* attribute found, return its value */
1130
1131         /* not an attribute, search the methods table */
1132         return Py_FindMethod( BPy_Image_methods, ( PyObject * ) self, name );
1133 }
1134
1135 /*****************************************************************************/
1136 /* Function:            Image_setAttr            */
1137 /* Description: This is a callback function for the BPy_Image type. It is the*/
1138 /*              function that changes Image object members values. If this  */
1139 /*              data is linked to a Blender Image, it also gets updated.  */
1140 /*****************************************************************************/
1141 static int Image_setAttr( BPy_Image * self, char *name, PyObject * value )
1142 {
1143         PyObject *valtuple;
1144         PyObject *error = NULL;
1145
1146 /* We're playing a trick on the Python API users here.  Even if they use
1147  * Image.member = val instead of Image.setMember(value), we end up using the
1148  * function anyway, since it already has error checking, clamps to the right
1149  * interval and updates the Blender Image structure when necessary. */
1150
1151         valtuple = Py_BuildValue( "(O)", value );       /*the set* functions expect a tuple */
1152
1153         if( !valtuple )
1154                 return EXPP_ReturnIntError( PyExc_MemoryError,
1155                                             "ImageSetAttr: couldn't create PyTuple" );
1156
1157         if( strcmp( name, "name" ) == 0 )
1158                 error = Image_setName( self, valtuple );
1159         if( strcmp( name, "filename" ) == 0 )
1160                 error = Image_setFilename( self, valtuple );
1161         else if( strcmp( name, "xrep" ) == 0 )
1162                 error = Image_setXRep( self, valtuple );
1163         else if( strcmp( name, "yrep" ) == 0 )
1164                 error = Image_setYRep( self, valtuple );
1165         else if( strcmp( name, "start" ) == 0 )
1166                 error = Image_setStart( self, valtuple );
1167         else if( strcmp( name, "end" ) == 0 )
1168                 error = Image_setEnd( self, valtuple );
1169         else if( strcmp( name, "speed" ) == 0 )
1170                 error = Image_setSpeed( self, valtuple );
1171         else {                  /* Error: no such member in the Image object structure */
1172                 /*Py_DECREF( value ); borrowed ref, no need to decref */
1173                 Py_DECREF( valtuple );
1174                 return ( EXPP_ReturnIntError( PyExc_KeyError,
1175                                               "attribute not found or immutable" ) );
1176         }
1177
1178         Py_DECREF( valtuple );
1179
1180         if( error != Py_None )
1181                 return -1;
1182
1183         Py_DECREF( Py_None );   /* incref'ed by the called set* function */
1184         return 0;               /* normal exit */
1185 }
1186
1187 /*****************************************************************************/
1188 /* Function:    Image_compare                    */
1189 /* Description: This is a callback function for the BPy_Image type. It   */
1190 /*              compares two Image_Type objects. Only the "==" and "!="  */
1191 /*              comparisons are meaninful. Returns 0 for equality and -1 if  */
1192 /*              they don't point to the same Blender Image struct.       */
1193 /*              In Python it becomes 1 if they are equal, 0 otherwise.   */
1194 /*****************************************************************************/
1195 static int Image_compare( BPy_Image * a, BPy_Image * b )
1196 {
1197         Image *pa = a->image, *pb = b->image;
1198         return ( pa == pb ) ? 0 : -1;
1199 }
1200
1201 /*****************************************************************************/
1202 /* Function:    Image_repr       */
1203 /* Description: This is a callback function for the BPy_Image type. It   */
1204 /*              builds a meaninful string to represent image objects.    */
1205 /*****************************************************************************/
1206 static PyObject *Image_repr( BPy_Image * self )
1207 {
1208         return PyString_FromFormat( "[Image \"%s\"]",
1209                                     self->image->id.name + 2 );
1210 }