Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Curioni <maxime.curioni@gmail.com>2008-05-08 23:16:40 +0400
committerMaxime Curioni <maxime.curioni@gmail.com>2008-05-08 23:16:40 +0400
commit64e4a3ec9aed6c8abe095e2cd1fe1552f7cde51c (patch)
tree6c77358bd447b6c2d215324ef48fc12d1f5ae5ca /source/blender/freestyle/intern/image
parentcf2e1e2857cfc5b3c2848c7fc6c9d919ac72fabb (diff)
parent106974a9d2d5caa5188322507980e3d57d2e3517 (diff)
soc-2008-mxcurioni: merged changes to revision 14747, cosmetic changes for source/blender/freestyle
Diffstat (limited to 'source/blender/freestyle/intern/image')
-rwxr-xr-xsource/blender/freestyle/intern/image/GaussianFilter.cpp96
-rwxr-xr-xsource/blender/freestyle/intern/image/GaussianFilter.h144
-rwxr-xr-xsource/blender/freestyle/intern/image/Image.h389
-rwxr-xr-xsource/blender/freestyle/intern/image/ImagePyramid.cpp166
-rwxr-xr-xsource/blender/freestyle/intern/image/ImagePyramid.h92
-rwxr-xr-xsource/blender/freestyle/intern/image/image.pro66
-rwxr-xr-xsource/blender/freestyle/intern/image/src.pri13
7 files changed, 966 insertions, 0 deletions
diff --git a/source/blender/freestyle/intern/image/GaussianFilter.cpp b/source/blender/freestyle/intern/image/GaussianFilter.cpp
new file mode 100755
index 00000000000..97c2aedc62e
--- /dev/null
+++ b/source/blender/freestyle/intern/image/GaussianFilter.cpp
@@ -0,0 +1,96 @@
+
+//
+// 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 "GaussianFilter.h"
+#include <stdlib.h>
+
+GaussianFilter::GaussianFilter(float iSigma )
+{
+ _sigma = iSigma;
+ _mask = 0;
+ computeMask();
+}
+
+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));
+}
+
+
+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;
+}
+
+
+GaussianFilter::~GaussianFilter()
+{
+ if(0!=_mask)
+ {
+ delete [] _mask;
+ }
+}
+
+int GaussianFilter::computeMaskSize(float sigma)
+{
+ int maskSize = (int)floor(4*sigma)+1;
+ if(0 == maskSize%2)
+ ++maskSize;
+
+ return maskSize;
+}
+
+void GaussianFilter::SetSigma(float sigma)
+{
+ _sigma = sigma;
+ computeMask();
+}
+
+void GaussianFilter::computeMask()
+{
+ if(0 != _mask){
+ delete [] _mask;
+ }
+
+ _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));
+}
+
diff --git a/source/blender/freestyle/intern/image/GaussianFilter.h b/source/blender/freestyle/intern/image/GaussianFilter.h
new file mode 100755
index 00000000000..c75177541d3
--- /dev/null
+++ b/source/blender/freestyle/intern/image/GaussianFilter.h
@@ -0,0 +1,144 @@
+//
+// 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
+
+#include "../system/FreestyleConfig.h"
+
+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)
+
+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;}
+
+
+protected:
+ void computeMask();
+};
+
+/*
+
+ #############################################
+ #############################################
+ #############################################
+ ###### ######
+ ###### I M P L E M E N T A T I O N ######
+ ###### ######
+ #############################################
+ #############################################
+ #############################################
+
+*/
+
+
+#include <math.h>
+
+#ifdef __MACH__
+#define sqrtf(x) (sqrt(x))
+#endif
+
+template<class Map>
+float GaussianFilter::getSmoothedPixel(Map * map, int x, int y)
+{
+ float sum = 0.f;
+ float L=0.f;
+ unsigned w=map->width();
+ unsigned h=map->height();
+
+ // 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
diff --git a/source/blender/freestyle/intern/image/Image.h b/source/blender/freestyle/intern/image/Image.h
new file mode 100755
index 00000000000..83d6785e32f
--- /dev/null
+++ b/source/blender/freestyle/intern/image/Image.h
@@ -0,0 +1,389 @@
+//
+// 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
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+//
+// 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
+
+# include <string> // 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.
+ */
+class Image
+{
+ public:
+
+ /*! Default constructor */
+ Image() {
+ _storedWidth = 0;
+ _storedHeight = 0;
+ _width = 0;
+ _height = 0;
+ _Ox = 0;
+ _Oy = 0;
+ }
+
+ /*! Copy constructor */
+ Image(const Image& brother) {
+ _storedWidth = brother._storedWidth;
+ _storedHeight = brother._storedHeight;
+ _width = brother._width;
+ _height = brother._height;
+ _Ox = brother._Ox;
+ _Oy = brother._Oy;
+ }
+
+ /*! Builds an image from its width and height.
+ * The memory is allocated consequently.
+ */
+ Image(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.
+ */
+ Image(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= */
+ Image& operator=(const Image& brother) {
+ _width = brother._width;
+ _height = brother._height;
+ _storedWidth = brother._storedWidth;
+ _storedHeight = brother._storedHeight;
+ _Ox = brother._Ox;
+ _Oy = brother._Oy;
+ return* this;
+ }
+
+ /*! Destructor */
+ virtual ~Image() {}
+
+ /*! 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
+};
+
+
+//
+// RGBImage
+//
+///////////////////////////////////////////////////////////////////////////////
+
+class RGBImage : public Image
+{
+ public:
+
+ RGBImage() : Image() {
+ _rgb = 0;
+ }
+
+ RGBImage(const RGBImage& brother) : Image(brother) {
+ _rgb = new float[3 * _storedWidth * _storedHeight];
+ memcpy(_rgb, brother._rgb, 3 * _storedWidth * _storedHeight * sizeof(float));
+ }
+
+ RGBImage(unsigned w, unsigned h) : Image(w, h) {
+ _rgb = new float[3 * _width * _height];
+ }
+
+ RGBImage(float* rgb, unsigned w, unsigned h) : Image(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) : Image(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<Image&>(*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;
+};
+
+
+//
+// GrayImage
+//
+///////////////////////////////////////////////////////////////////////////////
+
+class GrayImage : public Image
+{
+ public:
+
+ GrayImage() : Image() {
+ _lvl = 0;
+ }
+
+ GrayImage(const GrayImage& brother) : Image(brother) {
+ _lvl = new float[_storedWidth*_storedHeight];
+ memcpy(_lvl, brother._lvl, _storedWidth*_storedHeight*sizeof(*_lvl));
+ }
+
+ /*! Builds an empty gray image */
+ GrayImage(unsigned w, unsigned h) : Image(w, h) {
+ _lvl = new float[_width*_height];
+ }
+
+ GrayImage(float* lvl, unsigned w, unsigned h) : Image(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) : Image(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<Image&>(*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
diff --git a/source/blender/freestyle/intern/image/ImagePyramid.cpp b/source/blender/freestyle/intern/image/ImagePyramid.cpp
new file mode 100755
index 00000000000..45c02004d1c
--- /dev/null
+++ b/source/blender/freestyle/intern/image/ImagePyramid.cpp
@@ -0,0 +1,166 @@
+
+//
+// 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>
+
+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));
+ }
+ }
+}
+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];
+}
+
+float ImagePyramid::pixel(int x, int y, int level){
+ GrayImage *img = _levels[level];
+ if(0 == level){
+ return img->pixel(x,y);
+ }
+ int i = 1<<level;
+ int sx = x>>level;
+ 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);
+}
+
+int ImagePyramid::width(int level){
+ return _levels[level]->width();
+}
+
+int ImagePyramid::height(int level){
+ return _levels[level]->height();
+}
+
+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(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(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){
+ 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;
+ }
+ }
+}
diff --git a/source/blender/freestyle/intern/image/ImagePyramid.h b/source/blender/freestyle/intern/image/ImagePyramid.h
new file mode 100755
index 00000000000..9e326757f02
--- /dev/null
+++ b/source/blender/freestyle/intern/image/ImagePyramid.h
@@ -0,0 +1,92 @@
+//
+// 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
+
+#include "../system/FreestyleConfig.h"
+#include <vector>
+
+class GrayImage;
+class LIB_IMAGE_EXPORT ImagePyramid{
+protected:
+ 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();}
+};
+
+class LIB_IMAGE_EXPORT GaussianPyramid : public ImagePyramid
+{
+protected:
+ 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 */
+
+};
+#endif // IMAGEPYRAMID_H
diff --git a/source/blender/freestyle/intern/image/image.pro b/source/blender/freestyle/intern/image/image.pro
new file mode 100755
index 00000000000..133b6cf4f35
--- /dev/null
+++ b/source/blender/freestyle/intern/image/image.pro
@@ -0,0 +1,66 @@
+# This file should be viewed as a -*- mode: Makefile -*-
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# W A R N I N G ! ! ! #
+# a u t h o r i z e d p e r s o n a l o n l y #
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+include(../Config.pri)
+
+TEMPLATE = lib
+
+TARGET = $${LIB_IMAGE}
+VERSION = $${APPVERSION}
+TARGET_VERSION_EXT = $${APPVERSION_MAJ}.$${APPVERSION_MID}
+
+#
+# CONFIG
+#
+#######################################
+
+CONFIG *= dll
+
+#
+# DEFINES
+#
+#######################################
+
+win32:DEFINES *= MAKE_LIB_IMAGE_DLL
+
+#
+# INCLUDE PATH
+#
+#######################################
+
+#INCLUDEPATH *= ../system
+
+#
+# BUILD DIRECTORIES
+#
+#######################################
+
+BUILD_DIR = ../../build
+
+OBJECTS_DIR = $${BUILD_DIR}/$${REL_OBJECTS_DIR}
+!win32:DESTDIR = $${BUILD_DIR}/$${REL_DESTDIR}/lib
+win32:DESTDIR = $${BUILD_DIR}/$${REL_DESTDIR}
+
+#
+# INSTALL
+#
+#######################################
+
+LIB_DIR = ../../lib
+# install library
+target.path = $$LIB_DIR
+# "make install" configuration options
+INSTALLS += target
+
+#
+# SOURCES & HEADERS
+#
+#######################################
+
+!static {
+ include(src.pri)
+}
diff --git a/source/blender/freestyle/intern/image/src.pri b/source/blender/freestyle/intern/image/src.pri
new file mode 100755
index 00000000000..c047929b49f
--- /dev/null
+++ b/source/blender/freestyle/intern/image/src.pri
@@ -0,0 +1,13 @@
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# W A R N I N G ! ! ! #
+# a u t h o r i z e d p e r s o n a l o n l y #
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+IMAGE_DIR = ../image
+
+SOURCES *= $${IMAGE_DIR}/GaussianFilter.cpp \
+ $${IMAGE_DIR}/ImagePyramid.cpp
+
+HEADERS *= $${IMAGE_DIR}/Image.h \
+ $${IMAGE_DIR}/GaussianFilter.h \
+ $${IMAGE_DIR}/ImagePyramid.h