Struct image_texel::image::Image
source · [−]pub struct Image<Layout = Bytes> { /* private fields */ }Expand description
A container of allocated bytes, parameterized over the layout.
This type permits user defined layouts of any kind and does not unsafely depend on the validity of the layouts. Correctness is achieved in the common case by discouraging methods that would lead to a diverging size of the memory buffer and the layout. Hence, access to the image pixels should not lead to panic unless an incorrectly implemented layout is used.
It possible to convert the layout to a less strictly typed one without reallocating the buffer.
For example, all standard layouts such as Matrix can be weakened to DynLayout. The reverse
can not be done unchecked but is possible with fallible conversions.
Indeed, the image can arbitrarily change its own layout—different ImageRef and
ImageMut may even chose _conflicting layouts—and thus overwrite the content with completely
different types and layouts. This is intended to maximize the flexibility for users. In
complicated cases it could be hard for the type system to reflect the compatibility of a custom
pixel layout and a standard one. It is solely the user’s responsibility to use the interface
sensibly. The soundness of standard channel types (e.g. u8 or u32) is not impacted by
this as any byte content is valid for them.
Examples
Initialize a matrix as computed [u8; 4] rga pixels:
use image_texel::{Image, Matrix};
let mut image = Image::from(Matrix::<[u8; 4]>::with_width_and_height(400, 400));
image.shade(|x, y, rgba| {
rgba[0] = x as u8;
rgba[1] = y as u8;
rgba[3] = 0xff;
});
Design
Since a Image can not unsafely rely on the layout behaving correctly, direct accessors may
have suboptimal behaviour and perform a few (seemingly) redundant checks. More optimal, but
much more specialized, wrappers can be provided in other types that first reduce to a
first-party layout and byte buffer and then preserve this invariant by never calling
second/third-party code from traits. Some of these may be offered in this crate in the future.
Note also that Image provides fallible operations, some of them are meant to modify the
type. This can obviously not be performed in-place, in the manner with which it would be common
if the type did not change. Instead we approximate at least the result type by transferring the
buffer on success while leaving it unchanged in case of failure. An example signature for this is:
Implementations
sourceimpl<L: Layout> Image<L>
impl<L: Layout> Image<L>
Image methods for all layouts.
sourcepub fn with_bytes(layout: L, bytes: &[u8]) -> Self
pub fn with_bytes(layout: L, bytes: &[u8]) -> Self
Create a new image with initial byte content.
sourcepub fn with_buffer<T>(layout: L, bytes: TexelBuffer<T>) -> Self
pub fn with_buffer<T>(layout: L, bytes: TexelBuffer<T>) -> Self
Create a new image with initial texel contents.
The memory is reused as much as possible. If the layout is too large for the buffer then the remainder is filled up with zeroed bytes.
sourcepub fn as_bytes_mut(&mut self) -> &mut [u8]
pub fn as_bytes_mut(&mut self) -> &mut [u8]
Get a mutable reference to those bytes used by the layout.
sourcepub fn ensure_layout(&mut self)
pub fn ensure_layout(&mut self)
If necessary, reallocate the buffer to fit the layout.
Call this method after having mutated a layout with Image::layout_mut_unguarded
whenever you are not sure that the layout did not grow. This will ensure the contract that
the internal buffer is large enough for the layout.
Panics
This method panics when the allocation of the new buffer fails.
sourcepub fn with_layout<M>(self, layout: M) -> Image<M> where
M: Layout,
pub fn with_layout<M>(self, layout: M) -> Image<M> where
M: Layout,
Change the layer of the image.
Reallocates the buffer when growing a layout. Call Image::fits to check this property.
sourcepub fn decay<M>(self) -> Image<M> where
M: Decay<L>,
M: Layout,
pub fn decay<M>(self) -> Image<M> where
M: Decay<L>,
M: Layout,
Decay into a image with less specific layout.
See the Decay trait for an explanation of this operation.
Example
The common layouts define ways to decay into a dynamically typed variant.
let matrix = Matrix::<u8>::with_width_and_height(400, 400);
let image: Image<layout::Matrix<u8>> = Image::from(matrix);
// to turn hide the `u8` type but keep width, height, texel layout
let image: Image<layout::MatrixBytes> = image.decay();
assert_eq!(image.layout().width(), 400);
assert_eq!(image.layout().height(), 400);See also Image::mend and Image::try_mend for operations that reverse the effects.
Can also be used to forget specifics of the layout, turning the image into a more general container type. For example, to use a uniform type as an allocated buffer waiting on reuse.
let matrix = Matrix::<u8>::with_width_and_height(400, 400);
// Can always decay to a byte buffer.
let bytes: Image = Image::from(matrix).decay();
let _: &layout::Bytes = bytes.layout();sourcepub fn mend<Item>(self, mend: Item) -> Image<Item::Into> where
Item: Mend<L>,
L: Take,
pub fn mend<Item>(self, mend: Item) -> Image<Item::Into> where
Item: Mend<L>,
L: Take,
Strengthen the layout of the image.
See the Mend trait for an explanation of this operation.
sourcepub fn try_mend<Item>(
&mut self,
mend: Item
) -> Result<Image<Item::Into>, Item::Err> where
Item: TryMend<L>,
L: Take,
pub fn try_mend<Item>(
&mut self,
mend: Item
) -> Result<Image<Item::Into>, Item::Err> where
Item: TryMend<L>,
L: Take,
Strengthen the layout of the image.
See the Mend trait for an explanation of this operation.
This is a fallible operation. In case of success returns Ok and the byte buffer of the
image is moved into the result. When mending fails this method returns Err and the buffer
is kept by this image.
sourceimpl<L> Image<L>
impl<L> Image<L>
Image methods that do not require a layout.
sourcepub fn fits(&self, other: &impl Layout) -> bool
pub fn fits(&self, other: &impl Layout) -> bool
Check if the buffer could accommodate another layout without reallocating.
sourcepub fn as_capacity_bytes(&self) -> &[u8]
pub fn as_capacity_bytes(&self) -> &[u8]
Get a reference to the unstructured bytes of the image.
Note that this may return more bytes than required for the specific layout for various
reasons. See also as_bytes.
sourcepub fn as_capacity_bytes_mut(&mut self) -> &mut [u8]
pub fn as_capacity_bytes_mut(&mut self) -> &mut [u8]
Get a mutable reference to the unstructured bytes of the image.
Note that this may return more bytes than required for the specific layout for various
reasons. See also as_bytes_mut.
sourcepub fn as_texels<P>(&self, pixel: Texel<P>) -> &[P]
pub fn as_texels<P>(&self, pixel: Texel<P>) -> &[P]
View this buffer as a slice of pixels.
This reinterprets the bytes of the buffer. It can be used to view the buffer as any kind of pixel, regardless of its association with the layout. Use it with care.
An alternative way to get a slice of texels when a layout has an inherent texel type is
Self::as_slice.
sourcepub fn as_mut_texels<P>(&mut self, pixel: Texel<P>) -> &mut [P]
pub fn as_mut_texels<P>(&mut self, pixel: Texel<P>) -> &mut [P]
View this buffer as a slice of pixels.
This reinterprets the bytes of the buffer. It can be used to view the buffer as any kind of pixel, regardless of its association with the layout. Use it with care.
An alternative way to get a slice of texels when a layout has an inherent texel type is
Self::as_mut_slice.
sourcepub fn layout_mut_unguarded(&mut self) -> &mut L
pub fn layout_mut_unguarded(&mut self) -> &mut L
Get a mutable reference to the layout.
Be mindful not to modify the layout to exceed the allocated size. This does not cause any unsoundness but might lead to panics when calling other methods.
sourcepub fn try_to_ref<M: Layout>(&self, layout: M) -> Option<ImageRef<'_, M>>
pub fn try_to_ref<M: Layout>(&self, layout: M) -> Option<ImageRef<'_, M>>
Get a view of this image, if the alternate layout fits.
sourcepub fn to_mut<M: Layout>(&mut self, layout: M) -> ImageMut<'_, M>
pub fn to_mut<M: Layout>(&mut self, layout: M) -> ImageMut<'_, M>
Get a mutable view under an alternate layout.
sourcepub fn try_to_mut<M: Layout>(&mut self, layout: M) -> Option<ImageMut<'_, M>>
pub fn try_to_mut<M: Layout>(&mut self, layout: M) -> Option<ImageMut<'_, M>>
Get a mutable view of this image, if the alternate layout fits.
sourcepub fn get_texel<P>(&self, coord: Coord) -> Option<P> where
L: Raster<P>,
pub fn get_texel<P>(&self, coord: Coord) -> Option<P> where
L: Raster<P>,
Get a single texel from a raster image.
sourcepub fn put_texel<P>(&mut self, coord: Coord, texel: P) where
L: RasterMut<P>,
pub fn put_texel<P>(&mut self, coord: Coord, texel: P) where
L: RasterMut<P>,
Put a single texel to a raster image.
sourcepub fn shade<P>(&mut self, f: impl FnMut(u32, u32, &mut P)) where
L: RasterMut<P>,
pub fn shade<P>(&mut self, f: impl FnMut(u32, u32, &mut P)) where
L: RasterMut<P>,
Call a function on each texel of this raster image.
The order of evaluation is not defined although certain layouts may offer more specific guarantees. In general, one can expect that layouts call the function in a cache-efficient manner if they are aware of a better iteration strategy.
sourceimpl<L: SliceLayout> Image<L>
impl<L: SliceLayout> Image<L>
Image methods for layouts based on pod samples.
sourcepub fn from_buffer(buffer: TexelBuffer<L::Sample>, layout: L) -> Self
pub fn from_buffer(buffer: TexelBuffer<L::Sample>, layout: L) -> 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. This method will never reallocate data.
Panics
This function will panic if the buffer is shorter than the layout.
sourcepub fn as_slice(&self) -> &[L::Sample]
pub fn as_slice(&self) -> &[L::Sample]
Get a slice of the individual samples in the layout.
An alternative way to get a slice of texels when a layout does not have an inherent texel
type is Self::as_texels.
sourcepub fn as_mut_slice(&mut self) -> &mut [L::Sample]
pub fn as_mut_slice(&mut self) -> &mut [L::Sample]
Get a mutable slice of the individual samples in the layout.
An alternative way to get a slice of texels when a layout does not have an inherent texel
type is Self::as_mut_texels.
sourcepub fn into_buffer(self) -> TexelBuffer<L::Sample>
pub fn into_buffer(self) -> TexelBuffer<L::Sample>
Convert into an vector-like of sample types.
Trait Implementations
impl<Layout: Eq> Eq for Image<Layout>
impl<Layout> StructuralEq for Image<Layout>
impl<Layout> StructuralPartialEq for Image<Layout>
Auto Trait Implementations
impl<Layout> RefUnwindSafe for Image<Layout> where
Layout: RefUnwindSafe,
impl<Layout> Send for Image<Layout> where
Layout: Send,
impl<Layout> Sync for Image<Layout> where
Layout: Sync,
impl<Layout> Unpin for Image<Layout> where
Layout: Unpin,
impl<Layout> UnwindSafe for Image<Layout> where
Layout: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into)Uses borrowed data to replace owned data, usually by cloning. Read more