DGtal  1.5.beta
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 <cmath>
32 #include <vector>
33 //////////////////////////////////////////////////////////////////////////////
34 
35 ///////////////////////////////////////////////////////////////////////////////
36 // IMPLEMENTATION of inline methods.
37 ///////////////////////////////////////////////////////////////////////////////
38 
39 ///////////////////////////////////////////////////////////////////////////////
40 // ----------------------- Standard services ------------------------------
41 
42 template < typename PValue,
43  int PDefaultPreset,
44  int PDefaultFirstColor,
45  int PDefaultLastColor >
46 inline
47 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::GradientColorMap
48 ( const PValue & minV,
49  const PValue & maxV,
50  const ColorGradientPreset preset,
51  const Color firstColor,
52  const Color lastColor )
53  : myMin( minV ), myMax( maxV )
54 {
55  ASSERT_MSG(myMin < myMax, "Max should be strictly greather than Min in a colormap.");
56  switch ( preset ) {
57  case CMAP_GRAYSCALE:
58  myColors.push_back( Color::Black );
59  myColors.push_back( Color::White );
60  break;
61  case CMAP_SPRING:
62  myColors.push_back( Color( 255, 0, 255 ));
63  myColors.push_back( Color( 255, 255, 0 ));
64  break;
65  case CMAP_SUMMER:
66  myColors.push_back( Color( 0, 132, 100 ));
67  myColors.push_back( Color( 255, 255, 100 ));
68  break;
69  case CMAP_AUTUMN:
70  myColors.push_back( Color( 255, 0, 0 ));
71  myColors.push_back( Color( 255, 255, 0));
72  break;
73  case CMAP_WINTER:
74  myColors.push_back( Color( 0, 0, 255 ));
75  myColors.push_back( Color( 0, 255, 132 ));
76  break;
77  case CMAP_COOL:
78  myColors.push_back( Color( 0, 255, 255 ));
79  myColors.push_back( Color( 255, 0, 255 ));
80  break;
81  case CMAP_COPPER:
82  myColors.push_back( Color( 0, 0, 0 ));
83  myColors.push_back( Color( 255, 198, 123 ));
84  break;
85  case CMAP_HOT:
86  myColors.push_back( Color::Black );
87  myColors.push_back( Color::Red );
88  myColors.push_back( Color( 255, 140, 0 ) );
89  myColors.push_back( Color::Yellow );
90  myColors.push_back( Color::White );
91  break;
92  case CMAP_JET:
93  myColors.push_back( Color::Blue );
94  myColors.push_back( Color::Cyan );
95  myColors.push_back( Color::Yellow );
96  myColors.push_back( Color( 255, 140, 0 ) );
97  myColors.push_back( Color::Red );
98  myColors.push_back( Color( 132, 0, 0 ) );
99  break;
100  case CMAP_VIRIDIS:
101  myColors.push_back( Color(63,17,81) );
102  myColors.push_back( Color(63,110,139) );
103  myColors.push_back( Color( 40, 175, 127 ));
104  myColors.push_back( Color( 184, 222, 41 ));
105  myColors.push_back( Color( 253, 232, 37 ));
106 
107  break;
108  case CMAP_CUSTOM:
109  if ( firstColor != Color::None
110  && lastColor != Color::None ) {
111  myColors.push_back( firstColor );
112  myColors.push_back( lastColor );
113  }
114  break;
115  }
116 }
117 
118 template <typename PValue,
119  int PDefaultPreset,
120  int PDefaultFirstColor,
121  int PDefaultLastColor >
122 inline
123 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::GradientColorMap
124 ( const GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> & other )
125  : myMin( other.myMin ), myMax( other.myMax ), myColors( other.myColors )
126 {
127  ASSERT_MSG(myMin < myMax, "Max should be strictly greather than Min in a colormap.");
128 }
129 
130 template <typename PValue,
131  int PDefaultPreset,
132  int PDefaultFirstColor,
133  int PDefaultLastColor >
134 inline
135 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::~GradientColorMap()
136 {
137 }
138 
139 template <typename PValue,
140  int PDefaultPreset,
141  int PDefaultFirstColor,
142  int PDefaultLastColor >
143 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> &
144 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::operator=
145 ( const DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> & other )
146 {
147  if ( &other != this ) {
148  myMin = other.myMin;
149  myMax = other.myMax;
150  ASSERT_MSG(myMin < myMax, "Max should be strictly greather than Min in a colormap.");
151  myColors = other.myColors;
152  }
153  return *this;
154 }
155 
156 ///////////////////////////////////////////////////////////////////////////////
157 // Interface - public :
158 
159 
160 template<typename PValue,
161  int PDefaultPreset,
162  int PDefaultFirstColor,
163  int PDefaultLastColor >
164 inline
165 void
166 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::addColor
167 ( const Color & color )
168 {
169  myColors.push_back( color );
170 }
171 
172 template<typename PValue,
173  int PDefaultPreset,
174  int PDefaultFirstColor,
175  int PDefaultLastColor >
176 inline
177 void
178 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::clearColors()
179 {
180  myColors.clear();
181 }
182 
183 template<typename PValue,
184  int PDefaultPreset,
185  int PDefaultFirstColor,
186  int PDefaultLastColor >
187 inline
188 const PValue &
189 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::min() const
190 {
191  return myMin;
192 }
193 
194 template<typename PValue,
195  int PDefaultPreset,
196  int PDefaultFirstColor,
197  int PDefaultLastColor >
198 inline
199 const PValue &
200 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::max() const
201 {
202  return myMax;
203 }
204 
205 template<typename PValue,
206  int PDefaultPreset,
207  int PDefaultFirstColor,
208  int PDefaultLastColor >
209 inline
210 DGtal::Color
211 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::operator()
212  ( const Value & value ) const
213 {
214  return GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::getColor( myColors,
215  myMin,
216  myMax,
217  value );
218 }
219 
220 /**
221  * Writes/Displays the object on an output stream.
222  * @param out the output stream where the object is written.
223  */
224 template <typename PValue,
225  int PDefaultPreset,
226  int PDefaultFirstColor,
227  int PDefaultLastColor >
228 inline
229 void
230 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::selfDisplay
231 ( std::ostream & out ) const
232 {
233  out << "[GradientColorMap "
234  << " min=" << myMin
235  << " max=" << myMax;
236  std::vector<Color>::const_iterator it = myColors.begin();
237  while ( it != myColors.end() ) {
238  out << " RGB("
239  << it->red() << ","
240  << it->green() << ","
241  << it->blue() << ") ";
242  ++it;
243  }
244  out << " ]";
245 }
246 
247 /**
248  * Checks the validity/consistency of the object.
249  * @return 'true' if the object is valid, 'false' otherwise.
250  */
251 template <typename PValue,
252  int PDefaultPreset,
253  int PDefaultFirstColor,
254  int PDefaultLastColor >
255 inline
256 bool
257 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::isValid() const
258 {
259  return true;
260 }
261 
262 template <typename PValue,
263  int PDefaultPreset,
264  int PDefaultFirstColor,
265  int PDefaultLastColor >
266 inline
267 DGtal::Color
268 DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::getColor
269 ( const std::vector<Color> & colors,
270  const Value & min,
271  const Value & max,
272  Value value )
273 {
274  ASSERT_MSG(min < max, "Max should be strictly greather than Min in a colormap.");
275  if ( colors.size() < 2 )
276  return DGtal::Color::None;
277  if ( std::is_floating_point<PValue>::value
278  && ! ( std::isfinite( value ) || std::isinf( value ) ) )
279  return DGtal::Color::Black;
280  if ( value < min ) value = min;
281  if ( max < value ) value = max;
282  double scale = static_cast<double>( value - min ) / (max - min);
283  const int intervals = (const int)colors.size() - 1;
284  int upper_index = static_cast<int>( ceil( intervals * scale ) );
285  if ( !upper_index ) // Special case when value == min.
286  upper_index = 1;
287  const Color & firstColor = colors[ upper_index - 1 ];
288  const Color & lastColor = colors[ upper_index ];
289  scale = ( scale * intervals ) - (upper_index - 1);
290 
291  const unsigned char red = static_cast<unsigned char>( firstColor.red() +
292  scale * ( lastColor.red() -
293  firstColor.red() ));
294  const unsigned char green = static_cast<unsigned char>( firstColor.green() +
295  scale * ( lastColor.green() -
296  firstColor.green() ));
297  const unsigned char blue = static_cast<unsigned char>( firstColor.blue() +
298  scale * ( lastColor.blue() -
299  firstColor.blue() ));
300  return DGtal::Color( red, green, blue );
301 }
302 
303 ///////////////////////////////////////////////////////////////////////////////
304 // Implementation of inline functions //
305 
306 template <typename PValue,
307  int PDefaultPreset,
308  int PDefaultFirstColor,
309  int PDefaultLastColor >
310 inline
311 std::ostream&
312 DGtal::operator<< ( std::ostream & out,
313  const GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> & object )
314 {
315  object.selfDisplay( out );
316  return out;
317 }
318 
319 // //
320 ///////////////////////////////////////////////////////////////////////////////
321 
322 
323 ///////////////////////////////////////////////////////////////////////////////
324 // Interface - private :