DGtal  0.9.2
GradientColorMap.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file GradientColorMap.ih
19  * @author Sebastien Fourey (\c Sebastien.Fourey@greyc.ensicaen.fr )
20  * Groupe de Recherche en Informatique, Image, Automatique et Instrumentation de Caen - GREYC (CNRS, UMR 6072), ENSICAEN, France
21  *
22  * @date 2010/07/19
23  *
24  * Implementation of inline methods defined in GradientColorMap.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 //////////////////////////////////////////////////////////////////////////////
30 #include <cstdlib>
31 #include <vector>
32 //////////////////////////////////////////////////////////////////////////////
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // ----------------------- Standard services ------------------------------
40 
41 template < typename PValue,
42  int PDefaultPreset,
43  int PDefaultFirstColor,
44  int PDefaultLastColor >
45 inline
46 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::GradientColorMap
47 ( const PValue & minV,
48  const PValue & maxV,
49  const ColorGradientPreset preset,
50  const Color firstColor,
51  const Color lastColor )
52  : myMin( minV ), myMax( maxV )
53 {
54  ASSERT_MSG(myMin < myMax, "Max should be strictly greather than Min in a colormap.");
55  switch ( preset ) {
56  case CMAP_GRAYSCALE:
57  myColors.push_back( Color::Black );
58  myColors.push_back( Color::White );
59  break;
60  case CMAP_SPRING:
61  myColors.push_back( Color( 255, 0, 255 ));
62  myColors.push_back( Color( 255, 255, 0 ));
63  break;
64  case CMAP_SUMMER:
65  myColors.push_back( Color( 0, 132, 100 ));
66  myColors.push_back( Color( 255, 255, 100 ));
67  break;
68  case CMAP_AUTUMN:
69  myColors.push_back( Color( 255, 0, 0 ));
70  myColors.push_back( Color( 255, 255, 0));
71  break;
72  case CMAP_WINTER:
73  myColors.push_back( Color( 0, 0, 255 ));
74  myColors.push_back( Color( 0, 255, 132 ));
75  break;
76  case CMAP_COOL:
77  myColors.push_back( Color( 0, 255, 255 ));
78  myColors.push_back( Color( 255, 0, 255 ));
79  break;
80  case CMAP_COPPER:
81  myColors.push_back( Color( 0, 0, 0 ));
82  myColors.push_back( Color( 255, 198, 123 ));
83  break;
84  case CMAP_HOT:
85  myColors.push_back( Color::Black );
86  myColors.push_back( Color::Red );
87  myColors.push_back( Color( 255, 140, 0 ) );
88  myColors.push_back( Color::Yellow );
89  myColors.push_back( Color::White );
90  break;
91  case CMAP_JET:
92  myColors.push_back( Color::Blue );
93  myColors.push_back( Color::Cyan );
94  myColors.push_back( Color::Yellow );
95  myColors.push_back( Color( 255, 140, 0 ) );
96  myColors.push_back( Color::Red );
97  myColors.push_back( Color( 132, 0, 0 ) );
98  break;
99  case CMAP_CUSTOM:
100  if ( firstColor != Color::None
101  && lastColor != Color::None ) {
102  myColors.push_back( firstColor );
103  myColors.push_back( lastColor );
104  }
105  break;
106  }
107 }
108 
109 template <typename PValue,
110  int PDefaultPreset,
111  int PDefaultFirstColor,
112  int PDefaultLastColor >
113 inline
114 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::GradientColorMap
115 ( const GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> & other )
116  : myMin( other.myMin ), myMax( other.myMax ), myColors( other.myColors )
117 {
118  ASSERT_MSG(myMin < myMax, "Max should be strictly greather than Min in a colormap.");
119 }
120 
121 template <typename PValue,
122  int PDefaultPreset,
123  int PDefaultFirstColor,
124  int PDefaultLastColor >
125 inline
126 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::~GradientColorMap()
127 {
128 }
129 
130 template <typename PValue,
131  int PDefaultPreset,
132  int PDefaultFirstColor,
133  int PDefaultLastColor >
134 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> &
135 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::operator=
136 ( const DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> & other )
137 {
138  if ( &other != this ) {
139  myMin = other.myMin;
140  myMax = other.myMax;
141  ASSERT_MSG(myMin < myMax, "Max should be strictly greather than Min in a colormap.");
142  myColors = other.myColors;
143  }
144  return *this;
145 }
146 
147 ///////////////////////////////////////////////////////////////////////////////
148 // Interface - public :
149 
150 
151 template<typename PValue,
152  int PDefaultPreset,
153  int PDefaultFirstColor,
154  int PDefaultLastColor >
155 inline
156 void
157 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::addColor
158 ( const Color & color )
159 {
160  myColors.push_back( color );
161 }
162 
163 template<typename PValue,
164  int PDefaultPreset,
165  int PDefaultFirstColor,
166  int PDefaultLastColor >
167 inline
168 void
169 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::clearColors()
170 {
171  myColors.clear();
172 }
173 
174 template<typename PValue,
175  int PDefaultPreset,
176  int PDefaultFirstColor,
177  int PDefaultLastColor >
178 inline
179 const PValue &
180 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::min() const
181 {
182  return myMin;
183 }
184 
185 template<typename PValue,
186  int PDefaultPreset,
187  int PDefaultFirstColor,
188  int PDefaultLastColor >
189 inline
190 const PValue &
191 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::max() const
192 {
193  return myMax;
194 }
195 
196 template<typename PValue,
197  int PDefaultPreset,
198  int PDefaultFirstColor,
199  int PDefaultLastColor >
200 inline
201 DGtal::Color
202 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::operator()
203  ( const Value & value ) const
204 {
205  return GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::getColor( myColors,
206  myMin,
207  myMax,
208  value );
209 }
210 
211 /**
212  * Writes/Displays the object on an output stream.
213  * @param out the output stream where the object is written.
214  */
215 template <typename PValue,
216  int PDefaultPreset,
217  int PDefaultFirstColor,
218  int PDefaultLastColor >
219 inline
220 void
221 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::selfDisplay
222 ( std::ostream & out ) const
223 {
224  out << "[GradientColorMap "
225  << " min=" << myMin
226  << " max=" << myMax;
227  std::vector<Color>::iterator it = myColors.begin();
228  while ( it != myColors.end() ) {
229  out << " RGB("
230  << it->red() << ","
231  << it->green() << ","
232  << it->blue() << ") ";
233  ++it;
234  }
235  out << " ]";
236 }
237 
238 /**
239  * Checks the validity/consistency of the object.
240  * @return 'true' if the object is valid, 'false' otherwise.
241  */
242 template <typename PValue,
243  int PDefaultPreset,
244  int PDefaultFirstColor,
245  int PDefaultLastColor >
246 inline
247 bool
248 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::isValid() const
249 {
250  return true;
251 }
252 
253 template <typename PValue,
254  int PDefaultPreset,
255  int PDefaultFirstColor,
256  int PDefaultLastColor >
257 inline
258 DGtal::Color
259 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::getColor
260 ( const std::vector<Color> & colors,
261  const Value & min,
262  const Value & max,
263  const Value & value )
264 {
265  ASSERT_MSG(min < max, "Max should be strictly greather than Min in a colormap.");
266  if ( colors.size() < 2 )
267  return DGtal::Color::None;
268  double scale = static_cast<double>( value - min ) / (max - min);
269  const int intervals = (const int)colors.size() - 1;
270  int upper_index = static_cast<int>( ceil( intervals * scale ) );
271  if ( !upper_index ) // Special case when value == min.
272  upper_index = 1;
273  const Color & firstColor = colors[ upper_index - 1 ];
274  const Color & lastColor = colors[ upper_index ];
275  scale = ( scale * intervals ) - (upper_index - 1);
276 
277  const unsigned char red = static_cast<unsigned char>( firstColor.red() +
278  scale * ( lastColor.red() -
279  firstColor.red() ));
280  const unsigned char green = static_cast<unsigned char>( firstColor.green() +
281  scale * ( lastColor.green() -
282  firstColor.green() ));
283  const unsigned char blue = static_cast<unsigned char>( firstColor.blue() +
284  scale * ( lastColor.blue() -
285  firstColor.blue() ));
286  return DGtal::Color( red, green, blue );
287 }
288 
289 ///////////////////////////////////////////////////////////////////////////////
290 // Implementation of inline functions //
291 
292 template <typename PValue,
293  int PDefaultPreset,
294  int PDefaultFirstColor,
295  int PDefaultLastColor >
296 inline
297 std::ostream&
298 DGtal::operator<< ( std::ostream & out,
299  const GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> & object )
300 {
301  object.selfDisplay( out );
302  return out;
303 }
304 
305 // //
306 ///////////////////////////////////////////////////////////////////////////////
307 
308 
309 ///////////////////////////////////////////////////////////////////////////////
310 // Interface - private :