Index: ChangeLog
from Damien Thivolle <damien(a)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;
}