proto-1.0 78: Add border_resize in array2d

Index: ChangeLog from Damien Thivolle <damien@lrde.epita.fr> * tests/core/tests/border2d: New. * oln/core/abstract/image_with_data.hh: Add resize_border and impl_hold_large methods. * oln/core/abstract/data_storage.hh: Add resize_border in generic data_storage class. * oln/core/2d/array2d.hh: Add resize_border implementation for array2d. * oln/core/2d/image2d.hh: Add a border argument to image2d constructor. oln/core/2d/array2d.hh | 71 ++++++++++++++++++++++++++++------- oln/core/2d/image2d.hh | 4 - oln/core/abstract/data_storage.hh | 13 ++++-- oln/core/abstract/image_with_data.hh | 13 +++++- tests/core/tests/border2d | 38 ++++++++++++++++++ 5 files changed, 119 insertions(+), 20 deletions(-) Index: tests/core/tests/border2d --- tests/core/tests/border2d (revision 0) +++ tests/core/tests/border2d (revision 0) @@ -0,0 +1,38 @@ + +#include <iostream> + +#include <ntg/all.hh> +#include <oln/basics2d.hh> +#include <oln/level/fill.hh> + +#include "check.hh" +#include "data.hh" + + + +bool check() +{ + oln::point2d p(0,0); + + typedef oln::image2d<ntg::int_u8> image_type; + image_type ima(10, 10, 2); + + int i = 0; + + for (p.col() = -0; p.col() < 10; p.col()++) + for (p.row() = -0; p.row() < 10; p.row()++) + ima[p] = i++; + + ima.resize_border(3, true); + + i = 0; + for (p.col() = -3; p.col() < 13; p.col()++) + for (p.row() = -3; p.row() < 13; p.row()++) + { + if (p.col() >= -0 && p.col() < 10 && p.row() >= -0 && p.row() < 10) + if (ima[p] != i++) + return true; + } + + return false; +} Index: oln/core/abstract/data_storage.hh --- oln/core/abstract/data_storage.hh (revision 77) +++ oln/core/abstract/data_storage.hh (working copy) @@ -49,7 +49,7 @@ struct props_of < category::data_storage, type > { typedef mlc::true_type user_defined_; - + mlc_decl_prop(category::data_storage, size_type); mlc_decl_prop(category::data_storage, point_type); mlc_decl_prop(category::data_storage, data_type); @@ -65,9 +65,9 @@ }; - mlc_register_prop(category::data_storage, size_type); - mlc_register_prop(category::data_storage, point_type); - mlc_register_prop(category::data_storage, data_type); + mlc_register_prop(category::data_storage, size_type); + mlc_register_prop(category::data_storage, point_type); + mlc_register_prop(category::data_storage, data_type); namespace abstract { @@ -106,6 +106,11 @@ this->exact().impl_resize(s); } + void resize_border(size_t new_border, bool copy_border) + { + this->exact().impl_resize_border(new_border, copy_border); + } + unsigned long npoints() const { if (! this->has_data()) Index: oln/core/abstract/image_with_data.hh --- oln/core/abstract/image_with_data.hh (revision 77) +++ oln/core/abstract/image_with_data.hh (working copy) @@ -51,7 +51,7 @@ { typedef category::image ret; }; - + // super_type template <typename E> struct set_super_type < abstract::image_with_data<E> > @@ -139,7 +139,13 @@ return this->data_->hold(p); } + bool impl_hold_large(const point_type& p) const + { + precondition(this->has_data()); + return this->data_->hold_large(p); + } + /*! \brief Implement both abstract::readonly_image<E>::get(p) ** and abstract::readwrite_image<E>::get(p) so read-only access ** to the value stored at \a p in the current image. @@ -172,7 +178,12 @@ return data_ != 0; } + void resize_border(size_t new_border, bool copy_border = false) + { + this->data_->resize_border(new_border, copy_border); + } + protected: /*! \brief Constructor (protected) with no memory allocation for Index: oln/core/2d/array2d.hh --- oln/core/2d/array2d.hh (revision 77) +++ oln/core/2d/array2d.hh (working copy) @@ -39,13 +39,13 @@ template <typename T> struct array2d; // category - template <typename T> + template <typename T> struct set_category< array2d<T> > { typedef category::data_storage ret; }; // super_type - template <typename T> + template <typename T> struct set_super_type< array2d<T> > { typedef abstract::data_storage< array2d<T> > ret; }; - + // props template <typename T> struct set_props < category::data_storage, array2d<T> > : public props_of<category::data_storage> @@ -56,7 +56,26 @@ }; + template<class T> + void alloc_and_init(T*& buffer, T**& array, const size2d& s) + { + size_t nrows_eff = s.nrows() + 2 * s.border(); + size_t ncols_eff = s.ncols() + 2 * s.border(); + size_t nelts_eff = nrows_eff * ncols_eff; + buffer = new T[nelts_eff]; + array = new T*[nrows_eff]; + + buffer = buffer; + T* buf = buffer + s.border(); + for (size_t row = 0; row < nrows_eff; ++row) + { + array[row] = buf; + buf += ncols_eff; + } + array += s.border(); + } + template <typename T> class array2d : public abstract::data_storage< array2d<T> > { @@ -129,20 +148,44 @@ this->clear_data(); size_ = s; - size_t nrows_eff = size_.nrows() + 2 * size_.border(); - size_t ncols_eff = size_.ncols() + 2 * size_.border(); - size_t nelts_eff = nrows_eff * ncols_eff; + alloc_and_init(buffer_, array_, s); + invariant_(); + } - buffer_ = new T[nelts_eff]; - array_ = new T*[nrows_eff]; + void impl_resize_border(size_t new_border, bool copy_border) + { + invariant_(); + T* new_buffer_; + T** new_array_; + size2d new_size_(this->size_.nrows(), this->size_.ncols(), new_border); - T* buf = buffer_ + size_.border(); - for (size_t row = 0; row < nrows_eff; ++row) + alloc_and_init(new_buffer_, new_array_, new_size_); + + if (buffer_ != 0) { - array_[row] = buf; - buf += ncols_eff; + size_t border = this->size_.border(); + + if (border > new_border) + border = new_border; + + coord_t row_min = copy_border ? -border : 0; + coord_t row_max = int(this->size_.nrows()) + + (copy_border ? border : 0); + coord_t col_min = copy_border ? -border : 0; + size_t ncols = int(this->size_.ncols()) + + (copy_border ? (border * 2) : 0); + + for (coord_t row = row_min; row < row_max; ++row) + memcpy(new_array_[row] + col_min, this->array_[row] + col_min, + ncols * sizeof (T)); + + this->clear_data(); } - array_ += size_.border(); + + buffer_ = new_buffer_; + array_ = new_array_; + size_ = new_size_; + invariant_(); } @@ -213,6 +256,8 @@ size_.border().is_undefined())); } + + }; } // end of namespace oln Index: oln/core/2d/image2d.hh --- oln/core/2d/image2d.hh (revision 77) +++ oln/core/2d/image2d.hh (working copy) @@ -124,8 +124,8 @@ this->exact_ptr = this; } - image2d(coord_t nrows, coord_t ncols) : - super_type(size2d(nrows, ncols)) + image2d(coord_t nrows, coord_t ncols, size_t border = 2) : + super_type(size2d(nrows, ncols, border)) { this->exact_ptr = this; }
participants (1)
-
Damien Thivolle