1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
|
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2007 The Zdeno Ash Miklas
*
* This source file is part of blendTex library
*
* Contributor(s):
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file ImageBase.h
* \ingroup bgevideotex
*/
#ifndef __IMAGEBASE_H__
#define __IMAGEBASE_H__
#include "Common.h"
#include <vector>
#include "PyObjectPlus.h"
#include "PyTypeList.h"
#include "FilterBase.h"
// forward declarations
struct PyImage;
class ImageSource;
/// type for list of image sources
typedef std::vector<ImageSource*> ImageSourceList;
/// base class for image filters
class ImageBase
{
public:
/// constructor
ImageBase (bool staticSrc = false);
/// destructor
virtual ~ImageBase(void);
/// release contained objects, if returns true, object should be deleted
virtual bool release(void);
/// is an image available
bool isImageAvailable(void)
{ return m_avail; }
/// get image
unsigned int *getImage(unsigned int texId = 0, double timestamp=-1.0);
/// get image size
short * getSize(void) { return m_size; }
/// get image buffer size
unsigned long getBuffSize(void)
{ return m_size[0] * m_size[1] * sizeof(unsigned int); }
/// refresh image - invalidate its current content
virtual void refresh(void);
/// get scale
bool getScale(void) { return m_scale; }
/// set scale
void setScale(bool scale) { m_scale = scale; m_scaleChange = true; }
/// get vertical flip
bool getFlip(void) { return m_flip; }
/// set vertical flip
void setFlip(bool flip) { m_flip = flip; }
/// get Z buffer
bool getZbuff(void) { return m_zbuff; }
/// set Z buffer
void setZbuff(bool zbuff) { m_zbuff = zbuff; }
/// get depth
bool getDepth(void) { return m_depth; }
/// set depth
void setDepth(bool depth) { m_depth = depth; }
/// get source object
PyImage * getSource(const char *id);
/// set source object, return true, if source was set
bool setSource(const char *id, PyImage *source);
/// get pixel filter
PyFilter * getFilter(void) { return m_pyfilter; }
/// set pixel filter
void setFilter(PyFilter * filt);
/// calculate size(nearest power of 2)
static short calcSize(short size);
/// number of buffer pointing to m_image, public because not handled by this class
int m_exports;
protected:
/// image buffer
unsigned int * m_image;
/// image buffer size
unsigned int m_imgSize;
/// image size
short m_size[2];
/// image is available
bool m_avail;
/// scale image to power 2 sizes
bool m_scale;
/// scale was changed
bool m_scaleChange;
/// flip image vertically
bool m_flip;
/// use the Z buffer as a texture
bool m_zbuff;
/// extract the Z buffer with unisgned int precision
bool m_depth;
/// source image list
ImageSourceList m_sources;
/// flag for disabling addition and deletion of sources
bool m_staticSources;
/// pixel filter
PyFilter * m_pyfilter;
/// initialize image data
void init(short width, short height);
/// find source
ImageSourceList::iterator findSource(const char *id);
/// create new source
virtual ImageSource *newSource(const char *id) { return NULL; }
/// check source sizes
bool checkSourceSizes(void);
/// calculate image from sources and set its availability
virtual void calcImage(unsigned int texId, double ts) {}
/// perform loop detection
bool loopDetect(ImageBase * img);
/// template for image conversion
template<class FLT, class SRC> void convImage(FLT & filter, SRC srcBuff,
short * srcSize)
{
// destination buffer
unsigned int * dstBuff = m_image;
// pixel size from filter
unsigned int pixSize = filter.firstPixelSize();
// if no scaling is needed
if (srcSize[0] == m_size[0] && srcSize[1] == m_size[1])
// if flipping isn't required
if (!m_flip)
// copy bitmap
for (short y = 0; y < m_size[1]; ++y)
for (short x = 0; x < m_size[0]; ++x, ++dstBuff, srcBuff += pixSize)
// copy pixel
*dstBuff = filter.convert(srcBuff, x, y, srcSize, pixSize);
// otherwise flip image top to bottom
else
{
// go to last row of image
srcBuff += srcSize[0] * (srcSize[1] - 1) * pixSize;
// copy bitmap
for (short y = m_size[1] - 1; y >= 0; --y, srcBuff -= 2 * srcSize[0] * pixSize)
for (short x = 0; x < m_size[0]; ++x, ++dstBuff, srcBuff += pixSize)
// copy pixel
*dstBuff = filter.convert(srcBuff, x, y, srcSize, pixSize);
}
// else scale picture (nearest neighbor)
else
{
// interpolation accumulator
int accHeight = srcSize[1] >> 1;
// if flipping is required
if (m_flip)
// go to last row of image
srcBuff += srcSize[0] * (srcSize[1] - 1) * pixSize;
// process image rows
for (int y = 0; y < srcSize[1]; ++y)
{
// increase height accum
accHeight += m_size[1];
// if pixel row has to be drawn
if (accHeight >= srcSize[1])
{
// decrease accum
accHeight -= srcSize[1];
// width accum
int accWidth = srcSize[0] >> 1;
// process row
for (int x = 0; x < srcSize[0]; ++x)
{
// increase width accum
accWidth += m_size[0];
// if pixel has to be drawn
if (accWidth >= srcSize[0])
{
// decrease accum
accWidth -= srcSize[0];
// convert pixel
*dstBuff = filter.convert(srcBuff, x, m_flip ? srcSize[1] - y - 1 : y,
srcSize, pixSize);
// next pixel
++dstBuff;
}
// shift source pointer
srcBuff += pixSize;
}
}
// if pixel row will not be drawn
else
// move source pointer to next row
srcBuff += pixSize * srcSize[0];
// if y flipping is required
if (m_flip)
// go to previous row of image
srcBuff -= 2 * pixSize * srcSize[0];
}
}
}
// template for specific filter preprocessing
template <class F, class SRC> void filterImage (F & filt, SRC srcBuff, short *srcSize)
{
// find first filter in chain
FilterBase * firstFilter = NULL;
if (m_pyfilter != NULL) firstFilter = m_pyfilter->m_filter->findFirst();
// if first filter is available
if (firstFilter != NULL)
{
// python wrapper for filter
PyFilter pyFilt;
pyFilt.m_filter = &filt;
// set specified filter as first in chain
firstFilter->setPrevious(&pyFilt, false);
// convert video image
convImage(*(m_pyfilter->m_filter), srcBuff, srcSize);
// delete added filter
firstFilter->setPrevious(NULL, false);
}
// otherwise use given filter for conversion
else convImage(filt, srcBuff, srcSize);
// source was processed
m_avail = true;
}
};
// python structure for image filter
struct PyImage
{
PyObject_HEAD
// source object
ImageBase * m_image;
};
// size of id
const int SourceIdSize = 32;
/// class for source of image
class ImageSource
{
public:
/// constructor
ImageSource (const char *id);
/// destructor
virtual ~ImageSource (void);
/// get id
const char * getId (void) { return m_id; }
/// compare id to argument
bool is (const char *id);
/// get source object
PyImage * getSource (void) { return m_source; }
/// set source object
void setSource (PyImage *source);
/// get image from source
unsigned int * getImage (double ts=-1.0);
/// get buffered image
unsigned int * getImageBuf (void) { return m_image; }
/// refresh source
void refresh (void);
/// get image size
short * getSize (void)
{
static short defSize [] = {0, 0};
return m_source != NULL ? m_source->m_image->getSize() : defSize;
}
protected:
/// id of source
char m_id [SourceIdSize];
/// pointer to source structure
PyImage * m_source;
/// buffered image from source
unsigned int * m_image;
private:
/// default constructor is forbidden
ImageSource (void) {}
};
// list of python image types
extern PyTypeList pyImageTypes;
// functions for python interface
// object initialization
template <class T> static int Image_init(PyObject *pySelf, PyObject *args, PyObject *kwds)
{
PyImage *self = reinterpret_cast<PyImage *>(pySelf);
// create source object
if (self->m_image != NULL) delete self->m_image;
self->m_image = new T();
// initialization succeded
return 0;
}
// object allocation
PyObject *Image_allocNew(PyTypeObject *type, PyObject *args, PyObject *kwds);
// object deallocation
void Image_dealloc(PyImage *self);
// get image data
PyObject *Image_getImage(PyImage *self, char *mode);
// get image size
PyObject *Image_getSize(PyImage *self, void *closure);
// refresh image - invalidate current content
PyObject *Image_refresh(PyImage *self);
// get scale
PyObject *Image_getScale(PyImage *self, void *closure);
// set scale
int Image_setScale(PyImage *self, PyObject *value, void *closure);
// get flip
PyObject *Image_getFlip(PyImage *self, void *closure);
// set flip
int Image_setFlip(PyImage *self, PyObject *value, void *closure);
// get filter source object
PyObject *Image_getSource(PyImage *self, PyObject *args);
// set filter source object
PyObject *Image_setSource(PyImage *self, PyObject *args);
// get Z buffer
PyObject *Image_getZbuff(PyImage *self, void *closure);
// set Z buffer
int Image_setZbuff(PyImage *self, PyObject *value, void *closure);
// get depth
PyObject *Image_getDepth(PyImage *self, void *closure);
// set depth
int Image_setDepth(PyImage *self, PyObject *value, void *closure);
// get pixel filter object
PyObject *Image_getFilter(PyImage *self, void *closure);
// set pixel filter object
int Image_setFilter(PyImage *self, PyObject *value, void *closure);
// check if a buffer can be extracted
PyObject *Image_valid(PyImage *self, void *closure);
// for buffer access to PyImage objects
extern PyBufferProcs imageBufferProcs;
#endif
|