00001
00002 #ifndef vil3d_image_view_txx_
00003 #define vil3d_image_view_txx_
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "vil3d_image_view.h"
00017 #include <vcl_cstring.h>
00018 #include <vcl_string.h>
00019 #include <vcl_cassert.h>
00020 #include <vcl_ostream.h>
00021 #include <vcl_algorithm.h>
00022 #include <vil/vil_pixel_format.h>
00023
00024
00025
00026 template<class T>
00027 vil3d_image_view<T>::vil3d_image_view()
00028 : top_left_(0),istep_(0),jstep_(0),kstep_(0),planestep_(0)
00029 {}
00030
00031 template<class T>
00032 vil3d_image_view<T>::vil3d_image_view(unsigned ni, unsigned nj,
00033 unsigned nk, unsigned n_planes)
00034 : top_left_(0),istep_(1),jstep_(0),kstep_(0)
00035 {
00036 set_size(ni,nj,nk,n_planes);
00037 }
00038
00039
00040 template<class T>
00041 vil3d_image_view<T>::vil3d_image_view(const T* top_left,
00042 unsigned n_i, unsigned n_j, unsigned n_k, unsigned n_planes,
00043 vcl_ptrdiff_t i_step, vcl_ptrdiff_t j_step,
00044 vcl_ptrdiff_t k_step, vcl_ptrdiff_t plane_step)
00045 {
00046 set_to_memory(top_left,n_i,n_j,n_k,n_planes,i_step,j_step,k_step,plane_step);
00047 }
00048
00049
00050
00051 template<class T>
00052 vil3d_image_view<T>::vil3d_image_view(const vil_memory_chunk_sptr& mem_chunk,
00053 const T* top_left, unsigned n_i, unsigned n_j,
00054 unsigned n_k, unsigned n_planes,
00055 vcl_ptrdiff_t i_step, vcl_ptrdiff_t j_step,
00056 vcl_ptrdiff_t k_step, vcl_ptrdiff_t plane_step)
00057 : vil3d_image_view_base(n_i, n_j, n_k, n_planes)
00058 , top_left_(const_cast<T*>(top_left))
00059 , istep_(i_step), jstep_(j_step), kstep_(k_step)
00060 , planestep_(plane_step)
00061 , ptr_(mem_chunk)
00062 {
00063 if (mem_chunk)
00064 {
00065
00066 assert(mem_chunk->size() >= n_planes*n_i*n_j*n_k*sizeof(T));
00067 if (size() && (top_left < reinterpret_cast<const T*>(mem_chunk->data()) ||
00068 top_left >= reinterpret_cast<const T*>(reinterpret_cast<char*>(mem_chunk->data()) + mem_chunk->size()) ))
00069 vcl_cerr << "top_left at " << static_cast<const void*>(top_left) << ", memory_chunk at "
00070 << reinterpret_cast<const void*>(mem_chunk->data()) << ", size " << mem_chunk->size()
00071 << ", size of data type " << sizeof(T) << '\n';
00072 assert(!size() || (top_left >= reinterpret_cast<const T*>(mem_chunk->data()) &&
00073 top_left < reinterpret_cast<const T*>(reinterpret_cast<char*>(mem_chunk->data()) + mem_chunk->size()) ));
00074 }
00075 }
00076
00077
00078
00079
00080 template<class T>
00081 vil3d_image_view<T>::vil3d_image_view(const vil3d_image_view<T>& im)
00082 : vil3d_image_view_base(im.ni(), im.nj(), im.nk(), im.nplanes()),
00083 top_left_(im.top_left_), istep_(im.istep()), jstep_(im.jstep()),
00084 kstep_(im.kstep()), planestep_(im.planestep()), ptr_(im.memory_chunk())
00085 {
00086 if (static_cast<vil3d_image_view_base const&>(im).pixel_format() != pixel_format())
00087 clear();
00088 }
00089
00090
00091
00092 template<class T>
00093 vil3d_image_view<T>::vil3d_image_view(const vil3d_image_view_base& base_ref)
00094 : top_left_(0),istep_(0),jstep_(0),kstep_(0),planestep_(0)
00095 {
00096 operator=(base_ref);
00097 }
00098
00099
00100
00101 template<class T>
00102 vil3d_image_view<T>::vil3d_image_view(const vil3d_image_view_base_sptr& base_sptr)
00103 : top_left_(0),istep_(0),jstep_(0),kstep_(0),planestep_(0)
00104 {
00105 operator=(base_sptr);
00106 }
00107
00108
00109 template<class T>
00110 const vil3d_image_view<T>& vil3d_image_view<T>::operator=(const vil3d_image_view<T>& rhs)
00111 {
00112 return operator=( static_cast<vil3d_image_view_base const&>(rhs) );
00113 }
00114
00115
00116
00117 template<class T>
00118 const vil3d_image_view<T>& vil3d_image_view<T>::operator=(const vil3d_image_view_base& base_ref)
00119 {
00120 if (static_cast<const vil3d_image_view_base*>(this) == &base_ref)
00121 return *this;
00122
00123 if (base_ref.pixel_format() == pixel_format())
00124 {
00125 const vil3d_image_view<T> &that = static_cast<const vil3d_image_view<T>&>(base_ref);
00126 ni_=that.ni_;
00127 nj_=that.nj_;
00128 nk_=that.nk_;
00129 nplanes_=that.nplanes_;
00130 istep_=that.istep_;
00131 jstep_=that.jstep_;
00132 kstep_=that.kstep_;
00133 planestep_=that.planestep_;
00134 top_left_=that.top_left_;
00135 ptr_=that.ptr_;
00136 return *this;
00137 }
00138
00139 clear();
00140 return *this;
00141 }
00142
00143
00144 template<class T>
00145 void vil3d_image_view<T>::deep_copy(const vil3d_image_view<T>& src)
00146 {
00147 set_size(src.ni(),src.nj(),src.nk(),src.nplanes());
00148
00149 vcl_ptrdiff_t s_planestep = src.planestep();
00150 vcl_ptrdiff_t s_istep = src.istep();
00151 vcl_ptrdiff_t s_jstep = src.jstep();
00152 vcl_ptrdiff_t s_kstep = src.kstep();
00153
00154
00155
00156 const T* src_data = src.origin_ptr();
00157 T* data = top_left_;
00158 for (unsigned int p=0;p<nplanes_;++p,src_data+=s_planestep,data+=planestep_)
00159 {
00160 T* slice = data;
00161 const T* src_slice = src_data;
00162 for (unsigned int k=0;k<nk_;++k,slice+=kstep_,src_slice+=s_kstep)
00163 {
00164 T* row = slice;
00165 const T* src_row = src_slice;
00166 for (unsigned int j=0;j<nj_;++j,row += jstep_,src_row += s_jstep)
00167 {
00168 T* p = row;
00169 const T* sp = src_row;
00170 for (unsigned int i=0;i<ni_;++i,p+=istep_,sp+=s_istep) *p = *sp;
00171 }
00172 }
00173 }
00174 }
00175
00176
00177 template<class T> vil3d_image_view<T>::~vil3d_image_view()
00178 {
00179
00180 }
00181
00182
00183
00184 template<class T>
00185 void vil3d_image_view<T>::set_size(unsigned n_i, unsigned n_j, unsigned n_k)
00186 {
00187 set_size(n_i,n_j,n_k, nplanes_);
00188 }
00189
00190
00191 template<class T>
00192 bool vil3d_image_view<T>::is_contiguous() const
00193 {
00194
00195 if (planestep_==int(ni_*nj_*nk_))
00196 {
00197 if (istep_==1 && jstep_==int(ni_) && kstep_==int(ni_*nj_) ) return true;
00198 if (istep_==1 && kstep_==int(ni_) && jstep_==int(ni_*nk_) ) return true;
00199 if (jstep_==1 && istep_==int(nj_) && kstep_==int(ni_*nj_) ) return true;
00200 if (jstep_==1 && kstep_==int(nj_) && istep_==int(nj_*nk_) ) return true;
00201 if (kstep_==1 && istep_==int(nk_) && jstep_==int(ni_*nk_) ) return true;
00202 if (kstep_==1 && jstep_==int(nk_) && istep_==int(nj_*nk_) ) return true;
00203 }
00204
00205 int np = nplanes_;
00206
00207 if (planestep_==1)
00208 {
00209 if (istep_==np && jstep_==int(ni_*np) && kstep_==int(ni_*nj_*np) ) return true;
00210 if (istep_==np && kstep_==int(ni_*np) && jstep_==int(ni_*nk_*np) ) return true;
00211 if (jstep_==np && istep_==int(nj_*np) && kstep_==int(ni_*nj_*np) ) return true;
00212 if (jstep_==np && kstep_==int(nj_*np) && istep_==int(nj_*nk_*np) ) return true;
00213 if (kstep_==np && istep_==int(nk_*np) && jstep_==int(ni_*nk_*np) ) return true;
00214 if (kstep_==np && jstep_==int(nk_*np) && istep_==int(nj_*nk_*np) ) return true;
00215 }
00216
00217
00218 return false;
00219 }
00220
00221
00222
00223 template<class T>
00224 void vil3d_image_view<T>::set_size(unsigned n_i, unsigned n_j, unsigned n_k, unsigned n_planes)
00225 {
00226 if (n_i==ni_ && n_j==nj_ && n_k==nk_ && n_planes==nplanes_) return;
00227
00228 release_memory();
00229
00230 vil_pixel_format fmt = vil_pixel_format_of(T());
00231 ptr_ = new vil_memory_chunk(sizeof(T)*n_planes*n_k*n_j*n_i,
00232 vil_pixel_format_component_format(fmt));
00233
00234 ni_ = n_i;
00235 nj_ = n_j;
00236 nk_ = n_k;
00237 nplanes_ = n_planes;
00238 istep_ = 1;
00239 jstep_ = n_i;
00240 kstep_ = n_i*n_j;
00241 planestep_ = n_i*n_j*n_k;
00242
00243 top_left_ = reinterpret_cast<T*>(ptr_->data());
00244 }
00245
00246
00247
00248 template<class T>
00249 void vil3d_image_view<T>::set_to_memory(const T* top_left,
00250 unsigned n_i, unsigned n_j,
00251 unsigned n_k, unsigned n_planes,
00252 vcl_ptrdiff_t i_step, vcl_ptrdiff_t j_step,
00253 vcl_ptrdiff_t k_step, vcl_ptrdiff_t plane_step)
00254 {
00255 release_memory();
00256 top_left_ = const_cast<T*>(top_left);
00257
00258 ni_ = n_i;
00259 nj_ = n_j;
00260 nk_ = n_k;
00261 nplanes_ = n_planes;
00262 istep_ = i_step;
00263 jstep_ = j_step;
00264 kstep_ = k_step;
00265 planestep_ = plane_step;
00266 }
00267
00268
00269
00270 template<class T>
00271 void vil3d_image_view<T>::fill(T value)
00272 {
00273 if (is_contiguous())
00274 if (value == 0)
00275 vcl_memset(begin(), 0, this->size_bytes());
00276 else
00277 vcl_fill(begin(), end(), value);
00278 else
00279 {
00280 T* plane = top_left_;
00281 for (unsigned int p=0;p<nplanes_;++p,plane += planestep_)
00282 {
00283 T* slice = plane;
00284 for (unsigned int k=0;k<nk_;++k,slice += kstep_)
00285 {
00286 T* row = slice;
00287 for (unsigned int j=0;j<nj_;++j,row += jstep_)
00288 {
00289 T* p = row;
00290 for (unsigned int i=0;i<ni_;++i,p+=istep_) *p = value;
00291 }
00292 }
00293 }
00294 }
00295 }
00296
00297
00298
00299 template<class T>
00300 bool vil3d_image_view<T>::is_class(vcl_string const& s) const
00301 {
00302 return s==vil3d_image_view<T>::is_a() || vil3d_image_view_base::is_class(s);
00303 }
00304
00305
00306
00307 template<class T>
00308 void vil3d_image_view<T>::print(vcl_ostream& os) const
00309 {
00310 os<<nplanes_<<" planes, each "<<ni_<<" x "<<nj_<<" x "<<nk_;
00311 }
00312
00313
00314
00315
00316
00317
00318 template<class T>
00319 bool vil3d_image_view<T>::operator==(const vil3d_image_view<T> &other) const
00320 {
00321 if (!(bool) *this && !(bool)other) return true;
00322 return ptr_ == other.ptr_ &&
00323 top_left_ == other.top_left_ &&
00324 nplanes_ == other.nplanes_ &&
00325 ni_ == other.ni_ &&
00326 nj_ == other.nj_ &&
00327 nk_ == other.nk_ &&
00328 planestep_ == other.planestep_ &&
00329 istep_ == other.istep_ &&
00330 jstep_ == other.jstep_ &&
00331 kstep_ == other.kstep_;
00332 }
00333
00334
00335
00336
00337
00338
00339 template<class T>
00340 bool vil3d_image_view<T>::operator<(const vil3d_image_view<T>& other) const
00341 {
00342 if (ptr_ != other.ptr_) return ptr_<other.ptr_;
00343 if ((bool) *this && (bool)other) return false;
00344 if (nplanes_ != other.nplanes_) return nplanes_ < other.nplanes_;
00345 if (ni_ != other.ni_) return ni_ < other.ni_;
00346 if (nj_ != other.nj_) return nj_ < other.nj_;
00347 if (nk_ != other.nk_) return nk_ < other.nk_;
00348 if (planestep_ != other.planestep_) return planestep_ < other.planestep_;
00349 if (istep_ != other.istep_) return istep_ < other.istep_;
00350 if (jstep_ != other.jstep_) return jstep_ < other.jstep_;
00351 return kstep_ < other.kstep_;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361 template<class T>
00362 bool vil3d_image_view_deep_equality(const vil3d_image_view<T> &lhs,
00363 const vil3d_image_view<T> &rhs)
00364 {
00365 if (lhs.nplanes() != rhs.nplanes() ||
00366 lhs.nk() != rhs.nk() ||
00367 lhs.nj() != rhs.nj() ||
00368 lhs.ni() != rhs.ni())
00369 return false;
00370
00371 for (unsigned p = 0; p < rhs.nplanes(); ++p)
00372 for (unsigned k = 0; k < rhs.nk(); ++k)
00373 for (unsigned j = 0; j < rhs.nj(); ++j)
00374 for (unsigned i = 0; i < rhs.ni(); ++i)
00375 if (!(rhs(i,j,k,p) == lhs(i,j,k,p)))
00376 return false;
00377 return true;
00378 }
00379
00380 #define VIL3D_IMAGE_VIEW_INSTANTIATE(T) \
00381 VCL_DEFINE_SPECIALIZATION vcl_string vil3d_image_view<T >::is_a() const \
00382 { return vcl_string("vil3d_image_view<" #T ">"); } \
00383 template class vil3d_image_view<T >; \
00384 template bool vil3d_image_view_deep_equality(const vil3d_image_view<T >&, \
00385 const vil3d_image_view<T >&)
00386
00387 #endif // vil3d_image_view_txx_