soc-2008-mxcurioni: resolved uint issues (replaced with unsigned int). Still NOT...
[blender.git] / source / blender / freestyle / intern / image / ImagePyramid.cpp
1
2 //
3 //  Copyright (C) : Please refer to the COPYRIGHT file distributed 
4 //   with this source distribution. 
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 //
20 ///////////////////////////////////////////////////////////////////////////////
21 #include "ImagePyramid.h"
22 #include "Image.h"
23 #include "GaussianFilter.h"
24 #include <iostream>
25
26 using namespace std;
27
28 //ImagePyramid::ImagePyramid(const GrayImage& level0, unsigned nbLevels){
29 //  //BuildPyramid(level0,nbLevels);
30 //}
31
32 ImagePyramid::ImagePyramid(const ImagePyramid& iBrother){
33   if(!_levels.empty()){
34     for(vector<GrayImage*>::iterator im=_levels.begin(), imend=_levels.end();
35     im!=imend;
36     ++im){
37       _levels.push_back(new GrayImage(**im)); 
38     }
39   }
40 }
41 ImagePyramid::~ImagePyramid(){
42   if(!_levels.empty()){
43     for(vector<GrayImage*>::iterator im=_levels.begin(), imend=_levels.end();
44     im!=imend;
45     ++im){
46       delete (*im);
47     }
48     _levels.clear();
49   }
50 }
51
52 GrayImage * ImagePyramid::getLevel(int l){
53   return _levels[l];
54 }
55
56 float ImagePyramid::pixel(int x, int y, int level){
57   GrayImage *img = _levels[level];
58   if(0 == level){
59     return img->pixel(x,y);
60   }
61   unsigned int i  = 1<<level;
62   unsigned int sx = x>>level;
63   unsigned int sy = y>>level;
64   if(sx >= img->width())
65     sx = img->width()-1;
66   if(sy >= img->height())
67     sy = img->height()-1;
68   
69   // bilinear interpolation
70   float A = i*(sx+1)-x;
71   float B = x-i*sx;
72   float C = i*(sy+1)-y;
73   float D = y-i*sy;
74
75   float P1(0), P2(0);
76   P1 = A*img->pixel(sx,sy);
77   if(sx < img->width()-1){
78     if(x%i != 0)
79       P1 +=  B*img->pixel(sx+1,sy);
80   }else{
81     P1 +=  B*img->pixel(sx,sy);
82   }
83   if(sy<img->height()-1){
84     if(y%i != 0){
85       P2 = A*img->pixel(sx,sy+1);
86       if(sx < img->width()-1){
87         if(x%i != 0)
88           P2 += B*img->pixel(sx+1,sy+1);
89       }else{
90         P2 += B*img->pixel(sx,sy+1);
91       }
92     }
93   }else{
94     P2 = P1;
95   }
96   return (1.f/(float)(1<<2*level))*(C*P1 + D*P2);
97 }
98
99 int ImagePyramid::width(int level){
100   return _levels[level]->width();
101 }
102
103 int ImagePyramid::height(int level){
104   return _levels[level]->height();
105 }
106
107 GaussianPyramid::GaussianPyramid(const GrayImage& level0, unsigned nbLevels, float iSigma)
108     : ImagePyramid()
109 {
110   _sigma = iSigma;
111   BuildPyramid(level0,nbLevels);
112
113 GaussianPyramid::GaussianPyramid(GrayImage* level0, unsigned nbLevels, float iSigma)
114     : ImagePyramid()
115 {
116   _sigma = iSigma;
117   BuildPyramid(level0,nbLevels);
118 }
119
120 GaussianPyramid::GaussianPyramid(const GaussianPyramid& iBrother)
121 : ImagePyramid(iBrother){
122   _sigma = iBrother._sigma;
123 }
124 void GaussianPyramid::BuildPyramid(const GrayImage& level0, unsigned nbLevels){
125   GrayImage *pLevel = new GrayImage(level0);
126   BuildPyramid(pLevel, nbLevels);
127 }
128
129 void GaussianPyramid::BuildPyramid(GrayImage* level0, unsigned nbLevels){
130   GrayImage *pLevel = level0;
131   _levels.push_back(pLevel);
132   GaussianFilter gf(_sigma);
133   // build the nbLevels:
134   unsigned w = pLevel->width();
135   unsigned h = pLevel->height();
136   if(nbLevels!=0)
137   {
138     for(unsigned i=0; i<nbLevels; ++i){ //soc
139       w = pLevel->width()>>1;
140       h = pLevel->height()>>1;
141       GrayImage *img = new GrayImage(w,h);
142       for(unsigned y=0; y<h; ++y){
143         for(unsigned x=0; x<w; ++x){
144           float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2*x,2*y);
145           img->setPixel(x,y,v);
146         } 
147       } 
148       _levels.push_back(img);
149       pLevel = img;
150     }
151   }else{
152     while((w>1) && (h>1)){
153       w = pLevel->width()>>1;
154       h = pLevel->height()>>1;
155       GrayImage *img = new GrayImage(w,h);
156       for(unsigned y=0; y<h; ++y){
157         for(unsigned x=0; x<w; ++x){
158           float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2*x,2*y);
159           img->setPixel(x,y,v);
160         } 
161       } 
162       _levels.push_back(img);
163       pLevel = img;
164     } 
165   }
166 }