Skip to content

Commit 4a0cb44

Browse files
authored
Merge pull request #79 from image-rs/data-shader
Allow bytes to be bound as input/output planes
2 parents fed1389 + 01286bf commit 4a0cb44

File tree

9 files changed

+475
-7
lines changed

9 files changed

+475
-7
lines changed

canvas/src/frame.rs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use alloc::borrow::ToOwned;
44
use alloc::vec::Vec;
55

66
use image_texel::image::{
7-
AtomicImage, AtomicImageRef, CellImage, CellImageRef, Image, ImageMut, ImageRef,
7+
data, AtomicImage, AtomicImageRef, CellImage, CellImageRef, Image, ImageMut, ImageRef,
88
};
99
use image_texel::texels::U8;
1010

@@ -36,6 +36,24 @@ pub struct Plane {
3636
inner: Image<PlaneBytes>,
3737
}
3838

39+
/// A reference to bytes containing data of a single plane.
40+
///
41+
/// This can be created from a [`Plane`] but also by validating an arbitrary slice of bytes against
42+
/// some of the known layouts. These layouts can be partially defined by the user.
43+
///
44+
/// The common use for values is to pass an outside buffer to [`ConverterRun::
45+
pub struct PlaneDataRef<'data> {
46+
pub(crate) inner: data::DataRef<'data, PlaneBytes>,
47+
}
48+
49+
/// A reference to mutable bytes containing data of a single plane.
50+
///
51+
/// This can be created from a [`Plane`] but also by validating an arbitrary slice of bytes against
52+
/// some of the known layouts. These layouts can be partially defined by the user.
53+
pub struct PlaneDataMut<'data> {
54+
pub(crate) inner: data::DataMut<'data, PlaneBytes>,
55+
}
56+
3957
/// Represents a single matrix like layer of an image.
4058
///
4159
/// Created from [`Canvas::plane`].
@@ -645,3 +663,51 @@ impl From<ArcCanvas> for RcCanvas {
645663
RcCanvas { inner: out }
646664
}
647665
}
666+
667+
impl<'lt> From<&'lt Plane> for PlaneDataRef<'lt> {
668+
fn from(plane: &'_ Plane) -> PlaneDataRef<'_> {
669+
PlaneDataRef {
670+
inner: plane.inner.as_ref().into_cloned_layout().into_data(),
671+
}
672+
}
673+
}
674+
675+
impl<'lt> From<&'lt mut Plane> for PlaneDataMut<'lt> {
676+
fn from(plane: &'_ mut Plane) -> PlaneDataMut<'_> {
677+
PlaneDataMut {
678+
inner: plane.inner.as_mut().into_cloned_layout().into_data(),
679+
}
680+
}
681+
}
682+
683+
impl<'data> PlaneDataRef<'data> {
684+
/// Create plane data from bytes and a layout.
685+
///
686+
/// This returns `Some` if the data is long enough for the layout, and `None` otherwise.
687+
/// Extraneous data is ignored.
688+
pub fn new(data: &'data [u8], layout: PlaneBytes) -> Result<Self, LayoutError> {
689+
let err = LayoutError::length_required(
690+
data.len()..image_texel::layout::Layout::byte_len(&layout),
691+
);
692+
693+
let inner = data::DataRef::with_layout_at(data, layout, 0).ok_or(err)?;
694+
695+
Ok(PlaneDataRef { inner })
696+
}
697+
}
698+
699+
impl<'data> PlaneDataMut<'data> {
700+
/// Create mutable plane data from bytes and a layout.
701+
///
702+
/// This returns `Some` if the data is long enough for the layout, and `None` otherwise.
703+
/// Extraneous data is ignored.
704+
pub fn new(data: &'data mut [u8], layout: PlaneBytes) -> Result<Self, LayoutError> {
705+
let err = LayoutError::length_required(
706+
data.len()..image_texel::layout::Layout::byte_len(&layout),
707+
);
708+
709+
let inner = data::DataMut::with_layout_at(data, layout, 0).ok_or(err)?;
710+
711+
Ok(PlaneDataMut { inner })
712+
}
713+
}

canvas/src/layout.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ enum LayoutErrorInner {
405405
StrideError,
406406
NoChannelIndex(ColorChannel),
407407
ValidationError(u32),
408+
LengthRequired { actual: usize, expected: usize },
408409
}
409410

410411
impl Texel {
@@ -1229,6 +1230,15 @@ impl LayoutError {
12291230
inner: LayoutErrorInner::NoModel,
12301231
};
12311232

1233+
pub(crate) fn length_required(bytes: core::ops::Range<usize>) -> Self {
1234+
LayoutError {
1235+
inner: LayoutErrorInner::LengthRequired {
1236+
actual: bytes.start,
1237+
expected: bytes.end,
1238+
},
1239+
}
1240+
}
1241+
12321242
fn validation(num: u32) -> Self {
12331243
LayoutError {
12341244
inner: LayoutErrorInner::ValidationError(num),

canvas/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ pub use self::shader::{ConversionError, Converter, ConverterPlaneHandle, Convert
8585
pub mod canvas {
8686
pub use crate::frame::{
8787
ArcCanvas, BytePlaneAtomics, BytePlaneCells, BytePlaneMut, BytePlaneRef,
88-
BytePlaneRef as BytePlane, ChannelsMut, ChannelsRef, PlaneMut, PlaneRef, RcCanvas,
88+
BytePlaneRef as BytePlane, ChannelsMut, ChannelsRef, PlaneDataMut, PlaneDataRef, PlaneMut,
89+
PlaneRef, RcCanvas,
8990
};
9091
}
9192

0 commit comments

Comments
 (0)