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/TypeUtils.h"
37#include "drain/Sprinter.h"
38#include "drain/util/ValueScaling.h"
39#include "drain/util/VariableMap.h"
40
41#include "CoordinatePolicy.h"
42#include "Geometry.h"
43#include "ImageLike.h"
44
45namespace drain
46{
47
49namespace image
50{
51
52class Channel;
53
55
64class ImageFrame : public ImageLike {
65
66
67public:
68
69
70
71
72 typedef CastableIterator const_iterator; // TODO...
74
75 inline
76 ImageFrame() : propertiesPtr(&properties) { //, scalingPtr(&conf.getScaling()) {
78 init();
79 };
80
81 inline
82 ImageFrame(const ImageFrame & src) : ImageLike(src), propertiesPtr(&properties) { // , scalingPtr(&conf.getScaling()) {
84 init();
85 // copy properties? (no)
86 }
87
88
89 virtual inline
90 const ImageConf & getConf() const {
91 return conf; // *this;
92 }
93
94 /*
95 inline
96 ImageConf & getConf() {
97 return conf; // *this;
98 }
99 */
100
102 inline
103 void setPhysicalRange(const Range<double> &range, bool rescale=false){
104 conf.setPhysicalRange(range, rescale);
105 }
106
108 inline
109 void setPhysicalRange(double min, double max, bool rescale=false){
110 conf.setPhysicalRange(min, max, rescale);
111 }
112
113
115 inline
116 const iterator & begin() {
117 return segmentBegin;
118 }
119
121 inline
122 const iterator & end() {
123 return segmentEnd;
124 }
125
126
128 inline
129 const const_iterator & begin() const {
130 return segmentBegin;
131 }
132
134 inline
135 const const_iterator & end() const {
136 return segmentEnd;
137 }
138
140
143 // TODO where is this actually needed? If in ImageViews, then should be virtual here.
144 inline
145 size_t address(size_t i) const {
146 return (i);
147 }
148
150
153 // Note: this may change if box view is implemented in future. (viewBox width,height, offset i,j)
154 inline
155 size_t address(size_t i, size_t j) const {
156 return ( + j * conf.area.getWidth() + i);
157 }
158
160
163 inline
164 size_t address(size_t i, size_t j, size_t k) const {
165 return ( + k*conf.area.getArea() + j*conf.area.getWidth() + i);
166 }
167
169 inline
170 const void * getBuffer() const {
171 return & buffer[0];
172 };
173
175 inline
176 void * getBuffer() {
177 return &buffer[0];
178 };
179
180 // END ImageCore...
181
183
187 template <class T>
188 inline
189 void put(size_t i, T x){
190 conf.caster.put( & bufferPtr[address(i) * conf.byteSize], x); // why address(i)?
191 }
192
194
199 template <class T>
200 inline
201 void put(size_t i, size_t j, T x){
202 conf.caster.put( & bufferPtr[address(i,j) * conf.byteSize], x);
203 }
204
206
214 template <class T>
215 inline
216 void put(size_t i, size_t j, size_t k, T x){
217 conf.caster.put( & bufferPtr[address(i,j,k)*conf.byteSize], x);
218 }
219
220
222
225 template <class T, class P>
226 inline
227 void put(const Point2D<P> &p, T x){
228 conf.caster.put( & bufferPtr[address(p.x,p.y)*conf.byteSize], x);
229 }
230
231
233
236 // TODO: consider virtual, with Channel::scalingPtr->inv(x) and Image::scaling.inv(x) Could be just as fast, though...
237 inline
238 void putScaled(size_t i, size_t j, double x){
239 conf.caster.put( & bufferPtr[address(i,j) * conf.byteSize], getScaling().inv(x));
240 }
241
242
243
244
246
249 template <class T>
250 inline
251 T get(size_t i) const {
252 return conf.caster.get<T>( & bufferPtr[address(i)*conf.byteSize] );
253 }
254
256
260 template <class T>
261 inline
262 T get(size_t i, size_t j) const {
263 return conf.caster.get<T>( & bufferPtr[address(i,j) * conf.byteSize ] );
264 }
265
267
272 template <class T>
273 inline
274 T get(size_t i, size_t j, size_t k) const {
275 return conf.caster.get<T>( & bufferPtr[address(i,j,k) * conf.byteSize] );
276 }
277
279
282 // TODO: consider virtual, with Channel::scalingPtr->fwd(x) and Image::scaling.fwd(x) Could be just as fast, though...
283 inline
284 double getScaled(size_t i, size_t j) const {
285 return getScaling().fwd(conf.caster.get<double>( & bufferPtr[address(i,j) * conf.byteSize ] ));
286 }
287
289
292 template <class T,class P>
293 inline
294 T get(const Point2D<P> &p) const {
295 return conf.caster.get<T>( & bufferPtr[address(p.x,p.y) * conf.byteSize ] );
296 }
297
298
299 template <class T, class P>
300 inline
301 void putPixel(const Point2D<P> &p, const std::vector<T> & pixel) const {
302 for (typename std::vector<T>::size_type i = 0; i < pixel.size(); ++i) {
303 conf.caster.put( & bufferPtr[address(p.x,p.y,i)*conf.byteSize], pixel[i]);
304 }
305 }
306
307
308 template <class T, class P>
309 inline
310 void getPixel(const Point2D<P> &p, std::vector<T> & pixel) const {
311 for (typename std::vector<T>::size_type i = 0; i < pixel.size(); ++i) {
312 pixel[i] = conf.caster.get<T>( & bufferPtr[address(p.x,p.y,i)*conf.byteSize]);
313 }
314 }
315
316
318 // TODO: what about value corresponding to physical min?
319 inline
320 void clear(){
321 fill(0);
322 };
323
325 template <class T>
326 inline
327 void fill(T x){
328 for (iterator it = segmentBegin; it != segmentEnd; ++it)
329 *it = x;
330 }
331
333 void copyData(const ImageFrame & src);
334
335
337 inline
338 bool hasOverlap(const ImageFrame & image) const {
339 return ((image.begin() < end()) && (image.end() > begin()));
340 }
341
343 /*
344 inline
345 bool isSame(const ImageFrame & image) const {
346 return (getType() == image.getType()) && hasSameSegment(image);
347 }
348 */
349
351
357 inline
358 bool hasSameSegment(const ImageFrame & image) const {
359 return ((image.begin() == begin()) && (image.end() == end()));
360 }
361
362
363
364
367
368 virtual inline
369 const FlexVariableMap & getProperties() const {
370 return *propertiesPtr;
371 }
372
373 /*
374 virtual inline
375 FlexVariableMap & getProperties() {
376 return *propertiesPtr;
377 }
378 */
379
380
381 inline
382 void setName(const std::string & s){ name = s; };
383
384 inline
385 const std::string & getName() const { return name; };
386
388 void toStream(std::ostream &ostr = std::cout) const;
389
390 virtual
391 Channel & getChannel(size_t i) = 0;
392
393 virtual
394 const Channel & getChannel(size_t i) const = 0;
395
396 virtual
397 Channel & getAlphaChannel(size_t i=0) = 0;
398
399 virtual
400 const Channel & getAlphaChannel(size_t i=0) const = 0;
401
405 virtual
406 bool suggestType(const std::type_info &t);
407
411 virtual
412 bool requireGeometry(const Geometry & geometry);
413
415 // Experimental for ImageFrame
416 virtual inline
417 void initialize(const std::type_info &t, const Geometry & geometry){
418
419 if (conf.getType() != t){
420 Logger(getImgLog(), __FILE__, __FUNCTION__).error("tried to change type [", conf.getType(), "] to [", t, "]");
421 return;
422 }
423 else if (conf.getGeometry() != geometry){
424 Logger(getImgLog(), __FILE__, __FUNCTION__).error("tried to change geometry ", conf.getGeometry(), " to ", geometry);
425 return;
426 }
427 else {
428 return;
429 // Logger mout(__FILE__, __FUNCTION__);
430 // throw std::runtime_error(StringBuilder<>(__FILE__, "::",__FUNCTION__, ": tried to change ImageFrame geometry:", conf, " => ", conf.getGeometry()));
431 }
432
433 }
434
436 // Experimental for ImageFrame (does not change image; throws exception if change requested)
437 virtual inline
438 void initialize(const std::type_info &t, size_t width, size_t height, size_t imageChannels=1, size_t alphaChannels=0){
439 initialize(t, Geometry(width, height, imageChannels, alphaChannels));
440 }
441
442
443protected:
444
445 void init();
446
448 void adjustBuffer();
449
450 //std::vector<unsigned char> buffer;
451
452 unsigned char * bufferPtr;
453
454 iterator segmentBegin;
455 iterator segmentEnd;
456
457 // Caster caster;
458
459 // Size of the storage type (1 for 8 bits, 2 for 16 bits, etc.)
460 //size_t byteSize;
461
463 /* Sets the type of pixel elements of the image.
464 *
465 */
466 void setStorageType(const std::type_info &type);
467
468 inline
469 void unsetType(){
470 throw std::runtime_error("ImageFrame infinite loop: -> unsetType() ?");
471 //setStorageType(typeid(void));
472 };
473
475
478 void setView(const ImageFrame & src, size_t channelStart, size_t channelCount, bool catenate=false);
479
481 inline
482 bool isView() const {
483 return (bufferPtr != &buffer[0]);
484 }; // TODO: first channel not
485
486
487protected:
488
489 FlexVariableMap const * propertiesPtr;
490
491
493
496 virtual inline
497 void updateChannelVector() const {};
498
499 std::string name;
500
501 // Return pointer to pixel
502 template <class T>
503 inline
504 T * retrieve(size_t a){
505 return (T*) & buffer[ a*conf.byteSize ];
506 }
507
508 // Return pointer to pixel
509 template <class T>
510 inline
511 const T * retrieve(size_t a) const {
512 return (const T*) & buffer[ a*conf.byteSize ];
513 }
514
515
516 // Return pointer to pixel
517 /*
518 template <class T>
519 inline
520 T * retrieve(size_t i, size_t j){
521 return (T*) & buffer[ a*conf.byteSize ];
522 }
523
524 template <class T>
525 inline
526 const T * retrieve(size_t i, size_t j) const {
527 return (const T*) & buffer[ a*conf.byteSize ];
528 }
529 */
530
531 std::vector<unsigned char> buffer; // non-private, for Image::swap().
532
533private:
534
535 //drain::ValueScaling const * scalingPtr;
536
537};
538
539
540
541inline
542std::ostream & operator<<(std::ostream &ostr, const ImageFrame & src){
543 src.toStream(ostr);
544 return ostr;
545}
546
547
548
549} // image::
550
551template <>
552std::ostream & drain::Sprinter::toStream<drain::image::ImageFrame>(std::ostream & ostr, const drain::image::ImageFrame & src, const SprinterLayout & layout);
553
555
556} // drain::
557
558#endif /* IMAGE_FRAME_H_*/
559
560// 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
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & error(const TT &... args)
Echoes.
Definition Log.h:416
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:64
const iterator & begin()
Returns iterator pointing to the first image element.
Definition ImageFrame.h:116
T get(size_t i, size_t j) const
Gets the intensity at location i,j .
Definition ImageFrame.h:262
const iterator & end()
Returns the iterator pointing to the element after the last element of the image buffer.
Definition ImageFrame.h:122
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:164
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:135
T get(const Point2D< P > &p) const
Gets the intensity at location p=(i,j) .
Definition ImageFrame.h:294
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:201
T get(size_t i, size_t j, size_t k) const
Gets the intensity at location i,j,k .
Definition ImageFrame.h:274
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:438
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:216
void * getBuffer()
Returns the pointer to the start of the image array.
Definition ImageFrame.h:176
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:170
bool hasSameSegment(const ImageFrame &image) const
Return true, if both frames have same type and are using the same data segment.
Definition ImageFrame.h:358
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:189
void put(const Point2D< P > &p, T x)
Gets the intensity at location p=(i,j) .
Definition ImageFrame.h:227
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:155
size_t address(size_t i) const
Computes the index location from image coordinates. Does not involve bit resolution.
Definition ImageFrame.h:145
bool isView() const
Returns true, if the image "points to" another image. For example, channels are views.
Definition ImageFrame.h:482
FlexVariableMap properties
Container for user-defined KEY=VALUE metadata.
Definition ImageFrame.h:366
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:109
void clear()
Sets the intensities to zero. Does not change image geometry. See resetGeometry().
Definition ImageFrame.h:320
const const_iterator & begin() const
Returns iterator pointing to the first image element.
Definition ImageFrame.h:129
double getScaled(size_t i, size_t j) const
Get intensity in original physical scale.
Definition ImageFrame.h:284
T get(size_t i) const
Gets the intensity at location i. See address().
Definition ImageFrame.h:251
bool hasOverlap(const ImageFrame &image) const
Checks if images have a common memory segment.
Definition ImageFrame.h:338
void putScaled(size_t i, size_t j, double x)
Put intensity using original physical value.
Definition ImageFrame.h:238
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:103
void fill(T x)
Sets the intensities to given value. Does not change image geometry.
Definition ImageFrame.h:327
virtual void updateChannelVector() const
Updates channel vector. Copies scaling of the host image.
Definition ImageFrame.h:497
virtual void initialize(const std::type_info &t, const Geometry &geometry)
Sets the type and allocates a data buffer.
Definition ImageFrame.h:417
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