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/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
48namespace drain
49{
50
52namespace image
53{
54
55class Channel;
56
58
67class ImageFrame : public ImageLike {
68
69
70public:
71
72
73
74
75 typedef CastableIterator const_iterator; // TODO...
77
78 inline
79 ImageFrame() : propertiesPtr(&properties) { //, scalingPtr(&conf.getScaling()) {
81 init();
82 };
83
84 inline
85 ImageFrame(const ImageFrame & src) : ImageLike(src), propertiesPtr(&properties) { // , scalingPtr(&conf.getScaling()) {
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
431protected:
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
475protected:
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
521private:
522
523 //drain::ValueScaling const * scalingPtr;
524
525};
526
527
528
529inline
530std::ostream & operator<<(std::ostream &ostr, const ImageFrame & src){
531 src.toStream(ostr);
532 return ostr;
533}
534
535
536
537} // image::
538
539template <>
540std::ostream & drain::Sprinter::toStream<drain::image::ImageFrame>(std::ostream & ostr, const drain::image::ImageFrame & src, const SprinterLayout & layout);
541
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
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:145
Struct for image (excluding data)
Definition ImageConf.h:333
Image with static geometry.
Definition ImageFrame.h:67
const iterator & begin()
Returns iterator pointing to the first image element.
Definition ImageFrame.h:119
T get(size_t i, size_t j) const
Gets the intensity at location i,j .
Definition ImageFrame.h:265
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, 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
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(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
void * getBuffer()
Returns the pointer to the start of the image array.
Definition ImageFrame.h:179
const void * getBuffer() const
Returns the pointer to the start of the image array.
Definition ImageFrame.h:173
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
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
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
const const_iterator & begin() const
Returns iterator pointing to the first image element.
Definition ImageFrame.h:132
double getScaled(size_t i, size_t j) const
Get intensity in original physical scale.
Definition ImageFrame.h:287
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
DRAIN_TYPENAME(void)
Add a specialization for each type of those you want to support.
Definition Point.h:48