pub struct Matrix<P> { /* private fields */ }Expand description
A 2d, width-major matrix of pixels.
The layout describes placement of samples within the memory buffer. An abstraction layer that provides strided access to such pixel data is not intended to be baked into this struct. Instead, it will always store the data in a row-major layout without holes.
There are two levels of control over the allocation behaviour of a Matrix. The direct
methods, currently with_width_and_height only, lead to an image without intermediate steps
but may panic due to an invalid layout. Manually using the intermediate Layout gives custom
error handling options and additional offers inspection of the details of the to-be-allocated
buffer. A third option is currently not available and depends on support from the Rust standard
library, which could also handle allocation failures.
§Usage for trusted inputs
Directly allocate your desired layout with with_width_and_height. This may panic when the
allocation itself fails or when the allocation for the layout could not described, as the
layout would not fit inside the available memory space (i.e. the indices would overflow a
usize).
§Usage for untrusted inputs
In some cases, for untrusted input such as in image parsing libraries, more control is desired.
There is no way to currently catch an allocation failure in stable Rust. Thus, even reasonable
bounds can lead to a panic, and this is unpreventable (note: when the try_* methods of
Vec become stable this will change). But one still may want to check the required size
before allocation.
Firstly, no method will implicitly try to allocate memory and methods that will note the potential panic from allocation failure.
Secondly, an instance of Layout can be constructed in a panic free manner without any
allocation and independently from the Matrix instance. By providing it to the with_layout
constructor ensures that all potential intermediate failures–except as mentioned before–can be
explicitly handled by the caller. Furthermore, some utility methods allow inspection of the
eventual allocation size before the reservation of memory.
§Restrictions
As previously mentioned, the samples in the internal buffer layout always appear without any
holes. Therefore a fast crop operation requires wrapping the abstraction layer provided here
into another layer describing the accessible image, independent from the layout of the actual
pixel data. This separation of concern–layout versus access logic–simplifies the implementation
and keeps it agnostic of the desired low-cost operations. Consider that other use cases may
require operations other than crop with constant time. Instead of choosing some consistent by
limited set here, the mechanism to achieve it is deferred to an upper layer for further
freedom. Other structs may, in the future, provide other pixel layouts.
Implementations§
Source§impl<P> Matrix<P>
impl<P> Matrix<P>
Sourcepub fn with_layout(layout: Layout<P>) -> Self
pub fn with_layout(layout: Layout<P>) -> Self
Sourcepub fn with_width_and_height(width: usize, height: usize) -> Selfwhere
P: AsTexel,
pub fn with_width_and_height(width: usize, height: usize) -> Selfwhere
P: AsTexel,
Directly try to allocate an image from width and height.
§Panics
This panics when the layout described by width and height can not be allocated, for
example due to it being an invalid layout. If you want to handle the layout being invalid,
consider using Layout::from_width_and_height and Matrix::with_layout.
FIXME: on the layout this is named width_and_height and is fallible. We should align the
naming here and this isn’t even a with-type builder. And do we need this?
Sourcepub fn from_buffer(buffer: TexelBuffer<P>, layout: Layout<P>) -> Self
pub fn from_buffer(buffer: TexelBuffer<P>, layout: Layout<P>) -> Self
Interpret an existing buffer as a pixel image.
The data already contained within the buffer is not modified so that prior initialization
can be performed or one array of samples reinterpreted for an image of other sample type.
However, the TexelBuffer will be logically resized which will zero-initialize missing elements if
the current buffer is too short.
§Panics
This function will panic if resizing causes a reallocation that fails.
Sourcepub fn from_reused_buffer(
buffer: TexelBuffer<P>,
layout: Layout<P>,
) -> Result<Self, MatrixReuseError<P>>
pub fn from_reused_buffer( buffer: TexelBuffer<P>, layout: Layout<P>, ) -> Result<Self, MatrixReuseError<P>>
Reuse an existing buffer for a pixel image.
Similar to from_buffer but this function will never reallocate the inner buffer. Instead, it
will return the TexelBuffer unmodified if the creation fails. See MatrixReuseError for
further information on the error and retrieving the buffer.
pub fn as_slice(&self) -> &[P]
pub fn as_mut_slice(&mut self) -> &mut [P]
pub fn as_bytes(&self) -> &[u8]
pub fn as_bytes_mut(&mut self) -> &mut [u8]
Sourcepub fn resize(&mut self, layout: Layout<P>)
pub fn resize(&mut self, layout: Layout<P>)
Resize the buffer for a new image.
§Panics
This function will panic if an allocation is necessary but fails.
Sourcepub fn reuse(&mut self, layout: Layout<P>) -> Result<(), BufferReuseError>
pub fn reuse(&mut self, layout: Layout<P>) -> Result<(), BufferReuseError>
Reuse the buffer for a new image layout.
Sourcepub fn transmute<Q: AsTexel>(self) -> Matrix<Q>
pub fn transmute<Q: AsTexel>(self) -> Matrix<Q>
Reinterpret to another, same size pixel type.
See Matrix::transmute_to for details.
Sourcepub fn transmute_to<Q: AsTexel>(self, pixel: Texel<Q>) -> Matrix<Q>
pub fn transmute_to<Q: AsTexel>(self, pixel: Texel<Q>) -> Matrix<Q>
Reinterpret to another, same size pixel type.
§Panics
Like core::mem::transmute, the size of the two types need to be equal. This ensures that
all indices are valid in both directions.
pub fn into_buffer(self) -> TexelBuffer<P>
Sourcepub fn map<F, Q>(self, map: F) -> Matrix<Q>
pub fn map<F, Q>(self, map: F) -> Matrix<Q>
Apply a function to all pixel values.
See Matrix::map_to for the details.
§Panics
This function will panic if the new layout would be invalid (because the new pixel type requires a larger buffer than can be allocate) or if the reallocation fails.
Sourcepub fn map_to<F, Q>(self, map: F, pixel: Texel<Q>) -> Matrix<Q>where
F: Fn(P) -> Q,
pub fn map_to<F, Q>(self, map: F, pixel: Texel<Q>) -> Matrix<Q>where
F: Fn(P) -> Q,
Apply a function to all pixel values.
Unlike Matrix::transmute_to there are no restrictions on the pixel types. This will
reuse the underlying buffer or resize it if that is not possible.
§Panics
This function will panic if the new layout would be invalid (because the new pixel type requires a larger buffer than can be allocate) or if the reallocation fails.