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 
00123   inline virtual ~SubImage(){ ML_TRACE_IN_TIME_CRITICAL("SubImage::~SubImage()"); }
00124 
00127   inline SubImage &operator=(const SubImage &si)
00128   {
00129     ML_TRACE_IN_TIME_CRITICAL( "SubImage::operator=" );
00130 
00131     if (this != &si)
00132     {
00133       _box           = si._box;
00134       _sourceImageExtent = si._sourceImageExtent;
00135       _data          = si._data;
00136       _memoryBlock   = si._memoryBlock;
00137       _stride        = si._stride;
00138       _dataType      = si._dataType;
00139       _dataTypeSize  = si._dataTypeSize;
00140     }
00141     return *this;
00142   }
00144 
00145   //---------------------------------------------------------------------------
00147 
00148   //---------------------------------------------------------------------------
00151   inline void setBox(const SubImageBox &subImageBox)
00152   {
00153     ML_TRACE_IN_TIME_CRITICAL( "SubImage::setBox( )" );
00154     ML_TRY
00155     {
00156       _box = subImageBox;
00157       _stride.set(subImageBox.getExtent().getStrides());
00158     }
00159     ML_CATCH_RETHROW;
00160   }
00161 
00162 
00166   inline void setBox(const ImageVector &imageExtent)
00167   {
00168     ML_TRACE_IN_TIME_CRITICAL( "SubImage::setBox( )" );
00169     ML_TRY
00170     {
00171       _box = SubImageBox(imageExtent);
00172       _stride.set(imageExtent.getStrides());
00173     }
00174     ML_CATCH_RETHROW;
00175   }
00176 
00178   inline void translate(const ImageVector &offset)
00179   {
00180     ML_TRACE_IN_TIME_CRITICAL("void SubImage::translate(const ImageVector &offset)");
00181 
00182     _box.translate(offset);
00183   }
00184 
00186   inline const ImageVector& getOrigin() const { return _box.v1; }
00187 
00189   inline void setOrigin(const ImageVector& newOrigin) { _box.v1 = newOrigin; }
00190 
00192   inline ImageVector getExtent() const { return _box.getExtent(); }
00193 
00196   inline void setExtent(MLint x, MLint y, MLint z = 1, MLint c = 1, MLint t = 1, MLint u = 1) {
00197     setExtent(ImageVector(x,y,z,c,t,u));
00198   }
00199 
00201   inline void setExtent(const ImageVector& newExtent) {
00202     _box.v2 = _box.v1 + newExtent -1;
00203     _stride.set(newExtent.getStrides());
00204   }
00205 
00207   inline SubImageBox getBoxFromExtent() const  { return SubImageBox(getExtent()); }
00208 
00210 
00211 
00212 
00213   inline SubImageBox getBoxFromImageExtent() const { return getBoxFromExtent(); }
00214 
00217   inline ImageVector getImageExtent() const { return getExtent(); }
00218 
00221   inline void setImageExtent(const ImageVector& newExtent) { setExtent(newExtent);}
00223 
00225   inline const SubImageBox& getBox() const
00226   {
00227     ML_TRACE_IN_TIME_CRITICAL( "SubImage::getBox ( )" );
00228 
00229     return _box;
00230   }
00231 
00234   inline void setSourceImageExtent(const ImageVector& extent) { _sourceImageExtent = extent; }
00235 
00238   inline ImageVector getSourceImageExtent() const { return _sourceImageExtent; }
00239 
00242   inline SubImageBox getValidRegion() const {
00243     SubImageBox sourceBox(_sourceImageExtent);
00244     return SubImageBox::intersect(_box, sourceBox);
00245   }
00246 
00249   inline MLint getNumVoxels() const { return _box.getNumVoxels(); }
00250 
00253   inline MLint getSizeInBytes() const { return getNumVoxels() * static_cast<MLint>(_dataTypeSize); }
00254 
00258   inline ImageVector getStride() const
00259   {
00260     ML_TRACE_IN_TIME_CRITICAL( "SubImage::getStride() const" );
00261 
00262     return _stride;
00263   }
00264 
00266   inline MLint getOffset(const ImageVector& voxelPosition) const
00267   {
00268     ML_TRACE_IN_TIME_CRITICAL( "SubImage::getOffset(const ImageVector &p) const" );
00269 
00270     return ImageVector::dot(voxelPosition,_stride);
00271   }
00273 
00274 
00275   //---------------------------------------------------------------------------
00278   //---------------------------------------------------------------------------
00279   inline void setDataType(MLDataType dataType)
00280   {
00281     ML_TRACE_IN_TIME_CRITICAL("SubImage::setDataType()");
00282 
00283     _dataType = dataType;
00284     _dataTypeSize = MLSizeOf(dataType);
00285   }
00286 
00288   inline MLDataType getDataType() const               { return _dataType;        }
00289 
00291   inline const MLTypeInfos* getDataTypeInfos() const  { return MLGetTypeInfosForDataType(_dataType); }
00292 
00293 
00294   //---------------------------------------------------------------------------
00296 
00297   //---------------------------------------------------------------------------
00301   inline void* getSubImagePointer(const ImageVector &voxelPosition) const
00302   {
00303     // Use pointer arithmetics with one-byte sized data type, therefore we use make a char pointer.
00304     // (casting the offset to an unsigned type is ok - the resulting offset needs to be positive, and because of the wrap-around
00305     //  this would work for negative values anyway)
00306     return static_cast<void*>(static_cast<char*>(_data) + static_cast<size_t>(ImageVector::dot(voxelPosition, _stride) * _dataTypeSize));
00307   }
00308 
00312   inline void* getSubImagePointer(MLint x, MLint y, MLint z) const
00313   {
00314     // Use pointer arithmetics with one-byte sized data type, therefore we use make a char pointer.
00315     // (casting the offset to an unsigned type is ok - the resulting offset needs to be positive, and because of the wrap-around
00316     //  this would work for negative values anyway)
00317     return static_cast<void*>(static_cast<char*>(_data) + static_cast<size_t>((x*_stride.x + y*_stride.y + _stride.z*z) * _dataTypeSize));
00318   }
00319 
00323   inline void* getImagePointer(const ImageVector& voxelPosition) const
00324   {
00325     return getSubImagePointer(voxelPosition-_box.v1);
00326   }
00327 
00331   inline void* getImagePointer(MLint x, MLint y, MLint z) const
00332   {
00333     return getSubImagePointer(x-_box.v1.x, y-_box.v1.y, z-_box.v1.z);
00334   }
00336 
00337 
00338   //---------------------------------------------------------------------------
00340 
00341   //---------------------------------------------------------------------------
00354   MLEXPORT void copySubImage(const SubImage& fromImage, const ScaleShiftData& scaleShiftData);
00355 
00359   MLEXPORT void copySubImage(const SubImage& fromImage);
00360 
00362 
00363   //---------------------------------------------------------------------------
00365 
00366   //---------------------------------------------------------------------------
00369   inline bool isValid() const
00370   {
00371     ML_TRACE_IN_TIME_CRITICAL( "SubImage::isValid( )" );
00372     ML_TRY
00373     {
00374       return (_data!=0) && !(getBox().isEmpty());
00375     }
00376     ML_CATCH_RETHROW;
00377   }
00378 
00380   inline void* getData() const    { return _data; }
00381 
00385   MLEXPORT void setData(void* data) { _memoryBlock.clear(); _data = data; }
00386 
00391   MLEXPORT void setDataFromMemoryBlockHandle(const MLMemoryBlockHandle& data) { _memoryBlock = data; _data = _memoryBlock.data(); }
00392 
00396   inline const MLMemoryBlockHandle& getMemoryBlockHandle() const { return _memoryBlock; }
00397 
00398   //----------------------------------------------------------------------
00403   //----------------------------------------------------------------------
00404   MLEXPORT static MLint coordToIndex(MLint x, MLint y, MLint z, MLint c, MLint t, MLint u, const ImageVector& size);
00405 
00406   //----------------------------------------------------------------------
00410   //----------------------------------------------------------------------
00411   MLEXPORT static MLint coordToIndex(const ImageVector& voxelPosition, const ImageVector& size);
00412 
00413   //----------------------------------------------------------------------
00417   //----------------------------------------------------------------------
00418   MLEXPORT static ImageVector indexToCoord(MLint index, const ImageVector& extent);
00420 
00421 
00422   //---------------------------------------------------------------------------
00424 
00425   //---------------------------------------------------------------------------
00430   inline bool isValidSubImagePosition(const ImageVector& voxelPosition) const
00431   {
00432     ML_TRACE_IN_TIME_CRITICAL( "SubImage::isValidSubImagePosition( )" );
00433     const ImageVector extent = getExtent();
00434     return ((voxelPosition.x>=0)               && (voxelPosition.y>=0)               && (voxelPosition.z>=0)               &&
00435             (voxelPosition.c>=0)               && (voxelPosition.t>=0)               && (voxelPosition.u>=0)               &&
00436             voxelPosition.x < extent.x && voxelPosition.y < extent.y && voxelPosition.z < extent.z &&
00437             voxelPosition.c < extent.c && voxelPosition.t < extent.t && voxelPosition.u < extent.u );
00438   }
00439 
00444   inline bool isValidSubImagePosition(MLint x, MLint y, MLint z) const
00445   {
00446     ML_TRACE_IN_TIME_CRITICAL( "SubImage::isValidSubImagePosition( )" );
00447     const ImageVector extent = getExtent();
00448     return ((x>=0)                 && (y>=0)                 && (z>=0)                &&
00449             (x < extent.x) && (y < extent.y) && (z < extent.z));
00450   }
00451 
00456   inline bool isValidImagePosition(const ImageVector& voxelPosition) const
00457   {
00458     ML_TRACE_IN_TIME_CRITICAL( "SubImage::isValidImagePosition( )" );
00459 
00460     return ((voxelPosition.x>=_box.v1.x) && (voxelPosition.y>=_box.v1.y) && (voxelPosition.z>=_box.v1.z) &&
00461             (voxelPosition.c>=_box.v1.c) && (voxelPosition.t>=_box.v1.t) && (voxelPosition.u>=_box.v1.u) &&
00462             (voxelPosition.x<=_box.v2.x) && (voxelPosition.y<=_box.v2.y) && (voxelPosition.z<=_box.v2.z) &&
00463             (voxelPosition.c<=_box.v2.c) && (voxelPosition.t<=_box.v2.t) && (voxelPosition.u<=_box.v2.u)    );
00464   }
00465 
00470   inline bool isValidImagePosition(MLint x, MLint y, MLint z) const
00471   {
00472     ML_TRACE_IN_TIME_CRITICAL( "SubImage::isValidImagePosition( )" );
00473 
00474     return ((x>=_box.v1.x) && (y>=_box.v1.y) && (z>=_box.v1.z) &&
00475             (x<=_box.v2.x) && (y<=_box.v2.y) && (z<=_box.v2.z)   );
00476   }
00478 
00479   //---------------------------------------------------------------------------
00481 
00482   //---------------------------------------------------------------------------
00498   MLEXPORT void allocate(MLMemoryErrorHandling handleFailure);
00499 
00501   MLEXPORT void allocateAsMemoryBlockHandle(MLMemoryErrorHandling handleFailure = ML_RETURN_NULL);
00502 
00510   MLEXPORT void free();
00512 
00513 
00514   //---------------------------------------------------------------------------
00516 
00517   //---------------------------------------------------------------------------
00518 
00519   //---------------------------------------------------------------------------
00523   //---------------------------------------------------------------------------
00524   MLEXPORT bool isOneValued() const;
00525 
00526   //---------------------------------------------------------------------------
00537   //---------------------------------------------------------------------------
00538   MLEXPORT MLint calculateMinMax(MLdouble& minValue, MLdouble& maxValue,
00539                                  const SubImageBox* const validBox=NULL) const;
00540 
00541   //---------------------------------------------------------------------------
00562   //---------------------------------------------------------------------------
00563   MLEXPORT void compare(const SubImage& subImage2,
00564                         bool*         regionsMatch,
00565                         bool*         dataTypesMatch,
00566                         bool*         thisBoxIsPartOfRegion2,
00567                         bool*         region2IsPartOfThisBox,
00568                         bool*         overlapHasSameValues,
00569                         ImageVector*  firstMismatchPos) const;
00571 
00572 
00573   //-------------------------------------------------------------------------------------------
00575 
00576   //-------------------------------------------------------------------------------------------
00577 
00578   //---------------------------------------------------------------------------
00580   //---------------------------------------------------------------------------
00581   MLEXPORT void fill(MLdouble value);
00582 
00583   //---------------------------------------------------------------------------
00588   //---------------------------------------------------------------------------
00589   MLEXPORT void fillWithTypeData(const MLTypeData* value);
00590 
00591   //-------------------------------------------------------------------------------------------
00596   //-------------------------------------------------------------------------------------------
00597   MLEXPORT void fillBordersWithScalarValue(const SubImageBox &box, MLdouble fillValue);
00598   //-------------------------------------------------------------------------------------------
00599 
00600   //-------------------------------------------------------------------------------------------
00607   //-------------------------------------------------------------------------------------------
00608   MLEXPORT void fillBordersWithTypeData(const SubImageBox &box, const MLTypeData *fillValue);
00609 
00610   //-------------------------------------------------------------------------------------------
00619   //-------------------------------------------------------------------------------------------
00620   MLEXPORT void fillBordersWithInputValues(const SubImageBox &box, const SubImage &inputSubImage);
00621 
00622   //-------------------------------------------------------------------------------------------
00629   //-------------------------------------------------------------------------------------------
00630   MLEXPORT void fillBordersWithBorderValues(const SubImageBox& box);
00631 
00634   inline void fillInvalidRegionWithScalarValue(MLdouble value) {
00635     fillBordersWithScalarValue(getValidRegion(), value);
00636   }
00637 
00640   inline void fillInvalidRegionWithTypeData(const MLTypeData *value) {
00641     fillBordersWithTypeData(getValidRegion(), value);
00642   }
00643 
00647   inline void fillInvalidRegionWithBorderValues() {
00648     fillBordersWithBorderValues(getValidRegion());
00649   }
00650 
00652 
00653   //-------------------------------------------------------------------------------------------
00657   //-------------------------------------------------------------------------------------------
00658   MLEXPORT ImageProperties toImageProperties() const;
00659 
00660   //-------------------------------------------------------------------------------------------
00665   //-------------------------------------------------------------------------------------------
00666   MLEXPORT void setFromImageProperties(const ImageProperties& imageProperties);
00667 
00668   // Debug output to std::ostream, unoptimized
00669   void toStream(std::ostream &ostr) const;
00670 
00671 protected:
00672   //-------------------------------------------------------------------------------------------
00689   //-------------------------------------------------------------------------------------------
00690   void _calcFillAreaParams(const SubImageBox &box,
00691                            const SubImageBox &maxValidInputRegion,
00692                            ImageVector &boxV1,        ImageVector &boxV2,
00693                            ImageVector &outputTSubImageV1, ImageVector &outputTSubImageV2,
00694                            MLint &fullLineLenX,
00695                            MLint &fullLineLenXB,
00696                            MLint &leftLineStartX,
00697                            MLint &leftLineLenX,
00698                            MLint &leftLineLenXB,
00699                            MLint &rightLineStartX,
00700                            MLint &rightLineLenX,
00701                            MLint &rightLineLenXB);
00702   
00704   void _copySubImageGeneric(const SubImage& fromImage, const ScaleShiftData& scaleShiftData);
00705 
00707   const MLTypeInfos* _getDataTypeInfos(MLDataType dt) const;
00708 
00710   SubImageBox _box;
00711 
00713   ImageVector _sourceImageExtent;
00714 
00716   void* _data;
00717 
00719   MLMemoryBlockHandle _memoryBlock;
00720 
00724   ImageVector _stride;
00725 
00727   MLDataType _dataType;
00728 
00729 private:
00732   size_t _dataTypeSize;
00733 
00734 #ifdef ML_DEPRECATED
00735 
00737 
00738 
00739 public:
00740 
00743   inline ML_DEPRECATED SubImageBox getBoxFromImgExt() const { return getBoxFromExtent(); }
00746   inline ML_DEPRECATED ImageVector getImgExt() const {return getImageExtent(); }
00749   inline ML_DEPRECATED void setImgExt(const ImageVector& newExtent) { setImageExtent(newExtent); }
00752   inline ML_DEPRECATED MLint getSize() const { return getNumVoxels(); }
00755   inline ML_DEPRECATED MLint getByteSize() const { return getSizeInBytes(); }
00758   inline ML_DEPRECATED void* getVoidSubImgPos(const ImageVector &p) const { return getSubImagePointer(p); }
00761   inline ML_DEPRECATED void* getVoidSubImgPos(MLint x, MLint y, MLint z) const { return getSubImagePointer(x, y, z); }
00764   inline ML_DEPRECATED void* getVoidImgPos(const ImageVector &p) const { return getImagePointer(p); }
00767   inline ML_DEPRECATED void* getVoidImgPos(MLint x, MLint y, MLint z) const { return getImagePointer(x, y, z); }
00770   inline ML_DEPRECATED MLint isValidSubImgPos(const ImageVector& p) const { return isValidSubImagePosition(p); }
00773   inline ML_DEPRECATED MLint isValidSubImgPos(MLint x, MLint y, MLint z) const { return isValidSubImagePosition(x, y, z); }
00776   inline ML_DEPRECATED MLint isValidImgPos(const ImageVector& p) const { return isValidImagePosition(p); }
00779   inline ML_DEPRECATED MLint isValidImgPos(MLint x, MLint y, MLint z) const { return isValidImagePosition(x, y, z); }
00782   inline ML_DEPRECATED MLint calculateMinMax(MLldouble& minValue, MLldouble& maxValue,
00783                                              const SubImageBox* const validBox=NULL) const { MLdouble tmpMin, tmpMax; MLint result = calculateMinMax(tmpMin, tmpMax, validBox); minValue = tmpMin; maxValue = tmpMax; return result; }
00786   inline ML_DEPRECATED MLint calcMinMax(MLdouble& minVal, MLdouble& maxVal,
00787     const SubImageBox* const validBox=NULL) const { return calculateMinMax(minVal, maxVal, validBox); }
00790   inline ML_DEPRECATED MLint calcMinMax(MLldouble &minValue, MLldouble &maxValue,
00791                                         const SubImageBox * const validBox=NULL) const { MLdouble tmpMin, tmpMax; MLint result = calculateMinMax(tmpMin, tmpMax, validBox); minValue = tmpMin; maxValue = tmpMax; return result; }
00794   inline ML_DEPRECATED void fillSubImg(MLldouble val) { fill(static_cast<MLdouble>(val)); }
00797   inline ML_DEPRECATED void fillSubImgWithTypeData(const MLTypeData *val) { fillWithTypeData(val); }
00800   inline ML_DEPRECATED void fillBordersWithClampedInputValues(const SubImageBox& box) { fillBordersWithBorderValues(box); }
00803   inline ML_DEPRECATED void fillBordersWithLDoubleValue(const SubImageBox &box, MLldouble fillValue) { fillBordersWithScalarValue(box, static_cast<MLdouble>(fillValue)); }
00806   inline ML_DEPRECATED void fillInvalidRegionWithLDoubleValue(MLldouble value) { fillBordersWithScalarValue(getValidRegion(), static_cast<MLdouble>(value)); }
00807 
00808 
00810 
00811 #endif // ML_DEPRECATED
00812 
00813 };
00814 
00815 #ifdef ML_DEPRECATED
00816 
00817 
00818 
00819 
00820 ML_DEPRECATED typedef SubImage SubImg;
00822 #endif // ML_DEPRECATED
00823 
00824 
00825 ML_END_NAMESPACE
00826 
00827 // Stream output for std::ostream
00828 namespace std {
00830   MLEXPORT ostream& operator<<(ostream& s, const ML_NAMESPACE::SubImage &fc);
00831 }
00832 
00833 #endif //of __mlSubImage_H
00834 
00835 
00836 
00837