00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef OLENA_CORE_IMPL_IMAGE_ARRAY3D_HH
00029 # define OLENA_CORE_IMPL_IMAGE_ARRAY3D_HH
00030
00031 # include <oln/core/impl/image_array.hh>
00032 # include <oln/core/image3d_size.hh>
00033 # include <oln/core/point3d.hh>
00034
00035 namespace oln {
00036
00038
00039 template<class T>
00040 void
00041 pretreat_3d_data_(T*& buffer, T**& array2, T***& array,
00042 const image3d_size& s)
00043 {
00044 precondition(s.nslices() > 0
00045 && s.nrows() > 0
00046 && s.ncols() > 0
00047 && s.border() >= 0);
00048 coord nslices_eff = s.nslices() + 2 * s.border();
00049 coord nrows_eff = s.nrows() + 2 * s.border();
00050 coord ncols_eff = s.ncols() + 2 * s.border();
00051 array = new T**[size_t(nslices_eff)];
00052 array2 = new T*[size_t(nslices_eff)
00053 * size_t(nrows_eff)];
00054 T* buf = buffer + s.border();
00055
00056 for (coord slice = 0; slice < nslices_eff; ++slice)
00057 {
00058 T** a2 = array2 + slice * nrows_eff;
00059 array[slice] = a2 + s.border();
00060 for (coord row = 0; row < nrows_eff; ++row)
00061 {
00062 a2[row] = buf;
00063 buf += ncols_eff;
00064 }
00065 }
00066 array += s.border();
00067 }
00068
00070
00071 template<class T>
00072 void
00073 desallocate_3d_data_(T**& array2, T***& array, const
00074 image3d_size& s)
00075 {
00076 delete[] array2;
00077 array2 = 0;
00078 array -= s.border();
00079 delete[] array;
00080 array = 0;
00081 }
00082
00083
00084 namespace impl {
00085 template<class T>
00086 class image_array3d;
00087 }
00088
00095 template<class T>
00096 struct impl_traits<impl::image_array3d<T> >: public impl_traits<impl::image_array<T, impl::image_array3d<T> > >
00097 {
00098 enum { dim = 3 };
00099 typedef point3d point_type;
00100 typedef image3d_size size_type;
00101 typedef T value_type;
00102 };
00103
00104 namespace impl
00105 {
00106
00112 template<class T>
00113 class image_array3d :
00114 public image_array<T, image_array3d<T> >
00115 {
00116
00117 public:
00118
00119 typedef image_array3d<T> self_type;
00120 typedef image_array3d<T> exact_type;
00121
00122 typedef typename impl_traits<exact_type>::point_type point_type;
00123 typedef typename impl_traits<exact_type>::value_type value_type;
00124 typedef typename impl_traits<exact_type>::size_type size_type;
00125
00126 typedef image_array<T, image_array3d<T> > super_type;
00127
00128
00129 friend class image_impl<image_array3d<T> >;
00130 friend class image_array<T, image_array3d<T> >;
00131
00132 image_array3d(const size_type& s): super_type(s)
00133 {
00134 pretreat_3d_data_(this->buffer_, array2_, array_, s);
00135 }
00136
00137 image_array3d() : array_(0) {}
00138
00139 ~image_array3d()
00140 {
00141 if (array_)
00142 desallocate_3d_data_(array2_, array_, this->size_);
00143 }
00144
00145 protected:
00146
00148
00149 bool
00150 hold_(const point_type& p) const
00151 {
00152 return (p.slice() >= 0
00153 && p.slice() < this->size_.nslices()
00154 && p.row() >= 0
00155 && p.row() < this->size_.nrows()
00156 && p.col() >= 0
00157 && p.col() < this->size_.ncols());
00158 }
00159
00161
00162 bool
00163 hold_large_(const point_type& p) const
00164 {
00165 return (p.slice() >= -this->size_.border()
00166 && p.slice() < this->size_.nslices() + this->size_.border()
00167 && p.row() >= - this->size_.border()
00168 && p.row() < this->size_.nrows() + this->size_.border()
00169 && p.col() >= - this->size_.border()
00170 && p.col() < this->size_.ncols() + this->size_.border());
00171 }
00172
00174
00175 value_type&
00176 at_(const point_type& p)
00177 {
00178
00179 return at_(p.slice(), p.row(), p.col());
00180 }
00181
00183
00184 value_type&
00185 at_(coord slice, coord row, coord col)
00186 {
00187 invariant(this->buffer_ != 0);
00188 precondition_hold_large(point_type(slice, row, col));
00189 return array_[slice][row][col];
00190 }
00191
00193
00194 size_t
00195 len_(const size_type& s) const
00196 {
00197 coord nslices_eff = s.nslices() + 2 * s.border();
00198 coord ncols_eff = s.ncols() + 2 * s.border();
00199 coord nrows_eff = s.nrows() + 2 * s.border();
00200 return size_t(nslices_eff * nrows_eff * ncols_eff);
00201 }
00202
00203
00204
00209 void
00210 border_reallocate_and_copy_(coord new_border, bool
00211 copy_border)
00212 {
00213 T* buffer = 0;
00214 T** array2 = 0;
00215 T*** array = 0;
00216
00217
00218 allocate_data_(buffer, len_(size_type(this->size_.nslices(), this->size_.nrows(),
00219 this->size_.ncols(), new_border)));
00220 pretreat_3d_data_(buffer, array2, array, size_type(this->size_.nslices(), this->size_.nrows(),
00221 this->size_.ncols(), new_border));
00222
00223 coord border = this->size_.border();
00224 if (border > new_border)
00225 border = new_border;
00226 coord src_min_slice = copy_border ? -border : 0;
00227 coord src_max_slice = this->size_.nslices() + (copy_border ? border : 0);
00228 coord src_min_row = copy_border ? -border : 0;
00229 coord src_max_row = this->size_.nrows() + (copy_border ? border : 0);
00230 coord src_min_col = copy_border ? -border : 0;
00231 coord src_ncols = this->size_.ncols() + (copy_border ? (border * 2) : 0);
00232 for (coord slice = src_min_slice; slice < src_max_slice; ++slice)
00233 for (coord row = src_min_row; row < src_max_row; ++row)
00234 memcpy(array[slice][row],
00235 &at_(slice, row, src_min_col),
00236 src_ncols * sizeof(T));
00237
00238
00239 desallocate_data_(this->buffer_);
00240 desallocate_3d_data_(array2_, array_, this->size_);
00241 this->size_.border() = new_border;
00242 this->buffer_ = buffer;
00243 array2_ = array2;
00244 array_ = array;
00245 }
00246
00251 void
00252 border_replicate_(void)
00253 {
00254 const coord imax = this->size_.nslices() - 1;
00255 const coord jmax = this->size_.nrows() - 1;
00256 const coord kmax = this->size_.ncols() - 1;
00257
00258 for (coord i = - this->size_.border(); i; ++i)
00259 for (coord j = 0; j <= jmax; ++j)
00260 for (coord k = 0; k <= kmax; ++k)
00261 {
00262 at_(i, j, k) = at_(0, j, k);
00263 at_(imax - i, j, k) = at_(imax, j, k);
00264 }
00265
00266 for (coord i = - this->size_.border(); i <= imax + this->size_.border(); ++i)
00267 for (coord j = - this->size_.border(); j; ++j)
00268 for (coord k = 0; k <= kmax; ++k)
00269 {
00270 at_(i, j, k) = at_(i, 0, k);
00271 at_(i, jmax - j, k) = at_(i, jmax, k);
00272 }
00273
00274 for (coord i = - this->size_.border(); i <= imax + this->size_.border(); ++i)
00275 for (coord j = - this->size_.border(); j <= jmax + this->size_.border(); ++j)
00276 for (coord k = - this->size_.border(); k; ++k)
00277 {
00278 at_(i, j, k) = at_(i, j, 0);
00279 at_(i, j, kmax - k) = at_(i, j, kmax);
00280 }
00281 }
00282
00287 void
00288 border_mirror_(void)
00289 {
00290 const coord imax = this->size_.nslices() - 1;
00291 const coord jmax = this->size_.nrows() - 1;
00292 const coord kmax = this->size_.ncols() - 1;
00293
00294 for (coord i = - this->size_.border(); i; ++i)
00295 for (coord j = 0; j <= jmax; ++j)
00296 for (coord k = 0; k <= kmax; ++k)
00297 {
00298 at_(i, j, k) = at_(- i, j, k);
00299 at_(imax - i, j, k) = at_(imax + i, j, k);
00300 }
00301
00302 for (coord i = - this->size_.border(); i <= imax + this->size_.border(); ++i)
00303 for (coord j = - this->size_.border(); j; ++j)
00304 for (coord k = 0; k <= kmax; ++k)
00305 {
00306 at_(i, j, k) = at_(i, - j, k);
00307 at_(i, jmax - j, k) = at_(i, jmax + j, k);
00308 }
00309
00310 for (coord i = - this->size_.border(); i <= imax + this->size_.border(); ++i)
00311 for (coord j = - this->size_.border(); j <= jmax + this->size_.border(); ++j)
00312 for (coord k = - this->size_.border(); k; ++k)
00313 {
00314 at_(i, j, k) = at_(i, j, - k);
00315 at_(i, j, kmax - k) = at_(i, j, kmax + k);
00316 }
00317 }
00318
00320
00321 void
00322 border_assign_(value_type val)
00323 {
00324 const coord imax = this->size_.nslices() - 1;
00325 const coord jmax = this->size_.nrows() - 1;
00326 const coord kmax = this->size_.ncols() - 1;
00327
00328 for (coord i = - this->size_.border(); i; ++i)
00329 for (coord j = 0; j <= jmax; ++j)
00330 for (coord k = 0; k <= kmax; ++k)
00331 {
00332 at_(i, j, k) = val;
00333 at_(imax - i, j, k) = val;
00334 }
00335
00336 for (coord i = - this->size_.border(); i <= imax + this->size_.border(); ++i)
00337 for (coord j = - this->size_.border(); j; ++j)
00338 for (coord k = 0; k <= kmax; ++k)
00339 {
00340 at_(i, j, k) = val;
00341 at_(i, jmax - j, k) = val;
00342 }
00343
00344 for (coord i = - this->size_.border(); i <= imax + this->size_.border(); ++i)
00345 for (coord j = - this->size_.border(); j <= jmax + this->size_.border(); ++j)
00346 for (coord k = - this->size_.border(); k; ++k)
00347 {
00348 at_(i, j, k) = val;
00349 at_(i, j, kmax - k) = val;
00350 }
00351 }
00352
00353 private:
00354
00355 T** array2_;
00356 T*** array_;
00357
00358 };
00359
00360 }
00361
00362 }
00363
00364 #endif // ! OLENA_CORE_IMPL_IMAGE_ARRAY3D_HH