~ubuntu-branches/ubuntu/lucid/blender/lucid

« back to all changes in this revision

Viewing changes to source/gameengine/VideoTexture/ImageBase.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2009-08-06 22:32:19 UTC
  • mfrom: (1.2.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090806223219-8z4eej1u8levu4pz
Tags: 2.49a+dfsg-0ubuntu1
* Merge from debian unstable, remaining changes:
  - debian/control: Build-depend on python-2.6 rather than python-2.5.
  - debian/misc/*.desktop: Add Spanish translation to .desktop 
    files.
  - debian/pyversions: 2.6.
  - debian/rules: Clean *.o of source/blender/python/api2_2x/
* New upstream release (LP: #382153).
* Refreshed patches:
  - 01_sanitize_sys.patch
  - 02_tmp_in_HOME
  - 10_use_systemwide_ftgl
  - 70_portability_platform_detection
* Removed patches merged upstream:
  - 30_fix_python_syntax_warning
  - 90_ubuntu_ffmpeg_52_changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: ImageBase.cpp 20387 2009-05-24 23:12:38Z ben2610 $
 
2
-----------------------------------------------------------------------------
 
3
This source file is part of VideoTexture library
 
4
 
 
5
Copyright (c) 2007 The Zdeno Ash Miklas
 
6
 
 
7
This program is free software; you can redistribute it and/or modify it under
 
8
the terms of the GNU Lesser General Public License as published by the Free Software
 
9
Foundation; either version 2 of the License, or (at your option) any later
 
10
version.
 
11
 
 
12
This program is distributed in the hope that it will be useful, but WITHOUT
 
13
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
14
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 
15
 
 
16
You should have received a copy of the GNU Lesser General Public License along with
 
17
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
18
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
 
19
http://www.gnu.org/copyleft/lesser.txt.
 
20
-----------------------------------------------------------------------------
 
21
*/
 
22
 
 
23
#include "ImageBase.h"
 
24
 
 
25
#include <vector>
 
26
#include <string.h>
 
27
 
 
28
#include <PyObjectPlus.h>
 
29
#include <structmember.h>
 
30
 
 
31
#include "FilterBase.h"
 
32
 
 
33
#include "Exception.h"
 
34
 
 
35
 
 
36
 
 
37
// ImageBase class implementation
 
38
 
 
39
// constructor
 
40
ImageBase::ImageBase (bool staticSrc) : m_image(NULL), m_imgSize(0),
 
41
m_avail(false), m_scale(false), m_scaleChange(false), m_flip(false),
 
42
m_staticSources(staticSrc), m_pyfilter(NULL)
 
43
{
 
44
        m_size[0] = m_size[1] = 0;
 
45
}
 
46
 
 
47
 
 
48
// destructor
 
49
ImageBase::~ImageBase (void)
 
50
{
 
51
        // release image
 
52
        delete [] m_image;
 
53
}
 
54
 
 
55
 
 
56
// release python objects
 
57
bool ImageBase::release (void)
 
58
{
 
59
        // iterate sources
 
60
        for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
 
61
        {
 
62
                // release source object
 
63
                delete *it;
 
64
                *it = NULL;
 
65
        }
 
66
        // release filter object
 
67
        Py_XDECREF(m_pyfilter);
 
68
        m_pyfilter = NULL;
 
69
        return true;
 
70
}
 
71
 
 
72
 
 
73
// get image
 
74
unsigned int * ImageBase::getImage (unsigned int texId)
 
75
{
 
76
        // if image is not available
 
77
        if (!m_avail)
 
78
        {
 
79
                // if there are any sources
 
80
                if (!m_sources.empty())
 
81
                {
 
82
                        // get images from sources
 
83
                        for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
 
84
                                // get source image
 
85
                                (*it)->getImage();
 
86
                        // init image
 
87
                        init(m_sources[0]->getSize()[0], m_sources[0]->getSize()[1]);
 
88
                }
 
89
                // calculate new image
 
90
                calcImage(texId);
 
91
        }
 
92
        // if image is available, return it, otherwise NULL
 
93
        return m_avail ? m_image : NULL;
 
94
}
 
95
 
 
96
 
 
97
// refresh image source
 
98
void ImageBase::refresh (void)
 
99
{
 
100
        // invalidate this image
 
101
        m_avail = false;
 
102
        // refresh all sources
 
103
        for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
 
104
                (*it)->refresh();
 
105
}
 
106
 
 
107
 
 
108
// get source object
 
109
PyImage * ImageBase::getSource (const char * id)
 
110
{
 
111
        // find source
 
112
        ImageSourceList::iterator src = findSource(id);
 
113
        // return it, if found
 
114
        return src != m_sources.end() ? (*src)->getSource() : NULL;
 
115
}
 
116
 
 
117
 
 
118
// set source object
 
119
bool ImageBase::setSource (const char * id, PyImage * source)
 
120
{
 
121
        // find source
 
122
        ImageSourceList::iterator src = findSource(id);
 
123
        // check source loop
 
124
        if (source != NULL && source->m_image->loopDetect(this))
 
125
                return false;
 
126
        // if found, set new object
 
127
        if (src != m_sources.end())
 
128
                // if new object is not empty or sources are static
 
129
                if (source != NULL || m_staticSources)
 
130
                        // replace previous source
 
131
                        (*src)->setSource(source);
 
132
                // otherwise delete source
 
133
                else
 
134
                        m_sources.erase(src);
 
135
        // if source is not found and adding is allowed
 
136
        else
 
137
                if (!m_staticSources)
 
138
                {
 
139
                        // create new source
 
140
                        ImageSource * newSrc = newSource(id);
 
141
                        newSrc->setSource(source);
 
142
                        // if source was created, add it to source list
 
143
                        if (newSrc != NULL) m_sources.push_back(newSrc);
 
144
                }
 
145
                // otherwise source wasn't set
 
146
                else 
 
147
                        return false;
 
148
        // source was set
 
149
        return true;
 
150
}
 
151
 
 
152
 
 
153
// set pixel filter
 
154
void ImageBase::setFilter (PyFilter * filt)
 
155
{
 
156
        // reference new filter
 
157
        if (filt != NULL) Py_INCREF(filt);
 
158
        // release previous filter
 
159
        Py_XDECREF(m_pyfilter);
 
160
        // set new filter
 
161
        m_pyfilter = filt;
 
162
}
 
163
 
 
164
 
 
165
// initialize image data
 
166
void ImageBase::init (short width, short height)
 
167
{
 
168
        // if image has to be scaled
 
169
        if (m_scale)
 
170
        {
 
171
                // recalc sizes of image
 
172
                width = calcSize(width);
 
173
                height = calcSize(height);
 
174
        }
 
175
        // if sizes differ
 
176
        if (width != m_size[0] || height != m_size[1])
 
177
        {
 
178
                // new buffer size
 
179
                unsigned int newSize = width * height;
 
180
                // if new buffer is larger than previous
 
181
                if (newSize > m_imgSize)
 
182
                {
 
183
                        // set new buffer size
 
184
                        m_imgSize = newSize;
 
185
                        // release previous and create new buffer
 
186
                        delete [] m_image;
 
187
                        m_image = new unsigned int[m_imgSize];
 
188
                }
 
189
                // new image size
 
190
                m_size[0] = width;
 
191
                m_size[1] = height;
 
192
                // scale was processed
 
193
                m_scaleChange = false;
 
194
        }
 
195
}
 
196
 
 
197
 
 
198
// find source
 
199
ImageSourceList::iterator ImageBase::findSource (const char * id)
 
200
{
 
201
        // iterate sources
 
202
        ImageSourceList::iterator it;
 
203
        for (it = m_sources.begin(); it != m_sources.end(); ++it)
 
204
                // if id matches, return iterator
 
205
                if ((*it)->is(id)) return it;
 
206
        // source not found
 
207
        return it;
 
208
}
 
209
 
 
210
 
 
211
// check sources sizes
 
212
bool ImageBase::checkSourceSizes (void)
 
213
{
 
214
        // reference size
 
215
        short * refSize = NULL;
 
216
        // iterate sources
 
217
        for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
 
218
        {
 
219
                // get size of current source
 
220
                short * curSize = (*it)->getSize();
 
221
                // if size is available and is not empty
 
222
                if (curSize[0] != 0 && curSize[1] != 0)
 
223
                        // if reference size is not set
 
224
                        if (refSize == NULL)
 
225
                                // set current size as reference
 
226
                                refSize = curSize;
 
227
                // otherwise check with current size
 
228
                        else if (curSize[0] != refSize[0] || curSize[1] != refSize[1])
 
229
                                // if they don't match, report it
 
230
                                return false;
 
231
        }
 
232
        // all sizes match
 
233
        return true;
 
234
}
 
235
 
 
236
 
 
237
// compute nearest power of 2 value
 
238
short ImageBase::calcSize (short size)
 
239
{
 
240
        // while there is more than 1 bit in size value
 
241
        while ((size & (size - 1)) != 0)
 
242
                // clear last bit
 
243
                size = size & (size - 1);
 
244
        // return result
 
245
        return size;
 
246
}
 
247
 
 
248
 
 
249
// perform loop detection
 
250
bool ImageBase::loopDetect (ImageBase * img)
 
251
{
 
252
        // if this object is the same as parameter, loop is detected
 
253
        if (this == img) return true;
 
254
        // check all sources
 
255
        for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
 
256
                // if source detected loop, return this result
 
257
                if ((*it)->getSource() != NULL && (*it)->getSource()->m_image->loopDetect(img))
 
258
                        return true;
 
259
        // no loop detected
 
260
        return false;
 
261
}
 
262
 
 
263
 
 
264
// ImageSource class implementation
 
265
 
 
266
// constructor
 
267
ImageSource::ImageSource (const char * id) : m_source(NULL), m_image(NULL)
 
268
{
 
269
        // copy id
 
270
        int idx;
 
271
        for (idx = 0; id[idx] != '\0' && idx < SourceIdSize - 1; ++idx)
 
272
                m_id[idx] = id[idx];
 
273
        m_id[idx] = '\0';
 
274
}
 
275
 
 
276
// destructor
 
277
ImageSource::~ImageSource (void)
 
278
{
 
279
        // release source
 
280
        setSource(NULL);
 
281
}
 
282
 
 
283
 
 
284
// compare id
 
285
bool ImageSource::is (const char * id)
 
286
{
 
287
        for (char * myId = m_id; *myId != '\0'; ++myId, ++id)
 
288
                if (*myId != *id) return false;
 
289
        return *id == '\0';
 
290
}
 
291
 
 
292
 
 
293
// set source object
 
294
void ImageSource::setSource (PyImage * source)
 
295
{
 
296
        // reference new source
 
297
        if (source != NULL) Py_INCREF(source);
 
298
        // release previous source
 
299
        Py_XDECREF(m_source);
 
300
        // set new source
 
301
        m_source = source;
 
302
}
 
303
 
 
304
 
 
305
// get image from source
 
306
unsigned int * ImageSource::getImage (void)
 
307
{
 
308
        // if source is available
 
309
        if (m_source != NULL)
 
310
                // get image from source
 
311
                m_image = m_source->m_image->getImage();
 
312
        // otherwise reset buffer
 
313
        else
 
314
                m_image = NULL;
 
315
        // return image
 
316
        return m_image;
 
317
}
 
318
 
 
319
 
 
320
// refresh source
 
321
void ImageSource::refresh (void)
 
322
{
 
323
        // if source is available, refresh it
 
324
        if (m_source != NULL) m_source->m_image->refresh();
 
325
}
 
326
 
 
327
 
 
328
 
 
329
// list of image types
 
330
PyTypeList pyImageTypes;
 
331
 
 
332
 
 
333
 
 
334
// functions for python interface
 
335
 
 
336
// object allocation
 
337
PyObject * Image_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds)
 
338
{
 
339
        // allocate object
 
340
        PyImage * self = reinterpret_cast<PyImage*>(type->tp_alloc(type, 0));
 
341
        // initialize object structure
 
342
        self->m_image = NULL;
 
343
        // return allocated object
 
344
        return reinterpret_cast<PyObject*>(self);
 
345
}
 
346
 
 
347
// object deallocation
 
348
void Image_dealloc (PyImage * self)
 
349
{
 
350
        // release object attributes
 
351
        if (self->m_image != NULL)
 
352
        {
 
353
                // if release requires deleting of object, do it
 
354
                if (self->m_image->release())
 
355
                        delete self->m_image;
 
356
                self->m_image = NULL;
 
357
        }
 
358
}
 
359
 
 
360
// get image data
 
361
PyObject * Image_getImage (PyImage * self, void * closure)
 
362
{
 
363
        try
 
364
        {
 
365
                // get image
 
366
                unsigned int * image = self->m_image->getImage();
 
367
                return Py_BuildValue("s#", image, self->m_image->getBuffSize());
 
368
        }
 
369
        catch (Exception & exp)
 
370
        {
 
371
                exp.report();
 
372
        }
 
373
        Py_RETURN_NONE;
 
374
}
 
375
 
 
376
// get image size
 
377
PyObject * Image_getSize (PyImage * self, void * closure)
 
378
{
 
379
        return Py_BuildValue("(hh)", self->m_image->getSize()[0],
 
380
                self->m_image->getSize()[1]);
 
381
}
 
382
 
 
383
// refresh image
 
384
PyObject * Image_refresh (PyImage * self)
 
385
{
 
386
        self->m_image->refresh();
 
387
        Py_RETURN_NONE;
 
388
}
 
389
 
 
390
// get scale
 
391
PyObject * Image_getScale (PyImage * self, void * closure)
 
392
{
 
393
        if (self->m_image != NULL && self->m_image->getScale()) Py_RETURN_TRUE;
 
394
        else Py_RETURN_FALSE;
 
395
}
 
396
 
 
397
// set scale
 
398
int Image_setScale (PyImage * self, PyObject * value, void * closure)
 
399
{
 
400
        // check parameter, report failure
 
401
        if (value == NULL || !PyBool_Check(value))
 
402
        {
 
403
                PyErr_SetString(PyExc_TypeError, "The value must be a bool");
 
404
                return -1;
 
405
        }
 
406
        // set scale
 
407
        if (self->m_image != NULL) self->m_image->setScale(value == Py_True);
 
408
        // success
 
409
        return 0;
 
410
}
 
411
 
 
412
// get flip
 
413
PyObject * Image_getFlip (PyImage * self, void * closure)
 
414
{
 
415
        if (self->m_image != NULL && self->m_image->getFlip()) Py_RETURN_TRUE;
 
416
        else Py_RETURN_FALSE;
 
417
}
 
418
 
 
419
// set flip
 
420
int Image_setFlip (PyImage * self, PyObject * value, void * closure)
 
421
{
 
422
        // check parameter, report failure
 
423
        if (value == NULL || !PyBool_Check(value))
 
424
        {
 
425
                PyErr_SetString(PyExc_TypeError, "The value must be a bool");
 
426
                return -1;
 
427
        }
 
428
        // set scale
 
429
        if (self->m_image != NULL) self->m_image->setFlip(value == Py_True);
 
430
        // success
 
431
        return 0;
 
432
}
 
433
 
 
434
 
 
435
// get filter source object
 
436
PyObject * Image_getSource (PyImage * self, PyObject * args)
 
437
{
 
438
        // get arguments
 
439
        char * id;
 
440
        if (!PyArg_ParseTuple(args, "s:getSource", &id))
 
441
                return NULL;
 
442
        if (self->m_image != NULL)
 
443
        {
 
444
                // get source object
 
445
                PyObject * src = reinterpret_cast<PyObject*>(self->m_image->getSource(id));
 
446
                // if source is available
 
447
                if (src != NULL)
 
448
                {
 
449
                        // return source
 
450
                        Py_INCREF(src);
 
451
                        return src;
 
452
                }
 
453
        }
 
454
        // source was not found
 
455
        Py_RETURN_NONE;
 
456
}
 
457
 
 
458
 
 
459
// set filter source object
 
460
PyObject * Image_setSource (PyImage * self, PyObject * args)
 
461
{
 
462
        // get arguments
 
463
        char * id;
 
464
        PyObject * obj;
 
465
        if (!PyArg_ParseTuple(args, "sO:setSource", &id, &obj))
 
466
                return NULL;
 
467
        if (self->m_image != NULL)
 
468
        {
 
469
                // check type of object
 
470
                if (pyImageTypes.in(obj->ob_type))
 
471
                {
 
472
                        // convert to image struct
 
473
                        PyImage * img = reinterpret_cast<PyImage*>(obj);
 
474
                        // set source
 
475
                        if (!self->m_image->setSource(id, img))
 
476
                        {
 
477
                                // if not set, retport error
 
478
                                PyErr_SetString(PyExc_RuntimeError, "Invalid source or id");
 
479
                                return NULL;
 
480
                        }
 
481
                }
 
482
                // else report error
 
483
                else
 
484
                {
 
485
                        PyErr_SetString(PyExc_RuntimeError, "Invalid type of object");
 
486
                        return NULL;
 
487
                }
 
488
        }
 
489
        // return none
 
490
        Py_RETURN_NONE;
 
491
}
 
492
 
 
493
 
 
494
// get pixel filter object
 
495
PyObject * Image_getFilter (PyImage * self, void * closure)
 
496
{
 
497
        // if image object is available
 
498
        if (self->m_image != NULL)
 
499
        {
 
500
                // pixel filter object
 
501
                PyObject * filt = reinterpret_cast<PyObject*>(self->m_image->getFilter());
 
502
                // if filter is present
 
503
                if (filt != NULL)
 
504
                {
 
505
                        // return it
 
506
                        Py_INCREF(filt);
 
507
                        return filt;
 
508
                }
 
509
        }
 
510
        // otherwise return none
 
511
        Py_RETURN_NONE;
 
512
}
 
513
 
 
514
 
 
515
// set pixel filter object
 
516
int Image_setFilter (PyImage * self, PyObject * value, void * closure)
 
517
{
 
518
        // if image object is available
 
519
        if (self->m_image != NULL)
 
520
        {
 
521
                // check new value
 
522
                if (value == NULL || !pyFilterTypes.in(value->ob_type))
 
523
                {
 
524
                        // report value error
 
525
                        PyErr_SetString(PyExc_TypeError, "Invalid type of value");
 
526
                        return -1;
 
527
                }
 
528
                // set new value
 
529
                self->m_image->setFilter(reinterpret_cast<PyFilter*>(value));
 
530
        }
 
531
        // return success
 
532
        return 0;
 
533
}