MeVisLab Toolbox Reference
mlSubImage.h
Go to the documentation of this file.
1/*************************************************************************************
2**
3** Copyright 2007, MeVis Medical Solutions AG
4**
5** The user may use this file in accordance with the license agreement provided with
6** the Software or, alternatively, in accordance with the terms contained in a
7** written agreement between the user and MeVis Medical Solutions AG.
8**
9** For further information use the contact form at https://www.mevislab.de/contact
10**
11**************************************************************************************/
12
13#ifndef ML_SUB_IMAGE_H
14#define ML_SUB_IMAGE_H
15
19
20#include "mlInitSystemML.h"
21#include "mlImageProperties.h"
22
23#include "mlMemoryBlockHandle.h"
24#include "mlScaleShiftData.h"
25
26
27ML_START_NAMESPACE
28
29
30//-------------------------------------------------------------------------
33
73//-------------------------------------------------------------------------
74class ML_UNIX_ONLY_EXPORT(MLEXPORT) SubImage
75{
76
77public:
78
79 //---------------------------------------------------------------------------
82 //---------------------------------------------------------------------------
84 inline SubImage() :
85 //_box (),
87 _data (nullptr),
88 _stride (0),
90 _dataTypeSize (1)
91 {
92 }
93
94
97 inline SubImage(const SubImage &si) :
98 _box (si._box),
100 _data (si._data),
102 _stride (si._stride),
103 _dataType (si._dataType),
104 _dataTypeSize (si._dataTypeSize)
105 {
106 }
107
111 inline SubImage(const SubImageBox& box, MLDataType datatype, void* data = nullptr) :
112 _box (box),
114 _data (data),
115 _stride (box.getExtent().getStrides()),
116 _dataType (datatype),
117 _dataTypeSize(MLSizeOf(datatype))
118 {
119 }
120
124 inline SubImage(const SubImage &si, const ImageVector& offset) :
125 _box (si._box),
127 _data (si._data),
129 _stride (si._stride),
130 _dataType (si._dataType),
131 _dataTypeSize (si._dataTypeSize)
132 {
133 _box.translate(offset);
134 }
135
137 inline virtual ~SubImage() = default;
138
141 inline SubImage &operator=(const SubImage &si)
142 {
143 if (this != &si)
144 {
145 _box = si._box;
147 _data = si._data;
149 _stride = si._stride;
150 _dataType = si._dataType;
151 _dataTypeSize = si._dataTypeSize;
152 }
153 return *this;
154 }
155
156
157 //---------------------------------------------------------------------------
160 //---------------------------------------------------------------------------
163 inline void setBox(const SubImageBox &subImageBox)
164 {
165 _box = subImageBox;
166 _stride.set(subImageBox.getExtent().getStrides());
167 }
168
169
173 inline void setBox(const ImageVector &imageExtent)
174 {
175 _box = SubImageBox(imageExtent);
176 _stride.set(imageExtent.getStrides());
177 }
178
180 inline void translate(const ImageVector &offset)
181 {
182 _box.translate(offset);
183 }
184
186 inline const ImageVector& getOrigin() const { return _box.v1; }
187
190 inline void setOrigin(const ImageVector& newOrigin) {
191 ImageVector offset = _box.v2 - _box.v1;
192 _box.v1 = newOrigin;
193 _box.v2 = newOrigin + offset;
194 }
195
197 inline ImageVector getExtent() const { return _box.getExtent(); }
198
201 inline void setExtent(MLint x, MLint y, MLint z = 1, MLint c = 1, MLint t = 1, MLint u = 1) {
202 setExtent(ImageVector(x,y,z,c,t,u));
203 }
204
206 inline void setExtent(const ImageVector& newExtent) {
207 _box.v2 = _box.v1 + newExtent -1;
208 _stride.set(newExtent.getStrides());
209 }
210
212 inline SubImageBox getBoxFromExtent() const { return SubImageBox(getExtent()); }
213
219
222 inline ImageVector getImageExtent() const { return getExtent(); }
223
226 inline void setImageExtent(const ImageVector& newExtent) { setExtent(newExtent);}
228
230 inline const SubImageBox& getBox() const
231 {
232 return _box;
233 }
234
237 inline void setSourceImageExtent(const ImageVector& extent) { _sourceImageExtent = extent; }
238
242
250 return SubImageBox::intersect(_box, sourceBox);
251 }
252
255 inline MLint getNumVoxels() const { return _box.getNumVoxels(); }
256
259 inline MLint getSizeInBytes() const { return getNumVoxels() * static_cast<MLint>(_dataTypeSize); }
260
264 inline ImageVector getStride() const
265 {
266 return _stride;
267 }
268
270 inline MLint getOffset(const ImageVector& voxelPosition) const
271 {
272 return ImageVector::dot(voxelPosition,_stride);
273 }
274
275
276
277 //---------------------------------------------------------------------------
280 //---------------------------------------------------------------------------
281 inline void setDataType(MLDataType dataType)
282 {
283 _dataType = dataType;
284 _dataTypeSize = MLSizeOf(dataType);
285 }
286
288 inline MLDataType getDataType() const { return _dataType; }
289
292
293
294 //---------------------------------------------------------------------------
297 //---------------------------------------------------------------------------
301 inline void* getSubImagePointer(const ImageVector &voxelPosition) const
302 {
303 // Use pointer arithmetic with one-byte sized data type, therefore we use a char pointer.
304 // (casting the offset to an unsigned type is ok - the resulting offset needs to be positive, and because of the wrap-around
305 // this would work for negative values anyway)
306 return static_cast<void*>(static_cast<char*>(_data) + static_cast<size_t>(ImageVector::dot(voxelPosition, _stride) * static_cast<MLint>(_dataTypeSize)));
307 }
308
312 inline void* getSubImagePointer(MLint x, MLint y, MLint z) const
313 {
314 // Use pointer arithmetics with one-byte sized data type, therefore we use a char pointer.
315 // (casting the offset to an unsigned type is ok - the resulting offset needs to be positive, and because of the wrap-around
316 // this would work for negative values anyway)
317 return static_cast<void*>(static_cast<char*>(_data) + static_cast<size_t>((x*_stride.x + y*_stride.y + _stride.z*z) * static_cast<MLint>(_dataTypeSize)));
318 }
319
323 inline void* getImagePointer(const ImageVector& voxelPosition) const
324 {
325 return getSubImagePointer(voxelPosition-_box.v1);
326 }
327
331 inline void* getImagePointer(MLint x, MLint y, MLint z) const
332 {
333 return getSubImagePointer(x-_box.v1.x, y-_box.v1.y, z-_box.v1.z);
334 }
335
336
337
338 //---------------------------------------------------------------------------
341 //---------------------------------------------------------------------------
354 MLEXPORT void copySubImage(const SubImage& fromImage, const ScaleShiftData& scaleShiftData);
355
359 MLEXPORT void copySubImage(const SubImage& fromImage);
360
362
363 //---------------------------------------------------------------------------
366 //---------------------------------------------------------------------------
369 MLEXPORT bool isValid() const;
370
372 inline void* getData() const { return _data; }
373
377 MLEXPORT void setData(void* data) { _memoryBlock.clear(); _data = data; }
378
384
388 inline const MLMemoryBlockHandle& getMemoryBlockHandle() const { return _memoryBlock; }
389
390 //----------------------------------------------------------------------
395 //----------------------------------------------------------------------
396 MLEXPORT static MLint coordToIndex(MLint x, MLint y, MLint z, MLint c, MLint t, MLint u, const ImageVector& size);
397
398 //----------------------------------------------------------------------
402 //----------------------------------------------------------------------
403 MLEXPORT static MLint coordToIndex(const ImageVector& voxelPosition, const ImageVector& size);
404
405 //----------------------------------------------------------------------
409 //----------------------------------------------------------------------
410 MLEXPORT static ImageVector indexToCoord(MLint index, const ImageVector& extent);
412
413
414 //---------------------------------------------------------------------------
417 //---------------------------------------------------------------------------
422 inline bool isValidSubImagePosition(const ImageVector& voxelPosition) const
423 {
424 const ImageVector extent = getExtent();
425 return ((voxelPosition.x>=0) && (voxelPosition.y>=0) && (voxelPosition.z>=0) &&
426 (voxelPosition.c>=0) && (voxelPosition.t>=0) && (voxelPosition.u>=0) &&
427 voxelPosition.x < extent.x && voxelPosition.y < extent.y && voxelPosition.z < extent.z &&
428 voxelPosition.c < extent.c && voxelPosition.t < extent.t && voxelPosition.u < extent.u );
429 }
430
435 inline bool isValidSubImagePosition(MLint x, MLint y, MLint z) const
436 {
437 const ImageVector extent = getExtent();
438 return ((x>=0) && (y>=0) && (z>=0) &&
439 (x < extent.x) && (y < extent.y) && (z < extent.z));
440 }
441
446 inline bool isValidImagePosition(const ImageVector& voxelPosition) const
447 {
448 return ((voxelPosition.x>=_box.v1.x) && (voxelPosition.y>=_box.v1.y) && (voxelPosition.z>=_box.v1.z) &&
449 (voxelPosition.c>=_box.v1.c) && (voxelPosition.t>=_box.v1.t) && (voxelPosition.u>=_box.v1.u) &&
450 (voxelPosition.x<=_box.v2.x) && (voxelPosition.y<=_box.v2.y) && (voxelPosition.z<=_box.v2.z) &&
451 (voxelPosition.c<=_box.v2.c) && (voxelPosition.t<=_box.v2.t) && (voxelPosition.u<=_box.v2.u) );
452 }
453
458 inline bool isValidImagePosition(MLint x, MLint y, MLint z) const
459 {
460 return ((x>=_box.v1.x) && (y>=_box.v1.y) && (z>=_box.v1.z) &&
461 (x<=_box.v2.x) && (y<=_box.v2.y) && (z<=_box.v2.z) );
462 }
463
464
465 //---------------------------------------------------------------------------
468 //---------------------------------------------------------------------------
485
488
498
499
500 //---------------------------------------------------------------------------
503 //---------------------------------------------------------------------------
504
505 //---------------------------------------------------------------------------
509 //---------------------------------------------------------------------------
510 MLEXPORT bool isOneValued() const;
511
512 //---------------------------------------------------------------------------
523 //---------------------------------------------------------------------------
525 const SubImageBox* const validBox=nullptr) const;
526
527 //---------------------------------------------------------------------------
548 //---------------------------------------------------------------------------
549 MLEXPORT void compare(const SubImage& subImage2,
550 bool* regionsMatch,
551 bool* dataTypesMatch,
552 bool* thisBoxIsPartOfRegion2,
553 bool* region2IsPartOfThisBox,
554 bool* overlapHasSameValues,
555 ImageVector* firstMismatchPos) const;
557
558
559 //-------------------------------------------------------------------------------------------
562 //-------------------------------------------------------------------------------------------
563
564 //---------------------------------------------------------------------------
566 //---------------------------------------------------------------------------
567 MLEXPORT void fill(MLdouble value);
568
569 //---------------------------------------------------------------------------
574 //---------------------------------------------------------------------------
576
577 //-------------------------------------------------------------------------------------------
582 //-------------------------------------------------------------------------------------------
584 //-------------------------------------------------------------------------------------------
585
586 //-------------------------------------------------------------------------------------------
593 //-------------------------------------------------------------------------------------------
594 MLEXPORT void fillBordersWithTypeData(const SubImageBox &box, const MLTypeData *fillValue);
595
596 //-------------------------------------------------------------------------------------------
605 //-------------------------------------------------------------------------------------------
606 MLEXPORT void fillBordersWithInputValues(const SubImageBox &box, const SubImage &inputSubImage);
607
608 //-------------------------------------------------------------------------------------------
615 //-------------------------------------------------------------------------------------------
617
623
626 inline void fillInvalidRegionWithTypeData(const MLTypeData *value) {
628 }
629
636
638
639 //-------------------------------------------------------------------------------------------
643 //-------------------------------------------------------------------------------------------
645
646 //-------------------------------------------------------------------------------------------
651 //-------------------------------------------------------------------------------------------
652 MLEXPORT void setFromImageProperties(const ImageProperties& imageProperties);
653
654 // Debug output to std::ostream, unoptimized.
655 void toStream(std::ostream &ostr) const;
656
657protected:
658 //-------------------------------------------------------------------------------------------
675 //-------------------------------------------------------------------------------------------
677 const SubImageBox &maxValidInputRegion,
678 ImageVector &boxV1, ImageVector &boxV2,
679 ImageVector &outputTSubImageV1, ImageVector &outputTSubImageV2,
680 MLint &fullLineLenX,
681 MLint &fullLineLenXB,
682 MLint &leftLineStartX,
683 MLint &leftLineLenX,
684 MLint &leftLineLenXB,
685 MLint &rightLineStartX,
686 MLint &rightLineLenX,
687 MLint &rightLineLenXB);
688
690 void _copySubImageGeneric(const SubImage& fromImage, const ScaleShiftData& scaleShiftData);
691
694
697
700
702 void* _data;
703
706
711
714
715private:
718 size_t _dataTypeSize;
719};
720
721ML_END_NAMESPACE
722
723// Stream output for std::ostream
724namespace std {
726 MLEXPORT ostream& operator<<(ostream& s, const ML_NAMESPACE::SubImage &fc);
727}
728
729#endif //of __mlSubImage_H
730
731
732
733
const MLTypeInfos * _getDataTypeInfos(MLDataType dt) const
Returns MLTypeInfos for used datatypes, indicates error if the type dt is not registered.
void fillInvalidRegionWithScalarValue(MLdouble value)
Definition mlSubImage.h:620
SubImage & operator=(const SubImage &si)
Definition mlSubImage.h:141
ImageVector _stride
Definition mlSubImage.h:710
void * getSubImagePointer(const ImageVector &voxelPosition) const
Definition mlSubImage.h:301
void setBox(const SubImageBox &subImageBox)
Definition mlSubImage.h:163
MLEXPORT void compare(const SubImage &subImage2, bool *regionsMatch, bool *dataTypesMatch, bool *thisBoxIsPartOfRegion2, bool *region2IsPartOfThisBox, bool *overlapHasSameValues, ImageVector *firstMismatchPos) const
bool isValidSubImagePosition(const ImageVector &voxelPosition) const
Definition mlSubImage.h:422
void * getImagePointer(const ImageVector &voxelPosition) const
Definition mlSubImage.h:323
void fillInvalidRegionWithTypeData(const MLTypeData *value)
Definition mlSubImage.h:626
const SubImageBox & getBox() const
Returns the box describing the origin/extent of the subimage.
Definition mlSubImage.h:230
virtual ~SubImage()=default
Virtual destructor to suppress compiler warnings.
void setDataType(MLDataType dataType)
Definition mlSubImage.h:281
void translate(const ImageVector &offset)
Translates the box of the subimage by adding the vector offset.
Definition mlSubImage.h:180
MLEXPORT void allocateAsMemoryBlockHandle(MLMemoryErrorHandling handleFailure=ML_RETURN_NULL)
Allocates data using the ML memory manager. For failure handing, see SubImage::allocate().
MLDataType getDataType() const
Returns the type of image data.
Definition mlSubImage.h:288
MLEXPORT bool isOneValued() const
SubImageBox getBoxFromImageExtent() const
Definition mlSubImage.h:218
SubImage(const SubImage &si, const ImageVector &offset)
Definition mlSubImage.h:124
MLMemoryBlockHandle _memoryBlock
Memory block used by this subimage.
Definition mlSubImage.h:705
SubImageBox _box
The box of the subimage.
Definition mlSubImage.h:696
void _calcFillAreaParams(const SubImageBox &box, const SubImageBox &maxValidInputRegion, ImageVector &boxV1, ImageVector &boxV2, ImageVector &outputTSubImageV1, ImageVector &outputTSubImageV2, MLint &fullLineLenX, MLint &fullLineLenXB, MLint &leftLineStartX, MLint &leftLineLenX, MLint &leftLineLenXB, MLint &rightLineStartX, MLint &rightLineLenX, MLint &rightLineLenXB)
void setExtent(const ImageVector &newExtent)
Sets the extent of the subimage to newExtent. This also changes the strides.
Definition mlSubImage.h:206
SubImage(const SubImage &si)
Definition mlSubImage.h:97
MLEXPORT MLint calculateMinMax(MLdouble &minValue, MLdouble &maxValue, const SubImageBox *const validBox=nullptr) const
ImageVector getExtent() const
Returns the extent of the subimage, which is identical to getBox().getExtent().
Definition mlSubImage.h:197
ImageVector getStride() const
Definition mlSubImage.h:264
const ImageVector & getOrigin() const
Returns the origin of the subimage, which is identical to getBox().v1.
Definition mlSubImage.h:186
SubImageBox getValidRegion() const
Definition mlSubImage.h:248
void setExtent(MLint x, MLint y, MLint z=1, MLint c=1, MLint t=1, MLint u=1)
Definition mlSubImage.h:201
void _copySubImageGeneric(const SubImage &fromImage, const ScaleShiftData &scaleShiftData)
Generic, non-optimized version of copySubImage.
void toStream(std::ostream &ostr) const
MLEXPORT void free()
MLEXPORT void allocate(MLMemoryErrorHandling handleFailure)
void setSourceImageExtent(const ImageVector &extent)
Definition mlSubImage.h:237
void * _data
Memory chunk managed by this subimage.
Definition mlSubImage.h:702
static MLEXPORT MLint coordToIndex(const ImageVector &voxelPosition, const ImageVector &size)
MLEXPORT void copySubImage(const SubImage &fromImage)
MLEXPORT void fillBordersWithInputValues(const SubImageBox &box, const SubImage &inputSubImage)
static MLEXPORT MLint coordToIndex(MLint x, MLint y, MLint z, MLint c, MLint t, MLint u, const ImageVector &size)
MLEXPORT void fillBordersWithScalarValue(const SubImageBox &box, MLdouble fillValue)
void setOrigin(const ImageVector &newOrigin)
Definition mlSubImage.h:190
void fillInvalidRegionWithBorderValues()
Definition mlSubImage.h:633
SubImage(const SubImageBox &box, MLDataType datatype, void *data=nullptr)
Definition mlSubImage.h:111
MLint getOffset(const ImageVector &voxelPosition) const
Returns the array index offset from the origin (0,0,0,0,0,0) to the voxelPosition.
Definition mlSubImage.h:270
void * getData() const
Returns the memory address of the memory managed by the subimage.
Definition mlSubImage.h:372
bool isValidImagePosition(MLint x, MLint y, MLint z) const
Definition mlSubImage.h:458
SubImage()
Constructor: Creates a subimage with no data.
Definition mlSubImage.h:84
bool isValidSubImagePosition(MLint x, MLint y, MLint z) const
Definition mlSubImage.h:435
MLEXPORT bool isValid() const
SubImageBox getBoxFromExtent() const
Returns the size of image as box with origin 0.
Definition mlSubImage.h:212
MLint getSizeInBytes() const
Definition mlSubImage.h:259
ImageVector getSourceImageExtent() const
Definition mlSubImage.h:241
void * getImagePointer(MLint x, MLint y, MLint z) const
Definition mlSubImage.h:331
bool isValidImagePosition(const ImageVector &voxelPosition) const
Definition mlSubImage.h:446
void setImageExtent(const ImageVector &newExtent)
Definition mlSubImage.h:226
MLEXPORT void setFromImageProperties(const ImageProperties &imageProperties)
MLEXPORT void fillBordersWithTypeData(const SubImageBox &box, const MLTypeData *fillValue)
const MLMemoryBlockHandle & getMemoryBlockHandle() const
Definition mlSubImage.h:388
MLEXPORT ImageProperties toImageProperties() const
MLint getNumVoxels() const
Definition mlSubImage.h:255
MLEXPORT void fillWithTypeData(const MLTypeData *value)
MLEXPORT void fill(MLdouble value)
Fills the subimage with a value that is cast to the data type of the subimage.
MLEXPORT void setDataFromMemoryBlockHandle(const MLMemoryBlockHandle &data)
Definition mlSubImage.h:383
ImageVector getImageExtent() const
Definition mlSubImage.h:222
static MLEXPORT ImageVector indexToCoord(MLint index, const ImageVector &extent)
const MLTypeInfos * getDataTypeInfos() const
Returns MLTypeInfos for image data type.
Definition mlSubImage.h:291
void * getSubImagePointer(MLint x, MLint y, MLint z) const
Definition mlSubImage.h:312
MLEXPORT void fillBordersWithBorderValues(const SubImageBox &box)
MLEXPORT void copySubImage(const SubImage &fromImage, const ScaleShiftData &scaleShiftData)
MLEXPORT void setData(void *data)
Definition mlSubImage.h:377
void setBox(const ImageVector &imageExtent)
Definition mlSubImage.h:173
ImageVector _sourceImageExtent
The extent of the source image, which is used for getValidRegion().
Definition mlSubImage.h:699
MLDataType _dataType
Data type of the image.
Definition mlSubImage.h:713
static TSubImageBox< MLint > intersect(const TSubImageBox< MLint > &box1, const TSubImageBox< MLint > &box2)
VectorType getExtent() const
ComponentType c
Color component of the vector.
ComponentType t
Time component of the vector.
ComponentType u
Unit/Modality/User component of the vector.
ComponentType z
Z component of the vector.
ComponentType x
X component of the vector.
ComponentType y
Y component of the vector.
TVector< TVectorBase > getStrides(const ComponentType offset=1) const
ComponentType dot(const TVector< TVector6DBase< MLint > > &b) const
MLEXPORT size_t MLSizeOf(MLDataType dataType)
MLint32 MLDataType
Definition mlTypeDefs.h:595
@ MLuint8Type
Enumerator for the unsigned 8-bit ML integer type.
Definition mlTypeDefs.h:620
MLEXPORT MLTypeInfos * MLGetTypeInfosForDataType(MLDataType dataType)
#define MLEXPORT
Code it as import symbol if compiled elsewhere.
MLMemoryErrorHandling
Enumerator to specify memory error handling.
Definition mlTypeDefs.h:675
@ ML_RETURN_NULL
On allocation failure, NULL is returned without error handling.
Definition mlTypeDefs.h:675
double MLdouble
Definition mlTypeDefs.h:216
unsigned char MLTypeData
This is the pointer type used to point to the data of MLType data instances.
MLint64 MLint
Definition mlTypeDefs.h:489
std::ostream & operator<<(std::ostream &out, const ml::Variant &variant)
Definition mlVariant.h:210
TScaleShiftData< MLdouble > ScaleShiftData
Double version of TScaleShiftData for maximum reasonable precision.
TSubImageBox< MLint > SubImageBox
Defines the standard SubImageBox type used in the ML. Its size varies with the size of the MLint type...
TImageVector< MLint > ImageVector
Defines the standard ImageVector type that is used by the ML for indexing and coordinates.
STL namespace.