Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

BitImage3D.hpp

Go to the documentation of this file.
00001 /* ImLib3D
00002  * Copyright (c) 2001, ULP-IPB Strasbourg.
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or (at
00007  * your option) any later version.
00008  * 
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 // temporary object for assigning a value to an image position
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 //          BitValue(const ValueType &_val):ima(NULL),val(_val){}
00105 //          BitValue(float  _val):ima(NULL),val((ValueType)_val){}
00106 //          BitValue(double _val):ima(NULL),val((ValueType)_val){}
00107 };
00108 
00109 // ********************** BitImage3D ********************
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     // ****************** accessors *********************
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         // very simple (but common) case speedup, 1 bit = 1 voxel
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             // must split vpos into two to avoid integer overlow
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                 // clear old value 
00211                 f1&=~(valueMask<<(bitOffsetInField));
00212                 // set new value 
00213                 f1|=(v&valueMask)<<(bitOffsetInField);
00214                 int remainingBits=bitOffsetInField+bitsPerValue-bitsPerField;
00215                 ValueType mask1=((1<<remainingBits)-1);
00216                 // clear old value 
00217                 f2&=~mask1;
00218                 // set new value 
00219                 f2|=(v>>(bitsPerValue-remainingBits))&mask1;
00220             }
00221             else
00222             {
00223                 FieldType &f1=imageData(fieldNumber);
00224                 // clear old value 
00225                 f1&=~(valueMask<<(bitOffsetInField));
00226                 // set new value 
00227                 f1|=(v&valueMask)<<(bitOffsetInField);
00228             }
00229         }
00230     }
00231     inline ValueType Get(size_t vpos) const
00232     {
00233         // very simple (but common) case speedup, 1 bit = 1 voxel
00234         if(bitsPerValue==1 && bitsPerField==8)
00235         {
00236             return imageData(vpos>>3)&(1<<(vpos&7)) ? 1 : 0;
00237         }
00238         else
00239         {
00240             // general case
00241             ValueType res;
00242             // must split vpos into two to avoid integer overlow
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                 // clear old value 
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     // ****************** methods   *********************
00301     // **************************************************
00302 
00304     void  Fill(const ValueType & value)
00305     {
00306         // try to use a smart method for filling 
00307         
00308         // zero : easy, just set everything to zero
00309         if(value==0){imageData.Fill(0);return;}
00310         // integer num of values fit into field : fill image data
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         // the slow way
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         //if (this == &other){return *this;}
00348         // call parent operator =
00349         Image3D::operator=(other);
00350         // now copy the actual image data
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 //      copy(other.begin(),other.end(),begin());
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     // ****************** constructors/destructors*******
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 //      template<class OtherImageType >
00394 //      BitImage3D(const OtherImageType & other):
00395 //          Image3D(other)
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

Generated on Fri Jun 17 13:35:14 2005 for ImLib3D by  doxygen 1.4.2