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_ARRAY2D_HH
00029 # define OLENA_CORE_IMPL_IMAGE_ARRAY2D_HH
00030
00031 # include <oln/core/impl/image_array.hh>
00032 # include <oln/core/image2d_size.hh>
00033 # include <oln/core/point2d.hh>
00034
00035 namespace oln {
00036
00038
00039 template<class T>
00040 void
00041 pretreat_2d_data_(T*& buffer, T**& array, const image2d_size& s)
00042 {
00043 precondition(s.nrows() > 0 &&
00044 s.ncols() > 0 &&
00045 s.border() >= 0);
00046 coord nrows_eff = s.nrows() + 2 * s.border();
00047 coord ncols_eff = s.ncols() + 2 * s.border();
00048 array = new T*[size_t(nrows_eff)];
00049 T* buf = buffer + s.border();
00050 for (coord row = 0; row < nrows_eff; ++row)
00051 {
00052 array[row] = buf;
00053 buf += ncols_eff;
00054 }
00055 array += s.border();
00056 }
00057
00059
00060 template<class T>
00061 void
00062 desallocate_2d_data_(T**& array, const image2d_size& s)
00063 {
00064 array -= s.border();
00065 delete[] array;
00066 array = 0;
00067 }
00068
00069 namespace impl {
00070 template<class T>
00071 class image_array2d;
00072 }
00073
00080 template<class T>
00081 struct impl_traits<impl::image_array2d<T> >: public impl_traits<impl::image_array<T, impl::image_array2d<T> > >
00082 {
00083 enum { dim = 2 };
00084 typedef point2d point_type;
00085 typedef image2d_size size_type;
00086 typedef T value_type;
00087 };
00088
00089
00090 namespace impl
00091 {
00092
00098 template<class T>
00099 class image_array2d :
00100 public image_array<T, image_array2d<T> >
00101 {
00102
00103 public:
00104
00105 typedef image_array2d<T> self_type;
00106 typedef image_array2d<T> exact_type;
00107
00108 typedef typename impl_traits<exact_type>::point_type point_type;
00109 typedef typename impl_traits<exact_type>::value_type value_type;
00110 typedef typename impl_traits<exact_type>::size_type size_type;
00111
00112 typedef image_array<T, image_array2d<T> > super_type;
00113
00114
00115 friend class image_impl<image_array2d<T> >;
00116 friend class image_array<T, image_array2d<T> >;
00117
00118
00119
00120 image_array2d(const size_type& s): super_type(s)
00121 {
00122 pretreat_2d_data_(this->buffer_, array_, s);
00123 }
00124
00125 image_array2d() : array_(0) {}
00126
00127 ~image_array2d()
00128 {
00129 if (array_)
00130 desallocate_2d_data_(array_, this->size_);
00131 }
00132
00133 protected:
00134
00136
00137 bool
00138 hold_(const point_type& p) const
00139 {
00140 return
00141 p.row() >= 0 &&
00142 p.row() < this->size_.nrows() &&
00143 p.col() >= 0 &&
00144 p.col() < this->size_.ncols();
00145 }
00146
00148
00149 bool
00150 hold_large_(const point_type& p) const
00151 {
00152 return
00153 p.row() >= - this->size_.border() &&
00154 p.row() < this->size_.nrows() + this->size_.border() &&
00155 p.col() >= - this->size_.border() &&
00156 p.col() < this->size_.ncols() + this->size_.border();
00157 }
00158
00160
00161 value_type&
00162 at_(const point_type& p)
00163 {
00164 return at_(p.row(), p.col());
00165 }
00166
00168
00169 value_type&
00170 at_(coord row, coord col)
00171 {
00172 invariant(this->buffer_ != 0);
00173 precondition_hold_large(point_type(row, col));
00174 return array_[row][col];
00175 }
00176
00178
00179 size_t
00180 len_(const size_type& s) const
00181 {
00182 coord ncols_eff = s.ncols() + 2 * s.border();
00183 coord nrows_eff = s.nrows() + 2 * s.border();
00184 return size_t(nrows_eff * ncols_eff);
00185 }
00186
00187
00188
00193 void
00194 border_reallocate_and_copy_(coord new_border, bool
00195 copy_border)
00196 {
00197 T* buffer = 0;
00198 T** array = 0;
00199
00200 allocate_data_(buffer, len_(size_type(this->size_.nrows(), this->size_.ncols(), new_border)));
00201
00202 pretreat_2d_data_(buffer, array, size_type(this->size_.nrows(),
00203 this->size_.ncols(), new_border));
00204
00205 coord border = this->size_.border();
00206 if (border > new_border)
00207 border = new_border;
00208 coord src_min_row = copy_border ? -border : 0;
00209 coord src_max_row = this->size_.nrows() + (copy_border ? border : 0);
00210 coord src_min_col = copy_border ? -border : 0;
00211 coord src_ncols = this->size_.ncols() + (copy_border ? (border * 2) : 0);
00212 for (coord row = src_min_row; row < src_max_row; ++row)
00213 memcpy(array[row],
00214 &at_(row, src_min_col),
00215 src_ncols * sizeof(T));
00216
00217
00218 desallocate_data_(this->buffer_);
00219 desallocate_2d_data_(array_, this->size_);
00220 this->size_.border() = new_border;
00221 this->buffer_ = buffer;
00222 array_ = array;
00223 }
00224
00225
00230 void
00231 border_replicate_(void)
00232 {
00233 const coord imax = this->size_.nrows() - 1;
00234 const coord jmax = this->size_.ncols() - 1;
00235
00236 for (coord i = - this->size_.border(); i; ++i)
00237 for (coord j = 0; j <= jmax; ++j)
00238 {
00239 at_(i, j) = at_(0, j);
00240 at_(imax - i, j) = at_(imax, j);
00241 }
00242
00243 for (coord i = - this->size_.border(); i <= imax + this->size_.border(); ++i)
00244 for (coord j = - this->size_.border(); j; ++j)
00245 {
00246 at_(i, j) = at_(i, 0);
00247 at_(i, jmax - j) = at_(i, jmax );
00248 }
00249 }
00250
00255 void
00256 border_mirror_(void)
00257 {
00258
00259 const coord imax = this->size_.nrows() - 1;
00260 const coord jmax = this->size_.ncols() - 1;
00261
00262 for (coord i = - this->size_.border(); i; ++i)
00263 for (coord j = 0; j <= jmax; ++j)
00264 {
00265 at_(i, j) = at_(-i, j);
00266 at_(imax - i, j) = at_(imax + i, j);
00267 }
00268
00269 for (coord i = - this->size_.border(); i <= imax + this->size_.border(); ++i)
00270 for (coord j = - this->size_.border(); j; ++j)
00271 {
00272 at_(i, j) = at_(i, -j);
00273 at_(i, jmax - j) = at_(i, jmax + j);
00274 }
00275 }
00276
00278
00279 void
00280 border_assign_(value_type val)
00281 {
00282
00283 const coord imax = this->size_.nrows() - 1;
00284 const coord jmax = this->size_.ncols() - 1;
00285
00286 for (coord i = - this->size_.border(); i; ++i)
00287 for (coord j = 0; j <= jmax; ++j)
00288 {
00289 at_(i, j) = val;
00290 at_(imax - i, j) = val;
00291 }
00292
00293 for (coord i = - this->size_.border(); i <= imax + this->size_.border(); ++i)
00294 for (coord j = - this->size_.border(); j; ++j)
00295 {
00296 at_(i, j) = val;
00297 at_(i, jmax - j) = val;
00298 }
00299 }
00300
00301 private:
00302
00303 T** array_;
00304
00305 };
00306
00307 }
00308
00309 }
00310
00311 #endif // ! OLENA_CORE_IMPL_IMAGE_ARRAY2D_HH