diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-12-22 22:25:01 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-12-22 22:25:01 +0400 |
commit | fa0211df269a3398dd70467982f9e129c79e501b (patch) | |
tree | 404ee267890602b49470cb640986b50d2c2055c1 /source/blender/freestyle/intern/image | |
parent | 8b57a67f3eb57366c2b3abcb8f3b04403d339e1a (diff) |
Another "insanely" big code clean-up patch by Bastien Montagne, many thanks!
Diffstat (limited to 'source/blender/freestyle/intern/image')
-rw-r--r-- | source/blender/freestyle/intern/image/GaussianFilter.cpp | 144 | ||||
-rw-r--r-- | source/blender/freestyle/intern/image/GaussianFilter.h | 243 | ||||
-rw-r--r-- | source/blender/freestyle/intern/image/Image.h | 738 | ||||
-rw-r--r-- | source/blender/freestyle/intern/image/ImagePyramid.cpp | 310 | ||||
-rw-r--r-- | source/blender/freestyle/intern/image/ImagePyramid.h | 182 |
5 files changed, 862 insertions, 755 deletions
diff --git a/source/blender/freestyle/intern/image/GaussianFilter.cpp b/source/blender/freestyle/intern/image/GaussianFilter.cpp index 3a79f5f9949..be0bef8115c 100644 --- a/source/blender/freestyle/intern/image/GaussianFilter.cpp +++ b/source/blender/freestyle/intern/image/GaussianFilter.cpp @@ -1,96 +1,112 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/image/GaussianFilter.cpp + * \ingroup freestyle + * \brief Class to perform gaussian filtering operations on an image + * \author Stephane Grabli + * \date 20/05/2003 + */ -#include "GaussianFilter.h" #include <stdlib.h> -GaussianFilter::GaussianFilter(float iSigma ) +#include "GaussianFilter.h" + +GaussianFilter::GaussianFilter(float iSigma) { - _sigma = iSigma; - _mask = 0; - computeMask(); + _sigma = iSigma; + _mask = 0; + computeMask(); } -GaussianFilter::GaussianFilter(const GaussianFilter& iBrother) +GaussianFilter::GaussianFilter(const GaussianFilter& iBrother) { - _sigma = iBrother._sigma; - _maskSize = iBrother._maskSize; - _bound = iBrother._bound; - _storedMaskSize = iBrother._storedMaskSize; - _mask = new float[_maskSize*_maskSize]; - memcpy(_mask, iBrother._mask, _maskSize*_maskSize*sizeof(float)); + _sigma = iBrother._sigma; + _maskSize = iBrother._maskSize; + _bound = iBrother._bound; + _storedMaskSize = iBrother._storedMaskSize; + _mask = new float[_maskSize * _maskSize]; + memcpy(_mask, iBrother._mask, _maskSize * _maskSize * sizeof(float)); } - -GaussianFilter& GaussianFilter::operator= (const GaussianFilter& iBrother) +GaussianFilter& GaussianFilter::operator=(const GaussianFilter& iBrother) { - _sigma = iBrother._sigma; - _maskSize = iBrother._maskSize; - _bound = iBrother._bound; - _storedMaskSize = iBrother._storedMaskSize; - _mask = new float[_storedMaskSize*_storedMaskSize]; - memcpy(_mask, iBrother._mask, _storedMaskSize*_storedMaskSize*sizeof(float)); - return *this; + _sigma = iBrother._sigma; + _maskSize = iBrother._maskSize; + _bound = iBrother._bound; + _storedMaskSize = iBrother._storedMaskSize; + _mask = new float[_storedMaskSize * _storedMaskSize]; + memcpy(_mask, iBrother._mask, _storedMaskSize * _storedMaskSize * sizeof(float)); + return *this; } GaussianFilter::~GaussianFilter() { - if(0!=_mask) - { - delete [] _mask; - } + if (0 != _mask) { + delete[] _mask; + } } int GaussianFilter::computeMaskSize(float sigma) { - int maskSize = (int)floor(4*sigma)+1; - if(0 == maskSize%2) - ++maskSize; + int maskSize = (int)floor(4 * sigma) + 1; + if (0 == (maskSize % 2)) + ++maskSize; - return maskSize; + return maskSize; } void GaussianFilter::setSigma(float sigma) { - _sigma = sigma; - computeMask(); + _sigma = sigma; + computeMask(); } void GaussianFilter::computeMask() { - if(0 != _mask){ - delete [] _mask; - } + if (0 != _mask) { + delete[] _mask; + } - _maskSize = computeMaskSize(_sigma); - _storedMaskSize = (_maskSize+1)>>1; - _bound = _storedMaskSize-1; + _maskSize = computeMaskSize(_sigma); + _storedMaskSize = (_maskSize + 1) >> 1; + _bound = _storedMaskSize - 1; - float norm = _sigma*_sigma*2.f*M_PI; - float invNorm = 1.0/norm; - _mask = new float[_storedMaskSize*_storedMaskSize*sizeof(float)]; - for(int i=0; i<_storedMaskSize; ++i) - for(int j=0; j<_storedMaskSize; ++j) - _mask[i*_storedMaskSize+j] = invNorm*exp(-(i*i + j*j)/(2.0*_sigma*_sigma)); - //_mask[i*_storedMaskSize+j] = exp(-(i*i + j*j)/(2.0*_sigma*_sigma)); + float norm = _sigma * _sigma * 2.0f * M_PI; + float invNorm = 1.0f / norm; + _mask = new float[_storedMaskSize * _storedMaskSize * sizeof(float)]; + for (int i = 0; i < _storedMaskSize; ++i) { + for (int j = 0; j < _storedMaskSize; ++j) { +#if 0 + _mask[i * _storedMaskSize + j] = exp(-(i * i + j * j) / (2.0 * _sigma * _sigma)); +#else + _mask[i * _storedMaskSize + j] = invNorm * exp(-(i * i + j * j) / (2.0 * _sigma * _sigma)); +#endif + } + } } - diff --git a/source/blender/freestyle/intern/image/GaussianFilter.h b/source/blender/freestyle/intern/image/GaussianFilter.h index be0e3e2bada..9890e615a7c 100644 --- a/source/blender/freestyle/intern/image/GaussianFilter.h +++ b/source/blender/freestyle/intern/image/GaussianFilter.h @@ -1,95 +1,114 @@ -// -// Filename : Image.h -// Author(s) : Stephane Grabli -// Purpose : Class to perform gaussian filtering operations on an image -// Date of creation : 20/05/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef GAUSSIANFILTER_H -# define GAUSSIANFILTER_H +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __GAUSSIANFILTER_H__ +#define __GAUSSIANFILTER_H__ + +/** \file blender/freestyle/intern/image/GaussianFilter.h + * \ingroup freestyle + * \brief Class to perform gaussian filtering operations on an image + * \author Stephane Grabli + * \date 20/05/2003 + */ -#include <string.h> // for memcpy #include <cstdlib> // for abs +#include <string.h> // for memcpy + #include "../system/FreestyleConfig.h" -class LIB_IMAGE_EXPORT GaussianFilter{ +class LIB_IMAGE_EXPORT GaussianFilter +{ protected: - /* the mask is a symetrical 2d array (with respect - to the middle point). - Thus, M(i,j) = M(-i,j) = M(i,-j) = M(-i,-j). - For this reason, to represent a NxN array (N odd), we only store - a ((N+1)/2)x((N+1)/2) array. - */ - float _sigma; - float *_mask; - int _bound; - int _maskSize; // the real mask size (must be odd)(the size of the mask we store is ((_maskSize+1)/2)*((_maskSize+1)/2)) - int _storedMaskSize; //(_maskSize+1)/2) - + /* The mask is a symetrical 2d array (with respect to the middle point). + * Thus, M(i,j) = M(-i,j) = M(i,-j) = M(-i,-j). + * For this reason, to represent a NxN array (N odd), we only store a ((N+1)/2)x((N+1)/2) array. + */ + float _sigma; + float *_mask; + int _bound; + int _maskSize; // the real mask size (must be odd)(the size of the mask we store is ((_maskSize+1)/2)*((_maskSize+1)/2)) + int _storedMaskSize; // (_maskSize+1)/2) + public: - GaussianFilter(float iSigma = 1.f) ; - GaussianFilter(const GaussianFilter&) ; - GaussianFilter& operator= (const GaussianFilter&) ; - virtual ~GaussianFilter() ; - - /*! Returns the value for pixel x,y of image "map" after a gaussian blur, - * made using the sigma value. - * The sigma value determines the mask size (~ 2 x sigma). - * \param map - * The image we wish to work on. The Map template must implement the - * foloowing methods: - * - float pixel(unsigned int x,unsigned int y) const; - * - unsigned width() const; - * - unsigned height() const; - * \param x - * The abscissa of the pixel where we want to evaluate the gaussian blur. - * \param y - * The ordinate of the pixel where we want to evaluate the gaussian blur. - * \param sigma - * The sigma value of the gaussian function. - */ - template<class Map> - float getSmoothedPixel(Map * map, int x, int y) ; - - /*! Compute the mask size and returns the REAL mask size ((2*_maskSize)-1) - * This method is provided for convenience. - */ - static int computeMaskSize(float sigma) ; - - /*! accessors */ - inline float sigma() const {return _sigma;} - inline int maskSize() const {return _maskSize;} - inline int getBound() {return _bound;} - - /*! modifiers */ - void setSigma(float sigma) ; - // void SetMaskSize(int size) {_maskSize = size;_storedMaskSize=(_maskSize+1)>>1;} - - + GaussianFilter(float iSigma = 1.0f); + GaussianFilter(const GaussianFilter&); + GaussianFilter& operator=(const GaussianFilter&); + virtual ~GaussianFilter(); + + /*! Returns the value for pixel x,y of image "map" after a gaussian blur, made using the sigma value. + * The sigma value determines the mask size (~ 2 x sigma). + * \param map + * The image we wish to work on. The Map template must implement the following methods: + * - float pixel(unsigned int x,unsigned int y) const; + * - unsigned width() const; + * - unsigned height() const; + * \param x + * The abscissa of the pixel where we want to evaluate the gaussian blur. + * \param y + * The ordinate of the pixel where we want to evaluate the gaussian blur. + * \param sigma + * The sigma value of the gaussian function. + */ + template<class Map> + float getSmoothedPixel(Map *map, int x, int y); + + /*! Compute the mask size and returns the REAL mask size ((2*_maskSize)-1) + * This method is provided for convenience. + */ + static int computeMaskSize(float sigma); + + /*! accessors */ + inline float sigma() const + { + return _sigma; + } + + inline int maskSize() const + { + return _maskSize; + } + + inline int getBound() + { + return _bound; + } + + /*! modifiers */ + void setSigma(float sigma); +#if 0 + void SetMaskSize(int size) + { + _maskSize = size; + _storedMaskSize = (_maskSize + 1) >> 1; + } +#endif + protected: - void computeMask(); + void computeMask(); }; /* @@ -106,41 +125,37 @@ protected: */ - #include <math.h> #ifdef __MACH__ -#define sqrtf(x) (sqrt(x)) +# define sqrtf(x) (sqrt(x)) #endif template<class Map> -float GaussianFilter::getSmoothedPixel(Map * map, int x, int y) +float GaussianFilter::getSmoothedPixel(Map *map, int x, int y) { - float sum = 0.f; - float L=0.f; - int w = (int)map->width(); //soc - int h = (int)map->height(); //soc - - // Current pixel is x,y - // Sum surrounding pixels L value: - for(int i=-_bound; i<=_bound; ++i) - { - if((y+i < 0) || (y+i >= h)) - continue; - for(int j=-_bound; j<=_bound; ++j) - { - if((x+j < 0) || (x+j >= w)) - continue; - - float tmpL = map->pixel(x+j,y+i); - float m = _mask[abs(i)*_storedMaskSize+abs(j)]; - L += m*tmpL; - sum += m; - } - } - //L /= sum; - return L; + float sum = 0.0f; + float L = 0.0f; + int w = (int)map->width(); //soc + int h = (int)map->height(); //soc + + // Current pixel is x,y + // Sum surrounding pixels L value: + for (int i = -_bound; i <= _bound; ++i) { + if ((y + i < 0) || (y + i >= h)) + continue; + for (int j = -_bound; j <= _bound; ++j) { + if ((x + j < 0) || (x + j >= w)) + continue; + + float tmpL = map->pixel(x + j, y + i); + float m = _mask[abs(i) * _storedMaskSize + abs(j)]; + L += m * tmpL; + sum += m; + } + } + //L /= sum; + return L; } - -#endif // GAUSSIANFILTER +#endif // __GAUSSIANFILTER_H__ diff --git a/source/blender/freestyle/intern/image/Image.h b/source/blender/freestyle/intern/image/Image.h index 72affbc1023..1487e43a0b0 100644 --- a/source/blender/freestyle/intern/image/Image.h +++ b/source/blender/freestyle/intern/image/Image.h @@ -1,178 +1,177 @@ -// -// Filename : Image.h -// Author(s) : Stephane Grabli -// Purpose : Class to encapsulate an array of RGB or Gray level values -// Date of creation : 20/05/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __IMAGE_H__ +#define __IMAGE_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef IMAGE_H -# define IMAGE_H +/** \file blender/freestyle/intern/image/Image.h + * \ingroup freestyle + * \brief Class to encapsulate an array of RGB or Gray level values + * \author Stephane Grabli + * \date 20/05/2003 + */ -# include <string.h> // for memcpy +#include <string.h> // for memcpy // // Image base class, for all types of images // /////////////////////////////////////////////////////////////////////////////// -/*! This class allows the storing of part of an image, - * while allowing a normal access to its pixel values. - * You can for example only a rectangle of sw*sh, whose - * lower-left corner is at (ox, oy), of an image of - * size w*h, and access these pixels using x,y coordinates - * specified in the whole image coordinate system. +/*! This class allows the storing of part of an image, while allowing a normal access to its pixel values. + * You can for example only a rectangle of sw*sh, whose lower-left corner is at (ox, oy), of an image of + * size w*h, and access these pixels using x,y coordinates specified in the whole image coordinate system. */ class FrsImage { - public: - - /*! Default constructor */ - FrsImage() { - _storedWidth = 0; - _storedHeight = 0; - _width = 0; - _height = 0; - _Ox = 0; - _Oy = 0; - } - - /*! Copy constructor */ - FrsImage(const FrsImage& brother) { - _storedWidth = brother._storedWidth; - _storedHeight = brother._storedHeight; - _width = brother._width; - _height = brother._height; - _Ox = brother._Ox; - _Oy = brother._Oy; - } - - /*! Builds an FrsImage from its width and height. - * The memory is allocated consequently. - */ - FrsImage(unsigned w, unsigned h) { - _width = w; - _height = h; - _storedWidth = w; - _storedHeight = h; - _Ox = 0; - _Oy = 0; - } - - /*! Builds a partial-storing image. - * \param w - * The width of the complete image - * \param h - * The height of the complete image - * \param sw - * The width of the rectangle that will actually - * be stored. - * \param sh - * The height of the rectangle that will actually - * be stored. - * \param ox - * The x-abscissa of the origin of the rectangle that will actually - * be stored. - * \param oy - * The x-abscissa of the origin of the rectangle that will actually - * be stored. - */ - FrsImage(unsigned w, unsigned h, unsigned sw, unsigned sh, unsigned ox, unsigned oy) { - _width = w; - _height = h; - _storedWidth = sw; - _storedHeight = sh; - _Ox = ox; - _Oy = oy; - } - - /*! Operator= */ - FrsImage& operator=(const FrsImage& brother) { - _width = brother._width; - _height = brother._height; - _storedWidth = brother._storedWidth; - _storedHeight = brother._storedHeight; - _Ox = brother._Ox; - _Oy = brother._Oy; - return* this; - } - - /*! Destructor */ - virtual ~FrsImage() {} - - /*! Returns the width of the complete image */ - inline unsigned width() const { - return _width; - } - /*! Returns the height of the complete image */ - inline unsigned height() const { - return _height; - } - - /*! Returns the grey value for pixel x,y */ - virtual float pixel(unsigned x, unsigned y) const = 0; - - /*! Sets the array. - * \param array - * The array containing the values we wish to store. - * Its size is sw*sh. - * \param width - * The width of the complete image - * \param height - * The height of the complete image - * \param sw - * The width of the rectangle that will actually - * be stored. - * \param sh - * The height of the rectangle that will actually - * be stored. - * \param ox - * The x-abscissa of the origin of the rectangle that will actually - * be stored. - * \param oy - * The x-abscissa of the origin of the rectangle that will actually - * be stored. - * \param copy - * If true, the array is copied, otherwise the pointer is - * copied - */ - virtual void setArray(float* array, unsigned width, unsigned height, unsigned sw, unsigned sh, unsigned x, unsigned y, bool copy = true) = 0; - - /*! Returns the array containing the pixels values. - * Its size is sw*sh, i.e. potentially a smaller - * rectangular part of the complete image. - */ - virtual float * getArray() = 0; - - protected: - - unsigned _width; - unsigned _height; - unsigned _storedWidth; - unsigned _storedHeight; - unsigned _Ox; // origin of the stored part - unsigned _Oy; // origin of the stored part +public: + /*! Default constructor */ + FrsImage() + { + _storedWidth = 0; + _storedHeight = 0; + _width = 0; + _height = 0; + _Ox = 0; + _Oy = 0; + } + + /*! Copy constructor */ + FrsImage(const FrsImage& brother) + { + _storedWidth = brother._storedWidth; + _storedHeight = brother._storedHeight; + _width = brother._width; + _height = brother._height; + _Ox = brother._Ox; + _Oy = brother._Oy; + } + + /*! Builds an FrsImage from its width and height. + * The memory is allocated consequently. + */ + FrsImage(unsigned w, unsigned h) + { + _width = w; + _height = h; + _storedWidth = w; + _storedHeight = h; + _Ox = 0; + _Oy = 0; + } + + /*! Builds a partial-storing image. + * \param w + * The width of the complete image + * \param h + * The height of the complete image + * \param sw + * The width of the rectangle that will actually be stored. + * \param sh + * The height of the rectangle that will actually be stored. + * \param ox + * The x-abscissa of the origin of the rectangle that will actually be stored. + * \param oy + * The x-abscissa of the origin of the rectangle that will actually be stored. + */ + FrsImage(unsigned w, unsigned h, unsigned sw, unsigned sh, unsigned ox, unsigned oy) + { + _width = w; + _height = h; + _storedWidth = sw; + _storedHeight = sh; + _Ox = ox; + _Oy = oy; + } + + /*! Operator= */ + FrsImage& operator=(const FrsImage& brother) + { + _width = brother._width; + _height = brother._height; + _storedWidth = brother._storedWidth; + _storedHeight = brother._storedHeight; + _Ox = brother._Ox; + _Oy = brother._Oy; + return *this; + } + + /*! Destructor */ + virtual ~FrsImage() {} + + /*! Returns the width of the complete image */ + inline unsigned width() const + { + return _width; + } + + /*! Returns the height of the complete image */ + inline unsigned height() const + { + return _height; + } + + /*! Returns the grey value for pixel x,y */ + virtual float pixel(unsigned x, unsigned y) const = 0; + + /*! Sets the array. + * \param array + * The array containing the values we wish to store. + * Its size is sw*sh. + * \param width + * The width of the complete image + * \param height + * The height of the complete image + * \param sw + * The width of the rectangle that will actually be stored. + * \param sh + * The height of the rectangle that will actually be stored. + * \param ox + * The x-abscissa of the origin of the rectangle that will actually be stored. + * \param oy + * The x-abscissa of the origin of the rectangle that will actually be stored. + * \param copy + * If true, the array is copied, otherwise the pointer is copied + */ + virtual void setArray(float *array, unsigned width, unsigned height, unsigned sw, unsigned sh, + unsigned x, unsigned y, bool copy = true) = 0; + + /*! Returns the array containing the pixels values. + * Its size is sw*sh, i.e. potentially a smaller rectangular part of the complete image. + */ + virtual float *getArray() = 0; + +protected: + unsigned _width; + unsigned _height; + unsigned _storedWidth; + unsigned _storedHeight; + unsigned _Ox; // origin of the stored part + unsigned _Oy; // origin of the stored part }; @@ -180,114 +179,130 @@ class FrsImage // RGBImage // /////////////////////////////////////////////////////////////////////////////// - class RGBImage : public FrsImage { - public: - - RGBImage() : FrsImage() { - _rgb = 0; - } - - RGBImage(const RGBImage& brother) : FrsImage(brother) { - _rgb = new float[3 * _storedWidth * _storedHeight]; - memcpy(_rgb, brother._rgb, 3 * _storedWidth * _storedHeight * sizeof(float)); - } - - RGBImage(unsigned w, unsigned h) : FrsImage(w, h) { - _rgb = new float[3 * _width * _height]; - } - - RGBImage(float* rgb, unsigned w, unsigned h) : FrsImage(w, h) { - _rgb = new float[3 * _width * _height]; - memcpy(_rgb, rgb, 3 * _width * _height * sizeof(float)); - } - - /*! Builds an RGB partial image from the useful part buffer. - * \param rgb - * The array of size 3*sw*sh containing the RGB values - * of the sw*sh pixels we need to stored. - * These sw*sh pixels constitute a rectangular part of - * a bigger RGB image containing w*h pixels. - * \param w - * The width of the complete image - * \param h - * The height of the complete image - * \param sw - * The width of the part of the image we want to store and work on - * \param sh - * The height of the part of the image we want to store and work on - */ - RGBImage(float* rgb, unsigned w, unsigned h, unsigned sw, unsigned sh, unsigned ox, unsigned oy) : FrsImage(w, h, sw, sh, ox, oy) { - _rgb = new float[3 * _storedWidth * _storedHeight]; - memcpy(_rgb, rgb, 3 * _storedWidth * _storedHeight * sizeof(float)); - } - - RGBImage& operator=(const RGBImage& brother) { - dynamic_cast<FrsImage&>(*this) = brother; - _rgb = new float[3 * _storedWidth * _storedHeight]; - memcpy(_rgb, brother._rgb, 3 * _storedWidth * _storedHeight * sizeof(float)); - return* this; - } - - virtual ~RGBImage() { - if(_rgb) - delete[] _rgb; - } - - inline float getR(unsigned x, unsigned y) const { - return _rgb[3 * (y-_Oy) * _storedWidth + (x-_Ox) * 3]; - } - - inline float getG(unsigned x, unsigned y) const { - return _rgb[3 * (y-_Oy) * _storedWidth + (x-_Ox) * 3 + 1]; - } - - inline float getB(unsigned x, unsigned y) const { - return _rgb[3 * (y-_Oy) * _storedWidth + (x-_Ox) * 3 + 2]; - } - - virtual void setPixel(unsigned x, unsigned y, float r, float g, float b){ - float * tmp = &(_rgb[3 * (y-_Oy) * _storedWidth + (x-_Ox) * 3]); - *tmp = r;++tmp; - *tmp = g;++tmp; - *tmp = b; - } - - virtual float pixel(unsigned x, unsigned y) const { - float res = 0; - float* tmp = &(_rgb[3 * (y-_Oy) * _storedWidth + (x-_Ox) * 3]); - res += 11 * (*tmp++); - res += 16 * (*tmp++); - res += 5 * (*tmp); - return res / 32; - } - - /*! Sets the RGB array. - * copy - * If true, the array is copied, otherwise the pointer is - * copied - */ - virtual void setArray(float* rgb, unsigned width, unsigned height, unsigned sw, unsigned sh, unsigned x, unsigned y, bool copy = true) { - _width = width; - _height = height; - _storedWidth = sw; - _storedHeight = sh; - _Ox = x; - _Oy = y; - if(!copy) { - _rgb = rgb; - return; - } - - memcpy(_rgb, rgb, 3 * _storedWidth * _storedHeight* sizeof(float)); - } - - virtual float * getArray() {return _rgb;} - - protected: - - float* _rgb; +public: + RGBImage() : FrsImage() + { + _rgb = 0; + } + + RGBImage(const RGBImage& brother) : FrsImage(brother) + { + _rgb = new float[3 * _storedWidth * _storedHeight]; + memcpy(_rgb, brother._rgb, 3 * _storedWidth * _storedHeight * sizeof(float)); + } + + RGBImage(unsigned w, unsigned h) : FrsImage(w, h) + { + _rgb = new float[3 * _width * _height]; + } + + RGBImage(float *rgb, unsigned w, unsigned h) : FrsImage(w, h) + { + _rgb = new float[3 * _width * _height]; + memcpy(_rgb, rgb, 3 * _width * _height * sizeof(float)); + } + + /*! Builds an RGB partial image from the useful part buffer. + * \param rgb + * The array of size 3*sw*sh containing the RGB values of the sw*sh pixels we need to stored. + * These sw*sh pixels constitute a rectangular part of a bigger RGB image containing w*h pixels. + * \param w + * The width of the complete image + * \param h + * The height of the complete image + * \param sw + * The width of the part of the image we want to store and work on + * \param sh + * The height of the part of the image we want to store and work on + */ + RGBImage(float *rgb, unsigned w, unsigned h, unsigned sw, unsigned sh, unsigned ox, unsigned oy) + : FrsImage(w, h, sw, sh, ox, oy) + { + _rgb = new float[3 * _storedWidth * _storedHeight]; + memcpy(_rgb, rgb, 3 * _storedWidth * _storedHeight * sizeof(float)); + } + + RGBImage& operator=(const RGBImage& brother) + { + dynamic_cast<FrsImage&>(*this) = brother; + _rgb = new float[3 * _storedWidth * _storedHeight]; + memcpy(_rgb, brother._rgb, 3 * _storedWidth * _storedHeight * sizeof(float)); + return *this; + } + + virtual ~RGBImage() + { + if(_rgb) + delete[] _rgb; + } + + inline float getR(unsigned x, unsigned y) const + { + return _rgb[3 * (y - _Oy) * _storedWidth + (x - _Ox) * 3]; + } + + inline float getG(unsigned x, unsigned y) const + { + return _rgb[3 * (y - _Oy) * _storedWidth + (x - _Ox) * 3 + 1]; + } + + inline float getB(unsigned x, unsigned y) const + { + return _rgb[3 * (y - _Oy) * _storedWidth + (x - _Ox) * 3 + 2]; + } + + virtual void setPixel(unsigned x, unsigned y, float r, float g, float b) + { + float *tmp = &(_rgb[3 * (y - _Oy) * _storedWidth + (x - _Ox) * 3]); + *tmp = r; + tmp++; + *tmp = g; + tmp++; + *tmp = b; + } + + virtual float pixel(unsigned x, unsigned y) const + { + float res = 0.0f; + float *tmp = &(_rgb[3 * (y - _Oy) * _storedWidth + (x - _Ox) * 3]); + res += 11.0f * (*tmp); + tmp++; + res += 16.0f * (*tmp); + tmp++; + res += 5.0f * (*tmp); + return res / 32.0f; + } + + /*! Sets the RGB array. + * copy + * If true, the array is copied, otherwise the pointer is copied + */ + virtual void setArray(float *rgb, unsigned width, unsigned height, unsigned sw, unsigned sh, + unsigned x, unsigned y, bool copy = true) + { + _width = width; + _height = height; + _storedWidth = sw; + _storedHeight = sh; + _Ox = x; + _Oy = y; + if (!copy) { + _rgb = rgb; + return; + } + + memcpy(_rgb, rgb, 3 * _storedWidth * _storedHeight * sizeof(float)); + } + + virtual float *getArray() + { + return _rgb; + } + +protected: + float *_rgb; }; @@ -298,92 +313,103 @@ class RGBImage : public FrsImage class GrayImage : public FrsImage { - public: - - GrayImage() : FrsImage() { - _lvl = 0; - } - - GrayImage(const GrayImage& brother) : FrsImage(brother) { - _lvl = new float[_storedWidth*_storedHeight]; - memcpy(_lvl, brother._lvl, _storedWidth*_storedHeight*sizeof(*_lvl)); - } - - /*! Builds an empty gray image */ - GrayImage(unsigned w, unsigned h) : FrsImage(w, h) { - _lvl = new float[_width*_height]; - } - - GrayImage(float* lvl, unsigned w, unsigned h) : FrsImage(w, h) { - _lvl = new float[_width*_height]; - memcpy(_lvl, lvl, _width*_height*sizeof(*_lvl)); - } - - /*! Builds a partial image from the useful part buffer. - * \param lvl - * The array of size sw*sh containing the gray values - * of the sw*sh pixels we need to stored. - * These sw*sh pixels constitute a rectangular part of - * a bigger gray image containing w*h pixels. - * \param w - * The width of the complete image - * \param h - * The height of the complete image - * \param sw - * The width of the part of the image we want to store and work on - * \param sh - * The height of the part of the image we want to store and work on - */ - GrayImage(float* lvl, unsigned w, unsigned h, unsigned sw, unsigned sh, unsigned ox, unsigned oy) : FrsImage(w, h, sw, sh, ox, oy) { - _lvl = new float[_storedWidth*_storedHeight]; - memcpy(_lvl, lvl, _storedWidth*_storedHeight*sizeof(float)); - } - - GrayImage& operator=(const GrayImage& brother) { - dynamic_cast<FrsImage&>(*this) = brother; - _lvl = new float[_storedWidth * _storedHeight]; - memcpy(_lvl, brother._lvl, _storedWidth * _storedHeight * sizeof(float)); - return *this; - } - - virtual ~GrayImage() { - if(_lvl) - delete[] _lvl; - } - - inline void setPixel(unsigned x, unsigned y, float v){ - _lvl[(y-_Oy) * _storedWidth+ (x-_Ox)] = v; - } - - inline float pixel(unsigned x, unsigned y) const { - return _lvl[(y-_Oy) * _storedWidth+ (x-_Ox)]; - } - - /*! Sets the array. - * copy - * If true, the array is copie, otherwise the pounsigneder is - * copied - */ - void setArray(float *lvl, unsigned width, unsigned height, unsigned sw, unsigned sh, unsigned x, unsigned y, bool copy = true) { - _width = width; - _height = height; - _storedWidth = sw; - _storedHeight = sh; - _Ox = x; - _Oy = y; - if(!copy) { - _lvl = lvl; - return; - } - - memcpy(_lvl, lvl, _storedWidth * _storedHeight * sizeof(float)); - } - /*! Returns the array containing the gray values. */ - virtual float * getArray() {return _lvl;} - - protected: - - float *_lvl; +public: + GrayImage() : FrsImage() + { + _lvl = 0; + } + + GrayImage(const GrayImage& brother) : FrsImage(brother) + { + _lvl = new float[_storedWidth * _storedHeight]; + memcpy(_lvl, brother._lvl, _storedWidth * _storedHeight * sizeof(*_lvl)); + } + + /*! Builds an empty gray image */ + GrayImage(unsigned w, unsigned h) : FrsImage(w, h) + { + _lvl = new float[_width * _height]; + } + + GrayImage(float *lvl, unsigned w, unsigned h) : FrsImage(w, h) + { + _lvl = new float[_width * _height]; + memcpy(_lvl, lvl, _width * _height * sizeof(*_lvl)); + } + + /*! Builds a partial image from the useful part buffer. + * \param lvl + * The array of size sw*sh containing the gray values of the sw*sh pixels we need to stored. + * These sw*sh pixels constitute a rectangular part of a bigger gray image containing w*h pixels. + * \param w + * The width of the complete image + * \param h + * The height of the complete image + * \param sw + * The width of the part of the image we want to store and work on + * \param sh + * The height of the part of the image we want to store and work on + */ + GrayImage(float *lvl, unsigned w, unsigned h, unsigned sw, unsigned sh, unsigned ox, unsigned oy) + : FrsImage(w, h, sw, sh, ox, oy) + { + _lvl = new float[_storedWidth * _storedHeight]; + memcpy(_lvl, lvl, _storedWidth * _storedHeight * sizeof(float)); + } + + GrayImage& operator=(const GrayImage& brother) + { + dynamic_cast<FrsImage&>(*this) = brother; + _lvl = new float[_storedWidth * _storedHeight]; + memcpy(_lvl, brother._lvl, _storedWidth * _storedHeight * sizeof(float)); + return *this; + } + + virtual ~GrayImage() + { + if (_lvl) + delete[] _lvl; + } + + inline void setPixel(unsigned x, unsigned y, float v) + { + _lvl[(y - _Oy) * _storedWidth + (x - _Ox)] = v; + } + + inline float pixel(unsigned x, unsigned y) const + { + return _lvl[(y - _Oy) * _storedWidth + (x - _Ox)]; + } + + /*! Sets the array. + * copy + * If true, the array is copie, otherwise the pounsigneder is copied + */ + void setArray(float *lvl, unsigned width, unsigned height, unsigned sw, unsigned sh, + unsigned x, unsigned y, bool copy = true) + { + _width = width; + _height = height; + _storedWidth = sw; + _storedHeight = sh; + _Ox = x; + _Oy = y; + if (!copy) { + _lvl = lvl; + return; + } + + memcpy(_lvl, lvl, _storedWidth * _storedHeight * sizeof(float)); + } + + /*! Returns the array containing the gray values. */ + virtual float *getArray() + { + return _lvl; + } + +protected: + float *_lvl; }; -#endif // IMAGE_H +#endif // __IMAGE_H__ diff --git a/source/blender/freestyle/intern/image/ImagePyramid.cpp b/source/blender/freestyle/intern/image/ImagePyramid.cpp index 542ab7917e3..c7616fbce23 100644 --- a/source/blender/freestyle/intern/image/ImagePyramid.cpp +++ b/source/blender/freestyle/intern/image/ImagePyramid.cpp @@ -1,166 +1,192 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/freestyle/intern/image/ImagePyramid.cpp + * \ingroup freestyle + * \brief Class to represent a pyramid of images + * \author Stephane Grabli + * \date 25/12/2003 + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// -#include "ImagePyramid.h" -#include "Image.h" -#include "GaussianFilter.h" #include <iostream> +#include "GaussianFilter.h" +#include "Image.h" +#include "ImagePyramid.h" + using namespace std; -//ImagePyramid::ImagePyramid(const GrayImage& level0, unsigned nbLevels){ -// //BuildPyramid(level0,nbLevels); -//} - -ImagePyramid::ImagePyramid(const ImagePyramid& iBrother){ - if(!_levels.empty()){ - for(vector<GrayImage*>::iterator im=_levels.begin(), imend=_levels.end(); - im!=imend; - ++im){ - _levels.push_back(new GrayImage(**im)); - } - } +#if 0 +ImagePyramid::ImagePyramid(const GrayImage& level0, unsigned nbLevels) +{ + BuildPyramid(level0,nbLevels); +} +#endif + +ImagePyramid::ImagePyramid(const ImagePyramid& iBrother) +{ + if (!_levels.empty()) { + for (vector<GrayImage*>::iterator im = _levels.begin(), imend = _levels.end(); im != imend; ++im) { + _levels.push_back(new GrayImage(**im)); + } + } } -ImagePyramid::~ImagePyramid(){ - if(!_levels.empty()){ - for(vector<GrayImage*>::iterator im=_levels.begin(), imend=_levels.end(); - im!=imend; - ++im){ - delete (*im); - } - _levels.clear(); - } + +ImagePyramid::~ImagePyramid() +{ + if (!_levels.empty()) { + for (vector<GrayImage*>::iterator im = _levels.begin(), imend = _levels.end(); im != imend; ++im) { + delete (*im); + } + _levels.clear(); + } } -GrayImage * ImagePyramid::getLevel(int l){ - return _levels[l]; +GrayImage * ImagePyramid::getLevel(int l) +{ + return _levels[l]; } -float ImagePyramid::pixel(int x, int y, int level){ - GrayImage *img = _levels[level]; - if(0 == level){ - return img->pixel(x,y); - } - unsigned int i = 1<<level; - unsigned int sx = x>>level; - unsigned int sy = y>>level; - if(sx >= img->width()) - sx = img->width()-1; - if(sy >= img->height()) - sy = img->height()-1; - - // bilinear interpolation - float A = i*(sx+1)-x; - float B = x-i*sx; - float C = i*(sy+1)-y; - float D = y-i*sy; - - float P1(0), P2(0); - P1 = A*img->pixel(sx,sy); - if(sx < img->width()-1){ - if(x%i != 0) - P1 += B*img->pixel(sx+1,sy); - }else{ - P1 += B*img->pixel(sx,sy); - } - if(sy<img->height()-1){ - if(y%i != 0){ - P2 = A*img->pixel(sx,sy+1); - if(sx < img->width()-1){ - if(x%i != 0) - P2 += B*img->pixel(sx+1,sy+1); - }else{ - P2 += B*img->pixel(sx,sy+1); - } - } - }else{ - P2 = P1; - } - return (1.f/(float)(1<<2*level))*(C*P1 + D*P2); +float ImagePyramid::pixel(int x, int y, int level) +{ + GrayImage *img = _levels[level]; + if (0 == level) { + return img->pixel(x, y); + } + unsigned int i = 1 << level; + unsigned int sx = x >> level; + unsigned int sy = y >> level; + if (sx >= img->width()) + sx = img->width() - 1; + if (sy >= img->height()) + sy = img->height() - 1; + + // bilinear interpolation + float A = i * (sx + 1) - x; + float B = x - i * sx; + float C = i * (sy + 1) - y; + float D = y - i * sy; + + float P1(0), P2(0); + P1 = A * img->pixel(sx, sy); + if (sx < img->width() - 1) { + if (x % i != 0) + P1 += B * img->pixel(sx + 1, sy); + } + else { + P1 += B * img->pixel(sx, sy); + } + if (sy < img->height() - 1) { + if (y % i != 0) { + P2 = A * img->pixel(sx, sy + 1); + if (sx < img->width() - 1) { + if (x % i != 0) + P2 += B * img->pixel(sx + 1, sy + 1); + } + else { + P2 += B * img->pixel(sx, sy + 1); + } + } + } + else { + P2 = P1; + } + return (1.0f / (float)(1 << (2 * level))) * (C * P1 + D * P2); } -int ImagePyramid::width(int level){ - return _levels[level]->width(); +int ImagePyramid::width(int level) +{ + return _levels[level]->width(); } -int ImagePyramid::height(int level){ - return _levels[level]->height(); +int ImagePyramid::height(int level) +{ + return _levels[level]->height(); } -GaussianPyramid::GaussianPyramid(const GrayImage& level0, unsigned nbLevels, float iSigma) - : ImagePyramid() +GaussianPyramid::GaussianPyramid(const GrayImage& level0, unsigned nbLevels, float iSigma) : ImagePyramid() { - _sigma = iSigma; - BuildPyramid(level0,nbLevels); -} -GaussianPyramid::GaussianPyramid(GrayImage* level0, unsigned nbLevels, float iSigma) - : ImagePyramid() + _sigma = iSigma; + BuildPyramid(level0, nbLevels); +} + +GaussianPyramid::GaussianPyramid(GrayImage* level0, unsigned nbLevels, float iSigma) : ImagePyramid() { - _sigma = iSigma; - BuildPyramid(level0,nbLevels); + _sigma = iSigma; + BuildPyramid(level0, nbLevels); } -GaussianPyramid::GaussianPyramid(const GaussianPyramid& iBrother) -: ImagePyramid(iBrother){ - _sigma = iBrother._sigma; +GaussianPyramid::GaussianPyramid(const GaussianPyramid& iBrother) : ImagePyramid(iBrother) +{ + _sigma = iBrother._sigma; } -void GaussianPyramid::BuildPyramid(const GrayImage& level0, unsigned nbLevels){ - GrayImage *pLevel = new GrayImage(level0); - BuildPyramid(pLevel, nbLevels); + +void GaussianPyramid::BuildPyramid(const GrayImage& level0, unsigned nbLevels) +{ + GrayImage *pLevel = new GrayImage(level0); + BuildPyramid(pLevel, nbLevels); } -void GaussianPyramid::BuildPyramid(GrayImage* level0, unsigned nbLevels){ - GrayImage *pLevel = level0; - _levels.push_back(pLevel); - GaussianFilter gf(_sigma); - // build the nbLevels: - unsigned w = pLevel->width(); - unsigned h = pLevel->height(); - if(nbLevels!=0) - { - for(unsigned i=0; i<nbLevels; ++i){ //soc - w = pLevel->width()>>1; - h = pLevel->height()>>1; - GrayImage *img = new GrayImage(w,h); - for(unsigned y=0; y<h; ++y){ - for(unsigned x=0; x<w; ++x){ - float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2*x,2*y); - img->setPixel(x,y,v); - } - } - _levels.push_back(img); - pLevel = img; - } - }else{ - while((w>1) && (h>1)){ - w = pLevel->width()>>1; - h = pLevel->height()>>1; - GrayImage *img = new GrayImage(w,h); - for(unsigned y=0; y<h; ++y){ - for(unsigned x=0; x<w; ++x){ - float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2*x,2*y); - img->setPixel(x,y,v); - } - } - _levels.push_back(img); - pLevel = img; - } - } +void GaussianPyramid::BuildPyramid(GrayImage* level0, unsigned nbLevels) +{ + GrayImage *pLevel = level0; + _levels.push_back(pLevel); + GaussianFilter gf(_sigma); + // build the nbLevels: + unsigned w = pLevel->width(); + unsigned h = pLevel->height(); + if (nbLevels != 0) { + for (unsigned int i = 0; i < nbLevels; ++i) { //soc + w = pLevel->width() >> 1; + h = pLevel->height() >> 1; + GrayImage *img = new GrayImage(w, h); + for (unsigned int y = 0; y < h; ++y) { + for (unsigned int x = 0; x < w; ++x) { + float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2 * x, 2 * y); + img->setPixel(x, y, v); + } + } + _levels.push_back(img); + pLevel = img; + } + } + else { + while ((w > 1) && (h > 1)) { + w = pLevel->width() >> 1; + h = pLevel->height() >> 1; + GrayImage *img = new GrayImage(w, h); + for (unsigned int y = 0; y < h; ++y) { + for (unsigned int x = 0; x < w; ++x) { + float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2 * x, 2 * y); + img->setPixel(x, y, v); + } + } + _levels.push_back(img); + pLevel = img; + } + } } diff --git a/source/blender/freestyle/intern/image/ImagePyramid.h b/source/blender/freestyle/intern/image/ImagePyramid.h index 9e326757f02..4bab663318e 100644 --- a/source/blender/freestyle/intern/image/ImagePyramid.h +++ b/source/blender/freestyle/intern/image/ImagePyramid.h @@ -1,92 +1,116 @@ -// -// Filename : ImagePyramid.h -// Author(s) : Stephane Grabli -// Purpose : Class to represent a pyramid of images -// Date of creation : 25/12/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef IMAGEPYRAMID_H -# define IMAGEPYRAMID_H +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __IMAGEPYRAMID_H__ +#define __IMAGEPYRAMID_H__ + +/** \file blender/freestyle/intern/image/ImagePyramid.h + * \ingroup freestyle + * \brief Class to represent a pyramid of images + * \author Stephane Grabli + * \date 25/12/2003 + */ -#include "../system/FreestyleConfig.h" #include <vector> +#include "../system/FreestyleConfig.h" + class GrayImage; -class LIB_IMAGE_EXPORT ImagePyramid{ + +class LIB_IMAGE_EXPORT ImagePyramid +{ protected: - std::vector<GrayImage*> _levels; - + std::vector<GrayImage*> _levels; + public: - ImagePyramid(){} - ImagePyramid(const ImagePyramid& iBrother); - //ImagePyramid(const GrayImage& level0, unsigned nbLevels); - virtual ~ImagePyramid(); - - /*! Builds the pyramid. - * must be overloaded by inherited classes. - * if nbLevels==0, the complete pyramid is built - */ - virtual void BuildPyramid(const GrayImage& level0, unsigned nbLevels) = 0; - - /*! Builds a pyramid without copying the base level */ - virtual void BuildPyramid(GrayImage* level0, unsigned nbLevels) = 0; - - virtual GrayImage * getLevel(int l); - /*! Returns the pixel x,y using bilinear interpolation. - * \param x - * the abscissa specified in the finest level coordinate system - * \param y - * the ordinate specified in the finest level coordinate system - * \param level - * the level from which we want the pixel to be evaluated - */ - virtual float pixel(int x, int y, int level=0); - /*! Returns the width of the level-th level image */ - virtual int width(int level=0); - /*! Returns the height of the level-th level image */ - virtual int height(int level=0); - /*! Returns the number of levels in the pyramid */ - inline int getNumberOfLevels() const { return _levels.size();} -}; + ImagePyramid(){} + ImagePyramid(const ImagePyramid& iBrother); + //ImagePyramid(const GrayImage& level0, unsigned nbLevels); + virtual ~ImagePyramid(); + + /*! Builds the pyramid. + * must be overloaded by inherited classes. + * if nbLevels==0, the complete pyramid is built + */ + virtual void BuildPyramid(const GrayImage& level0, unsigned nbLevels) = 0; + + /*! Builds a pyramid without copying the base level */ + virtual void BuildPyramid(GrayImage* level0, unsigned nbLevels) = 0; + + virtual GrayImage * getLevel(int l); + /*! Returns the pixel x,y using bilinear interpolation. + * \param x + * the abscissa specified in the finest level coordinate system + * \param y + * the ordinate specified in the finest level coordinate system + * \param level + * the level from which we want the pixel to be evaluated + */ + virtual float pixel(int x, int y, int level=0); + + /*! Returns the width of the level-th level image */ + virtual int width(int level=0); + + /*! Returns the height of the level-th level image */ + virtual int height(int level=0); + + /*! Returns the number of levels in the pyramid */ + inline int getNumberOfLevels() const + { + return _levels.size(); + } +}; class LIB_IMAGE_EXPORT GaussianPyramid : public ImagePyramid { protected: - float _sigma; + float _sigma; + public: - GaussianPyramid(float iSigma=1.f) : ImagePyramid() {_sigma=iSigma;} - GaussianPyramid(const GrayImage& level0, unsigned nbLevels, float iSigma=1.f); - GaussianPyramid(GrayImage* level0, unsigned nbLevels, float iSigma=1.f); - GaussianPyramid(const GaussianPyramid& iBrother); - virtual ~GaussianPyramid(){} - - virtual void BuildPyramid(const GrayImage& level0, unsigned nbLevels); - virtual void BuildPyramid(GrayImage* level0, unsigned nbLevels); - /* accessors */ - inline float getSigma() const {return _sigma;} - /* modifiers */ + GaussianPyramid(float iSigma=1.f) : ImagePyramid() + { + _sigma = iSigma; + } + + GaussianPyramid(const GrayImage& level0, unsigned nbLevels, float iSigma=1.0f); + GaussianPyramid(GrayImage* level0, unsigned nbLevels, float iSigma=1.0f); + GaussianPyramid(const GaussianPyramid& iBrother); + virtual ~GaussianPyramid() {} + + virtual void BuildPyramid(const GrayImage& level0, unsigned nbLevels); + virtual void BuildPyramid(GrayImage* level0, unsigned nbLevels); + /* accessors */ + inline float getSigma() const + { + return _sigma; + } + + /* modifiers */ }; -#endif // IMAGEPYRAMID_H + +#endif // __IMAGEPYRAMID_H__ |