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 // TODO: CHECK: -Wdeprecated-copy fires because this copy constructor is user-declared but
80 // operator= is not. The constructor itself only calls adjustBuffer()+init() (its own comment
81 // "copy properties? (no)" already flags that properties aren't copied), so it's unclear what
82 // a correct operator= should even do here; needs a real look, not a blind `=default`.
83 inline
84 ImageFrame(const ImageFrame & src) : ImageLike(src), propertiesPtr(&properties) { // , scalingPtr(&conf.getScaling()) {
86 init();
87 // copy properties? (no)
88 }
89
90
91 virtual inline
92 const ImageConf & getConf() const {
93 return conf; // *this;
94 }
95
96 /*
97 inline
98 ImageConf & getConf() {
99 return conf; // *this;
100 }
101 */
102
104 inline
105 void setPhysicalRange(const Range<double> &range, bool rescale=false){
106 conf.setPhysicalRange(range, rescale);
107 }
108
110 inline
111 void setPhysicalRange(double min, double max, bool rescale=false){
112 conf.setPhysicalRange(min, max, rescale);
113 }
114
115
117 inline
118 const iterator & begin() {
119 return segmentBegin;
120 }
121
123 inline
124 const iterator & end() {
125 return segmentEnd;
126 }
127
128
130 inline
131 const const_iterator & begin() const {
132 return segmentBegin;
133 }
134
136 inline
137 const const_iterator & end() const {
138 return segmentEnd;
139 }
140
142
145 // TODO where is this actually needed? If in ImageViews, then should be virtual here.
146 inline
147 size_t address(size_t i) const {
148 return (i);
149 }
150
152
155 // Note: this may change if box view is implemented in future. (viewBox width,height, offset i,j)
156 inline
157 size_t address(size_t i, size_t j) const {
158 return ( + j * conf.area.getWidth() + i);
159 }
160
162
165 inline
166 size_t address(size_t i, size_t j, size_t k) const {
167 return ( + k*conf.area.getArea() + j*conf.area.getWidth() + i);
168 }
169
171 inline
172 const void * getBuffer() const {
173 return & buffer[0];
174 };
175
177 inline
178 void * getBuffer() {
179 return &buffer[0];
180 };
181
182 // END ImageCore...
183
185
189 template <class T>
190 inline
191 void put(size_t i, T x){
192 conf.caster.put( & bufferPtr[address(i) * conf.byteSize], x); // why address(i)?
193 }
194
196
201 template <class T>
202 inline
203 void put(size_t i, size_t j, T x){
204 conf.caster.put( & bufferPtr[address(i,j) * conf.byteSize], x);
205 }
206
208
216 template <class T>
217 inline
218 void put(size_t i, size_t j, size_t k, T x){
219 conf.caster.put( & bufferPtr[address(i,j,k)*conf.byteSize], x);
220 }
221
222
224
227 template <class T, class P>
228 inline
229 void put(const Point2D<P> &p, T x){
230 conf.caster.put( & bufferPtr[address(p.x,p.y)*conf.byteSize], x);
231 }
232
233
235
238 inline
239 void putScaled(size_t i, double x) const {
240 conf.caster.put( & bufferPtr[i*conf.byteSize], getScaling().inv(x));
241 // return getScaling().fwd(conf.caster.get<double>( & bufferPtr[i * conf.byteSize ] ));
242 }
243
245
248 // TODO: consider virtual, with Channel::scalingPtr->inv(x) and Image::scaling.inv(x) Could be just as fast, though...
249 inline
250 void putScaled(size_t i, size_t j, double x){
251 conf.caster.put( & bufferPtr[address(i,j) * conf.byteSize], getScaling().inv(x));
252 }
253
254
255
256
258
261 template <class T>
262 inline
263 T get(size_t i) const {
264 return conf.caster.get<T>( & bufferPtr[address(i)*conf.byteSize] );
265 }
266
268
272 template <class T>
273 inline
274 T get(size_t i, size_t j) const {
275 return conf.caster.get<T>( & bufferPtr[address(i,j) * conf.byteSize ] );
276 }
277
279
284 template <class T>
285 inline
286 T get(size_t i, size_t j, size_t k) const {
287 return conf.caster.get<T>( & bufferPtr[address(i,j,k) * conf.byteSize] );
288 }
289
291 inline
292 double getScaled(size_t i) const {
293 return getScaling().fwd(conf.caster.get<double>( & bufferPtr[i * conf.byteSize ] ));
294 }
295
297
300 // TODO: consider virtual, with Channel::scalingPtr->fwd(x) and Image::scaling.fwd(x) Could be just as fast, though...
301 inline
302 double getScaled(size_t i, size_t j) const {
303 return getScaling().fwd(conf.caster.get<double>( & bufferPtr[address(i,j) * conf.byteSize ] ));
304 }
305
307
310 template <class T,class P>
311 inline
312 T get(const Point2D<P> &p) const {
313 return conf.caster.get<T>( & bufferPtr[address(p.x,p.y) * conf.byteSize ] );
314 }
315
316 template <class P>
317 inline
318 double getScaled(const Point2D<P> &p) const {
319 return getScaling().fwd(conf.caster.get<double>( & bufferPtr[address(p.x,p.y) * conf.byteSize ] ));
320 // return getScaling().fwd(conf.caster.get<double>( & bufferPtr[address(i,j) * conf.byteSize ] ));
321 }
322
323
324 template <class T, class P>
325 inline
326 void putPixel(const Point2D<P> &p, const std::vector<T> & pixel) const {
327 for (typename std::vector<T>::size_type i = 0; i < pixel.size(); ++i) {
328 conf.caster.put( & bufferPtr[address(p.x,p.y,i)*conf.byteSize], pixel[i]);
329 }
330 }
331
332
333 template <class T, class P>
334 inline
335 void getPixel(const Point2D<P> &p, std::vector<T> & pixel) const {
336 for (typename std::vector<T>::size_type i = 0; i < pixel.size(); ++i) {
337 pixel[i] = conf.caster.get<T>( & bufferPtr[address(p.x,p.y,i)*conf.byteSize]);
338 }
339 }
340
341
343 // TODO: what about value corresponding to physical min?
344 inline
345 void clear(){
346 fill(0);
347 };
348
350 template <class T>
351 inline
352 void fill(T x){
353 for (iterator it = segmentBegin; it != segmentEnd; ++it)
354 *it = x;
355 }
356
358 void copyData(const ImageFrame & src);
359
360
362 inline
363 bool hasOverlap(const ImageFrame & image) const {
364 return ((image.begin() < end()) && (image.end() > begin()));
365 }
366
368 /*
369 inline
370 bool isSame(const ImageFrame & image) const {
371 return (getType() == image.getType()) && hasSameSegment(image);
372 }
373 */
374
376
382 inline
383 bool hasSameSegment(const ImageFrame & image) const {
384 return ((image.begin() == begin()) && (image.end() == end()));
385 }
386
387
388
389
392
393 virtual inline
394 const FlexVariableMap & getProperties() const {
395 return *propertiesPtr;
396 }
397
398 /*
399 virtual inline
400 FlexVariableMap & getProperties() {
401 return *propertiesPtr;
402 }
403 */
404
405
406 inline
407 void setName(const std::string & s){ name = s; };
408
409 inline
410 const std::string & getName() const { return name; };
411
413 void toStream(std::ostream &ostr = std::cout) const;
414
415 virtual
416 Channel & getChannel(size_t i) = 0;
417
418 virtual
419 const Channel & getChannel(size_t i) const = 0;
420
421 virtual
422 Channel & getAlphaChannel(size_t i=0) = 0;
423
424 virtual
425 const Channel & getAlphaChannel(size_t i=0) const = 0;
426
430 virtual
431 bool suggestType(const std::type_info &t);
432
436 virtual
437 bool requireGeometry(const Geometry & geometry);
438
440 // Experimental for ImageFrame
441 virtual inline
442 void initialize(const std::type_info &t, const Geometry & geometry){
443
444 if (conf.getType() != t){
445 Logger(getImgLog(), __FILE__, __FUNCTION__).error("tried to change type [", conf.getType(), "] to [", t, "]");
446 return;
447 }
448 else if (conf.getGeometry() != geometry){
449 Logger(getImgLog(), __FILE__, __FUNCTION__).error("tried to change geometry ", conf.getGeometry(), " to ", geometry);
450 return;
451 }
452 else {
453 return;
454 // Logger mout(__FILE__, __FUNCTION__);
455 // throw std::runtime_error(StringBuilder<>(__FILE__, "::",__FUNCTION__, ": tried to change ImageFrame geometry:", conf, " => ", conf.getGeometry()));
456 }
457
458 }
459
461 // Experimental for ImageFrame (does not change image; throws exception if change requested)
462 virtual inline
463 void initialize(const std::type_info &t, size_t width, size_t height, size_t imageChannels=1, size_t alphaChannels=0){
464 initialize(t, Geometry(width, height, imageChannels, alphaChannels));
465 }
466
467
468protected:
469
470 void init();
471
473 void adjustBuffer();
474
475 //std::vector<unsigned char> buffer;
476
477 unsigned char * bufferPtr;
478
479 iterator segmentBegin;
480 iterator segmentEnd;
481
482 // Caster caster;
483
484 // Size of the storage type (1 for 8 bits, 2 for 16 bits, etc.)
485 //size_t byteSize;
486
488 /* Sets the type of pixel elements of the image.
489 *
490 */
491 void setStorageType(const std::type_info &type);
492
493 inline
494 void unsetType(){
495 throw std::runtime_error("ImageFrame infinite loop: -> unsetType() ?");
496 //setStorageType(typeid(void));
497 };
498
500
503 void setView(const ImageFrame & src, size_t channelStart, size_t channelCount, bool catenate=false);
504
506 inline
507 bool isView() const {
508 return (bufferPtr != &buffer[0]);
509 }; // TODO: first channel not
510
511
512protected:
513
514 FlexVariableMap const * propertiesPtr;
515
516
518
521 virtual inline
522 void updateChannelVector() const {};
523
524 std::string name;
525
526 // Return pointer to pixel
527 template <class T>
528 inline
529 T * retrieve(size_t a){
530 return (T*) & buffer[ a*conf.byteSize ];
531 }
532
533 // Return pointer to pixel
534 template <class T>
535 inline
536 const T * retrieve(size_t a) const {
537 return (const T*) & buffer[ a*conf.byteSize ];
538 }
539
540
541 // Return pointer to pixel
542 /*
543 template <class T>
544 inline
545 T * retrieve(size_t i, size_t j){
546 return (T*) & buffer[ a*conf.byteSize ];
547 }
548
549 template <class T>
550 inline
551 const T * retrieve(size_t i, size_t j) const {
552 return (const T*) & buffer[ a*conf.byteSize ];
553 }
554 */
555
556 std::vector<unsigned char> buffer; // non-private, for Image::swap().
557
558private:
559
560 //drain::ValueScaling const * scalingPtr;
561
562};
563
564
565
566inline
567std::ostream & operator<<(std::ostream &ostr, const ImageFrame & src){
568 src.toStream(ostr);
569 return ostr;
570}
571
572
573
574} // image::
575
576template <>
577std::ostream & drain::Sprinter::toStream<drain::image::ImageFrame>(std::ostream & ostr, const drain::image::ImageFrame & src, const SprinterLayout & layout);
578
579DRAIN_TYPENAME(drain::image::ImageFrame);
580
581} // drain::
582
583#endif /* IMAGE_FRAME_H_*/
584
585// Drain
Definition CastableIterator.h:57
T get(const void *p) const
Default implementation throws an error. See specialized implementation below.
Definition Caster.h:207
void put(void *p, const T &x) const
Default conversion (for unconventional types). Uses std::stringstream for conversion.
Definition Caster.h:167
A map of FlexVariable:s.
Definition VariableMap.h:144
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:326
Logger & error(const TT &... args)
Echoes.
Definition Log.h:426
Definition Range.h:52
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: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:118
T get(size_t i, size_t j) const
Gets the intensity at location i,j .
Definition ImageFrame.h:274
const iterator & end()
Returns the iterator pointing to the element after the last element of the image buffer.
Definition ImageFrame.h:124
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:166
void putScaled(size_t i, double x) const
Put intensity using original physical value.
Definition ImageFrame.h:239
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:137
T get(const Point2D< P > &p) const
Gets the intensity at location p=(i,j) .
Definition ImageFrame.h:312
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:203
T get(size_t i, size_t j, size_t k) const
Gets the intensity at location i,j,k .
Definition ImageFrame.h:286
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:463
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:218
void * getBuffer()
Returns the pointer to the start of the image array.
Definition ImageFrame.h:178
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:172
bool hasSameSegment(const ImageFrame &image) const
Return true, if both frames have same type and are using the same data segment.
Definition ImageFrame.h:383
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.
Definition ImageFrame.h:191
void put(const Point2D< P > &p, T x)
Gets the intensity at location p=(i,j) .
Definition ImageFrame.h:229
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:157
size_t address(size_t i) const
Computes the index location from image coordinates. Does not involve bit resolution.
Definition ImageFrame.h:147
bool isView() const
Returns true, if the image "points to" another image. For example, channels are views.
Definition ImageFrame.h:507
FlexVariableMap properties
Container for user-defined KEY=VALUE metadata.
Definition ImageFrame.h:391
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:111
void clear()
Sets the intensities to zero. Does not change image geometry. See resetGeometry().
Definition ImageFrame.h:345
const const_iterator & begin() const
Returns iterator pointing to the first image element.
Definition ImageFrame.h:131
double getScaled(size_t i) const
Get intensity in original physical scale.
Definition ImageFrame.h:292
double getScaled(size_t i, size_t j) const
Get intensity in original physical scale.
Definition ImageFrame.h:302
T get(size_t i) const
Gets the intensity at location i. See address().
Definition ImageFrame.h:263
bool hasOverlap(const ImageFrame &image) const
Checks if images have a common memory segment.
Definition ImageFrame.h:363
void putScaled(size_t i, size_t j, double x)
Put intensity using original physical value.
Definition ImageFrame.h:250
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:105
void fill(T x)
Sets the intensities to given value. Does not change image geometry.
Definition ImageFrame.h:352
virtual void updateChannelVector() const
Updates channel vector. Copies scaling of the host image.
Definition ImageFrame.h:522
virtual void initialize(const std::type_info &t, const Geometry &geometry)
Sets the type and allocates a data buffer.
Definition ImageFrame.h:442
A base class for images.
Definition ImageLike.h:61
Definition Data.h:1473
std::ostream & operator<<(std::ostream &ostr, const PlainData< DT > &d)
Definition Data.h:631
Definition Point.h:48