From 91dadd4edec864737df29de6a93a92544e808f96 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Tue, 21 Apr 2026 18:28:56 +0200 Subject: [PATCH 1/2] chore: add no_std compatibility --- src/chroma.rs | 2 +- src/chroma/tests.rs | 2 +- src/frame.rs | 2 +- src/frame/error.rs | 4 ++-- src/frame/tests.rs | 2 ++ src/lib.rs | 4 ++++ src/pixel.rs | 2 +- src/plane.rs | 2 +- src/plane/aligned.rs | 39 +++++++++++++++++++++++++-------------- src/plane/error.rs | 4 ++-- src/plane/geometry.rs | 2 +- src/plane/tests.rs | 2 ++ 12 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/chroma.rs b/src/chroma.rs index 473aeb1..39deaa4 100644 --- a/src/chroma.rs +++ b/src/chroma.rs @@ -56,7 +56,7 @@ #[cfg(test)] mod tests; -use std::num::NonZeroU8; +use core::num::NonZeroU8; /// Specifies the chroma subsampling for a YUV frame. #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/src/chroma/tests.rs b/src/chroma/tests.rs index affb05e..ed4795e 100644 --- a/src/chroma/tests.rs +++ b/src/chroma/tests.rs @@ -10,7 +10,7 @@ #![allow(clippy::unwrap_used, reason = "test file")] use super::*; -use std::num::NonZeroU8; +use core::num::NonZeroU8; #[test] fn has_chroma() { diff --git a/src/frame.rs b/src/frame.rs index cf1df65..3235769 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -81,7 +81,7 @@ pub use error::FrameError; #[cfg(test)] mod tests; -use std::num::NonZeroU8; +use core::num::NonZeroU8; use crate::{ chroma::ChromaSubsampling, diff --git a/src/frame/error.rs b/src/frame/error.rs index 7c5a411..d10e75b 100644 --- a/src/frame/error.rs +++ b/src/frame/error.rs @@ -7,7 +7,7 @@ // Media Patent License 1.0 was not distributed with this source code in the // PATENTS file, you can obtain it at www.aomedia.org/license/patent. -use std::fmt; +use core::fmt; /// This enum represents all possible error conditions that can occur during /// frame creation, including data validation errors, unsupported formats, @@ -52,4 +52,4 @@ impl fmt::Display for FrameError { } } -impl std::error::Error for FrameError {} +impl core::error::Error for FrameError {} diff --git a/src/frame/tests.rs b/src/frame/tests.rs index 39c0e2b..efd0c42 100644 --- a/src/frame/tests.rs +++ b/src/frame/tests.rs @@ -12,6 +12,8 @@ use super::*; use crate::chroma::ChromaSubsampling; +use alloc::format; + #[test] fn plane_access() { let mut frame = FrameBuilder::new(1920, 1080, ChromaSubsampling::Yuv420, 8) diff --git a/src/lib.rs b/src/lib.rs index 5e26476..7bf4f4c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,10 @@ //! .unwrap(); //! ``` +#![no_std] + +extern crate alloc; + pub mod chroma; pub mod frame; pub mod pixel; diff --git a/src/pixel.rs b/src/pixel.rs index f8a1c0e..6ff25b2 100644 --- a/src/pixel.rs +++ b/src/pixel.rs @@ -22,8 +22,8 @@ //! - 8-bit frames must use `u8` //! - 9-16 bit frames must use `u16` +use core::fmt::Debug; use num_traits::PrimInt; -use std::fmt::Debug; mod private { pub trait Sealed {} diff --git a/src/plane.rs b/src/plane.rs index 0fcae4b..b65e1f3 100644 --- a/src/plane.rs +++ b/src/plane.rs @@ -42,7 +42,7 @@ pub use error::CopyError; mod tests; #[cfg(feature = "padding_api")] -use std::mem::MaybeUninit; +use core::mem::MaybeUninit; mod aligned; use aligned::AlignedData; diff --git a/src/plane/aligned.rs b/src/plane/aligned.rs index de17c70..df09135 100644 --- a/src/plane/aligned.rs +++ b/src/plane/aligned.rs @@ -1,9 +1,11 @@ -use std::alloc::{Layout, alloc, alloc_zeroed, dealloc, handle_alloc_error}; -use std::fmt::Debug; -use std::marker::PhantomData; -use std::mem::{ManuallyDrop, MaybeUninit, align_of}; -use std::ops::{Deref, DerefMut}; -use std::ptr::NonNull; +use alloc::alloc::{alloc, alloc_zeroed, dealloc, handle_alloc_error}; + +use core::alloc::Layout; +use core::fmt::{self, Debug}; +use core::marker::PhantomData; +use core::mem::{ManuallyDrop, MaybeUninit}; +use core::ops::{Deref, DerefMut}; +use core::ptr::NonNull; use crate::pixel::Pixel; @@ -148,7 +150,7 @@ impl, U> PartialEq> for AlignedData { impl Eq for AlignedData {} impl Debug for AlignedData { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if self.len() > 5 { f.debug_list().entries(&self[..5]).finish_non_exhaustive() } else { @@ -209,6 +211,8 @@ impl Drop for AlignedData { mod tests { use super::*; + use alloc::{format, string::String, vec::Vec}; + #[test] fn empty() { AlignedData::::new(0); @@ -295,19 +299,24 @@ mod tests { // SAFETY: Initialized above. let data = unsafe { data.assume_init() }; - println!("{:?}", &data[100..140]); + for (idx, x) in data[100..140].iter().enumerate() { + let idx = 100 + idx; + assert_eq!(*x, (idx % 42) as u8); + } } #[test] fn uninit_with_drop() { let mut data = AlignedData::::new_uninit(3); - data[0].write("Hello World".into()); + data[0].write(String::from("Hello World")); data[1].write(String::new()); - data[2].write("This is a test".into()); + data[2].write(String::from("This is a test")); // SAFETY: Initialized above. let data = unsafe { data.assume_init() }; - println!("{:?}", &*data); + assert_eq!(data[0], String::from("Hello World")); + assert_eq!(data[1], String::new()); + assert_eq!(data[2], String::from("This is a test")); } #[test] @@ -374,14 +383,16 @@ mod tests { #[test] fn clone() { let mut data = AlignedData::::new_uninit(3); - data[0].write("Hello World".into()); + data[0].write(String::from("Hello World")); data[1].write(String::new()); - data[2].write("This is a test".into()); + data[2].write(String::from("This is a test")); // SAFETY: Initialized above. let data = unsafe { data.assume_init() }; let data2 = data.clone(); drop(data); - println!("{:?}", &*data2); + assert_eq!(data2[0], String::from("Hello World")); + assert_eq!(data2[1], String::new()); + assert_eq!(data2[2], String::from("This is a test")); } } diff --git a/src/plane/error.rs b/src/plane/error.rs index de7c5c1..3f82af1 100644 --- a/src/plane/error.rs +++ b/src/plane/error.rs @@ -7,7 +7,7 @@ // Media Patent License 1.0 was not distributed with this source code in the // PATENTS file, you can obtain it at www.aomedia.org/license/patent. -use std::fmt; +use core::fmt; /// An error representing why data couldn't be copied into a Plane. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -50,4 +50,4 @@ impl fmt::Display for CopyError { } } -impl std::error::Error for CopyError {} +impl core::error::Error for CopyError {} diff --git a/src/plane/geometry.rs b/src/plane/geometry.rs index 776f43d..c7881a6 100644 --- a/src/plane/geometry.rs +++ b/src/plane/geometry.rs @@ -1,4 +1,4 @@ -use std::num::{NonZeroU8, NonZeroUsize}; +use core::num::{NonZeroU8, NonZeroUsize}; use crate::chroma::ChromaSubsampling; diff --git a/src/plane/tests.rs b/src/plane/tests.rs index f2ad4d3..872f789 100644 --- a/src/plane/tests.rs +++ b/src/plane/tests.rs @@ -11,6 +11,8 @@ use super::*; +use alloc::{format, vec, vec::Vec}; + /// Helper function to create a simple plane geometry without padding fn simple_geometry(width: usize, height: usize) -> PlaneGeometry { PlaneGeometry::unpadded(width, height, 1, 1).expect("can create simple geometry") From 687eacd1f8652c53eedd72ef0a5ba2134091c2b6 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Fri, 15 May 2026 11:59:13 +0200 Subject: [PATCH 2/2] docs: add no_std section --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 7cbce08..83cb5f0 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,12 @@ The crate automatically adjusts memory alignment for WebAssembly: non-WASI use a 64-byte minimum. Over-aligned pixel data uses `align_of::()` if that is larger. +## `no_std` support + +This crate does not depend on the standard library `std` but does require `alloc` to allocate memory for `Plane` data. + +Users linking against `std` don't have to do anything. If you want to use this crate without `std`, you need to setup and configure a global allocator. The [Embedded Rust Book](https://docs.rust-embedded.org/book/collections/index.html#using-alloc) might be helpful. + ## Feature Flags - `padding_api`: Exposes low-level APIs for direct access to plane padding data (`geometry()`, `data()`, `data_mut()`)