Loading...
Searching...
No Matches
ImageFrame.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood 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/Sprinter.h"
37#include "drain/util/ValueScaling.h"
38#include "drain/util/VariableMap.h"
39
40#include "Geometry.h"
41#include "ImageLike.h"
42
43namespace drain
44{
45
47namespace image
48{
49
50class Channel;
51
53
62class ImageFrame : public ImageLike {
63
64
65public:
66
67
68
69
70 typedef CastableIterator const_iterator; // TODO...
72
73 inline
74 ImageFrame() : propertiesPtr(&properties) { //, scalingPtr(&conf.getScaling()) {
76 init();
77 };
78
79 inline
80 ImageFrame(const ImageFrame & src) : ImageLike(src), propertiesPtr(&properties) { // , scalingPtr(&conf.getScaling()) {
82 init();
83 // copy properties? (no)
84 }
85
86
87 virtual inline
88 const ImageConf & getConf() const {
89 return conf; // *this;
90 }
91
92 /*
93 inline
94 ImageConf & getConf() {
95 return conf; // *this;
96 }
97 */
98
100 inline
101 void setPhysicalRange(const Range<double> &range, bool rescale=false){
102 conf.setPhysicalRange(range, rescale);
103 }
104
106 inline
107 void setPhysicalRange(double min, double max, bool rescale=false){
108 conf.setPhysicalRange(min, max, rescale);
109 }
110
111
113 inline
114 const iterator & begin() {
115 return segmentBegin;
116 }
117
119 inline
120 const iterator & end() {
121 return segmentEnd;
122 }
123
124
126 inline
127 const const_iterator & begin() const {
128 return segmentBegin;
129 }
130
132 inline
133 const const_iterator & end() const {
134 return segmentEnd;
135 }
136
138
141 // TODO where is this actually needed? If in ImageViews, then should be virtual here.
142 inline
143 size_t address(size_t i) const {
144 return (i);
145 }
146
148
151 // Note: this may change if box view is implemented in future. (viewBox width,height, offset i,j)
152 inline
153 size_t address(size_t i, size_t j) const {
154 return ( + j * conf.area.getWidth() + i);
155 }
156
158
161 inline
162 size_t address(size_t i, size_t j, size_t k) const {
163 return ( + k*conf.area.getArea() + j*conf.area.getWidth() + i);
164 }
165
167 inline
168 const void * getBuffer() const {
169 return & buffer[0];
170 };
171
173 inline
174 void * getBuffer() {
175 return &buffer[0];
176 };
177
178 // END ImageCore...
179
181
185 template <class T>
186 inline
187 void put(size_t i, T x){
188 conf.caster.put( & bufferPtr[address(i) * conf.byteSize], x); // why address(i)?
189 }
190
192
197 template <class T>
198 inline
199 void put(size_t i, size_t j, T x){
200 conf.caster.put( & bufferPtr[address(i,j) * conf.byteSize], x);
201 }
202
204
212 template <class T>
213 inline
214 void put(size_t i, size_t j, size_t k, T x){
215 conf.caster.put( & bufferPtr[address(i,j,k)*conf.byteSize], x);
216 }
217
218
220
223 template <class T, class P>
224 inline
225 void put(const Point2D<P> &p, T x){
226 conf.caster.put( & bufferPtr[address(p.x,p.y)*conf.byteSize], x);
227 }
228
229
231
234 // TODO: consider virtual, with Channel::scalingPtr->inv(x) and Image::scaling.inv(x) Could be just as fast, though...
235 inline
236 void putScaled(size_t i, size_t j, double x){
237 conf.caster.put( & bufferPtr[address(i,j) * conf.byteSize], getScaling().inv(x));
238 }
239
240
241
242
244
247 template <class T>
248 inline
249 T get(size_t i) const {
250 return conf.caster.get<T>( & bufferPtr[address(i)*conf.byteSize] );
251 }
252
254
258 template <class T>
259 inline
260 T get(size_t i, size_t j) const {
261 return conf.caster.get<T>( & bufferPtr[address(i,j) * conf.byteSize ] );
262 }
263
265
270 template <class T>
271 inline
272 T get(size_t i, size_t j, size_t k) const {
273 return conf.caster.get<T>( & bufferPtr[address(i,j,k) * conf.byteSize] );
274 }
275
277
280 // TODO: consider virtual, with Channel::scalingPtr->fwd(x) and Image::scaling.fwd(x) Could be just as fast, though...
281 inline
282 double getScaled(size_t i, size_t j) const {
283 return getScaling().fwd(conf.caster.get<double>( & bufferPtr[address(i,j) * conf.byteSize ] ));
284 }
285
287
290 template <class T,class P>
291 inline
292 T get(const Point2D<P> &p) const {
293 return conf.caster.get<T>( & bufferPtr[address(p.x,p.y) * conf.byteSize ] );
294 }
295
296
297 template <class T, class P>
298 inline
299 void putPixel(const Point2D<P> &p, const std::vector<T> & pixel) const {
300 for (typename std::vector<T>::size_type i = 0; i < pixel.size(); ++i) {
301 conf.caster.put( & bufferPtr[address(p.x,p.y,i)*conf.byteSize], pixel[i]);
302 }
303 }
304
305
306 template <class T, class P>
307 inline
308 void getPixel(const Point2D<P> &p, std::vector<T> & pixel) const {
309 for (typename std::vector<T>::size_type i = 0; i < pixel.size(); ++i) {
310 pixel[i] = conf.caster.get<T>( & bufferPtr[address(p.x,p.y,i)*conf.byteSize]);
311 }
312 }
313
314
316 // TODO: what about value corresponding to physical min?
317 inline
318 void clear(){
319 fill(0);
320 };
321
323 template <class T>
324 inline
325 void fill(T x){
326 for (iterator it = segmentBegin; it != segmentEnd; ++it)
327 *it = x;
328 }
329
331 void copyData(const ImageFrame & src);
332
333
335 inline
336 bool hasOverlap(const ImageFrame & image) const {
337 return ((image.begin() < end()) && (image.end() > begin()));
338 }
339
341 /*
342 inline
343 bool isSame(const ImageFrame & image) const {
344 return (getType() == image.getType()) && hasSameSegment(image);
345 }
346 */
347
349
355 inline
356 bool hasSameSegment(const ImageFrame & image) const {
357 return ((image.begin() == begin()) && (image.end() == end()));
358 }
359
360
361
362
365
366 virtual inline
367 const FlexVariableMap & getProperties() const {
368 return *propertiesPtr;
369 }
370
371 /*
372 virtual inline
373 FlexVariableMap & getProperties() {
374 return *propertiesPtr;
375 }
376 */
377
378
379 inline
380 void setName(const std::string & s){ name = s; };
381
382 inline
383 const std::string & getName() const { return name; };
384
386 void toStream(std::ostream &ostr = std::cout) const;
387
388 virtual
389 Channel & getChannel(size_t i) = 0;
390
391 virtual
392 const Channel & getChannel(size_t i) const = 0;
393
394 virtual
395 Channel & getAlphaChannel(size_t i=0) = 0;
396
397 virtual
398 const Channel & getAlphaChannel(size_t i=0) const = 0;
399
403 virtual
404 bool suggestType(const std::type_info &t);
405
409 virtual
410 bool requireGeometry(const Geometry & geometry);
411
413 // Experimental for ImageFrame
414 virtual inline
415 void initialize(const std::type_info &t, const Geometry & geometry){
416
417 if (conf.getType() != t){
418 Logger(getImgLog(), __FILE__, __FUNCTION__).error("tried to change type [", conf.getType(), "] to [", t, "]");
419 return;
420 }
421 else if (conf.getGeometry() != geometry){
422 Logger(getImgLog(), __FILE__, __FUNCTION__).error("tried to change geometry ", conf.getGeometry(), " to ", geometry);
423 return;
424 }
425 else {
426 return;
427 // Logger mout(__FILE__, __FUNCTION__);
428 // throw std::runtime_error(StringBuilder<>(__FILE__, "::",__FUNCTION__, ": tried to change ImageFrame geometry:", conf, " => ", conf.getGeometry()));
429 }
430
431 }
432
434 // Experimental for ImageFrame (does not change image; throws exception if change requested)
435 virtual inline
436 void initialize(const std::type_info &t, size_t width, size_t height, size_t imageChannels=1, size_t alphaChannels=0){
437 initialize(t, Geometry(width, height, imageChannels, alphaChannels));
438 }
439
440
441protected:
442
443 void init();
444
446 void adjustBuffer();
447
448 //std::vector<unsigned char> buffer;
449
450 unsigned char * bufferPtr;
451
452 iterator segmentBegin;
453 iterator segmentEnd;
454
455 // Caster caster;
456
457 // Size of the storage type (1 for 8 bits, 2 for 16 bits, etc.)
458 //size_t byteSize;
459
461 /* Sets the type of pixel elements of the image.
462 *
463 */
464 void setStorageType(const std::type_info &type);
465
466 inline
467 void unsetType(){
468 throw std::runtime_error("ImageFrame infinite loop: -> unsetType() ?");
469 //setStorageType(typeid(void));
470 };
471
473
476 void setView(const ImageFrame & src, size_t channelStart, size_t channelCount, bool catenate=false);
477
479 inline
480 bool isView() const {
481 return (bufferPtr != &buffer[0]);
482 }; // TODO: first channel not
483
484
485protected:
486
487 FlexVariableMap const * propertiesPtr;
488
489
491
494 virtual inline
495 void updateChannelVector() const {};
496
497 std::string name;
498
499 // Return pointer to pixel
500 template <class T>
501 inline
502 T * retrieve(size_t a){
503 return (T*) & buffer[ a*conf.byteSize ];
504 }
505
506 // Return pointer to pixel
507 template <class T>
508 inline
509 const T * retrieve(size_t a) const {
510 return (const T*) & buffer[ a*conf.byteSize ];
511 }
512
513
514 // Return pointer to pixel
515 /*
516 template <class T>
517 inline
518 T * retrieve(size_t i, size_t j){
519 return (T*) & buffer[ a*conf.byteSize ];
520 }
521
522 template <class T>
523 inline
524 const T * retrieve(size_t i, size_t j) const {
525 return (const T*) & buffer[ a*conf.byteSize ];
526 }
527 */
528
529 std::vector<unsigned char> buffer; // non-private, for Image::swap().
530
531private:
532
533 //drain::ValueScaling const * scalingPtr;
534
535};
536
537
538
539inline
540std::ostream & operator<<(std::ostream &ostr, const ImageFrame & src){
541 src.toStream(ostr);
542 return ostr;
543}
544
545
546
547} // image::
548
549template <>
550std::ostream & drain::Sprinter::toStream<drain::image::ImageFrame>(std::ostream & ostr, const drain::image::ImageFrame & src, const SprinterLayout & layout);
551
552DRAIN_TYPENAME(drain::image::ImageFrame);
553
554} // drain::
555
556#endif /* IMAGE_FRAME_H_*/
557
558// Drain
Definition CastableIterator.h:57
T get(const void *p) const
Default implementation throws an error. See specialized implementation below.
Definition Caster.h:195
void put(void *p, const T &x) const
Default conversion (for unconventional types). Uses std::stringstream for conversion.
Definition Caster.h:158
A map of FlexVariable:s.
Definition VariableMap.h:138
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:313
Logger & error(const TT &... args)
Echoes.
Definition Log.h:417
Definition Range.h:52
double fwd(double x) const
Forward scaling: given encoded value x, returns corresponding value (possibly physically meaningful).
Definition ValueScaling.h:294
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:143
Struct for image (excluding data)
Definition ImageConf.h:333
Image with static geometry.
Definition ImageFrame.h:62
const iterator & begin()
Returns iterator pointing to the first image element.
Definition ImageFrame.h:114
T get(size_t i, size_t j) const
Gets the intensity at location i,j .
Definition ImageFrame.h:260
const iterator & end()
Returns the iterator pointing to the element after the last element of the image buffer.
Definition ImageFrame.h:120
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:162
void toStream(std::ostream &ostr=std::cout) const
Prints images geometry, buffer size and type information.
Definition ImageFrame.cpp:256
const const_iterator & end() const
Returns the iterator pointing to the element after the last element of the image buffer.
Definition ImageFrame.h:133
T get(const Point2D< P > &p) const
Gets the intensity at location p=(i,j) .
Definition ImageFrame.h:292
void adjustBuffer()
Resize data buffer to match the geometry.
Definition ImageFrame.cpp:99
void put(size_t i, size_t j, T x)
Sets the intensity at location i,j to x. See address().
Definition ImageFrame.h:199
T get(size_t i, size_t j, size_t k) const
Gets the intensity at location i,j,k .
Definition ImageFrame.h:272
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:436
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:214
void * getBuffer()
Returns the pointer to the start of the image array.
Definition ImageFrame.h:174
virtual bool suggestType(const std::type_info &t)
Definition ImageFrame.cpp:73
const void * getBuffer() const
Returns the pointer to the start of the image array.
Definition ImageFrame.h:168
bool hasSameSegment(const ImageFrame &image) const
Return true, if both frames have same type and are using the same data segment.
Definition ImageFrame.h:356
void copyData(const ImageFrame &src)
Copies data. Does not change encoding, geometry, or coordinate policy.
Definition ImageFrame.cpp:236
void put(size_t i, T x)
Sets the intensity in location i to x. See \address.
Definition ImageFrame.h:187
void put(const Point2D< P > &p, T x)
Gets the intensity at location p=(i,j) .
Definition ImageFrame.h:225
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:142
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:153
size_t address(size_t i) const
Computes the index location from image coordinates. Does not involve bit resolution.
Definition ImageFrame.h:143
bool isView() const
Returns true, if the image "points to" another image. For example, channels are views.
Definition ImageFrame.h:480
FlexVariableMap properties
Container for user-defined KEY=VALUE metadata.
Definition ImageFrame.h:364
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:107
void clear()
Sets the intensities to zero. Does not change image geometry. See resetGeometry().
Definition ImageFrame.h:318
const const_iterator & begin() const
Returns iterator pointing to the first image element.
Definition ImageFrame.h:127
double getScaled(size_t i, size_t j) const
Get intensity in original physical scale.
Definition ImageFrame.h:282
T get(size_t i) const
Gets the intensity at location i. See address().
Definition ImageFrame.h:249
bool hasOverlap(const ImageFrame &image) const
Checks if images have a common memory segment.
Definition ImageFrame.h:336
void putScaled(size_t i, size_t j, double x)
Put intensity using original physical value.
Definition ImageFrame.h:236
virtual bool requireGeometry(const Geometry &geometry)
Definition ImageFrame.cpp:87
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:101
void fill(T x)
Sets the intensities to given value. Does not change image geometry.
Definition ImageFrame.h:325
virtual void updateChannelVector() const
Updates channel vector. Copies scaling of the host image.
Definition ImageFrame.h:495
virtual void initialize(const std::type_info &t, const Geometry &geometry)
Sets the type and allocates a data buffer.
Definition ImageFrame.h:415
A base class for images.
Definition ImageLike.h:61
Definition DataSelector.cpp:1277
Definition Point.h:48