ImageConf.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25  */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30  */
31 #ifndef IMAGE_CONF_H_
32 #define IMAGE_CONF_H_ "ImageConf 2, 2021/03 Markus.Peura@fmi.fi"
33 
34 #include <drain/image/CoordinatePolicy.h>
35 #include <stddef.h> // size_t
36 
37 #include <drain/Caster.h>
38 #include "drain/util/ValueScaling.h"
39 
40 #include "Geometry.h"
41 
42 namespace drain
43 {
44 
46 namespace image
47 {
48 
49 
50 
51 class Encoding : public drain::ValueScaling { //{ //public drain::Caster,
52 
53 public:
54 
55  inline
56  Encoding(const std::type_info & t = typeid(unsigned char)){ // : scalingPtr(this) {
57  setType(t);
58  }
59 
60  inline
61  Encoding(const Encoding & encoding){ // : scalingPtr(this) {
62  setEncoding(encoding);
63  //setType(encoding.caster.getType());
64  }
65 
67  inline
68  const Encoding & getEncoding() const {
69  // NOTE: scaling will not be local (scalingPtr)
70  return *this;
71  }
72 
74  inline
76  // NOTE: scaling will not be local (scalingPtr)
77  return *this;
78  }
79 
80 
82  inline
83  void setEncoding(const Encoding & e){
84  setType(e.getType());
85  setScaling(e);
87  }
88 
89  Encoding & operator=(const Encoding & e){
90  if (&e != this){
91  setEncoding(e);
92  }
93  return *this;
94  }
95 
98 
99  // Size of the storage type (1 for 8 bits, 2 for 16 bits, etc.)
100  size_t byteSize;
101 
103  std::string type; // synch?
104 
106  // drain::ValueScaling & scaling;
107 
109  inline
110  const std::type_info & getType() const {
111  return caster.getType();
112  }
113 
115  inline
116  bool typeIsSet() const {
117  return caster.typeIsSet();
118  }
119 
121  void setType(const std::type_info & t){
122 
123  if (t == typeid(bool)){
124  //mout.warn("storage type 'bool' not supported, using 'unsigned char'" );
125  setType(typeid(unsigned char)); // re-invoke
126  }
127  else if (t == typeid(std::string)){
128  //mout.error("storage type 'std::string' not applicable to images" );
129  //setType(typeid(unsigned char));
130  throw std::runtime_error("storage type 'std::string' not applicable to images");
131  return;
132  }
133 
134  caster.setType(t);
135  byteSize = caster.getElementSize();
136  type.resize(1);
137  type.at(0) = drain::Type::getTypeChar(caster.getType());
138 
139  }
140 
142  template <class T>
143  inline
144  void setType(){
145  setType(typeid(T));
146  }
147 
148 
149  template <class T>
150  inline
151  typename drain::typeLimiter<T>::value_t getLimiter() const {
152  return drain::Type::call<drain::typeLimiter<T> >(caster.getType());
153  }
154 
155 
156 
158  inline
159  size_t getElementSize() const {
160  return byteSize;
161  };
162 
163 
164 
166  /*
167  inline
168  void useOwnScaling() {
169  if (scalingPtr != this){
170  scalingPtr = this;
171  }
172  }
173 
175  inline
176  bool hasOwnScaling() const {
177  return scalingPtr == this; //& conf.getScaling();
178  }
179  */
180 
181  /*
182  virtual inline
183  const drain::ValueScaling & getScaling() const {
184  return *this;
185  //return *scalingPtr;
186  }
187  */
188 
190 
195  /*
196  virtual inline
197  drain::ValueScaling & getScaling(){
198  //useOwnScaling();
199  return *this; // return *scalingPtr; // conf; // *scalingPtr; //
200  }
201 
202  virtual inline
203  void setScaling(const drain::ValueScaling & scaling){
204  //useOwnScaling();
205  ValueScaling::assign(scaling);
206  }
207  */
208 
210  /*
211  virtual inline
212  void setScaling(double scale, double offset){
213  //useOwnScaling();
214  ValueScaling::set(scale, offset); // virtual IMPORTANT for channels/view
215  }
216  */
217 
218  /*
219  virtual inline
220  void linkScaling(const drain::ValueScaling & scaling){
221  scalingPtr = &scaling;
222  }
223  */
224 
225 
226 
227 
228  inline
229  void setPhysicalRange(const Range<double> &range, bool rescale=false){ // , const std::string &unit ?
230  //conf.physRange.assign(range);
231  getScaling().setPhysicalRange(range);
232  if (rescale)
233  setOptimalScale();
234  }
235 
237  inline
238  void setPhysicalRange(double min, double max, bool rescale=false){ // , const std::string &unit ?
239  //conf.physRange.set(min,max);
240  getScaling().setPhysicalRange(min,max);
241  if (rescale)
242  setOptimalScale();
243  }
244 
245 
246  inline
247  void setOptimalScale(){
249  }
250 
251  inline
252  void setOptimalPhysicalScale(double min, double max){ // , const std::string &unit ?
253  setPhysicalRange(min, max, true);
254  }
255 
256 
258 
265  template <class T>
266  inline
267  T getTypeMin() const {
268  return Type::call<typeMin, T>(caster.getType());
269  }
270 
272 
279  template <class T>
280  inline
281  T getTypeMax() const {
282  return Type::call<typeMax, T>(caster.getType());
283  }
284 
285 
286 
287 
289 
292  inline
293  double requestPhysicalMax(double defaultMax = static_cast<double>(std::numeric_limits<short int>::max())) const {
294  const ValueScaling & scaling = getScaling();
295  if (scaling.isPhysical())
296  return scaling.getMaxPhys();
297  else {
298  const std::type_info & t = getType();
299  if (Type::call<drain::typeIsSmallInt>(t))
300  return scaling.fwd(Type::call<typeMax, double>(t));
301  else
302  return defaultMax;
303  }
304  }
305 
307 
310  // ( Used at least by optical flow.)
311  inline
312  double requestPhysicalMin(double defaultMin = static_cast<double>(std::numeric_limits<short int>::min())) const {
313  const ValueScaling & scaling = getScaling();
314  if (scaling.isPhysical())
315  return scaling.getMinPhys();
316  else {
317  const std::type_info & t = getType();
318  if (Type::call<drain::typeIsSmallInt>(t))
319  return scaling.fwd(Type::call<typeMin, double>(t));
320  else
321  return defaultMin;
322  }
323  }
324 
325 private:
326 
327  //drain::ValueScaling const * scalingPtr;
328 
329 };
330 
331 
333 class ImageConf : public Encoding, public Geometry {
334 
335 public:
336 
337 
338  inline
339  ImageConf(const drain::Type & t=typeid(unsigned char), size_t width=0, size_t height=0, size_t imageChannels=1, size_t alphaChannels=0) :
340  Encoding(t),
341  Geometry(width,height ? height : width, imageChannels, alphaChannels)
342  {
343  }
344 
345 
346  inline
347  ImageConf(const ImageConf & conf) : Encoding(conf), Geometry(conf), coordinatePolicy(conf.getCoordinatePolicy()) {
348  }
349 
350 
351  inline
352  void setConf(const ImageConf & conf){
353  setEncoding(conf);
354  setGeometry(conf.getGeometry());
355  setCoordinatePolicy(conf.getCoordinatePolicy());
356  }
357 
358 
359  ImageConf & operator=(const ImageConf & conf){
360  setConf(conf);
361  return *this;
362  }
363 
364 
366  template <class T>
367  inline
368  void setCoordinatePolicy(const T & policy){
369  coordinatePolicy.set(policy);
370  }
371 
372  inline
373  void setCoordinatePolicy(EdgePolicy::index_t xUnderFlowPolicy, EdgePolicy::index_t yUnderFlowPolicy, EdgePolicy::index_t xOverFlowPolicy, EdgePolicy::index_t yOverFlowPolicy){
374  coordinatePolicy.set(xUnderFlowPolicy, yUnderFlowPolicy, xOverFlowPolicy, yOverFlowPolicy);
375  }
376 
377  inline
378  const CoordinatePolicy & getCoordinatePolicy() const {
379  return coordinatePolicy;
380  }
381 
384 
385 
386 
387 };
388 
389 
390 
391 inline
392 std::ostream & operator<<(std::ostream &ostr, const ImageConf & conf){
393 
394  //ostr << ' ';
395  if (conf.getChannelCount() > 1)
396  ostr << conf.getGeometry(); // todo w x h (1+0)
397  else
398  ostr << conf.area;
399  ostr << ' ' << Type::getTypeChar(conf.getType()) << '@' << (conf.getElementSize()*8) << 'b';
400  //const drain::ValueScaling & s = conf; // .scaling;
401  const drain::ValueScaling & s = conf.getScaling(); // .scaling;
402  if (s.isScaled() || s.isPhysical()){
403  ostr << "*(" << s << ")";
404  }
405  //ostr << (conf.hasOwnScaling() ? '!' : '&');
406  ostr << ' ' << 'c' << conf.coordinatePolicy;
407  return ostr;
408 }
409 
410 } // image::
411 } // drain::
412 
413 #endif /* IMAGE_CONF_H_*/
414 
415 // Drain
Definition: Caster.h:67
const std::type_info & getType() const
Returns type_info of the current type.
Definition: Caster.h:144
size_t getElementSize() const
Returns the size of the base type (size of an element, not of element array).
Definition: Caster.h:151
void setType(const std::type_info &t)
Calls setType<T>() for which typeid(T) = t.
Definition: Caster.h:119
Utilities related to std::type_info.
Definition: Type.h:51
Linear scaling and physical range for image intensities.
Definition: ValueScaling.h:64
double getMinPhys() const
Returns the minimum physical value.
Definition: ValueScaling.h:269
bool isPhysical() const
Returns true, physical intensity range has been set.
Definition: ValueScaling.h:281
double fwd(double x) const
Forward scaling: given encoded value x, returns corresponding value (possibly physically meaningful).
Definition: ValueScaling.h:295
virtual const ValueScaling & getScaling() const
Get linear scaling.
Definition: ValueScaling.h:147
void setPhysicalRange(const Range< T > &range)
Sets the supported range for physical values. Does not change scaling or type.
Definition: ValueScaling.h:240
double getMaxPhys() const
Returns the maximum physical value.
Definition: ValueScaling.h:275
const Range< double > & getPhysicalRange() const
Returns a typical or supported range for physical values.
Definition: ValueScaling.h:221
virtual void setScaling(double scale, double offset)
Set linear scaling.
Definition: ValueScaling.h:136
void setOptimalScale(const std::type_info &t)
If storage type is integer, adjust scale such that resolution is maximized.
Definition: ValueScaling.cpp:36
Policies for coordinate underflows and overflows.
Definition: CoordinatePolicy.h:106
Definition: ImageConf.h:51
const Encoding & getEncoding() const
Return type and scaling.
Definition: ImageConf.h:68
bool typeIsSet() const
Get the storage type.
Definition: ImageConf.h:116
double requestPhysicalMin(double defaultMin=static_cast< double >(std::numeric_limits< short int >::min())) const
Returns the actual or guessed minimum physical value,.
Definition: ImageConf.h:312
void setEncoding(const Encoding &e)
Set type and scaling.
Definition: ImageConf.h:83
const std::type_info & getType() const
Linear scaling.
Definition: ImageConf.h:110
double requestPhysicalMax(double defaultMax=static_cast< double >(std::numeric_limits< short int >::max())) const
Returns the actual or guessed maximum physical value,.
Definition: ImageConf.h:293
std::string type
Information of the current type.
Definition: ImageConf.h:103
size_t getElementSize() const
Returns the size in bytes of the storage type (1 for unsigned char, 2 for 16-bit types,...
Definition: ImageConf.h:159
Encoding & getEncoding()
Return type and scaling.
Definition: ImageConf.h:75
Caster caster
In base class(es), mainly for storing storage type. In derived classes, also for value conversions.
Definition: ImageConf.h:97
void setType(const std::type_info &t)
Set storage type.
Definition: ImageConf.h:121
void setPhysicalRange(double min, double max, bool rescale=false)
Sets the supported range for physical values. Does not change scaling or type.
Definition: ImageConf.h:238
T getTypeMax() const
Returns the maximum value supported by the current storage type.
Definition: ImageConf.h:281
void setType()
Convenience.
Definition: ImageConf.h:144
void setPhysicalRange(const Range< double > &range, bool rescale=false)
Sets channel specific scaling instead of shared (image-level) scaling.
Definition: ImageConf.h:229
T getTypeMin() const
Returns the minimum value supported by the current storage type.
Definition: ImageConf.h:267
Definition: Geometry.h:145
Geometry(size_t width=0, size_t height=0, size_t channels=1, size_t alphas=0)
Constructor with dimensions. Channel count is one by default, allowing construction with width and he...
Definition: Geometry.h:159
size_t getChannelCount() const
Set...
Definition: Geometry.h:257
Struct for image (excluding data)
Definition: ImageConf.h:333
void setCoordinatePolicy(const T &policy)
Does not set any CoordinateHandler object.
Definition: ImageConf.h:368
CoordinatePolicy coordinatePolicy
Rules to handle under- and overflows of horizontal and vertical coordinates.
Definition: ImageConf.h:383
Class for ensuring that variable of type D remains within limits of type S.
Definition: TypeUtils.h:653
Definition: DataSelector.cpp:1277