1
/* $Id: ImageBase.cpp 20387 2009-05-24 23:12:38Z ben2610 $
2
-----------------------------------------------------------------------------
3
This source file is part of VideoTexture library
5
Copyright (c) 2007 The Zdeno Ash Miklas
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
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.
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
-----------------------------------------------------------------------------
23
#include "ImageBase.h"
28
#include <PyObjectPlus.h>
29
#include <structmember.h>
31
#include "FilterBase.h"
33
#include "Exception.h"
37
// ImageBase class implementation
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)
44
m_size[0] = m_size[1] = 0;
49
ImageBase::~ImageBase (void)
56
// release python objects
57
bool ImageBase::release (void)
60
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
62
// release source object
66
// release filter object
67
Py_XDECREF(m_pyfilter);
74
unsigned int * ImageBase::getImage (unsigned int texId)
76
// if image is not available
79
// if there are any sources
80
if (!m_sources.empty())
82
// get images from sources
83
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
87
init(m_sources[0]->getSize()[0], m_sources[0]->getSize()[1]);
89
// calculate new image
92
// if image is available, return it, otherwise NULL
93
return m_avail ? m_image : NULL;
97
// refresh image source
98
void ImageBase::refresh (void)
100
// invalidate this image
102
// refresh all sources
103
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
109
PyImage * ImageBase::getSource (const char * id)
112
ImageSourceList::iterator src = findSource(id);
113
// return it, if found
114
return src != m_sources.end() ? (*src)->getSource() : NULL;
119
bool ImageBase::setSource (const char * id, PyImage * source)
122
ImageSourceList::iterator src = findSource(id);
124
if (source != NULL && source->m_image->loopDetect(this))
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
134
m_sources.erase(src);
135
// if source is not found and adding is allowed
137
if (!m_staticSources)
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);
145
// otherwise source wasn't set
154
void ImageBase::setFilter (PyFilter * filt)
156
// reference new filter
157
if (filt != NULL) Py_INCREF(filt);
158
// release previous filter
159
Py_XDECREF(m_pyfilter);
165
// initialize image data
166
void ImageBase::init (short width, short height)
168
// if image has to be scaled
171
// recalc sizes of image
172
width = calcSize(width);
173
height = calcSize(height);
176
if (width != m_size[0] || height != m_size[1])
179
unsigned int newSize = width * height;
180
// if new buffer is larger than previous
181
if (newSize > m_imgSize)
183
// set new buffer size
185
// release previous and create new buffer
187
m_image = new unsigned int[m_imgSize];
192
// scale was processed
193
m_scaleChange = false;
199
ImageSourceList::iterator ImageBase::findSource (const char * id)
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;
211
// check sources sizes
212
bool ImageBase::checkSourceSizes (void)
215
short * refSize = NULL;
217
for (ImageSourceList::iterator it = m_sources.begin(); it != m_sources.end(); ++it)
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
225
// set current size as reference
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
237
// compute nearest power of 2 value
238
short ImageBase::calcSize (short size)
240
// while there is more than 1 bit in size value
241
while ((size & (size - 1)) != 0)
243
size = size & (size - 1);
249
// perform loop detection
250
bool ImageBase::loopDetect (ImageBase * img)
252
// if this object is the same as parameter, loop is detected
253
if (this == img) return true;
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))
264
// ImageSource class implementation
267
ImageSource::ImageSource (const char * id) : m_source(NULL), m_image(NULL)
271
for (idx = 0; id[idx] != '\0' && idx < SourceIdSize - 1; ++idx)
277
ImageSource::~ImageSource (void)
285
bool ImageSource::is (const char * id)
287
for (char * myId = m_id; *myId != '\0'; ++myId, ++id)
288
if (*myId != *id) return false;
294
void ImageSource::setSource (PyImage * source)
296
// reference new source
297
if (source != NULL) Py_INCREF(source);
298
// release previous source
299
Py_XDECREF(m_source);
305
// get image from source
306
unsigned int * ImageSource::getImage (void)
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
321
void ImageSource::refresh (void)
323
// if source is available, refresh it
324
if (m_source != NULL) m_source->m_image->refresh();
329
// list of image types
330
PyTypeList pyImageTypes;
334
// functions for python interface
337
PyObject * Image_allocNew (PyTypeObject * type, PyObject * args, PyObject * kwds)
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);
347
// object deallocation
348
void Image_dealloc (PyImage * self)
350
// release object attributes
351
if (self->m_image != NULL)
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;
361
PyObject * Image_getImage (PyImage * self, void * closure)
366
unsigned int * image = self->m_image->getImage();
367
return Py_BuildValue("s#", image, self->m_image->getBuffSize());
369
catch (Exception & exp)
377
PyObject * Image_getSize (PyImage * self, void * closure)
379
return Py_BuildValue("(hh)", self->m_image->getSize()[0],
380
self->m_image->getSize()[1]);
384
PyObject * Image_refresh (PyImage * self)
386
self->m_image->refresh();
391
PyObject * Image_getScale (PyImage * self, void * closure)
393
if (self->m_image != NULL && self->m_image->getScale()) Py_RETURN_TRUE;
394
else Py_RETURN_FALSE;
398
int Image_setScale (PyImage * self, PyObject * value, void * closure)
400
// check parameter, report failure
401
if (value == NULL || !PyBool_Check(value))
403
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
407
if (self->m_image != NULL) self->m_image->setScale(value == Py_True);
413
PyObject * Image_getFlip (PyImage * self, void * closure)
415
if (self->m_image != NULL && self->m_image->getFlip()) Py_RETURN_TRUE;
416
else Py_RETURN_FALSE;
420
int Image_setFlip (PyImage * self, PyObject * value, void * closure)
422
// check parameter, report failure
423
if (value == NULL || !PyBool_Check(value))
425
PyErr_SetString(PyExc_TypeError, "The value must be a bool");
429
if (self->m_image != NULL) self->m_image->setFlip(value == Py_True);
435
// get filter source object
436
PyObject * Image_getSource (PyImage * self, PyObject * args)
440
if (!PyArg_ParseTuple(args, "s:getSource", &id))
442
if (self->m_image != NULL)
445
PyObject * src = reinterpret_cast<PyObject*>(self->m_image->getSource(id));
446
// if source is available
454
// source was not found
459
// set filter source object
460
PyObject * Image_setSource (PyImage * self, PyObject * args)
465
if (!PyArg_ParseTuple(args, "sO:setSource", &id, &obj))
467
if (self->m_image != NULL)
469
// check type of object
470
if (pyImageTypes.in(obj->ob_type))
472
// convert to image struct
473
PyImage * img = reinterpret_cast<PyImage*>(obj);
475
if (!self->m_image->setSource(id, img))
477
// if not set, retport error
478
PyErr_SetString(PyExc_RuntimeError, "Invalid source or id");
485
PyErr_SetString(PyExc_RuntimeError, "Invalid type of object");
494
// get pixel filter object
495
PyObject * Image_getFilter (PyImage * self, void * closure)
497
// if image object is available
498
if (self->m_image != NULL)
500
// pixel filter object
501
PyObject * filt = reinterpret_cast<PyObject*>(self->m_image->getFilter());
502
// if filter is present
510
// otherwise return none
515
// set pixel filter object
516
int Image_setFilter (PyImage * self, PyObject * value, void * closure)
518
// if image object is available
519
if (self->m_image != NULL)
522
if (value == NULL || !pyFilterTypes.in(value->ob_type))
524
// report value error
525
PyErr_SetString(PyExc_TypeError, "Invalid type of value");
529
self->m_image->setFilter(reinterpret_cast<PyFilter*>(value));