ML Reference
MeVis/Foundation/Sources/ML/include/mlSubImage.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //-------------------------------------------------------------------------
00011 //-------------------------------------------------------------------------
00012 #ifndef __mlSubImage_H
00013 #define __mlSubImage_H
00014 
00015 // ML-includes
00016 #ifndef __mlInitSystemML_H
00017 #include "mlInitSystemML.h"
00018 #endif
00019 #ifndef __mlImageProperties_H
00020 #include "mlImageProperties.h"
00021 #endif
00022 
00023 #include "mlMemoryBlockHandle.h"
00024 
00025 ML_START_NAMESPACE
00026 
00027 
00028 //-------------------------------------------------------------------------
00031 
00071 //-------------------------------------------------------------------------
00072 class SubImage
00073 {
00074 
00075 public:
00076 
00077   //---------------------------------------------------------------------------
00079 
00080   //---------------------------------------------------------------------------
00082   inline SubImage() :
00083   //_box         (),
00084   _sourceImageExtent(0),
00085   _data          (NULL),
00086   _stride        (0),
00087   _dataType      (MLuint8Type),
00088   _dataTypeSize  (1)
00089   {
00090     ML_TRACE_IN_TIME_CRITICAL( "SubImage::SubImage( )" );
00091   }
00092 
00093 
00096   inline SubImage(const SubImage &si) :
00097   _box           (si._box),
00098   _sourceImageExtent(si._sourceImageExtent),
00099   _data          (si._data),
00100   _memoryBlock   (si._memoryBlock),
00101   _stride        (si._stride),
00102   _dataType      (si._dataType),
00103   _dataTypeSize  (si._dataTypeSize)
00104   {
00105     ML_TRACE_IN_TIME_CRITICAL( "SubImage::SubImage( )" );
00106   }
00107 
00111   inline SubImage(const SubImageBox& box, MLDataType datatype, void* data = NULL) :
00112   _box         (box),
00113   _sourceImageExtent(0),
00114   _data        (data),
00115   _stride      (box.getExtent().getStrides()),
00116   _dataType    (datatype),
00117   _dataTypeSize(MLSizeOf(datatype))
00118   {
00119     ML_TRACE_IN_TIME_CRITICAL( "SubImage::SubImage( )" );
00120   }
00121 
00125   inline SubImage(const SubImage &si, const ImageVector& offset) :
00126     _box           (si._box),
00127     _sourceImageExtent(si._sourceImageExtent),
00128     _data          (si._data),
00129     _memoryBlock   (si._memoryBlock),
00130     _stride        (si._stride),
00131     _dataType      (si._dataType),
00132     _dataTypeSize  (si._dataTypeSize)
00133   {
00134     ML_TRACE_IN_TIME_CRITICAL( "SubImage::SubImage( )" );
00135 
00136     _box.translate(offset);
00137   }
00138 
00140   inline virtual ~SubImage(){ ML_TRACE_IN_TIME_CRITICAL("SubImage::~SubImage()"); }
00141 
00144   inline SubImage &operator=(const SubImage &si)
00145   {
00146     ML_TRACE_IN_TIME_CRITICAL( "SubImage::operator=" );
00147 
00148     if (this != &si)
00149     {
00150       _box           = si._box;
00151       _sourceImageExtent = si._sourceImageExtent;
00152       _data          = si._data;
00153       _memoryBlock   = si._memoryBlock;
00154       _stride        = si._stride;
00155       _dataType      = si._dataType;
00156       _dataTypeSize  = si._dataTypeSize;
00157     }
00158     return *this;
00159   }
00161 
00162   //---------------------------------------------------------------------------
00164 
00165   //---------------------------------------------------------------------------
00168   inline void setBox(const SubImageBox &subImageBox)
00169   {
00170     ML_TRACE_IN_TIME_CRITICAL( "SubImage::setBox( )" );
00171     ML_TRY
00172     {
00173       _box = subImageBox;
00174       _stride.set(subImageBox.getExtent().getStrides());
00175     }
00176     ML_CATCH_RETHROW;
00177   }
00178 
00179 
00183   inline void setBox(const ImageVector &imageExtent)
00184   {
00185     ML_TRACE_IN_TIME_CRITICAL( "SubImage::setBox( )" );
00186     ML_TRY
00187     {
00188       _box = SubImageBox(imageExtent);
00189       _stride.set(imageExtent.getStrides());
00190     }
00191     ML_CATCH_RETHROW;
00192   }
00193 
00195   inline void translate(const ImageVector &offset)
00196   {
00197     ML_TRACE_IN_TIME_CRITICAL("void SubImage::translate(const ImageVector &offset)");
00198 
00199     _box.translate(offset);
00200   }
00201 
00203   inline const ImageVector& getOrigin() const { return _box.v1; }
00204 
00206   inline void setOrigin(const ImageVector& newOrigin) { _box.v1 = newOrigin; }
00207 
00209   inline ImageVector getExtent() const { return _box.getExtent(); }
00210 
00213   inline void setExtent(MLint x, MLint y, MLint z = 1, MLint c = 1, MLint t = 1, MLint u = 1) {
00214     setExtent(ImageVector(x,y,z,c,t,u));
00215   }
00216 
00218   inline void setExtent(const ImageVector& newExtent) {
00219     _box.v2 = _box.v1 + newExtent -1;
00220     _stride.set(newExtent.getStrides());
00221   }
00222 
00224   inline SubImageBox getBoxFromExtent() const  { return SubImageBox(getExtent()); }
00225 
00227 
00228 
00229 
00230   inline SubImageBox getBoxFromImageExtent() const { return getBoxFromExtent(); }
00231 
00234   inline ImageVector getImageExtent() const { return getExtent(); }
00235 
00238   inline void setImageExtent(const ImageVector& newExtent) { setExtent(newExtent);}
00240 
00242   inline const SubImageBox& getBox() const
00243   {
00244     ML_TRACE_IN_TIME_CRITICAL( "SubImage::getBox ( )" );
00245 
00246     return _box;
00247   }
00248 
00251   inline void setSourceImageExtent(const ImageVector& extent) { _sourceImageExtent = extent; }
00252 
00255   inline ImageVector getSourceImageExtent() const { return _sourceImageExtent; }
00256 
00259   inline SubImageBox getValidRegion() const {
00260     SubImageBox sourceBox(_sourceImageExtent);
00261     return SubImageBox::intersect(_box, sourceBox);
00262   }
00263 
00266   inline MLint getNumVoxels() const { return _box.getNumVoxels(); }
00267 
00270   inline MLint getSizeInBytes() const { return getNumVoxels() * static_cast<MLint>(_dataTypeSize); }
00271 
00275   inline ImageVector getStride() const
00276   {
00277     ML_TRACE_IN_TIME_CRITICAL( "SubImage::getStride() const" );
00278 
00279     return _stride;
00280   }
00281 
00283   inline MLint getOffset(const ImageVector& voxelPosition) const
00284   {
00285     ML_TRACE_IN_TIME_CRITICAL( "SubImage::getOffset(const ImageVector &p) const" );
00286 
00287     return ImageVector::dot(voxelPosition,_stride);
00288   }
00290 
00291 
00292   //---------------------------------------------------------------------------
00295   //---------------------------------------------------------------------------
00296   inline void setDataType(MLDataType dataType)
00297   {
00298     ML_TRACE_IN_TIME_CRITICAL("SubImage::setDataType()");
00299 
00300     _dataType = dataType;
00301     _dataTypeSize = MLSizeOf(dataType);
00302   }
00303 
00305   inline MLDataType getDataType() const               { return _dataType;        }
00306 
00308   inline const MLTypeInfos* getDataTypeInfos() const  { return MLGetTypeInfosForDataType(_dataType); }
00309 
00310 
00311   //---------------------------------------------------------------------------
00313 
00314   //---------------------------------------------------------------------------
00318   inline void* getSubImagePointer(const ImageVector &voxelPosition) const
00319   {
00320     // Use pointer arithmetics with one-byte sized data type, therefore we use make a char pointer.
00321     // (casting the offset to an unsigned type is ok - the resulting offset needs to be positive, and because of the wrap-around
00322     //  this would work for negative values anyway)
00323     return static_cast<void*>(static_cast<char*>(_data) + static_cast<size_t>(ImageVector::dot(voxelPosition, _stride) * _dataTypeSize));
00324   }
00325 
00329   inline void* getSubImagePointer(MLint x, MLint y, MLint z) const
00330   {
00331     // Use pointer arithmetics with one-byte sized data type, therefore we use make a char pointer.
00332     // (casting the offset to an unsigned type is ok - the resulting offset needs to be positive, and because of the wrap-around
00333     //  this would work for negative values anyway)
00334     return static_cast<void*>(static_cast<char*>(_data) + static_cast<size_t>((x*_stride.x + y*_stride.y + _stride.z*z) * _dataTypeSize));
00335   }
00336 
00340   inline void* getImagePointer(const ImageVector& voxelPosition) const
00341   {
00342     return getSubImagePointer(voxelPosition-_box.v1);
00343   }
00344 
00348   inline void* getImagePointer(MLint x, MLint y, MLint z) const
00349   {
00350     return getSubImagePointer(x-_box.v1.x, y-_box.v1.y, z-_box.v1.z);
00351   }
00353 
00354 
00355   //---------------------------------------------------------------------------
00357 
00358   //---------------------------------------------------------------------------
00371   MLEXPORT void copySubImage(const SubImage& fromImage, const ScaleShiftData& scaleShiftData);
00372 
00376   MLEXPORT void copySubImage(const SubImage& fromImage);
00377 
00379 
00380   //---------------------------------------------------------------------------
00382 
00383   //---------------------------------------------------------------------------
00386   inline bool isValid() const
00387   {
00388     ML_TRACE_IN_TIME_CRITICAL( "SubImage::isValid( )" );
00389     ML_TRY
00390     {
00391       return (_data!=0) && !(getBox().isEmpty());
00392     }
00393     ML_CATCH_RETHROW;
00394   }
00395 
00397   inline void* getData() const    { return _data; }
00398 
00402   MLEXPORT void setData(void* data) { _memoryBlock.clear(); _data = data; }
00403 
00408   MLEXPORT void setDataFromMemoryBlockHandle(const MLMemoryBlockHandle& data) { _memoryBlock = data; _data = _memoryBlock.data(); }
00409 
00413   inline const MLMemoryBlockHandle& getMemoryBlockHandle() const { return _memoryBlock; }
00414 
00415   //----------------------------------------------------------------------
00420   //----------------------------------------------------------------------
00421   MLEXPORT static MLint coordToIndex(MLint x, MLint y, MLint z, MLint c, MLint t, MLint u, const ImageVector& size);
00422 
00423   //----------------------------------------------------------------------
00427   //----------------------------------------------------------------------
00428   MLEXPORT static MLint coordToIndex(const ImageVector& voxelPosition, const ImageVector& size);
00429 
00430   //----------------------------------------------------------------------
00434   //----------------------------------------------------------------------
00435   MLEXPORT static ImageVector indexToCoord(MLint index, const ImageVector& extent);
00437 
00438 
00439   //---------------------------------------------------------------------------
00441 
00442   //---------------------------------------------------------------------------
00447   inline bool isValidSubImagePosition(const ImageVector& voxelPosition) const
00448   {
00449     ML_TRACE_IN_TIME_CRITICAL( "SubImage::isValidSubImagePosition( )" );
00450     const ImageVector extent = getExtent();
00451     return ((voxelPosition.x>=0)               && (voxelPosition.y>=0)               && (voxelPosition.z>=0)               &&
00452             (voxelPosition.c>=0)               && (voxelPosition.t>=0)               && (voxelPosition.u>=0)               &&
00453             voxelPosition.x < extent.x && voxelPosition.y < extent.y && voxelPosition.z < extent.z &&
00454             voxelPosition.c < extent.c && voxelPosition.t < extent.t && voxelPosition.u < extent.u );
00455   }
00456 
00461   inline bool isValidSubImagePosition(MLint x, MLint y, MLint z) const
00462   {
00463     ML_TRACE_IN_TIME_CRITICAL( "SubImage::isValidSubImagePosition( )" );
00464     const ImageVector extent = getExtent();
00465     return ((x>=0)                 && (y>=0)                 && (z>=0)                &&
00466             (x < extent.x) && (y < extent.y) && (z < extent.z));
00467   }
00468 
00473   inline bool isValidImagePosition(const ImageVector& voxelPosition) const
00474   {
00475     ML_TRACE_IN_TIME_CRITICAL( "SubImage::isValidImagePosition( )" );
00476 
00477     return ((voxelPosition.x>=_box.v1.x) && (voxelPosition.y>=_box.v1.y) && (voxelPosition.z>=_box.v1.z) &&
00478             (voxelPosition.c>=_box.v1.c) && (voxelPosition.t>=_box.v1.t) && (voxelPosition.u>=_box.v1.u) &&
00479             (voxelPosition.x<=_box.v2.x) && (voxelPosition.y<=_box.v2.y) && (voxelPosition.z<=_box.v2.z) &&
00480             (voxelPosition.c<=_box.v2.c) && (voxelPosition.t<=_box.v2.t) && (voxelPosition.u<=_box.v2.u)    );
00481   }
00482 
00487   inline bool isValidImagePosition(MLint x, MLint y, MLint z) const
00488   {
00489     ML_TRACE_IN_TIME_CRITICAL( "SubImage::isValidImagePosition( )" );
00490 
00491     return ((x>=_box.v1.x) && (y>=_box.v1.y) && (z>=_box.v1.z) &&
00492             (x<=_box.v2.x) && (y<=_box.v2.y) && (z<=_box.v2.z)   );
00493   }
00495 
00496   //---------------------------------------------------------------------------
00498 
00499   //---------------------------------------------------------------------------
00515   MLEXPORT void allocate(MLMemoryErrorHandling handleFailure);
00516 
00518   MLEXPORT void allocateAsMemoryBlockHandle(MLMemoryErrorHandling handleFailure = ML_RETURN_NULL);
00519 
00527   MLEXPORT void free();
00529 
00530 
00531   //---------------------------------------------------------------------------
00533 
00534   //---------------------------------------------------------------------------
00535 
00536   //---------------------------------------------------------------------------
00540   //---------------------------------------------------------------------------
00541   MLEXPORT bool isOneValued() const;
00542 
00543   //---------------------------------------------------------------------------
00554   //---------------------------------------------------------------------------
00555   MLEXPORT MLint calculateMinMax(MLdouble& minValue, MLdouble& maxValue,
00556                                  const SubImageBox* const validBox=NULL) const;
00557 
00558   //---------------------------------------------------------------------------
00579   //---------------------------------------------------------------------------
00580   MLEXPORT void compare(const SubImage& subImage2,
00581                         bool*         regionsMatch,
00582                         bool*         dataTypesMatch,
00583                         bool*         thisBoxIsPartOfRegion2,
00584                         bool*         region2IsPartOfThisBox,
00585                         bool*         overlapHasSameValues,
00586                         ImageVector*  firstMismatchPos) const;
00588 
00589 
00590   //-------------------------------------------------------------------------------------------
00592 
00593   //-------------------------------------------------------------------------------------------
00594 
00595   //---------------------------------------------------------------------------
00597   //---------------------------------------------------------------------------
00598   MLEXPORT void fill(MLdouble value);
00599 
00600   //---------------------------------------------------------------------------
00605   //---------------------------------------------------------------------------
00606   MLEXPORT void fillWithTypeData(const MLTypeData* value);
00607 
00608   //-------------------------------------------------------------------------------------------
00613   //-------------------------------------------------------------------------------------------
00614   MLEXPORT void fillBordersWithScalarValue(const SubImageBox &box, MLdouble fillValue);
00615   //-------------------------------------------------------------------------------------------
00616 
00617   //-------------------------------------------------------------------------------------------
00624   //-------------------------------------------------------------------------------------------
00625   MLEXPORT void fillBordersWithTypeData(const SubImageBox &box, const MLTypeData *fillValue);
00626 
00627   //-------------------------------------------------------------------------------------------
00636   //-------------------------------------------------------------------------------------------
00637   MLEXPORT void fillBordersWithInputValues(const SubImageBox &box, const SubImage &inputSubImage);
00638 
00639   //-------------------------------------------------------------------------------------------
00646   //-------------------------------------------------------------------------------------------
00647   MLEXPORT void fillBordersWithBorderValues(const SubImageBox& box);
00648 
00651   inline void fillInvalidRegionWithScalarValue(MLdouble value) {
00652     fillBordersWithScalarValue(getValidRegion(), value);
00653   }
00654 
00657   inline void fillInvalidRegionWithTypeData(const MLTypeData *value) {
00658     fillBordersWithTypeData(getValidRegion(), value);
00659   }
00660 
00664   inline void fillInvalidRegionWithBorderValues() {
00665     fillBordersWithBorderValues(getValidRegion());
00666   }
00667 
00669 
00670   //-------------------------------------------------------------------------------------------
00674   //-------------------------------------------------------------------------------------------
00675   MLEXPORT ImageProperties toImageProperties() const;
00676 
00677   //-------------------------------------------------------------------------------------------
00682   //-------------------------------------------------------------------------------------------
00683   MLEXPORT void setFromImageProperties(const ImageProperties& imageProperties);
00684 
00685   // Debug output to std::ostream, unoptimized
00686   void toStream(std::ostream &ostr) const;
00687 
00688 protected:
00689   //-------------------------------------------------------------------------------------------
00706   //-------------------------------------------------------------------------------------------
00707   void _calcFillAreaParams(const SubImageBox &box,
00708                            const SubImageBox &maxValidInputRegion,
00709                            ImageVector &boxV1,        ImageVector &boxV2,
00710                            ImageVector &outputTSubImageV1, ImageVector &outputTSubImageV2,
00711                            MLint &fullLineLenX,
00712                            MLint &fullLineLenXB,
00713                            MLint &leftLineStartX,
00714                            MLint &leftLineLenX,
00715                            MLint &leftLineLenXB,
00716                            MLint &rightLineStartX,
00717                            MLint &rightLineLenX,
00718                            MLint &rightLineLenXB);
00719   
00721   void _copySubImageGeneric(const SubImage& fromImage, const ScaleShiftData& scaleShiftData);
00722 
00724   const MLTypeInfos* _getDataTypeInfos(MLDataType dt) const;
00725 
00727   SubImageBox _box;
00728 
00730   ImageVector _sourceImageExtent;
00731 
00733   void* _data;
00734 
00736   MLMemoryBlockHandle _memoryBlock;
00737 
00741   ImageVector _stride;
00742 
00744   MLDataType _dataType;
00745 
00746 private:
00749   size_t _dataTypeSize;
00750 
00751 #ifdef ML_DEPRECATED
00752 
00754 
00755 
00756 public:
00757 
00760   inline ML_DEPRECATED SubImageBox getBoxFromImgExt() const { return getBoxFromExtent(); }
00763   inline ML_DEPRECATED ImageVector getImgExt() const {return getImageExtent(); }
00766   inline ML_DEPRECATED void setImgExt(const ImageVector& newExtent) { setImageExtent(newExtent); }
00769   inline ML_DEPRECATED MLint getSize() const { return getNumVoxels(); }
00772   inline ML_DEPRECATED MLint getByteSize() const { return getSizeInBytes(); }
00775   inline ML_DEPRECATED void* getVoidSubImgPos(const ImageVector &p) const { return getSubImagePointer(p); }
00778   inline ML_DEPRECATED void* getVoidSubImgPos(MLint x, MLint y, MLint z) const { return getSubImagePointer(x, y, z); }
00781   inline ML_DEPRECATED void* getVoidImgPos(const ImageVector &p) const { return getImagePointer(p); }
00784   inline ML_DEPRECATED void* getVoidImgPos(MLint x, MLint y, MLint z) const { return getImagePointer(x, y, z); }
00787   inline ML_DEPRECATED MLint isValidSubImgPos(const ImageVector& p) const { return isValidSubImagePosition(p); }
00790   inline ML_DEPRECATED MLint isValidSubImgPos(MLint x, MLint y, MLint z) const { return isValidSubImagePosition(x, y, z); }
00793   inline ML_DEPRECATED MLint isValidImgPos(const ImageVector& p) const { return isValidImagePosition(p); }
00796   inline ML_DEPRECATED MLint isValidImgPos(MLint x, MLint y, MLint z) const { return isValidImagePosition(x, y, z); }
00799   inline ML_DEPRECATED MLint calculateMinMax(MLldouble& minValue, MLldouble& maxValue,
00800                                              const SubImageBox* const validBox=NULL) const { MLdouble tmpMin, tmpMax; MLint result = calculateMinMax(tmpMin, tmpMax, validBox); minValue = tmpMin; maxValue = tmpMax; return result; }
00803   inline ML_DEPRECATED MLint calcMinMax(MLdouble& minVal, MLdouble& maxVal,
00804     const SubImageBox* const validBox=NULL) const { return calculateMinMax(minVal, maxVal, validBox); }
00807   inline ML_DEPRECATED MLint calcMinMax(MLldouble &minValue, MLldouble &maxValue,
00808                                         const SubImageBox * const validBox=NULL) const { MLdouble tmpMin, tmpMax; MLint result = calculateMinMax(tmpMin, tmpMax, validBox); minValue = tmpMin; maxValue = tmpMax; return result; }
00811   inline ML_DEPRECATED void fillSubImg(MLldouble val) { fill(static_cast<MLdouble>(val)); }
00814   inline ML_DEPRECATED void fillSubImgWithTypeData(const MLTypeData *val) { fillWithTypeData(val); }
00817   inline ML_DEPRECATED void fillBordersWithClampedInputValues(const SubImageBox& box) { fillBordersWithBorderValues(box); }
00820   inline ML_DEPRECATED void fillBordersWithLDoubleValue(const SubImageBox &box, MLldouble fillValue) { fillBordersWithScalarValue(box, static_cast<MLdouble>(fillValue)); }
00823   inline ML_DEPRECATED void fillInvalidRegionWithLDoubleValue(MLldouble value) { fillBordersWithScalarValue(getValidRegion(), static_cast<MLdouble>(value)); }
00824 
00825 
00827 
00828 #endif // ML_DEPRECATED
00829 
00830 };
00831 
00832 #ifdef ML_DEPRECATED
00833 
00834 
00835 
00836 
00837 ML_DEPRECATED typedef SubImage SubImg;
00839 #endif // ML_DEPRECATED
00840 
00841 
00842 ML_END_NAMESPACE
00843 
00844 // Stream output for std::ostream
00845 namespace std {
00847   MLEXPORT ostream& operator<<(ostream& s, const ML_NAMESPACE::SubImage &fc);
00848 }
00849 
00850 #endif //of __mlSubImage_H
00851 
00852 
00853 
00854