Skip to main content

Image

Struct 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, by re-interpreting the bytes. For example, all standard layouts such as Matrix can be weakened to Bytes. 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:

fn mend<M>(&mut self, with: L::Item) -> Option<Image<M>>

Implementations§

Source§

impl<L> Image<L>

Source

pub fn assign<E>(&mut self, data: AsCopySource<'_, E>)
where E: LayoutEngine<Layout = L>, L: Layout,

Write to an image, changing the layout in the process.

Allocates, contrary to assign functions on shared and reference types, if the allocated buffer does not fit the new data’s layout. Then copies data and assigns the layout to the image buffer.

Consider AsCopySource::write_to_mut with the whole Image::as_mut buffer when you want to instead ignore the keep the current layout and only copy data. See AsCopySource::write_to_image for changing the layout type in the process.

Source

pub fn as_source(&self) -> AsCopySource<'_, RangeEngine<L>>
where L: Clone + Layout,

An adapter reading from the data as one contiguous chunk.

See RangeEngine for more explanations.

Source

pub fn as_target(&mut self) -> AsCopyTarget<'_, RangeEngine<L>>
where L: Clone + Layout,

An adapter writing to this buffer in one contiguous chunk.

See RangeEngine for more explanations.

Source§

impl<L: Layout> Image<L>

Image methods for all layouts.

Source

pub fn new(layout: L) -> Self

Create a new image for a specific layout.

Source

pub fn with_bytes(layout: L, bytes: &[u8]) -> Self

Create a new image with initial byte content.

Source

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.

Source

pub fn as_bytes(&self) -> &[u8]

Get a reference to those bytes used by the layout.

Source

pub fn as_bytes_mut(&mut self) -> &mut [u8]

Get a mutable reference to those bytes used by the layout.

Source

pub fn as_buf(&self) -> &buf

Get a reference to the aligned unstructured bytes of the image.

Source

pub fn as_mut_buf(&mut self) -> &mut buf

Get a reference to the mutable aligned unstructured bytes of the image.

Source

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.

Source

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.

Source

pub fn decay<M>(self) -> Image<M>
where M: Decay<L> + 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();
Source

pub fn checked_decay<M>(self) -> Option<Image<M>>
where M: Decay<L> + Layout,

Like Self::decaybut returnsNone` rather than panicking. While this is strictly speaking a violation of the trait contract, you may want to handle this yourself.

Source

pub fn take(&mut self) -> Image<L>
where L: Take,

Move the buffer into a new image.

Source

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.

Source

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.

Source§

impl<L> Image<L>

Image methods that do not require a layout.

Source

pub fn fits(&self, other: &impl Layout) -> bool

Check if the buffer could accommodate another layout without reallocating.

Source

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.

Source

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.

Source

pub fn as_capacity_buf(&self) -> &buf

Get a reference to the aligned unstructured bytes of the image.

Note that this may return more bytes than required for the specific layout for various reasons. See also Self::as_capacity_bytes.

Source

pub fn as_capacity_buf_mut(&mut self) -> &mut buf

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 Self::as_capacity_bytes_mut.

Source

pub fn as_texels<P>(&self, pixel: Texel<P>) -> &[P]
where L: Layout,

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.

Source

pub fn as_mut_texels<P>(&mut self, pixel: Texel<P>) -> &mut [P]
where L: Layout,

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.

Source

pub fn layout(&self) -> &L

Get a reference to the layout.

Source

pub fn set_layout(&mut self, layout: L)
where L: Layout,

Change the layout, growing the buffer in the process.

Note that there is no equivalent method on any of the other buffer types since this is the only one that can reallocate the buffer when necessary.

Source

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.

Source

pub fn as_ref(&self) -> ImageRef<'_, &L>

Get a view of this image.

Source

pub fn try_to_ref<M: Layout>(&self, layout: M) -> Option<ImageRef<'_, M>>

Get a view of this image, if the alternate layout fits.

Source

pub fn as_mut(&mut self) -> ImageMut<'_, &mut L>

Get a mutable view of this image.

Source

pub fn to_mut<M: Layout>(&mut self, layout: M) -> ImageMut<'_, M>

Get a mutable view under an alternate layout.

Reallocates the buffer when necessary, adding new bytes to the end. The layout of this image itself is not modified.

Source

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.

Source

pub fn get_texel<P>(&self, coord: Coord) -> Option<P>
where L: Raster<P>,

Get a single texel from a raster image.

Source

pub fn put_texel<P>(&mut self, coord: Coord, texel: P)
where L: RasterMut<P>,

Put a single texel to a raster image.

Source

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.

Source§

impl<L: SliceLayout> Image<L>

Image methods for layouts based on pod samples.

Source

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.

Source

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.

Source

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.

Source

pub fn into_buffer(self) -> TexelBuffer<L::Sample>

Convert into an vector-like of sample types.

Trait Implementations§

Source§

impl<Layout: Clone> Clone for Image<Layout>

Source§

fn clone(&self) -> Image<Layout>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<L> Debug for Image<L>
where L: SliceLayout + Debug, L::Sample: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<L: Layout + Default> Default for Image<L>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<Layout: Eq> Eq for Image<Layout>

Source§

impl<'lt, L> From<&'lt Image<L>> for ImageRef<'lt, &'lt L>

Source§

fn from(image: &'lt Image<L>) -> Self

Converts to this type from the input type.
Source§

impl<'lt, L: Layout + Clone> From<&'lt Image<L>> for ImageRef<'lt, L>

Source§

fn from(image: &'lt Image<L>) -> Self

Converts to this type from the input type.
Source§

impl<'lt, L> From<&'lt mut Image<L>> for ImageMut<'lt, &'lt mut L>

Source§

fn from(image: &'lt mut Image<L>) -> Self

Converts to this type from the input type.
Source§

impl<'lt, L: Layout + Clone> From<&'lt mut Image<L>> for ImageMut<'lt, L>

Source§

fn from(image: &'lt mut Image<L>) -> Self

Converts to this type from the input type.
Source§

impl<'lt, L: Layout + Clone> From<Image<&'lt L>> for Image<L>

Source§

fn from(image: Image<&'lt L>) -> Self

Converts to this type from the input type.
Source§

impl<'lt, L: Layout + Clone> From<Image<&'lt mut L>> for Image<L>

Source§

fn from(image: Image<&'lt mut L>) -> Self

Converts to this type from the input type.
Source§

impl<P> From<Image<Matrix<P>>> for Matrix<P>

Source§

fn from(image: Image<Layout<P>>) -> Self

Converts to this type from the input type.
Source§

impl<P> From<Matrix<P>> for Image<Matrix<P>>

Source§

fn from(matrix: Matrix<P>) -> Self

Converts to this type from the input type.
Source§

impl<Layout: PartialEq> PartialEq for Image<Layout>

Source§

fn eq(&self, other: &Image<Layout>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<Layout> StructuralPartialEq for Image<Layout>

Auto Trait Implementations§

§

impl<Layout> Freeze for Image<Layout>
where Layout: Freeze,

§

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> UnsafeUnpin for Image<Layout>
where Layout: UnsafeUnpin,

§

impl<Layout> UnwindSafe for Image<Layout>
where Layout: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, L> PlaneOf<&L> for P
where P: PlaneOf<L>,

Source§

type Plane = <P as PlaneOf<L>>::Plane

Source§

fn get_plane(self, layout: &&L) -> Option<<P as PlaneOf<&L>>::Plane>

Get the layout describing the plane.
Source§

impl<P, L> PlaneOf<&mut L> for P
where P: PlaneOf<L>,

Source§

type Plane = <P as PlaneOf<L>>::Plane

Source§

fn get_plane(self, layout: &&mut L) -> Option<<P as PlaneOf<&mut L>>::Plane>

Get the layout describing the plane.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.