Make library no_std compatible by gating std use (#59)

* feat: initial `no_std` support attempt

* fix: feature gate some required imports

* fix: unimported `Vec` references in NEON convolution modules
This commit is contained in:
Erica Marigold
2026-01-07 02:31:31 +03:00
committed by GitHub
parent 5ea4ad2c0e
commit 18a45b7ba4
97 changed files with 282 additions and 122 deletions
Generated
+1
View File
@@ -580,6 +580,7 @@ dependencies = [
"fast_image_resize",
"image",
"itertools 0.14.0",
"libm",
"libvips",
"nix",
"num-traits",
+10 -6
View File
@@ -21,28 +21,32 @@ exclude = ["/data", "/.github"]
[dependencies]
cfg-if = "1.0"
num-traits = "0.2.19"
thiserror = "2.0"
document-features = "0.2.12"
num-traits = { version = "0.2.19", default-features = false }
thiserror = { version = "2.0", default-features = false }
document-features = { version = "0.2.12", optional = true }
# Optional dependencies
image = { version = "0.25.6", optional = true, default-features = false }
bytemuck = { version = "1.24", optional = true }
rayon = { version = "1.11", optional = true }
libm = "0.2.15"
[features]
# default = ["std"]
## Whether or not to depend on the Rust `std`
std = ["thiserror/std", "num-traits/std", "dep:document-features"]
## Enable this feature to implement traits [IntoImageView](crate::IntoImageView) and
## [IntoImageViewMut](crate::IntoImageViewMut) for the
## [DynamicImage](https://docs.rs/image/latest/image/enum.DynamicImage.html)
## type and some variants of
## [ImageBuffer](https://docs.rs/image/latest/image/struct.ImageBuffer.html)
## type from the `image` crate.
image = ["dep:image", "dep:bytemuck"]
image = ["std", "dep:image", "dep:bytemuck"]
## Enable this feature to implement traits [bytemuck::Pod] and
## [bytemuck::Zeroable] for the `Pixel` type.
bytemuck = ["dep:bytemuck"]
bytemuck = ["std", "dep:bytemuck"]
## This feature enables image processing in the ` rayon ` thread pool.
rayon = ["dep:rayon", "resize/rayon", "image/rayon"]
rayon = ["std", "dep:rayon", "resize/rayon", "image/rayon"]
for_testing = ["image", "image/png", "bytemuck"]
only_u8x4 = [] # This can be used to experiment with the crate's code.
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::pixels::F32x2;
use crate::{ImageView, ImageViewMut};
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::pixels::F32x2;
use crate::{ImageView, ImageViewMut};
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::pixels::F32x4;
use crate::{ImageView, ImageViewMut};
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::pixels::F32x4;
use crate::{ImageView, ImageViewMut};
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use super::sse4;
use crate::pixels::U16x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::neon_utils;
use crate::pixels::U16x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use super::native;
use crate::pixels::U16x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::pixels::U16x2;
use crate::utils::foreach_with_pre_reading;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use super::sse4;
use crate::pixels::U16x4;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::neon_utils;
use crate::pixels::U16x4;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::pixels::U16x4;
use crate::utils::foreach_with_pre_reading;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::pixels::U16x4;
use crate::utils::foreach_with_pre_reading;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::pixels::U8x2;
use crate::utils::foreach_with_pre_reading;
+1 -1
View File
@@ -56,7 +56,7 @@ pub(crate) fn divide_alpha(
#[inline]
pub(crate) fn divide_alpha_inplace(image_view: &mut impl ImageViewMut<Pixel = U8x2>) {
for dst_row in image_view.iter_rows_mut(0) {
let src_row = unsafe { std::slice::from_raw_parts(dst_row.as_ptr(), dst_row.len()) };
let src_row = unsafe { core::slice::from_raw_parts(dst_row.as_ptr(), dst_row.len()) };
divide_alpha_row(src_row, dst_row);
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::neon_utils;
use crate::pixels::U8x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use super::native;
use crate::pixels::U8x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::pixels::U8x2;
use crate::wasm32_utils::u16x8_mul_add_shr16;
+1 -1
View File
@@ -1,7 +1,7 @@
use crate::pixels::U8x4;
use crate::utils::foreach_with_pre_reading;
use crate::{simd_utils, ImageView, ImageViewMut};
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use super::sse4;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::neon_utils;
use crate::pixels::U8x4;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::pixels::U8x4;
use crate::utils::foreach_with_pre_reading;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::pixels::U8x4;
use crate::wasm32_utils::u16x8_mul_add_shr16;
+1 -1
View File
@@ -1,7 +1,7 @@
use core::array::IntoIter;
use core::iter::Take;
use core::iter::{FusedIterator, Iterator};
use std::mem::MaybeUninit;
use core::mem::MaybeUninit;
/// An iterator over `N` elements of the iterator at a time.
///
+2
View File
@@ -1,3 +1,5 @@
#[cfg(not(feature = "std"))]
use crate::float_ext::FloatExt;
use crate::PixelComponentMapper;
fn gamma_into_linear(input: f32) -> f32 {
+5
View File
@@ -1,5 +1,10 @@
//! Functions and structs for working with colorspace and gamma.
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
use num_traits::bounds::UpperBounded;
#[cfg(not(feature = "std"))]
use num_traits::float::FloatCore;
use num_traits::Zero;
use crate::pixels::{
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::{Coefficients, CoefficientsChunk};
use crate::pixels::F32;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::{Coefficients, CoefficientsChunk};
use crate::pixels::F32;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::{Coefficients, CoefficientsChunk};
use crate::pixels::F32x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::{Coefficients, CoefficientsChunk};
use crate::pixels::F32x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::{Coefficients, CoefficientsChunk};
use crate::pixels::{F32x3, InnerPixel};
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::{Coefficients, CoefficientsChunk};
use crate::pixels::{F32x3, InnerPixel};
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::{Coefficients, CoefficientsChunk};
use crate::pixels::F32x4;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::{Coefficients, CoefficientsChunk};
use crate::pixels::F32x4;
+8 -3
View File
@@ -1,7 +1,12 @@
use std::f64::consts::PI;
use std::fmt::{Debug, Formatter};
use core::f64::consts::PI;
use core::fmt::{Debug, Formatter};
#[cfg(not(feature = "std"))]
use num_traits::float::FloatCore;
use thiserror::Error;
#[cfg(not(feature = "std"))]
use crate::float_ext::FloatExt;
type FilterFn = fn(f64) -> f64;
/// Description of custom filter for image convolution.
@@ -24,7 +29,7 @@ impl PartialEq for Filter {
impl Eq for Filter {}
impl Debug for Filter {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Filter")
.field("name", &self.name)
.field("support", &self.support)
+3
View File
@@ -2,6 +2,9 @@ use crate::convolution::Coefficients;
use crate::pixels::I32;
use crate::{ImageView, ImageViewMut};
#[cfg(not(feature = "std"))]
use num_traits::float::FloatCore;
pub(crate) fn horiz_convolution(
src_view: &impl ImageView<Pixel = I32>,
dst_view: &mut impl ImageViewMut<Pixel = I32>,
+6
View File
@@ -1,8 +1,14 @@
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
pub use filters::*;
use crate::pixels::InnerPixel;
use crate::{CpuExtensions, ImageView, ImageViewMut};
#[cfg(not(feature = "std"))]
use num_traits::float::FloatCore;
#[macro_use]
mod macros;
+8
View File
@@ -1,3 +1,11 @@
#[cfg(not(feature = "std"))]
use alloc::borrow::ToOwned;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
#[cfg(not(feature = "std"))]
use num_traits::float::FloatCore;
use crate::convolution::Coefficients;
// This code is based on C-implementation from Pillow-SIMD package for Python
// https://github.com/uploadcare/pillow-simd
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::convolution::optimisations::{CoefficientsI32Chunk, Normalizer32};
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::convolution::optimisations::{CoefficientsI32Chunk, Normalizer32};
use crate::neon_utils;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16x3;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::convolution::optimisations::{CoefficientsI32Chunk, Normalizer32};
use crate::neon_utils;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16x3;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16x3;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16x4;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::convolution::optimisations::{CoefficientsI32Chunk, Normalizer32};
use crate::neon_utils;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16x4;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::convolution::optimisations::Normalizer32;
use crate::pixels::U16x4;
+3 -1
View File
@@ -1,4 +1,6 @@
use std::arch::x86_64::*;
#[cfg(not(feature = "std"))]
use alloc::borrow::ToOwned;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::convolution::optimisations::Normalizer16;
use crate::neon_utils;
+3 -1
View File
@@ -1,4 +1,6 @@
use std::arch::x86_64::*;
#[cfg(not(feature = "std"))]
use alloc::borrow::ToOwned;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::convolution::optimisations::{CoefficientsI16Chunk, Normalizer16};
use crate::pixels::U8x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8x2;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8x3;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::convolution::optimisations::{CoefficientsI16Chunk, Normalizer16};
use crate::neon_utils;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8x3;
+2 -2
View File
@@ -1,5 +1,5 @@
use std::arch::wasm32::*;
use std::mem::transmute;
use core::arch::wasm32::*;
use core::mem::transmute;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8x3;
+2 -2
View File
@@ -1,5 +1,5 @@
use std::arch::x86_64::*;
use std::mem::transmute;
use core::arch::x86_64::*;
use core::mem::transmute;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8x4;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::convolution::optimisations::{CoefficientsI16Chunk, Normalizer16};
use crate::neon_utils;
+2 -2
View File
@@ -1,5 +1,5 @@
use std::arch::x86_64::*;
use std::mem::transmute;
use core::arch::x86_64::*;
use core::mem::transmute;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8x4;
+2 -2
View File
@@ -1,5 +1,5 @@
use std::arch::wasm32::*;
use std::mem::transmute;
use core::arch::wasm32::*;
use core::mem::transmute;
use crate::convolution::optimisations::Normalizer16;
use crate::pixels::U8x4;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::{Coefficients, CoefficientsChunk};
use crate::pixels::InnerPixel;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::{Coefficients, CoefficientsChunk};
use crate::pixels::InnerPixel;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::{CoefficientsI32Chunk, Normalizer32};
use crate::pixels::InnerPixel;
+5 -2
View File
@@ -1,5 +1,8 @@
use std::arch::aarch64::*;
use std::mem::transmute;
#[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec};
use core::arch::aarch64::*;
use core::mem::transmute;
use crate::convolution::optimisations::{CoefficientsI32Chunk, Normalizer32};
use crate::neon_utils;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::{CoefficientsI32Chunk, Normalizer32};
use crate::convolution::vertical_u16::native::convolution_by_u16;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::convolution::optimisations::{CoefficientsI32Chunk, Normalizer32};
use crate::convolution::vertical_u16::native::convolution_by_u16;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::{CoefficientsI16Chunk, Normalizer16};
use crate::convolution::vertical_u8::native;
+5 -2
View File
@@ -1,5 +1,8 @@
use std::arch::aarch64::*;
use std::mem::transmute;
#[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec};
use core::arch::aarch64::*;
use core::mem::transmute;
use crate::convolution::optimisations::{CoefficientsI16Chunk, Normalizer16};
use crate::neon_utils;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::convolution::optimisations::{CoefficientsI16Chunk, Normalizer16};
use crate::convolution::vertical_u8::native;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::convolution::optimisations::{CoefficientsI16Chunk, Normalizer16};
use crate::convolution::vertical_u8::native;
+46 -10
View File
@@ -23,24 +23,63 @@ impl CpuExtensions {
pub fn is_supported(&self) -> bool {
match self {
#[cfg(target_arch = "x86_64")]
Self::Avx2 => is_x86_feature_detected!("avx2"),
Self::Avx2 => Self::has_avx2(),
#[cfg(target_arch = "x86_64")]
Self::Sse4_1 => is_x86_feature_detected!("sse4.1"),
Self::Sse4_1 => Self::has_sse41(),
#[cfg(target_arch = "aarch64")]
Self::Neon => std::arch::is_aarch64_feature_detected!("neon"),
// FIXME: Not sure how, I don't know ARM assembly. AFAIK, all ARM compliant
// processors must implement NEON
Self::Neon => true,
#[cfg(target_arch = "wasm32")]
Self::Simd128 => true,
Self::None => true,
}
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[inline]
fn has_avx2() -> bool {
use core::arch::x86_64::{__cpuid, __cpuid_count, _xgetbv};
unsafe {
let cpuid1 = __cpuid(1);
if (cpuid1.ecx & (1 << 27)) == 0 || (cpuid1.ecx & (1 << 28)) == 0 {
// OSXSAVE + AVX
return false;
}
let xcr0 = _xgetbv(0);
if (xcr0 & 0b110) != 0b110 {
// XCR0: XMM (bit 1) and YMM (bit 2) enabled
return false;
}
// CPUID leaf 7 subleaf 0: AVX2
let cpuid7 = __cpuid_count(7, 0);
(cpuid7.ebx & (1 << 5)) != 0
}
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[inline]
fn has_sse41() -> bool {
use core::arch::x86_64::__cpuid;
// CPUID leaf 1: feature bits
let res = unsafe { __cpuid(1) };
// ECX bit 19 = SSE4.1
(res.ecx & (1 << 19)) != 0
}
}
impl Default for CpuExtensions {
#[cfg(target_arch = "x86_64")]
fn default() -> Self {
if is_x86_feature_detected!("avx2") {
if Self::has_avx2() {
Self::Avx2
} else if is_x86_feature_detected!("sse4.1") {
} else if Self::has_sse41() {
Self::Sse4_1
} else {
Self::None
@@ -49,11 +88,8 @@ impl Default for CpuExtensions {
#[cfg(target_arch = "aarch64")]
fn default() -> Self {
if std::arch::is_aarch64_feature_detected!("neon") {
Self::Neon
} else {
Self::None
}
// FIXME: Maybe we detect?
Self::Neon
}
#[cfg(target_arch = "wasm32")]
fn default() -> Self {
+43
View File
@@ -0,0 +1,43 @@
pub trait FloatExt {
fn sin(self) -> Self;
fn cos(self) -> Self;
fn sqrt(self) -> Self;
fn exp(self) -> Self;
fn powf(self, exp: Self) -> Self;
}
impl FloatExt for f32 {
fn sin(self) -> Self {
libm::sinf(self)
}
fn cos(self) -> Self {
libm::cosf(self)
}
fn sqrt(self) -> Self {
libm::sqrtf(self)
}
fn exp(self) -> Self {
libm::expf(self)
}
fn powf(self, exp: f32) -> Self {
libm::powf(self, exp)
}
}
impl FloatExt for f64 {
fn sin(self) -> Self {
libm::sin(self)
}
fn cos(self) -> Self {
libm::cos(self)
}
fn sqrt(self) -> Self {
libm::sqrt(self)
}
fn exp(self) -> Self {
libm::exp(self)
}
fn powf(self, exp: f64) -> Self {
libm::pow(self, exp)
}
}
+6 -1
View File
@@ -1,9 +1,14 @@
use std::num::NonZeroU32;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::num::NonZeroU32;
use crate::images::{TypedCroppedImage, TypedCroppedImageMut, UnsafeImageMut};
use crate::pixels::InnerPixel;
use crate::{ArrayChunks, ImageError, PixelTrait, PixelType};
#[cfg(not(feature = "std"))]
use num_traits::float::FloatCore;
/// A trait for getting access to image data.
///
/// # Safety
+3
View File
@@ -1,3 +1,6 @@
#[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec};
use crate::images::{BufferContainer, TypedImage, TypedImageRef};
use crate::pixels::InnerPixel;
use crate::{
+1 -1
View File
@@ -1,4 +1,4 @@
use std::ops::DerefMut;
use core::ops::DerefMut;
use crate::image_view::try_pixel_type;
use crate::images::{TypedImage, TypedImageRef};
+3 -1
View File
@@ -1,5 +1,7 @@
//! Contains different types of images and wrappers for them.
use std::fmt::Debug;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::fmt::Debug;
pub use cropped_image::*;
pub use image::*;
+4 -1
View File
@@ -1,6 +1,9 @@
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::num::NonZeroU32;
use crate::images::{View, ViewMut};
use crate::{CropBoxError, ImageView, ImageViewMut};
use std::num::NonZeroU32;
pub(crate) fn check_crop_box(
img_width: u32,
+8 -2
View File
@@ -1,8 +1,14 @@
#[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec};
use core::fmt::Debug;
use core::num::NonZeroU32;
use crate::images::BufferContainer;
use crate::pixels::InnerPixel;
use crate::{ImageBufferError, ImageView, ImageViewMut, InvalidPixelsSize};
use std::fmt::Debug;
use std::num::NonZeroU32;
#[cfg(not(feature = "std"))]
use num_traits::float::FloatCore;
/// Generic reference to image data that provides [ImageView].
#[derive(Debug)]
+7 -4
View File
@@ -1,13 +1,16 @@
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::marker::PhantomData;
use core::num::NonZeroU32;
use crate::{ArrayChunks, ImageView, ImageViewMut};
use std::marker::PhantomData;
use std::num::NonZeroU32;
#[derive(Copy)]
pub(crate) struct UnsafeImageMut<'a, V>
where
V: ImageViewMut,
{
image: std::ptr::NonNull<V>,
image: core::ptr::NonNull<V>,
p: PhantomData<&'a V>,
}
@@ -28,7 +31,7 @@ unsafe impl<'a, V: ImageViewMut> Sync for UnsafeImageMut<'a, V> {}
impl<'a, V: ImageViewMut> UnsafeImageMut<'a, V> {
pub fn new(image: &'a mut V) -> Self {
let ptr = std::ptr::NonNull::new(image as *mut V).unwrap();
let ptr = core::ptr::NonNull::new(image as *mut V).unwrap();
Self {
image: ptr,
p: PhantomData,
+7 -1
View File
@@ -1,7 +1,12 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![doc = include_str!("../README.md")]
//!
//! ## Feature flags
#![doc = document_features::document_features!()]
#![cfg_attr(feature = "std", doc = document_features::document_features!())]
#[cfg(not(feature = "std"))]
extern crate alloc;
pub use alpha::errors::*;
pub use array_chunks::*;
@@ -30,6 +35,7 @@ mod convolution;
mod cpu_extensions;
mod crop_box;
mod errors;
mod float_ext;
mod image_view;
pub mod images;
mod mul_div;
+3 -3
View File
@@ -1,4 +1,4 @@
use std::arch::aarch64::*;
use core::arch::aarch64::*;
use crate::pixels::InnerPixel;
@@ -110,7 +110,7 @@ pub unsafe fn load_deintrel_u16x1x3<T: InnerPixel<Component = u16>>(
let mut arr = [0u16; 12];
let src_ptr = buf.get_unchecked(index..).as_ptr() as *const u16;
let dst_ptr = arr.as_mut_ptr();
std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, 3);
core::ptr::copy_nonoverlapping(src_ptr, dst_ptr, 3);
vld3_u16(arr.as_ptr())
}
@@ -122,7 +122,7 @@ pub unsafe fn load_deintrel_u16x2x3<T: InnerPixel<Component = u16>>(
let mut arr = [0u16; 12];
let src_ptr = buf.get_unchecked(index..).as_ptr() as *const u16;
let dst_ptr = arr.as_mut_ptr();
std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, 6);
core::ptr::copy_nonoverlapping(src_ptr, dst_ptr, 6);
vld3_u16(arr.as_ptr())
}
+8 -5
View File
@@ -1,8 +1,11 @@
//! Contains types of pixels.
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
use std::mem::size_of;
use std::slice;
use core::fmt::{Debug, Formatter};
use core::marker::PhantomData;
use core::mem::size_of;
use core::slice;
#[cfg(not(feature = "std"))]
use num_traits::float::FloatCore;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
@@ -248,7 +251,7 @@ macro_rules! pixel_struct {
}
impl Debug for $name {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
let components_ptr = self as *const _ as *const $comp_type;
let components: &[$comp_type] =
unsafe { slice::from_raw_parts(components_ptr, $comp_count) };
+8 -2
View File
@@ -1,3 +1,6 @@
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use crate::convolution::{self, FilterType};
use crate::crop_box::CroppedSrcImageView;
use crate::image_view::{try_pixel_type, ImageView, ImageViewMut, IntoImageView, IntoImageViewMut};
@@ -7,6 +10,9 @@ use crate::{
CpuExtensions, CropBox, DifferentDimensionsError, MulDiv, PixelTrait, PixelType, ResizeError,
};
#[cfg(not(feature = "std"))]
use num_traits::float::FloatCore;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[non_exhaustive]
pub enum ResizeAlg {
@@ -320,7 +326,7 @@ impl Resizer {
) {
if use_alpha && self.mul_div.is_supported(P::pixel_type()) {
let src_view = cropped_src_view.image_view();
let mut alpha_buffer = std::mem::take(&mut self.alpha_buffer);
let mut alpha_buffer = core::mem::take(&mut self.alpha_buffer);
let mut premultiplied_src =
get_temp_image_from_buffer(&mut alpha_buffer, src_view.width(), src_view.height());
@@ -517,7 +523,7 @@ impl Resizer {
let tmp_width = (crop_box.width / factor).round() as u32;
let tmp_height = (crop_box.height / factor).round() as u32;
let mut super_sampling_buffer = std::mem::take(&mut self.super_sampling_buffer);
let mut super_sampling_buffer = core::mem::take(&mut self.super_sampling_buffer);
let mut tmp_img =
get_temp_image_from_buffer(&mut super_sampling_buffer, tmp_width, tmp_height);
resample_nearest(cropped_src_view, &mut tmp_img);
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use crate::pixels::{U8x3, U8x4};
+1 -1
View File
@@ -1,4 +1,4 @@
use std::num::NonZeroU32;
use core::num::NonZeroU32;
use rayon::current_num_threads;
use rayon::prelude::*;
+1 -1
View File
@@ -1,4 +1,4 @@
use std::arch::wasm32::*;
use core::arch::wasm32::*;
use crate::pixels::{U8x3, U8x4};
+1 -1
View File
@@ -952,7 +952,7 @@ mod u8x4 {
#[test]
fn custom_filter_u8x4() {
std::env::set_var("DONT_SAVE_RESULT", "1");
unsafe { std::env::set_var("DONT_SAVE_RESULT", "1") };
const LANCZOS3_RESULT: [u64; 4] = [2942547, 2947799, 2885025, 6122718];
const LANCZOS4_RESULT: [u64; 4] = [2943083, 2948315, 2885436, 6122629];