13#ifndef ML_TSUB_IMAGE_H
14#define ML_TSUB_IMAGE_H
30#pragma warning(disable: 4244)
39template <
typename DATATYPE>
class TSubImageCursor;
41template <
typename DATATYPE>
class ConstTSubImageCursor;
44#define _ML_TSUBIMG_SUBDOT6(pos, offset, stride) \
45 (((pos).x - (offset).x) * (stride).x + \
46 ((pos).y - (offset).y) * (stride).y + \
47 ((pos).z - (offset).z) * (stride).z + \
48 ((pos).c - (offset).c) * (stride).c + \
49 ((pos).t - (offset).t) * (stride).t + \
50 ((pos).u - (offset).u) * (stride).u)
53#define _ML_TSUBIMG_SUBDOT3(x, y, z, offset, stride) \
54 (((x) - (offset).x) * (stride).x + \
55 ((y) - (offset).y) * (stride).y + \
56 ((z) - (offset).z) * (stride).z)
59#define _ML_TSUBIMG_SUBDOT2(x, y, offset, stride) \
60 (((x) - (offset).x) * (stride).x + \
61 ((y) - (offset).y) * (stride).y)
108template <
typename DATATYPE>
143 "Mismatch of data type between argument and template typename.");
158 "Data type has no registered TypeTraits.");
188 "Mismatch of data type between argument and template typename.");
217 inline const DATATYPE*
getData()
const {
return static_cast<DATATYPE*
>(
_data); }
275 {
return getStride().getVectorPosition(pointer -
static_cast<DATATYPE*
>(
_data)); }
284 const MLint offset = pointer -
static_cast<DATATYPE*
>(
_data);
291 *x = (offset/stride.x) % imgExt.
x;
297 *y = (offset/stride.y) % imgExt.
y;
303 *z = (offset/stride.z) % imgExt.
z;
323 if (x){ *x +=
_box.v1.x; }
324 if (y){ *y +=
_box.v1.y; }
325 if (z){ *z +=
_box.v1.z; }
429 if (numVoxels==0){ minValue=0; maxValue=0;
return 0; }
439 const DATATYPE* dataEnd =
static_cast<DATATYPE*
>(
_data) + numVoxels;
442 for (DATATYPE* i=
static_cast<DATATYPE*
>(
_data)+1; i<dataEnd; ++i)
444 if (*i < minValue){ minValue = *i; }
445 if (*i > maxValue){ maxValue = *i; }
457 p.
set(box.
v1.
x, y, z, c, t, u);
460 for (
MLint x=box.
v1.
x; x <= pEnd; ++x, ++dPtr){
461 if (*dPtr < minValue){ minValue = *dPtr; }
462 if (*dPtr > maxValue){ maxValue = *dPtr; }
482#define _ML_CHECK_SUBIMAGE_DATA_POINTERS(FROM_PTR, TO_PTR) \
485 if (!FROM_PTR || !TO_PTR){ \
486 ML_PRINT_ERROR("TSubImage::copySubImageTyped( )", \
487 ML_BAD_POINTER_OR_0, \
488 "Valid data pointers in source and target subimage required for" \
489 "subimage copying, thus call is ignored."); \
497 template <
typename FROM_DATATYPE>
514 const FROM_DATATYPE* fromPt =
nullptr;
515 DATATYPE* toPt =
nullptr;
529 if (identicalScaling) {
530 for (p.
u=intersection.
v1.
u; p.
u<=intersection.
v2.
u; ++p.
u) {
531 for (p.
t=intersection.
v1.
t; p.
t<=intersection.
v2.
t; ++p.
t) {
532 for (p.
c=intersection.
v1.
c; p.
c<=intersection.
v2.
c; ++p.
c) {
533 for (p.
z=intersection.
v1.
z; p.
z<=intersection.
v2.
z; ++p.
z) {
534 for (p.
y=intersection.
v1.
y; p.
y<=intersection.
v2.
y; ++p.
y) {
541 for (p.
x = intersection.
v1.
x; p.
x <= intersection.
v2.
x; ++p.
x, ++fromPt) {
542 *toPt =
static_cast<DATATYPE
>(*fromPt);
551 for (p.
u=intersection.
v1.
u; p.
u<=intersection.
v2.
u; ++p.
u) {
552 for (p.
t=intersection.
v1.
t; p.
t<=intersection.
v2.
t; ++p.
t) {
553 for (p.
c=intersection.
v1.
c; p.
c<=intersection.
v2.
c; ++p.
c) {
554 for (p.
z=intersection.
v1.
z; p.
z<=intersection.
v2.
z; ++p.
z) {
555 for (p.
y=intersection.
v1.
y; p.
y<=intersection.
v2.
y; ++p.
y) {
562 for (p.
x = intersection.
v1.
x; p.
x <= intersection.
v2.
x; ++p.
x, ++fromPt) {
563 *toPt =
static_cast<DATATYPE
>(
static_cast<MLdouble>(*fromPt)*scaleDbl + shiftDbl);
589 template <
typename FROM_DATATYPE>
621 const FROM_DATATYPE *fromPt = typedFromImg.
getData();
632 memcpy( toPt, fromPt, bytesize );
636 if (!isDTScalarType){
640 for (DATATYPE* toPtEnd=toPt+size; toPt<toPtEnd; ++toPt){
641 *toPt=
static_cast<DATATYPE
>(
static_cast<DATATYPE
>(*toPt)*scaleDbl + shiftDbl);
645 for (DATATYPE* toPtEnd=toPt+size; toPt<toPtEnd; ++toPt){
646 *toPt=
static_cast<DATATYPE
>(
static_cast<MLdouble>(*toPt)*scaleDbl + shiftDbl);
661 const FROM_DATATYPE *fromPt =
nullptr;
662 DATATYPE *toPt =
nullptr,
667 const MLint dist = intersection.
v2.
x - intersection.
v1.
x;
668 const MLint size_x = dist+1;
672 for (p.
u=intersection.
v1.
u; p.
u<=intersection.
v2.
u; ++p.
u){
673 for (p.
t=intersection.
v1.
t; p.
t<=intersection.
v2.
t; ++p.
t){
674 for (p.
c=intersection.
v1.
c; p.
c<=intersection.
v2.
c; ++p.
c){
675 for (p.
z=intersection.
v1.
z; p.
z<=intersection.
v2.
z; ++p.
z){
684 for (p.
y=intersection.
v1.
y; p.
y<=intersection.
v2.
y; ++p.
y,fromPt+=fromStr.
y,toPt+=toStr.
y){
687 memcpy(toPt, fromPt, bytesize_x);
690 if (!isDTScalarType){
692 for (toPtEnd = toPt_+size_x;
695 *toPt_=
static_cast<DATATYPE
>(
static_cast<DATATYPE
>(*toPt_)*scaleDbl + shiftDbl);
699 for (toPtEnd = toPt_+size_x;
702 *toPt_=
static_cast<DATATYPE
>(
static_cast<MLdouble>(*toPt_)*scaleDbl + shiftDbl);
725 const FROM_DATATYPE *fromPt =
nullptr;
726 DATATYPE *toPt =
nullptr;
729 for (p.
u=intersection.
v1.
u; p.
u<=intersection.
v2.
u; ++p.
u){
730 for (p.
t=intersection.
v1.
t; p.
t<=intersection.
v2.
t; ++p.
t){
731 for (p.
c=intersection.
v1.
c; p.
c<=intersection.
v2.
c; ++p.
c){
732 for (p.
z=intersection.
v1.
z; p.
z<=intersection.
v2.
z; ++p.
z){
733 for (p.
y=intersection.
v1.
y; p.
y<=intersection.
v2.
y; ++p.
y){
739 const MLint startX = intersection.
v1.
x;
740 const MLint endX = intersection.
v2.
x;
742 if (!isFDTScalarType){
745 for (p.
x = startX; p.
x <= endX; ++p.
x, ++fromPt, ++toPt){
746 *toPt=
static_cast<DATATYPE
>(
static_cast<FROM_DATATYPE
>(*fromPt)*scaleDbl + shiftDbl);
750 for (p.
x = startX; p.
x <= endX; ++p.
x, ++fromPt, ++toPt){
751 *toPt=
static_cast<DATATYPE
>(
static_cast<MLdouble>(*fromPt)*scaleDbl + shiftDbl);
777 inline void fill(DATATYPE value)
783 for (DATATYPE* i =
static_cast<DATATYPE*
>(
_data); i<dataEnd; ++i){ *i=value; }
822template <
typename DATATYPE>
919template <
typename DATATYPE>
945template <
typename DATATYPE>
988template <
typename DATATYPE>
1018 _cursor = tSubImg._cursor;
1039 inline void setCursorPosition(
const DATATYPE* pointer) { _cursor =
const_cast<DATATYPE*
>(pointer); }
1134template <
typename T>
1141 "Mismatch of data type between argument and template typename.");
1146template <
typename T>
1153 "Mismatch of data type between argument and template typename.");
1158template <
typename T>
1165 "Mismatch of data type between argument and template typename.");
1170template <
typename T>
1177 "Mismatch of data type between argument and template typename.");
1195 template <
typename DATATYPE>
1196 inline ostream &
operator<<(ostream &ostr,
const ML_NAMESPACE::TSubImage<DATATYPE> &v)
1199 const ML_NAMESPACE::SubImageBox& box = v.getBox();
1200 ML_NAMESPACE::ImageVector p;
1201 for (p.u=box.v1.u; p.u<=box.v2.u; ++p.u){
1202 for (p.t=box.v1.t; p.t<=box.v2.t; ++p.t){
1203 for (p.c=box.v1.c; p.c<=box.v2.c; ++p.c){
1204 for (p.z=box.v1.z; p.z<=box.v2.z; ++p.z){
1205 for (p.y=box.v1.y; p.y<=box.v2.y; ++p.y){
1209 for (; p.x<=box.v2.x; p.x++){
1210 ostr << v.getImageValue(p) <<
" ";
Predeclaration for const cursor.
ConstTSubImageCursor(const TSubImage< DATATYPE > &subImage)
const DATATYPE * getPointerWithOffset(const ImageVector &offset) const
Returns the cursor position of the voxel computed from the current cursor shifted by offset.
const DATATYPE * getPointerWithOffset(MLint dx, MLint dy, MLint dz) const
Returns the cursor position of the voxel computed from the current cursor shifted by (dx,...
const DATATYPE * getPointer() const
SubImage & operator=(const SubImage &si)
void setBox(const SubImageBox &subImageBox)
const SubImageBox & getBox() const
Returns the box describing the origin/extent of the subimage.
void setDataType(MLDataType dataType)
MLDataType getDataType() const
Returns the type of image data.
SubImageBox _box
The box of the subimage.
ImageVector getExtent() const
Returns the extent of the subimage, which is identical to getBox().getExtent().
ImageVector getStride() const
SubImageBox getValidRegion() const
void setSourceImageExtent(const ImageVector &extent)
void * _data
Memory chunk managed by this subimage.
void * getData() const
Returns the memory address of the memory managed by the subimage.
SubImage()
Constructor: Creates a subimage with no data.
ImageVector getSourceImageExtent() const
MLEXPORT void fillBordersWithTypeData(const SubImageBox &box, const MLTypeData *fillValue)
MLint getNumVoxels() const
ImageVector getImageExtent() const
MLEXPORT void fillBordersWithBorderValues(const SubImageBox &box)
MLEXPORT void copySubImage(const SubImage &fromImage, const ScaleShiftData &scaleShiftData)
MLEXPORT void setData(void *data)
void set(const ComponentType v=0)
Sets all components to v or - if v is not specified - to 0.
DT getScale() const
Returns the scale constant of the transformation y=scale*x+offset.
ReorderMode getReorderMode() const
Returns the reorder mode.
@ ReorderColorPlanesToInterleaved
DT getShift() const
Returns the addition constant of the transformation y=scale*x+shift.
static TSubImageBox< MLint > intersect(const TSubImageBox< MLint > &box1, const TSubImageBox< MLint > &box2)
intT getNumVoxels() const
void reverseMoveC()
Moves the cursor backward in c direction.
void moveT()
Moves the cursor forward in t direction.
void reverseMoveX()
Moves the cursor backward in x direction.
void moveZ()
Moves the cursor forward in z direction.
void setPosition(const DATATYPE *pointer)
Sets the cursor to the given pointer where the pointer is the memory address of the voxel.
void reverseMoveY()
Moves the cursor backward in y direction.
DATATYPE getValue() const
Returns the voxel value at cursor position.
void reverseMoveT()
Moves the cursor backward in t direction.
ImageVector _stride
Stride for the subimage.
void moveU()
Moves the cursor forward in u direction.
void setSubImagePosition(MLint x, MLint y, MLint z)
DATATYPE getValueWithOffset(MLint dx, MLint dy, MLint dz) const
Return the voxel value at (cursor position + (dx, dy, dz)).
void moveX()
Moves the cursor forward in x direction.
DATATYPE getValueWithOffset(const ImageVector &offset) const
Returns the voxel value at (cursor position + offset).
ImageVector _subImageOffset
SubImage offset in original image.
DATATYPE * _data
SubImage data.
void reverseMoveZ()
Moves the cursor backward in z direction.
void setImagePosition(const ImageVector &position)
void moveByOffset(const ImageVector &offset)
Moves the cursor to cursor position + offset.
DATATYPE * _cursor
Cursor address for image data access.
void reverseMoveU()
Moves the cursor backward in u direction.
TSubImageCursorBase(const TSubImage< DATATYPE > &subImage)
void moveY()
Moves the cursor forward in y direction.
void setSubImagePosition(const ImageVector &position)
void moveByOffset(MLint x, MLint y, MLint z)
Moves the cursor to cursor position + (x, y, z).
void setImagePosition(MLint x, MLint y, MLint z)
void moveC()
Moves the cursor forward in c direction.
Predeclaration for cursor.
DATATYPE * getPointerWithOffset(const ImageVector &offset) const
Returns the cursor position of the voxel computed from the current cursor shifted by offset.
DATATYPE * getPointer() const
void setValueWithOffset(MLint dx, MLint dy, MLint dz, DATATYPE value) const
Sets the voxel value at (cursor position + (dx, dy, dz)) to value.
TSubImageCursor(TSubImage< DATATYPE > &subImage)
void setValueWithOffset(const ImageVector &offset, DATATYPE value) const
Sets the voxel value at (cursor position + offset) to value.
void setValue(DATATYPE value) const
Sets the voxel value at the cursor position to value.
DATATYPE * getPointerWithOffset(MLint dx, MLint dy, MLint dz) const
Returns the cursor position of the voxel computed from the current cursor shifted by (dx,...
void setCursorValue(DATATYPE value)
Sets the voxel value at the cursor position to value.
void reverseMoveCursorC()
Moves the cursor backward in c direction.
void moveCursorT()
Moves the cursor forward in t direction.
void moveCursorByOffset(const ImageVector &offset)
Moves the cursor to cursor position + offset.
void setCursorImagePosition(MLint x, MLint y, MLint z)
DATATYPE getCursorValue() const
Returns the voxel value at the cursor position.
void reverseMoveCursorU()
Moves the cursor backward in u direction.
void reverseMoveCursorY()
Moves the cursor backward in y direction.
DATATYPE getCursorValueWithOffset(MLint dx, MLint dy, MLint dz) const
Returns the voxel value at (cursor position + (dx, dy, dz)).
void reverseMoveCursorX()
Moves the cursor backward in x direction.
void moveCursorByOffset(MLint x, MLint y, MLint z)
Moves the cursor to cursor position + (x, y, z).
TSubImageWithCursor(const TSubImage< DATATYPE > &subImage)
Constructor with TSubImage.
void moveCursorZ()
Moves the cursor forward in z direction.
void reverseMoveCursorZ()
Moves the cursor backward in z direction.
void moveCursorC()
Moves the cursor forward in c direction.
DATATYPE * getCursorPointerWithOffset(const ImageVector &offset) const
Returns the cursor pointer of the voxel computed from the current cursor shifted by offset.
void reverseMoveCursorT()
Moves the cursor backward in t direction.
void setCursorValueWithOffset(const ImageVector &offset, DATATYPE value)
Sets the voxel value at (cursor position + offset) to value.
void setCursorImagePosition(const ImageVector &position)
DATATYPE * getCursorPointerWithOffset(MLint dx, MLint dy, MLint dz) const
Returns the cursor pointer of the voxel computed from the current cursor shifted by (dx,...
void setCursorPosition(const DATATYPE *pointer)
Sets the cursor to the given pointer where pointer is the memory address of the voxel.
void moveCursorY()
Moves the cursor forward in y direction.
void moveCursorX()
Moves the cursor forward in x direction.
TSubImageWithCursor(const TSubImageWithCursor &subImage)
Constructor with TSubImageWithCursor.
TSubImageWithCursor(const SubImage &subImage)
Constructor with SubImage.
void moveCursorU()
Moves the cursor forward in u direction.
DATATYPE getCursorValueWithOffset(const ImageVector &offset) const
Returns the voxel value at (cursor position + offset).
void setCursorSubImagePosition(MLint x, MLint y, MLint z)
void setCursorSubImagePosition(const ImageVector &position)
DATATYPE * getCursorPointer() const
TSubImageWithCursor()
Default constructor.
TSubImageWithCursor & operator=(const TSubImageWithCursor< DATATYPE > &tSubImg)
void setCursorValueWithOffset(MLint dx, MLint dy, MLint dz, DATATYPE value)
Sets voxel value at (cursor position + (dx, dy,dz)) to value.
TSubImage(const SubImage &subImage)
const DATATYPE * getImagePointer(const ImageVector &position) const
DATATYPE getSubImageValue(MLint x, MLint y, MLint z) const
void copySubImageTyped(const TSubImage< FROM_DATATYPE > &typedFromImg, const ScaleShiftData &scaleShiftData)
DATATYPE * getImagePointer(const ImageVector &position)
TSubImage(const TSubImage< DATATYPE > &typedSubImage)
void copySubImageReorderColorPlanesToInterleaved(const TSubImage< FROM_DATATYPE > &typedFromImage, const ScaleShiftData &scaleShiftData)
void setSubImageValue(MLint x, MLint y, DATATYPE value)
DATATYPE getImageValue(MLint x, MLint y) const
TSubImage(const SubImageBox &box, MLDataType dataType, void *data)
const DATATYPE * getSubImagePointer(MLint x, MLint y, MLint z) const
void setImageValue(const ImageVector &position, DATATYPE value)
DATATYPE getSubImageValue(MLint x, MLint y) const
ConstTSubImageCursor< DATATYPE > ConstCursor
A read-only cursor.
~TSubImage() override=default
Virtual destructor to suppress compiler warnings.
void fill(DATATYPE value)
Sets all voxel values in subimage to value.
ImageVector convertPointerToImagePosition(DATATYPE *pointer) const
DATATYPE & operator[](const ImageVector &position)
DATATYPE getImageValue(MLint x, MLint y, MLint z) const
TSubImageCursor< DATATYPE > Cursor
A read/write cursor.
ImageVector convertPointerToSubImagePosition(DATATYPE *pointer) const
const DATATYPE * getSubImagePointer(const ImageVector &position) const
DATATYPE getImageValue(const ImageVector &position) const
const DATATYPE * getImagePointer(MLint x, MLint y, MLint z) const
void fillInvalidRegionWithValue(DATATYPE value)
DATATYPE * getSubImagePointer(const ImageVector &position)
const DATATYPE & operator[](const ImageVector &position) const
DATATYPE * getImagePointer(MLint x, MLint y, MLint z)
DATATYPE ComponentType
A typedef to 'export' the type of voxels components.
void setImageValue(MLint x, MLint y, MLint z, DATATYPE value)
void fillBordersWithValue(const SubImageBox &box, DATATYPE fillValue)
DATATYPE getSubImageValue(const ImageVector &position) const
void setSubImageValue(const ImageVector &position, DATATYPE value)
MLint calculateMinMax(DATATYPE &minValue, DATATYPE &maxValue, const SubImageBox *const validBox=nullptr) const
void convertPointerToSubImagePosition(DATATYPE *pointer, MLint *x, MLint *y, MLint *z) const
TSubImage & operator=(const TSubImage< DATATYPE > &typedSubImage)
void setImageValue(MLint x, MLint y, DATATYPE value)
const DATATYPE * getData() const
Returns the memory address of the image region. Overloads methods from SubImage.
void setSubImageValue(MLint x, MLint y, MLint z, DATATYPE value)
void convertPointerToImagePosition(DATATYPE *pointer, MLint *x, MLint *y, MLint *z) const
DATATYPE * getSubImagePointer(MLint x, MLint y, MLint z)
void fillInvalidRegionWithBorderValues()
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.
ComponentType dot(const TVector< TVector6DBase< MLint > > &b) const
MLEXPORT size_t MLSizeOf(MLDataType dataType)
#define ML_INVALID_DATA_TYPE
bool MLValuesAreEqual(MLint8 a, MLint8 b, MLint8)
#define ML_PRINT_FATAL_ERROR(FUNC_NAME, REASON, HANDLING)
#define ML_CHECK_THROW(x)
#define _ML_TSUBIMG_SUBDOT6(pos, offset, stride)
Private helper macro for calculation of memory offset, calculates (pos-offset) * stride.
#define _ML_TSUBIMG_SUBDOT2(x, y, offset, stride)
Private helper macro for calculation of memory offset, calculates ((xy)-offset) * stride.
#define _ML_TSUBIMG_SUBDOT3(x, y, z, offset, stride)
Private helper macro for calculation of memory offset, calculates ((xyz)-offset) * stride.
#define _ML_CHECK_SUBIMAGE_DATA_POINTERS(FROM_PTR, TO_PTR)
Internal helper macro to check validity of data pointers of subimages.
MLint32 MLIsScalarTypePtr(const T *)
unsigned char MLTypeData
This is the pointer type used to point to the data of MLType data instances.
TSubImage< T > & tsubimage_cast(SubImage &subImg)
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.
MLEXPORT std::ostream & operator<<(std::ostream &s, const ml::Field &v)
Overloads the operator '<<' for stream output of Field objects.
static bool matches(MLDataType)
@ dataType
Gives the data type ID for the given type, e.g., TypeTrait<MLuint8>::dataType == MLuint8Type,...