00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00021 #ifndef _BitImage3D_hpp
00022 #define _BitImage3D_hpp
00023
00024 #include<imlib3dconfig.h>
00025
00026 #include<ImLib3D/CppTools.hpp>
00027 #include<ImLib3D/RectZone3D.hpp>
00028 #include<ImLib3D/Vect3D.hpp>
00029 #include <assert.h>
00030 #include <fstream>
00031 #include<ImLib3D/ImLib3DFile.hpp>
00032 #include<ImLib3D/Size3D.hpp>
00033 #include<ImLib3D/Properties.hpp>
00034 #include<ImLib3D/Image3D.hpp>
00035
00036
00037 #define bitsPerField (8*sizeof(FieldType))
00038 #define valuesPerField (bitsPerField/bitsPerValue)
00039 #define valueMask ((1<<bitsPerValue)-1)
00040
00041
00042
00043
00044 #define _BitImage3D_internal
00045 #include<ImLib3D/BitImage3DIterators.hpp>
00046 #undef _BitImage3D_internal
00047
00048
00049 extern void BitImage3D_Test();
00050
00051 template<class FieldType,int bitsPerValue,class ValueType> class BitImage3D;
00052
00053
00054 template<class FieldType,int bitsPerValue,class ValueType>
00055 class BitImage3DValue
00056 {
00057 typedef BitImage3D<FieldType,bitsPerValue,ValueType> ImageType;
00058 typedef BitImage3DValue _Self;
00059 ImageType *ima;
00060 size_t vpos;
00061 ValueType val;
00062 inline ValueType Get() const {return ima ? ima->Get(vpos) : val;}
00063 inline void Set(const ValueType &v) {if(ima){ima->Set(vpos,v);}else{val=v;}}
00064 public:
00065 inline bool operator< (const _Self &other){return Get()< other.Get();}
00066 inline bool operator<=(const _Self &other){return Get()<=other.Get();}
00067 inline bool operator> (const _Self &other){return Get()> other.Get();}
00068 inline bool operator>=(const _Self &other){return Get()>=other.Get();}
00069
00070 inline _Self &operator+=(const _Self &other){Set(Get()+other.Get());return *this;}
00071 inline _Self &operator-=(const _Self &other){Set(Get()-other.Get());return *this;}
00072 inline _Self &operator*=(const _Self &other){Set(Get()*other.Get());return *this;}
00073 inline _Self &operator/=(const _Self &other){Set(Get()/other.Get());return *this;}
00074
00075 inline bool operator< (ValueType v){return Get()< v;}
00076 inline bool operator<=(ValueType v){return Get()<=v;}
00077 inline bool operator> (ValueType v){return Get()> v;}
00078 inline bool operator>=(ValueType v){return Get()>=v;}
00079
00080 inline bool operator==(const _Self &other){return Get()==other.Get();}
00081 inline bool operator!=(const _Self &other){return Get()!=other.Get();}
00082
00083 inline bool operator==(ValueType v){return Get()==v;}
00084 inline bool operator!=(ValueType v){return Get()!=v;}
00085
00086 template<class FieldType1,int bitsPerValue1,class ValueType1>
00087 inline void operator=(const BitImage3DValue<FieldType1,bitsPerValue1,ValueType1> &other)
00088 {Set((ValueType1)other);}
00089
00090 inline void operator=(const ValueType &v){Set(v);}
00091 inline void operator=(const _Self &other){Set(other.Get());}
00092
00093 inline operator ValueType() const {return Get();}
00094
00095 BitImage3DValue(ImageType *_ima,int _vpos):ima(_ima),vpos(_vpos){}
00096 BitImage3DValue(const ImageType *_ima,int _vpos):
00097 ima((ImageType *)_ima),vpos(_vpos){}
00098 BitImage3DValue():ima(NULL){}
00099 BitImage3DValue(const BitImage3DValue &other):
00100 ima((ImageType *)other.ima),vpos(other.vpos),val(other.val){}
00101
00102 template<class NumType>
00103 BitImage3DValue(NumType _val):ima(NULL),val((ValueType)_val){}
00104
00105
00106
00107 };
00108
00109
00111
00116
00117 template<class FieldType,int bitsPerValue,class ValueType=FieldType>
00118 class BitImage3D : public Image3D , public MaskConcept<BitImage3D<FieldType,bitsPerValue,ValueType> >
00119 {
00120 public:
00121 typedef BitImage3DValue<FieldType,bitsPerValue,ValueType> BitValue;
00122 private:
00123 friend class BitImage3DValue<FieldType,bitsPerValue,ValueType>;
00124 typedef BitImage3D<FieldType,bitsPerValue,ValueType> _Self;
00125 typedef Container3D<FieldType> FieldImage;
00127 FieldImage imageData;
00129 int widthXheight;
00130
00131 public:
00133 typedef BitValue value_type;
00134 typedef ValueType Value;
00135 public:
00137
00138 typedef BIM3D_iteratorFast<BitImage3D,BitValue> iterator;
00139 typedef BIM3D_iteratorFast<BitImage3D,BitValue> iteratorFast;
00140 typedef BIM3D_iteratorXYZ< BitImage3D,BitValue> iteratorXYZ;
00141 typedef BIM3D_iteratorZone<BitImage3D,BitValue> iteratorZone;
00142
00143 typedef BIM3D_iteratorFast<const BitImage3D,const BitValue> const_iterator;
00144 typedef BIM3D_iteratorFast<const BitImage3D,const BitValue> const_iteratorFast;
00145 typedef BIM3D_iteratorXYZ< const BitImage3D,const BitValue> const_iteratorXYZ;
00146 typedef BIM3D_iteratorZone<const BitImage3D,const BitValue> const_iteratorZone;
00147
00148 typedef iterator iteratorFastMasked;
00149 typedef const_iterator const_iteratorFastMasked;
00150
00151 typedef reverse_iterator<const_iterator> const_reverse_iterator;
00152 typedef reverse_iterator< iterator> reverse_iterator;
00154
00156 iterator imageDataEnd;
00157 const_iterator const_imageDataEnd;
00158
00159 public:
00161
00162 iteratorFast begin() {return iteratorFast(this,0);}
00163 const_iteratorFast begin() const {return const_iteratorFast(this,0);}
00165 inline iteratorFast end() {return imageDataEnd;}
00166 inline const_iteratorFast end() const {return const_imageDataEnd;}
00167
00168 inline reverse_iterator rbegin() { return reverse_iterator(end()); }
00169 inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
00170 inline reverse_iterator rend() { return reverse_iterator(begin()); }
00171 inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00172
00174
00175
00176
00178 RectZone3Df &AddSupport(const Vect3Df &p0,const Vect3Df &p1)
00179 {properties.Add("Support",RectZone3Df(p0,p1));return Support();}
00180 RectZone3Df &Support() {return Property<RectZone3Df>("Support");}
00181 RectZone3Df const &Support() const {return Property<RectZone3Df>("Support");}
00183
00184
00185 inline FieldImage GetData() {return imageData;}
00186 inline const FieldImage GetData() const {return imageData;}
00188
00190 private:
00191 inline void Set(size_t vpos,ValueType v)
00192 {
00193
00194 if(bitsPerValue==1 && bitsPerField==8)
00195 {
00196 if(v&1){imageData(vpos>>3)|= (1<<(vpos&7));}
00197 else {imageData(vpos>>3)&=~(1<<(vpos&7));}
00198 }
00199 else
00200 {
00201
00202 size_t a=vpos>>16;
00203 size_t b=vpos&((1<<16)-1);
00204 size_t fieldNumber=(a*bitsPerValue)*((1<<16)/bitsPerField)+(b*bitsPerValue)/bitsPerField;
00205 size_t bitOffsetInField=(b*bitsPerValue)%bitsPerField;
00206 if(bitOffsetInField>(bitsPerField-bitsPerValue))
00207 {
00208 FieldType &f1=imageData(fieldNumber);
00209 FieldType &f2=imageData(fieldNumber+1);
00210
00211 f1&=~(valueMask<<(bitOffsetInField));
00212
00213 f1|=(v&valueMask)<<(bitOffsetInField);
00214 int remainingBits=bitOffsetInField+bitsPerValue-bitsPerField;
00215 ValueType mask1=((1<<remainingBits)-1);
00216
00217 f2&=~mask1;
00218
00219 f2|=(v>>(bitsPerValue-remainingBits))&mask1;
00220 }
00221 else
00222 {
00223 FieldType &f1=imageData(fieldNumber);
00224
00225 f1&=~(valueMask<<(bitOffsetInField));
00226
00227 f1|=(v&valueMask)<<(bitOffsetInField);
00228 }
00229 }
00230 }
00231 inline ValueType Get(size_t vpos) const
00232 {
00233
00234 if(bitsPerValue==1 && bitsPerField==8)
00235 {
00236 return imageData(vpos>>3)&(1<<(vpos&7)) ? 1 : 0;
00237 }
00238 else
00239 {
00240
00241 ValueType res;
00242
00243 size_t a=vpos>>16;
00244 size_t b=vpos&((1<<16)-1);
00245 size_t fieldNumber=(a*bitsPerValue)*((1<<16)/bitsPerField)+(b*bitsPerValue)/bitsPerField;
00246 size_t bitOffsetInField=(b*bitsPerValue)%bitsPerField;
00247 if(bitOffsetInField>(bitsPerField-bitsPerValue))
00248 {
00249 const FieldType &f1=imageData(fieldNumber);
00250 const FieldType &f2=imageData(fieldNumber+1);
00251 int remainingBits=bitOffsetInField+bitsPerValue-bitsPerField;
00252
00253 res=f2&((1<<remainingBits)-1);
00254 res<<=bitsPerValue-remainingBits;
00255 res|=(f1>>bitOffsetInField)&((1<<(bitsPerValue-remainingBits))-1);
00256 return res;
00257 }
00258 else
00259 {
00260 const FieldType &f1=imageData(fieldNumber);
00261 res=(f1>>bitOffsetInField)&valueMask;
00262 return res;
00263 }
00264 }
00265 }
00266 public:
00267 #ifdef SAFE_DEBUG
00268 inline BitValue operator()(int pos) {AssertBounds(pos);return BitValue(this,pos);}
00269 inline BitValue operator()(int pos) const {AssertBounds(pos);return Get(pos);}
00270 inline BitValue operator()(int x,int y,int z)
00271 {AssertBounds(x,y,z);return BitValue(this,x+y*width+z*widthXheight);}
00272 inline BitValue operator()(int x,int y,int z) const
00273 {AssertBounds(x,y,z);return Get(x+y*width+z*widthXheight);}
00274 inline BitValue operator()(const Vect3Di &v)
00275 {AssertBounds(v.x,v.y,v.z);return BitValue(this,v.x+v.y*width+v.z*widthXheight);}
00276 inline BitValue operator()(const Vect3Di &v) const
00277 {AssertBounds(v.x,v.y,v.z);return Get(v.x+v.y*width+v.z*widthXheight);}
00278 #else //SAFE_DEBUG
00279 inline BitValue operator()(int pos) {return BitValue(this,pos);}
00280 inline BitValue operator()(int pos) const {return Get(pos);}
00281 inline BitValue operator()(int x,int y,int z) {return BitValue(this,x+y*width+z*widthXheight);}
00282 inline BitValue operator()(int x,int y,int z) const {return Get(x+y*width+z*widthXheight);}
00283 inline BitValue operator()(const Vect3Di &v) {return BitValue(this,v.x+v.y*width+v.z*widthXheight);}
00284 inline BitValue operator()(const Vect3Di &v) const {return Get(v.x+v.y*width+v.z*widthXheight);}
00285 #endif //SAFE_DEBUG
00286 virtual float FloatValue(int x,int y,int z) const {return (float)(*this)(x,y,z);}
00288
00290 _Self& operator+=(const _Self &im);
00291 _Self& operator+=(const FieldType &scalarValue);
00292 _Self& operator-=(const _Self &im);
00293 _Self& operator-=(const FieldType &scalarValue);
00294 _Self& operator*=(const _Self &im);
00295 _Self& operator*=(double scalarValue);
00296 _Self& operator/=(const _Self &im);
00297
00298
00299
00300
00301
00302
00304 void Fill(const ValueType & value)
00305 {
00306
00307
00308
00309 if(value==0){imageData.Fill(0);return;}
00310
00311 if((bitsPerField%bitsPerValue)==0 && imageData.GetNVoxels()!=0)
00312 {
00313 for(uint i=0;i<valuesPerField;i++){(*this)(i)=value;}
00314 FieldType fval=imageData(0);
00315 imageData.Fill(fval);
00316 return;
00317 }
00318
00319 fill(begin(),end(),value);
00320 }
00321
00323 public:
00324 virtual string GetTypeName() const;
00326
00331 virtual void Read( ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL) ;
00332 virtual void Write(ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL) const;
00333 public:
00335 virtual void WriteToFile (const string &fname) const {Streamable::WriteToFile(fname);}
00337
00338 public:
00339 void Resize(const Size3D &newSize);
00340
00342 _Self& operator= (const _Self & other);
00343 template<class OtherImageType >
00344 _Self& operator= (const OtherImageType & other)
00345 {
00346 if(other.Size()!=Size()){Resize(other.Size());}
00347
00348
00349 Image3D::operator=(other);
00350
00351 iteratorFast p;
00352 typename OtherImageType::const_iteratorFast op;
00353 for(p=begin(),op=other.begin();p!=end();++p,op++)
00354 {
00355 *p=(value_type)(*op);
00356 }
00357
00358 return *this;
00359 }
00360
00361 bool operator==(const _Self & other) const;
00362 bool operator!=(const _Self & other) const {return !(this->operator==(other));}
00363 template<class OtherImage >
00364 bool operator== (const OtherImage & other){return Size()==other.Size() && equal(other.begin(),other.end(),begin());}
00365 template<class OtherImage >
00366 bool operator!= (const OtherImage & other){return !((*this)==other);}
00368
00369 BitValue SafeValue(int pos) const {return IsInside(pos) ? Get(pos) : 0;}
00370 BitValue SafeValue(int x,int y,int z) const
00371 {return IsInside(x,y,z) ? (*this)(x,y,z) : BitValue(0) ;}
00372 BitValue SafeValue(const Vect3Di &v) const
00373 {return IsInside(v ) ? (*this)(v ) : BitValue(0) ;}
00374
00375
00376
00377
00378
00380
00381 public:
00383 virtual ~BitImage3D();
00384 public:
00385 BitImage3D();
00386 BitImage3D(int _width, int _height, int _depth);
00387 explicit BitImage3D(const string& fname){ReadFromFile(fname);}
00388 explicit BitImage3D(const char *fname){ReadFromFile(fname);}
00389 explicit BitImage3D( char *fname){ReadFromFile(fname);}
00391 BitImage3D(const Size3D &size);
00392 BitImage3D(const BitImage3D & origCont);
00393
00394
00395
00396
00398 };
00399
00400
00401 template<class FieldType,int bitsPerValue,class ValueType>
00402 struct HasPointerIterators<BitImage3D<FieldType,bitsPerValue,ValueType> >
00403 {
00404 typedef __false_type value;
00405 };
00406
00407 template<class FieldType,int bitsPerValue,class ValueType>
00408 struct HasPointerIterators<const BitImage3D<FieldType,bitsPerValue,ValueType> >
00409 {
00410 typedef __false_type value;
00411 };
00412
00413
00414 typedef BitImage3D<byte,1,byte> BitMask3D;
00415
00416 #include<ImLib3D/BitImage3D.hxx>
00417 #undef bitsPerField
00418 #undef valuesPerField
00419 #undef valueMask
00420
00421 #endif // _BitImage3D_hpp