N-dimensional buffer images
- Include:
<mln/core/image/ndbuffer_image.hpp>
forndbuffer_image
<mln/core/image/ndimage.hpp>
forndimage<T>
<mln/core/image/ndimage_fwd.hpp>
for forward declarations.
N-dimensional buffer images __ndbuffer_image
are the most common image types that stores elements within a buffer.
Memory layout and memory management
__ndbuffer_image
supports strided access (this is necessary for border management and clipping operations)
but ensures that elemnents of a row are contiguous.
__ndbuffer_image
can own the buffer or can borrow data from an external buffer (see
__ndbuffer_image::from_buffer()
). In both case __ndbuffer_image
has reference semantics on
the owned buffer. It means that copying the image results in a shallow copy. The memory is automatically freed when
the last reference goes out.
Dynamic vs Static image and Type-erasure
While the type of the element T and the number of dimension pdim are
known at compile-time, __ndbuffer_image
supports partial type and dimension erasure.
T |
pdim |
Type alias |
Description |
---|---|---|---|
void |
dynamic = -1 |
:cpp:any: |
Full type-erased |
T |
1 |
:cpp:any: |
1d image type |
T |
2 |
:cpp:any: |
2d image type |
T |
3 |
:cpp:any: |
3d image type |
T |
N |
:cpp:any: |
nd image type |
-
using ndbuffer_image = __ndbuffer_image<void, dynamic>
-
template<class T>
using image1d = __ndbuffer_image<T, 1>
-
template<class T>
using image2d = __ndbuffer_image<T, 2>
-
template<class T>
using image3d = __ndbuffer_image<T, 3>
-
template<class T, int N>
using ndimage = __ndbuffer_image<T, N>
Border management
FIXME. to be documented
Overview of the n-dimensional image API
|
|
|
---|---|---|
Constructors |
|
|
Constructors from external sources |
|
|
Resizing |
|
|
Geometry information |
||
Data & Layout information |
|
|
Data accessors |
|
|
Slicing & clipping operations |
|
|
Casting operators |
|
Implicitely convertible to |
Iteration facilities |
API Reference of the dynamic N-dimensional buffer images (ndbuffer_image)
-
template<>
class __ndbuffer_image<void, dynamic> Type definitions
-
using point_type = Point
-
using value_type = void*
-
using index_type = int
-
using domain_type = Box
Constructors
-
__ndbuffer_image()
-
__ndbuffer_image(sample_type_id sample_type, ConstBoxRef domain, const image_build_params& = {})
-
__ndbuffer_image(sample_type_id sample_type, int width, const image_build_params ¶ms = {})
-
__ndbuffer_image(sample_type_id sample_type, int width, int height, const image_build_params ¶ms = {})
-
__ndbuffer_image(sample_type_id sample_type, int width, int height, int depth, const image_build_params ¶ms = {})
-
__ndbuffer_image(const __ndbuffer_image &other, const image_build_params&)
-
template<class T>
__ndbuffer_image(std::initializer_list<T>) -
template<class T>
__ndbuffer_image(std::initializer_list<std::initializer_list<T>>) -
template<class T>
__ndbuffer_image(std::initializer_list<std::initializer_list<std::initializer_list<T>>>)
Construction from external buffers
-
static ndbuffer_image from_buffer(std::byte *buffer, sample_type_id sample_type, int dim, const int sizes[], const std::ptrdiff_t byte_strides[] = nullptr, bool copy = false)
-
static ndbuffer_image from_buffer(std::byte *buffer, sample_type_id sample_type, int dim, const int topleft[], const int sizes[], const std::ptrdiff_t byte_strides[] = nullptr, bool copy = false)
Resizing facilities
-
void resize(const __ndbuffer_image &other, image_build_params params)
-
void resize(sample_type_id sample_type, int width, const image_build_params& = {})
-
void resize(sample_type_id sample_type, int width, int height, const image_build_params& = {})
-
void resize(sample_type_id sample_type, int width, int height, int depth, const image_build_params& = {})
-
void resize(sample_type_id sample_type, ConstBoxRef domain, const image_build_params& = {})
Geometry information
-
int pdim() const noexcept
-
int width() const noexcept
-
int height() const noexcept
-
int depth() const noexcept
-
int size(int dim = 0) const noexcept
-
int border() const noexcept
-
Box domain() const noexcept
Data and layout information
-
sample_type_id sample_type() const noexcept
-
std::byte *buffer() const noexcept
-
std::ptrdiff_t byte_stride(int dim = 1) const noexcept
-
std::ptrdiff_t stride(int dim = 1) const noexcept
-
index_type index_of_point(ConstPointRef p) const noexcept
-
point_type point_at_index(index_type i) const noexcept
-
index_type delta_index(ConstPointRef p) const noexcept
Data accessors
-
const void *operator()(ConstPointRef p) const noexcept
-
void *operator()(ConstPointRef p) noexcept
-
const void *at(ConstPointRef p) const noexcept
-
void *at(ConstPointRef p) noexcept
-
const void *operator[](index_type i) const noexcept
-
void *operator[](index_type i) noexcept
Slicing & clipping operations
-
ndbuffer_image clip(ConstBoxRef roi) const
-
ndbuffer_image row(int y) const
-
ndbuffer_image slice(int z) const
Casting operators
-
template<class T, int N>
const __ndbuffer_image *cast_to() const -
template<class T, int N>
__ndbuffer_image *cast_to()
Constructors
-
__ndbuffer_image()
Creates a empty image
-
__ndbuffer_image(sample_type_id sample_type, ConstBoxRef domain, const image_build_params& = {})
-
__ndbuffer_image(sample_type_id sample_type, int width, const image_build_params ¶ms = {})
-
__ndbuffer_image(sample_type_id sample_type, int width, int height, const image_build_params ¶ms = {})
-
__ndbuffer_image(sample_type_id sample_type, int width, int height, int depth, const image_build_params ¶ms = {})
Creates an image of dimensions given by domain with the given sample_type. The overloads are provided for convenience:
Creates a 1d image of the given width
Creates a 2d image of size width × height
Creates a 3d image of size width × height × depth
By default, the memory is left default-initialized. The optional params parameter can be used to provide advanced initialization information:
params.init_value can be used to value-initialize the buffer
params.border can be used to allocate the image with a given border size.
// Create a 3d image of size (width=2, height=3, depth=4) with type uint8_t and default border width (3) // and random values ndbuffer_image a(sample_type_id::UINT8, 2, 3, 4); // Create a 2d image of size (width=5, height=5) with type uint16_t and border width = 5px // with values set to zero. image_build_params params; params.init_value = uint16_t{0}; params.border = 5 ndbuffer_image b(sample_type_id::UINT16, 5, 5, params);
-
__ndbuffer_image(const __ndbuffer_image &other, const image_build_params&)
Initialization constructor
-
template<class T>
__ndbuffer_image(std::initializer_list<T>) -
template<class T>
__ndbuffer_image(std::initializer_list<std::initializer_list<T>>) -
template<class T>
__ndbuffer_image(std::initializer_list<std::initializer_list<std::initializer_list<T>>>) Constructor from initializer lists (1d, 2d or 3d images).:
mln::ndbuffer_image f = {{1,2,3}, {4,5,6}}; // Extents: (width=3 x height=2) of type: INT32 mln::ndbuffer_image g = { {{1.f,2.f,3.f}, {4.f,5.f,6.f}}, {{7.f,8.f,9.f}, {10.f,11.f,12.f}} }; // Extents (width=3 x height=2 x depth=2) of type FLOAT
Construction from external buffers
-
static ndbuffer_image from_buffer(std::byte *buffer, sample_type_id sample_type, int dim, const int sizes[], const std::ptrdiff_t byte_strides[] = nullptr, bool copy = false)
-
static ndbuffer_image from_buffer(std::byte *buffer, sample_type_id sample_type, int dim, const int topleft[], const int sizes[], const std::ptrdiff_t byte_strides[] = nullptr, bool copy = false)
Constructs an image using an external buffer.
- Parameters:
buffer – Pointer to the buffer
sample_type – Type of elements
dim – Number of dimensions
topleft – Pointer to an array of dim elements holding the coordinates of the top-left corner (x, y, z, …) In (1), it is assumed to be (0, 0, 0,…)
sizes – Pointer to an array of dim elements holding the sizes of the image (width, height, depth, …)
byte_strides (optional) – Pointer to an array of dim elements holding the strides between consecutive elements in each dimension (in bytes). If NULL, strides are computed assuming the data are stored contiguously.
copy (optional) – If true, a copy of the buffer is done and managed internally. Otherwise, the buffer is not copied and the user is responsible for its destruction.
Resizing facilities
-
void resize(const __ndbuffer_image &other, image_build_params params)
-
void resize(sample_type_id sample_type, int width, const image_build_params& = {})
-
void resize(sample_type_id sample_type, int width, int height, const image_build_params& = {})
-
void resize(sample_type_id sample_type, int width, int height, int depth, const image_build_params& = {})
-
void resize(sample_type_id sample_type, ConstBoxRef domain, const image_build_params& = {})
See the corresponding contructors. These functions allow an image to be default-constructed and resized afterward.
Note
A new buffer is allocated. If a buffer was already attached to the image and this is the last reference, the memory is reclaimed.
Geometry information
-
int pdim() const noexcept
Get the number of dimensions of the image
-
int width() const noexcept
Get the width of the image (0 if empty)
-
int height() const noexcept
Get the height of the image (0 if empty). Returns 1 if the image is 1D.
-
int depth() const noexcept
Get the depth of the image (0 if empty). Returns 1 if the image is 1D or 2D.
-
int size(int dim = 0) const noexcept
Get the number of elements in the given dimension (0 if empty). Returns 1 if dim >= pdim().
-
int border() const noexcept
Get the size of the border.
Data and layout information
-
sample_type_id sample_type() const noexcept
Get the sample type of the data.
-
std::byte *buffer() const noexcept
Get a pointer to first element (in the domain).
-
std::ptrdiff_t byte_stride(int dim = 1) const noexcept
Get the stride (in bytes) between two consecutive elements in the given dim.
-
std::ptrdiff_t stride(int dim = 1) const noexcept
Get the stride (in number of elements) between two consecutive elements in the given dim.
-
index_type index_of_point(ConstPointRef p) const noexcept
Get the linear index (offset in the buffer) of multi-dimensional point.
-
point_type point_at_index(index_type i) const noexcept
Get the point corresponding to the given index.
-
index_type delta_index(ConstPointRef p) const noexcept
Get the linear index offset for the given point.
Slicing & clipping operations
-
ndbuffer_image slice(int z) const
Return the slice at coordinate z in the 3th dimension.
- Except:
std::runtime_error if y in invalid or dim() != 3.
-
ndbuffer_image row(int y) const
Return the row at coordinate y in the 2nd dimension.
- Except:
std::runtime_error if y in invalid or dim() != 2.
-
ndbuffer_image clip(ConstBoxRef roi) const
Return the image restricted to the ROI roi. roi must be included in the domain.
- Except:
std::runtime_error if
domain().includes(roi)
is false or dimensions mismatch.
Data accessors
-
const void *operator()(ConstPointRef p) const noexcept
-
void *operator()(ConstPointRef p) noexcept
Returns a pointer to the element at p.
Precondition:
this->domain().has(p)
-
const void *at(ConstPointRef p) const noexcept
-
void *at(ConstPointRef p) noexcept
Returns a pointer to the element at p. p can be in the extension.
Precondition: p belongs to the extended domain.
-
const void *operator[](index_type i) const noexcept
-
void *operator[](index_type i) noexcept
Returns a pointer to the element at index i.
Precondition: i must be a valid index.
Casting operators
-
template<class T, int N>
const __ndbuffer_image *cast_to() const -
template<class T, int N>
__ndbuffer_image *cast_to() Down-cast (or trans-cast) to the requested n-dimensional image type. Returns nullptr if the requested types do not match the dynamic type information.
// Create a 3d image of size (width=2, height=3, depth=4) with type uint8_t and default border width (3) // and random values ndbuffer_image a(sample_type_id::UINT8, 2, 3, 4); image3d<uint8_t>* b1 = a.template cast_to<uint8_t, 3>(); // Ok image2d<uint8_t>* b2 = a.template cast_to<uint8_t, 2>(); // Fails (null pointer returned)
-
using point_type = Point
API Reference of the static N-dimensional buffer images (ndimage<T, N>)
-
template<class T, int N>
class __ndbuffer_image Type definitions
-
using point_type = ndpoint<N>
-
using value_type = T
-
using index_type = int
-
using domain_type = ndbox<N>
-
type pixel_type
-
type const_pixel_type
Constructors
-
template<class T, int N>
class __ndbuffer_image -
__ndbuffer_image()
-
__ndbuffer_image(ndbox<N> domain, const image_build_params& = {})
-
[[when N = 1]] __ndbuffer_image(int width, const image_build_params ¶ms = {})
-
[[when N = 2]] __ndbuffer_image(int width, int height, const image_build_params ¶ms = {})
-
[[when N = 3]] __ndbuffer_image(int width, int height, int depth, const image_build_params ¶ms = {})
-
__ndbuffer_image(const __ndbuffer_image &other, const image_build_params&)
-
[[when N = 1]] __ndbuffer_image(std::initializer_list<T>)
-
[[when N = 2]] __ndbuffer_image(std::initializer_list<std::initializer_list<T>>)
-
[[when N = 3]] __ndbuffer_image(std::initializer_list<std::initializer_list<std::initializer_list<T>>>)
Construction from external buffers
-
static ndbuffer_image from_buffer(T *buffer, const int sizes[], const std::ptrdiff_t byte_strides[] = nullptr, bool copy = false)
-
static ndbuffer_image from_buffer(T *buffer, const int topleft[], const int sizes[], const std::ptrdiff_t byte_strides[] = nullptr, bool copy = false)
Resizing facilities
-
void resize(const __ndbuffer_image &other, image_build_params params)
-
void resize(int width, const image_build_params& = {})
-
void resize(int width, int height, const image_build_params& = {})
-
void resize(int width, int height, int depth, const image_build_params& = {})
-
void resize(ConstBoxRef domain, const image_build_params& = {})
Geometry information
-
int pdim() const noexcept
-
int width() const noexcept
-
int height() const noexcept
-
int depth() const noexcept
-
int size(int dim = 0) const noexcept
-
int border() const noexcept
-
ndbox<N> domain() const noexcept
Data and layout information
-
sample_type_id sample_type() const noexcept
-
T *buffer() const noexcept
-
std::ptrdiff_t byte_stride(int dim = 1) const noexcept
-
std::ptrdiff_t stride(int dim = 1) const noexcept
-
index_type index_of_point(ndpoint<N> p) const noexcept
-
ndpoint<N> point_at_index(index_type i) const noexcept
-
index_type delta_index(ndpoint<N> p) const noexcept
Data accessors
-
const T &operator()(ndpoint<N> p) const noexcept
-
T &operator()(ndpoint<N> p) noexcept
-
const T &at(ndpoint<N> p) const noexcept
-
T &at(ndpoint<N> p) noexcept
-
const T &operator[](index_type i) const noexcept
-
T &operator[](index_type i) noexcept
Slicing & clipping operations
-
__ndbuffer_image clip(ndbox<N> roi) const
-
[[when N = 2]] image1d<T> row(int y) const noexcept
-
[[when N = 3]] image2d<T> slice(int z) const noexcept
Casting operators
Implcitely convertible to
ndbuffer_image
.Iteration
Constructors
-
__ndbuffer_image()
Creates a empty
N
-d image with sample typeT
-
__ndbuffer_image(ndbox<N> domain, const image_build_params& = {})
-
[[when N = 1]] __ndbuffer_image(int width, const image_build_params ¶ms = {})
-
[[when N = 2]] __ndbuffer_image(int width, int height, const image_build_params ¶ms = {})
-
[[when N = 3]] __ndbuffer_image(int width, int height, int depth, const image_build_params ¶ms = {})
Creates an image of dimensions given by domain with value type given by
T
. The overloads are provided for convenience and availability depends onN
:When N = 1 Creates a 1d image of the given width
When N = 2 Creates a 2d image of size width × height
When N = 3 Creates a 3d image of size width × height × depth
By default, the memory is left default-initialized. The optional params parameter can be used to provide advanced initialization information:
params.init_value can be used to value-initialize the buffer
params.border can be used to allocate the image with a given border size.
// Create a 3d image of size (width=2, height=3, depth=4) with type uint8_t and default border width (3) // and random values image3d<uint8_t> a(2, 3, 4); // Create a 2d image of size (width=5, height=5) with type uint16_t and border width = 5px // with values set to zero. image_build_params params; params.init_value = uint16_t{0}; params.border = 5 image2d<uint16_t> b(5, 5, params);
-
__ndbuffer_image(const __ndbuffer_image &other, const image_build_params&)
Initialization constructor
-
[[when N = 1]] __ndbuffer_image(std::initializer_list<T>)
-
[[when N = 2]] __ndbuffer_image(std::initializer_list<std::initializer_list<T>>)
-
[[when N = 3]] __ndbuffer_image(std::initializer_list<std::initializer_list<std::initializer_list<T>>>)
Constructor from initializer lists. Availability depends on
N
.image2d<int> = {{1,2,3}, {4,5,6}}; // Extents: (width=3 x height=2) of type: INT32 image3d<float> g = { {{1.f,2.f,3.f}, {4.f,5.f,6.f}}, {{7.f,8.f,9.f}, {10.f,11.f,12.f}} }; // Extents (width=3 x height=2 x depth=2) of type FLOAT
Construction from external buffers
-
static ndbuffer_image from_buffer(T *buffer, const int sizes[], const std::ptrdiff_t byte_strides[] = nullptr, bool copy = false)
-
static ndbuffer_image from_buffer(T *buffer, const int topleft[], const int sizes[], const std::ptrdiff_t byte_strides[] = nullptr, bool copy = false)
Constructs an image using an external buffer.
- Parameters:
buffer – Pointer to the buffer
topleft – Pointer to an array of dim elements holding the coordinates of the top-left corner (x, y, z, …) In (1), it is assumed to be (0, 0, 0,…)
sizes – Pointer to an array of dim elements holding the sizes of the image (width, height, depth, …)
byte_strides (optional) – Pointer to an array of dim elements holding the strides between consecutive elements in each dimension (in bytes). If NULL, strides are computed assuming the data are stored contiguously.
copy (optional) – If true, a copy of the buffer is done and managed internally. Otherwise, the buffer is not copied and the user is responsible for its destruction.
Resizing facilities
-
void resize(const __ndbuffer_image &other, image_build_params params)
-
void resize(int width, const image_build_params& = {})
-
void resize(int width, int height, const image_build_params& = {})
-
void resize(int width, int height, int depth, const image_build_params& = {})
-
void resize(ConstBoxRef domain, const image_build_params& = {})
See the corresponding contructors. These functions allow an image to be default-constructed and resized afterward.
Note
A new buffer is allocated. If a buffer was already attached to the image and this is the last reference, the memory is reclaimed.
Geometry information
-
int pdim() const noexcept
Get the number of dimensions of the image
-
int width() const noexcept
Get the width of the image.
-
int height() const noexcept
Get the height of the image. Returns 1 if the image is 1D.
-
int depth() const noexcept
Get the depth of the image. Returns 1 if the image is 1D or 2D.
-
int size(int dim = 0) const noexcept
Get the number of elements in the given dimension. Returns 1 if dim >= pdim().
-
int border() const noexcept
Get the size of the border.
Data and layout information
-
sample_type_id sample_type() const noexcept
Get the sample type of the data.
-
std::ptrdiff_t byte_stride(int dim = 1) const noexcept
Get the stride (in bytes) between two consecutive elements in the given dim.
-
std::ptrdiff_t stride(int dim = 1) const noexcept
Get the stride (in number of elements) between two consecutive elements in the given dim.
-
index_type index_of_point(ndpoint<N> p) const noexcept
Get the linear index (offset in the buffer) of multi-dimensional point.
-
ndpoint<N> point_at_index(index_type i) const noexcept
Get the point corresponding to the given index.
-
index_type delta_index(ndpoint<N> p) const noexcept
Get the linear index offset for the given point.
Slicing & clipping operations
-
[[when N = 3]] image2d<T> slice(int z) const noexcept
Return the slice at coordinate z in the 3th dimension.
exceptions: std::runtime_error if z is invalid
-
[[when N = 2]] image1d<T> row(int y) const noexcept
Return the row at coordinate y in the 2nd dimension.
exceptions: std::runtime_error if y is invalid
-
__ndbuffer_image clip(ndbox<N> roi) const
Return the image restricted to the ROI roi. roi must be included in the domain.
- Except:
std::runtime_error if
domain().includes(roi)
is false or dimensions mismatch.
Data accessors
-
const T &operator()(ndpoint<N> p) const noexcept
-
T &operator()(ndpoint<N> p) noexcept
Returns a reference to the element at p.
Precondition:
this->domain().has(p)
-
const T &at(ndpoint<N> p) const noexcept
-
T &at(ndpoint<N> p) noexcept
Returns a reference to the element at p. p can be in the extension.
Precondition: p belongs to the extended domain.
-
const T &operator[](index_type i) const noexcept
-
T &operator[](index_type i) noexcept
Returns a reference to the element at index i.
Precondition: i must be a valid index.
Iteration
-
using point_type = ndpoint<N>