ImageFrame.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_FRAME_H_
32 #define IMAGE_FRAME_H_ "ImageFrame 0.9, 2011.09.25 Markus.Peura@fmi.fi"
33 
34 #include <stddef.h> // size_t
35 
36 //#include <drain/util/CastableIterator.h>
37 #include <drain/TypeUtils.h>
38 #include <drain/Sprinter.h>
39 //#include "drain/util/FlexibleVariable.h"
40 #include <drain/image/CoordinatePolicy.h>
41 
42 #include "drain/util/ValueScaling.h"
43 #include "drain/util/VariableMap.h"
44 
45 #include "Geometry.h"
46 #include "ImageLike.h"
47 
48 namespace drain
49 {
50 
52 namespace image
53 {
54 
55 class Channel;
56 
58 
67 class ImageFrame : public ImageLike {
68 
69 
70 public:
71 
72 
73 
74 
75  typedef CastableIterator const_iterator; // TODO...
76  typedef CastableIterator iterator;
77 
78  inline
79  ImageFrame() : propertiesPtr(&properties) { //, scalingPtr(&conf.getScaling()) {
80  adjustBuffer();
81  init();
82  };
83 
84  inline
85  ImageFrame(const ImageFrame & src) : ImageLike(src), propertiesPtr(&properties) { // , scalingPtr(&conf.getScaling()) {
86  adjustBuffer();
87  init();
88  // copy properties? (no)
89  }
90 
91 
92  virtual inline
93  const ImageConf & getConf() const {
94  return conf; // *this;
95  }
96 
97  /*
98  inline
99  ImageConf & getConf() {
100  return conf; // *this;
101  }
102  */
103 
105  inline
106  void setPhysicalRange(const Range<double> &range, bool rescale=false){
107  conf.setPhysicalRange(range, rescale);
108  }
109 
111  inline
112  void setPhysicalRange(double min, double max, bool rescale=false){
113  conf.setPhysicalRange(min, max, rescale);
114  }
115 
116 
118  inline
119  const iterator & begin() {
120  return segmentBegin;
121  }
122 
124  inline
125  const iterator & end() {
126  return segmentEnd;
127  }
128 
129 
131  inline
132  const const_iterator & begin() const {
133  return segmentBegin;
134  }
135 
137  inline
138  const const_iterator & end() const {
139  return segmentEnd;
140  }
141 
143 
146  // TODO where is this actually needed? If in ImageViews, then should be virtual here.
147  inline
148  size_t address(size_t i) const {
149  return (i);
150  }
151 
153 
156  // Note: this may change if box view is implemented in future. (viewBox width,height, offset i,j)
157  inline
158  size_t address(size_t i, size_t j) const {
159  return ( + j * conf.area.getWidth() + i);
160  }
161 
163 
166  inline
167  size_t address(size_t i, size_t j, size_t k) const {
168  return ( + k*conf.area.getArea() + j*conf.area.getWidth() + i);
169  }
170 
172  inline
173  const void * getBuffer() const {
174  return & buffer[0];
175  };
176 
178  inline
179  void * getBuffer() {
180  return &buffer[0];
181  };
182 
183  // END ImageCore...
184 
186 
190  template <class T>
191  inline
192  void put(size_t i, T x){
193  conf.caster.put( & bufferPtr[address(i) * conf.byteSize], x); // why address(i)?
194  }
195 
197 
202  template <class T>
203  inline
204  void put(size_t i, size_t j, T x){
205  conf.caster.put( & bufferPtr[address(i,j) * conf.byteSize], x);
206  }
207 
209 
217  template <class T>
218  inline
219  void put(size_t i, size_t j, size_t k, T x){
220  conf.caster.put( & bufferPtr[address(i,j,k)*conf.byteSize], x);
221  }
222 
223 
225 
228  template <class T, class P>
229  inline
230  void put(const Point2D<P> &p, T x){
231  conf.caster.put( & bufferPtr[address(p.x,p.y)*conf.byteSize], x);
232  }
233 
234 
236 
239  // TODO: consider virtual, with Channel::scalingPtr->inv(x) and Image::scaling.inv(x) Could be just as fast, though...
240  inline
241  void putScaled(size_t i, size_t j, double x){
242  conf.caster.put( & bufferPtr[address(i,j) * conf.byteSize], getScaling().inv(x));
243  }
244 
245 
246 
247 
249 
252  template <class T>
253  inline
254  T get(size_t i) const {
255  return conf.caster.get<T>( & bufferPtr[address(i)*conf.byteSize] );
256  }
257 
259 
263  template <class T>
264  inline
265  T get(size_t i, size_t j) const {
266  return conf.caster.get<T>( & bufferPtr[address(i,j) * conf.byteSize ] );
267  }
268 
270 
275  template <class T>
276  inline
277  T get(size_t i, size_t j, size_t k) const {
278  return conf.caster.get<T>( & bufferPtr[address(i,j,k) * conf.byteSize] );
279  }
280 
282 
285  // TODO: consider virtual, with Channel::scalingPtr->fwd(x) and Image::scaling.fwd(x) Could be just as fast, though...
286  inline
287  double getScaled(size_t i, size_t j) const {
288  return getScaling().fwd(conf.caster.get<double>( & bufferPtr[address(i,j) * conf.byteSize ] ));
289  }
290 
292 
295  template <class T,class P>
296  inline
297  T get(const Point2D<P> &p) const {
298  return conf.caster.get<T>( & bufferPtr[address(p.x,p.y) * conf.byteSize ] );
299  }
300 
301 
302  template <class T, class P>
303  inline
304  void putPixel(const Point2D<P> &p, const std::vector<T> & pixel) const {
305  for (typename std::vector<T>::size_type i = 0; i < pixel.size(); ++i) {
306  conf.caster.put( & bufferPtr[address(p.x,p.y,i)*conf.byteSize], pixel[i]);
307  }
308  }
309 
310 
311  template <class T, class P>
312  inline
313  void getPixel(const Point2D<P> &p, std::vector<T> & pixel) const {
314  for (typename std::vector<T>::size_type i = 0; i < pixel.size(); ++i) {
315  pixel[i] = conf.caster.get<T>( & bufferPtr[address(p.x,p.y,i)*conf.byteSize]);
316  }
317  }
318 
319 
321  // TODO: what about value corresponding to physical min?
322  inline
323  void clear(){
324  fill(0);
325  };
326 
328  template <class T>
329  inline
330  void fill(T x){
331  for (iterator it = segmentBegin; it != segmentEnd; ++it)
332  *it = x;
333  }
334 
336  void copyData(const ImageFrame & src);
337 
338 
340  inline
341  bool hasOverlap(const ImageFrame & image) const {
342  return ((image.begin() < end()) && (image.end() > begin()));
343  }
344 
346  /*
347  inline
348  bool isSame(const ImageFrame & image) const {
349  return (getType() == image.getType()) && hasSameSegment(image);
350  }
351  */
352 
354 
360  inline
361  bool hasSameSegment(const ImageFrame & image) const {
362  return ((image.begin() == begin()) && (image.end() == end()));
363  }
364 
365 
366 
367 
370 
371  virtual inline
372  const FlexVariableMap & getProperties() const {
373  return *propertiesPtr;
374  }
375 
376  /*
377  virtual inline
378  FlexVariableMap & getProperties() {
379  return *propertiesPtr;
380  }
381  */
382 
383 
384  inline
385  void setName(const std::string & s){ name = s; };
386 
387  inline
388  const std::string & getName() const { return name; };
389 
391  void toStream(std::ostream &ostr = std::cout) const;
392 
393  virtual
394  Channel & getChannel(size_t i) = 0;
395 
396  virtual
397  const Channel & getChannel(size_t i) const = 0;
398 
399  virtual
400  Channel & getAlphaChannel(size_t i=0) = 0;
401 
402  virtual
403  const Channel & getAlphaChannel(size_t i=0) const = 0;
404 
405 
407 
410  //size_t getChannelIndex(const std::string & index) const;
411 
413  // Experimental for ImageFrame
414  virtual inline
415  void initialize(const std::type_info &t, const Geometry & geometry){
416  if ((conf.getType() == t) && (conf.getGeometry() == geometry))
417  return;
418  else {
419  throw std::runtime_error(std::string("ImageFrame::")+__FUNCTION__+": tried to change ImageFrame geometry");
420  }
421  }
422 
424  // Experimental for ImageFrame (does not change image; throws exception if change requested)
425  virtual inline
426  void initialize(const std::type_info &t, size_t width, size_t height, size_t imageChannels=1, size_t alphaChannels=0){
427  initialize(t, Geometry(width, height, imageChannels, alphaChannels));
428  }
429 
430 
431 protected:
432 
433  void init();
434 
436  void adjustBuffer();
437 
438  //std::vector<unsigned char> buffer;
439 
440  unsigned char * bufferPtr;
441 
442  iterator segmentBegin;
443  iterator segmentEnd;
444 
445  // Caster caster;
446 
447  // Size of the storage type (1 for 8 bits, 2 for 16 bits, etc.)
448  //size_t byteSize;
449 
451  /* Sets the type of pixel elements of the image.
452  *
453  */
454  void setStorageType(const std::type_info &type);
455 
456  inline
457  void unsetType(){
458  throw std::runtime_error("ImageFrame infinite loop: -> unsetType() ?");
459  //setStorageType(typeid(void));
460  };
461 
463 
466  void setView(const ImageFrame & src, size_t channelStart, size_t channelCount, bool catenate=false);
467 
469  inline
470  bool isView() const {
471  return (bufferPtr != &buffer[0]);
472  }; // TODO: first channel not
473 
474 
475 protected:
476 
477  FlexVariableMap const * propertiesPtr;
478 
479 
481 
484  virtual inline
485  void updateChannelVector() const {};
486 
487  std::string name;
488 
489  // Return pointer to pixel
490  template <class T>
491  inline
492  T * retrieve(size_t a){
493  return (T*) & buffer[ a*conf.byteSize ];
494  }
495 
496  // Return pointer to pixel
497  template <class T>
498  inline
499  const T * retrieve(size_t a) const {
500  return (const T*) & buffer[ a*conf.byteSize ];
501  }
502 
503 
504  // Return pointer to pixel
505  /*
506  template <class T>
507  inline
508  T * retrieve(size_t i, size_t j){
509  return (T*) & buffer[ a*conf.byteSize ];
510  }
511 
512  template <class T>
513  inline
514  const T * retrieve(size_t i, size_t j) const {
515  return (const T*) & buffer[ a*conf.byteSize ];
516  }
517  */
518 
519  std::vector<unsigned char> buffer; // non-private, for Image::swap().
520 
521 private:
522 
523  //drain::ValueScaling const * scalingPtr;
524 
525 };
526 
527 
528 
529 inline
530 std::ostream & operator<<(std::ostream &ostr, const ImageFrame & src){
531  src.toStream(ostr);
532  return ostr;
533 }
534 
535 
536 
537 } // image::
538 
539 template <>
540 std::ostream & drain::Sprinter::toStream<drain::image::ImageFrame>(std::ostream & ostr, const drain::image::ImageFrame & src, const SprinterLayout & layout);
541 
542 DRAIN_TYPENAME(drain::image::ImageFrame);
543 
544 } // drain::
545 
546 #endif /* IMAGE_FRAME_H_*/
547 
548 // Drain
Definition: CastableIterator.h:57
T get(const void *p) const
Default implementation throws an error. See specialized implementation below.
Definition: Caster.h:194
void put(void *p, const T &x) const
Default conversion (for unconventional types). Uses std::stringstream for conversion.
Definition: Caster.h:157
A map of FlexVariable:s.
Definition: VariableMap.h:138
double fwd(double x) const
Forward scaling: given encoded value x, returns corresponding value (possibly physically meaningful).
Definition: ValueScaling.h:295
const std::type_info & getType() const
Linear scaling.
Definition: ImageConf.h:110
Caster caster
In base class(es), mainly for storing storage type. In derived classes, also for value conversions.
Definition: ImageConf.h:97
void setPhysicalRange(const Range< double > &range, bool rescale=false)
Sets channel specific scaling instead of shared (image-level) scaling.
Definition: ImageConf.h:229
Definition: Geometry.h:145
Struct for image (excluding data)
Definition: ImageConf.h:333
Image with static geometry.
Definition: ImageFrame.h:67
const void * getBuffer() const
Returns the pointer to the start of the image array.
Definition: ImageFrame.h:173
T get(size_t i, size_t j) const
Gets the intensity at location i,j .
Definition: ImageFrame.h:265
size_t address(size_t i, size_t j, size_t k) const
Computes the index location from image coordinates. Does not involve bit resolution.
Definition: ImageFrame.h:167
void toStream(std::ostream &ostr=std::cout) const
Prints images geometry, buffer size and type information.
Definition: ImageFrame.cpp:229
void * getBuffer()
Returns the pointer to the start of the image array.
Definition: ImageFrame.h:179
const iterator & begin()
Returns iterator pointing to the first image element.
Definition: ImageFrame.h:119
T get(const Point2D< P > &p) const
Gets the intensity at location p=(i,j) .
Definition: ImageFrame.h:297
void adjustBuffer()
Resize data buffer to match the geometry.
Definition: ImageFrame.cpp:72
void put(size_t i, size_t j, T x)
Sets the intensity at location i,j to x. See address().
Definition: ImageFrame.h:204
T get(size_t i, size_t j, size_t k) const
Gets the intensity at location i,j,k .
Definition: ImageFrame.h:277
virtual void initialize(const std::type_info &t, size_t width, size_t height, size_t imageChannels=1, size_t alphaChannels=0)
Sets the type and allocates a data buffer.
Definition: ImageFrame.h:426
void setStorageType(const std::type_info &type)
Sets the storage type of the image - typically unsigned char, unsigned int or float....
Definition: ImageFrame.cpp:62
void put(size_t i, size_t j, size_t k, T x)
Sets the intensity at location i,j,k to x.
Definition: ImageFrame.h:219
bool hasSameSegment(const ImageFrame &image) const
Return true, if both frames have same type and are using the same data segment.
Definition: ImageFrame.h:361
void copyData(const ImageFrame &src)
Copies data. Does not change encoding, geometry, or coordinate policy.
Definition: ImageFrame.cpp:209
void put(size_t i, T x)
Sets the intensity in location i to x. See \address.
Definition: ImageFrame.h:192
void put(const Point2D< P > &p, T x)
Gets the intensity at location p=(i,j) .
Definition: ImageFrame.h:230
void setView(const ImageFrame &src, size_t channelStart, size_t channelCount, bool catenate=false)
Sets the image to view the data and scaling of another image.
Definition: ImageFrame.cpp:115
const iterator & end()
Returns the iterator pointing to the element after the last element of the image buffer.
Definition: ImageFrame.h:125
size_t address(size_t i, size_t j) const
Computes the index location from image coordinates. Does not involve bit resolution.
Definition: ImageFrame.h:158
size_t address(size_t i) const
Computes the index location from image coordinates. Does not involve bit resolution.
Definition: ImageFrame.h:148
bool isView() const
Returns true, if the image "points to" another image. For example, channels are views.
Definition: ImageFrame.h:470
FlexVariableMap properties
Container for user-defined KEY=VALUE metadata.
Definition: ImageFrame.h:369
const const_iterator & begin() const
Returns iterator pointing to the first image element.
Definition: ImageFrame.h:132
void setPhysicalRange(double min, double max, bool rescale=false)
Sets the supported range for physical values and optionally adjusts the scaling for maximal resolutio...
Definition: ImageFrame.h:112
void clear()
Sets the intensities to zero. Does not change image geometry. See resetGeometry().
Definition: ImageFrame.h:323
double getScaled(size_t i, size_t j) const
Get intensity in original physical scale.
Definition: ImageFrame.h:287
const const_iterator & end() const
Returns the iterator pointing to the element after the last element of the image buffer.
Definition: ImageFrame.h:138
T get(size_t i) const
Gets the intensity at location i. See address().
Definition: ImageFrame.h:254
bool hasOverlap(const ImageFrame &image) const
Checks if images have a common memory segment.
Definition: ImageFrame.h:341
void putScaled(size_t i, size_t j, double x)
Put intensity using original physical value.
Definition: ImageFrame.h:241
void setPhysicalRange(const Range< double > &range, bool rescale=false)
Sets the supported range for physical values and optionally adjusts the scaling for maximal resolutio...
Definition: ImageFrame.h:106
void fill(T x)
Sets the intensities to given value. Does not change image geometry.
Definition: ImageFrame.h:330
virtual void updateChannelVector() const
Updates channel vector. Copies scaling of the host image.
Definition: ImageFrame.h:485
virtual void initialize(const std::type_info &t, const Geometry &geometry)
Returns numeric channel index from "r", "g", "b", or "a" or a non-negative number in string format.
Definition: ImageFrame.h:415
A base class for images.
Definition: ImageLike.h:61
Definition: DataSelector.cpp:1277
Definition: Point.h:48