Skip to main content

CellImage

Struct CellImage 

Source
pub struct CellImage<Layout = Bytes> { /* private fields */ }
Expand description

A container of allocated bytes, parameterized over the layout.

This is a unsynchronized, shared equivalent to Image. That is the buffer of bytes of this container is shared between clones of this value but can not be sent between threads. In particular the same buffer may be owned and viewed with different layouts.

§Examples

As a type with shared ownership over the underling buffer, this type can be cloned very cheaply. Such duplicates refer to the same buffer, making changes in one visible to the other.

use image_texel::{image::CellImage, layout::Matrix};
let matrix = Matrix::<u8>::width_and_height(16, 16).unwrap();
let image: CellImage<_> = CellImage::new(matrix);

let another_reference = image.clone();
assert!(CellImage::ptr_eq(&image, &another_reference));

another_reference.as_slice().as_slice_of_cells()[0].set(0xff);
let value = image.as_slice().as_slice_of_cells()[0].get();
assert_eq!(value, 0xff);

Implementations§

Source§

impl<L: Layout> CellImage<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 try_with_layout<M>( self, layout: M, ) -> Result<CellImage<M>, BufferReuseError>
where M: Layout,

Change the layer of the image.

Call CellImage::fits to check if this will work beforehand. Returns an Err with the original image if the buffer does not fit the new layout. Returns Ok with the new image if the buffer does fit. Never reallocates the buffer, the new image will always alias any other image sharing the buffer.

This returns a BufferReuseError with information about the exceeded limits. If you need the prior value then you can make a CellImage::clone` of it, it is cheap.

Source

pub fn decay<M>(self) -> CellImage<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>::width_and_height(32, 32).unwrap();
let image: CellImage<layout::Matrix<u8>> = CellImage::new(matrix);

// to turn hide the `u8` type but keep width, height, texel layout
let as_bytes: CellImage<layout::MatrixBytes> = image.clone().decay();
assert_eq!(as_bytes.layout().width(), 32);
assert_eq!(as_bytes.layout().height(), 32);

See also CellImage::mend and CellImage::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>::width_and_height(32, 32).unwrap();

// Can always decay to a byte buffer.
let bytes: CellImage = CellImage::new(matrix).decay();
let _: &layout::Bytes = bytes.layout();
Source

pub fn checked_decay<M>(self) -> Option<CellImage<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 into_owned(self) -> Image<L>

Copy all bytes to a newly allocated image.

Note this will allocate a buffer according to the capacity length of this reference, not merely the layout. When this is not the intention, consider first adjusting the buffer by reference with Self::as_ref.

§Examples

Here we make an independent copy of a pixel matrix image.

use image_texel::image::{CellImage, Image};
use image_texel::layout::{PlaneMatrices, Matrix};
use image_texel::texels::U8;

let matrix = Matrix::from_width_height(U8, 8, 8).unwrap();
let buffer = CellImage::new(matrix);

// … some code to initialize those planes.

let clone_of: Image<_> = buffer.clone().into_owned();

assert!(clone_of.as_bytes() == buffer.as_cell_buf());
Source

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

Move the bytes into a new image.

Afterwards, self will refer to an empty but unique new buffer.

Source

pub fn mend<Item>(self, mend: Item) -> CellImage<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<CellImage<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> CellImage<L>

Image methods that do not require a layout.

Source

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

Check if the buffer could accommodate another layout without reallocating.

Source

pub fn ptr_eq<O>(&self, other: &CellImage<O>) -> bool

Check if two images refer to the same buffer.

Note that two buffers can use different layout types to describe their share of the data or even to refer to the same data in different ways.

Source

pub fn as_cell_buf(&self) -> &cell_buf
where L: Layout,

Get a reference to the underlying buffer.

Source

pub fn as_capacity_cell_buf(&self) -> &cell_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::make_mut.

Source

pub fn get_mut(&mut self) -> Option<&mut cell_buf>

Get a mutable reference to all allocated bytes if this image does not alias any other.

§Example
use image_texel::{image::CellImage, layout::Matrix};

let layout = Matrix::<[u8; 4]>::width_and_height(10, 10).unwrap();
let mut image = CellImage::new(layout);
assert!(image.get_mut().is_some());

let mut clone_of = image.clone();
assert!(image.get_mut().is_none());
Source

pub fn make_mut(&mut self) -> &mut cell_buf

Ensure this image does not alias any other.

Then returns a mutable reference to all the bytes allocated in the buffer.

§Example
use image_texel::{image::CellImage, layout::Matrix, texels::U8};
let texel = U8.array::<4>();

let layout = Matrix::<[u8; 4]>::width_and_height(10, 10).unwrap();
let image = CellImage::new(layout);

let mut clone_of = image.clone();
let atomic_mut_buf = clone_of.make_mut();

// Now these are independent buffers.
atomic_mut_buf.as_texels(texel).as_slice_of_cells()[0].set([0xff; 4]);
assert_ne!(image.as_slice().as_slice_of_cells()[0].get(), [0xff; 4]);

// With mutable reference we initialized the new buffer.
assert_eq!(clone_of.as_slice().as_slice_of_cells()[0].get(), [0xff; 4]);
Source

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

View this buffer as a slice of texels.

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_slice(&self) -> &Cell<[L::Sample]>
where L: SliceLayout,

View this buffer as a slice of its inherent pixels.

Source

pub fn layout(&self) -> &L

Get a reference to the layout.

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) -> CellImageRef<'_, &L>

Get a view of this image.

Source

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

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

Source§

impl<L> CellImage<L>

Source

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

Write to this image, modifying the view of layout in the process.

Returns an error and keeps the current layout unchanged if the allocated buffer does not fit the new data’s layout. Otherwise copies data and assigns the layout to the image buffer.

Consider AsCopySource::write_to_cell_ref with the whole Self::as_ref buffer when you want to instead ignore the keep the current layout and only copy data. See AsCopySource::write_to_cell_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.

Trait Implementations§

Source§

impl<Layout: Clone> Clone for CellImage<Layout>

Source§

fn clone(&self) -> CellImage<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<Layout: Eq> Eq for CellImage<Layout>

Source§

impl<Layout: PartialEq> PartialEq for CellImage<Layout>

Source§

fn eq(&self, other: &CellImage<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 CellImage<Layout>

Auto Trait Implementations§

§

impl<Layout = Bytes> !RefUnwindSafe for CellImage<Layout>

§

impl<Layout = Bytes> !Send for CellImage<Layout>

§

impl<Layout = Bytes> !Sync for CellImage<Layout>

§

impl<Layout = Bytes> !UnwindSafe for CellImage<Layout>

§

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

§

impl<Layout> Unpin for CellImage<Layout>
where Layout: Unpin,

§

impl<Layout> UnsafeUnpin for CellImage<Layout>
where Layout: UnsafeUnpin,

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.