diff --git a/Cargo.toml b/Cargo.toml index 50e8cf2..b9a8052 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,18 +5,24 @@ version = "1.4.3" authors = ["DarthSim "] edition = "2024" license-file = "LICENSE" -repository="https://github.com/DarthSim/quantizr" +repository = "https://github.com/DarthSim/quantizr" [lib] name = "quantizr" +[dependencies] +hashbrown = { version = "0.16.1", default-features = false } +num-traits = { version = "0.2.19", default-features = false, features = ["libm"] } + +[features] +default = ["std"] +std = [] +capi = ["std"] + [profile.release] opt-level = 3 lto = true debug = false debug-assertions = false -[features] -"capi" = [] - # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/capi.rs b/src/capi.rs index 601ce44..8c8c589 100644 --- a/src/capi.rs +++ b/src/capi.rs @@ -1,6 +1,7 @@ #![allow(clippy::missing_safety_doc)] -use std::slice; +use alloc::boxed::Box; +use core::slice; use crate::error::Error; use crate::histogram::Histogram; @@ -17,7 +18,7 @@ pub enum QuantizrError { QuantizrBufferTooSmall = 1, } -impl std::convert::From for QuantizrError { +impl From for QuantizrError { fn from(error: Error) -> Self { match error { Error::ValueOutOfRange => Self::QuantizrValueOutOfRange, @@ -131,20 +132,20 @@ pub unsafe extern "C" fn quantizr_remap( #[unsafe(no_mangle)] pub extern "C" fn quantizr_free_result(result: Box) { - std::mem::drop(result) + drop(result) } #[unsafe(no_mangle)] pub extern "C" fn quantizr_free_histogram(hist: Box) { - std::mem::drop(hist) + drop(hist) } #[unsafe(no_mangle)] pub extern "C" fn quantizr_free_image(image: Box) { - std::mem::drop(image) + drop(image) } #[unsafe(no_mangle)] pub extern "C" fn quantizr_free_options(options: Box) { - std::mem::drop(options) + drop(options) } diff --git a/src/cluster.rs b/src/cluster.rs index e2a2108..81e2896 100644 --- a/src/cluster.rs +++ b/src/cluster.rs @@ -1,3 +1,7 @@ +use alloc::vec::Vec; +#[cfg(not(feature = "std"))] +use num_traits::Float; + use crate::ord_float::OrdFloat32; use crate::histogram::{Histogram, HistogramEntry}; @@ -186,7 +190,7 @@ impl<'clust> Cluster<'clust> { #[inline(always)] fn add_color(dst: &mut [f32; 4], src: &[f32; 4], weight: f32) { unsafe { - use std::arch::x86_64::*; + use core::arch::x86_64::*; let mut psrc = _mm_loadu_ps(src.as_ptr()); let mut pdst = _mm_loadu_ps(dst.as_ptr()); @@ -203,7 +207,7 @@ fn add_color(dst: &mut [f32; 4], src: &[f32; 4], weight: f32) { #[inline(always)] fn add_color(dst: &mut [f32; 4], src: &[f32; 4], weight: f32) { unsafe { - use std::arch::aarch64::*; + use core::arch::aarch64::*; let mut psrc = vld1q_f32(src.as_ptr()); let mut pdst = vld1q_f32(dst.as_ptr()); @@ -232,7 +236,7 @@ fn add_color(dst: &mut [f32; 4], src: &[f32; 4], weight: f32) { #[inline(always)] fn add_diff(dst: &mut [f32; 4], a: &[f32; 4], b: &[f32; 4], weight: f32) { unsafe { - use std::arch::x86_64::*; + use core::arch::x86_64::*; let pa = _mm_loadu_ps(a.as_ptr()); let pb = _mm_loadu_ps(b.as_ptr()); @@ -256,7 +260,7 @@ fn add_diff(dst: &mut [f32; 4], a: &[f32; 4], b: &[f32; 4], weight: f32) { #[inline(always)] fn add_diff(dst: &mut [f32; 4], a: &[f32; 4], b: &[f32; 4], weight: f32) { unsafe { - use std::arch::aarch64::*; + use core::arch::aarch64::*; let pa = vld1q_f32(a.as_ptr()); let pb = vld1q_f32(b.as_ptr()); diff --git a/src/colormap.rs b/src/colormap.rs index f8ee29d..7227bd9 100644 --- a/src/colormap.rs +++ b/src/colormap.rs @@ -1,3 +1,7 @@ +use alloc::vec::Vec; +#[cfg(not(feature = "std"))] +use num_traits::Float; + use crate::ord_float::OrdFloat32; use crate::vpsearch; @@ -180,7 +184,7 @@ fn sort_colors(entries: &mut [[f32; 4]], weights: &mut [f32]) { #[inline(always)] fn add_color(dst: &mut [f32; 4], src: &[f32; 4], weight: f32) { unsafe { - use std::arch::x86_64::*; + use core::arch::x86_64::*; let mut psrc = _mm_loadu_ps(src.as_ptr()); let mut pdst = _mm_loadu_ps(dst.as_ptr()); @@ -197,7 +201,7 @@ fn add_color(dst: &mut [f32; 4], src: &[f32; 4], weight: f32) { #[inline(always)] fn add_color(dst: &mut [f32; 4], src: &[f32; 4], weight: f32) { unsafe { - use std::arch::aarch64::*; + use core::arch::aarch64::*; let mut psrc = vld1q_f32(src.as_ptr()); let mut pdst = vld1q_f32(dst.as_ptr()); diff --git a/src/error.rs b/src/error.rs index 5c6a884..234af1d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; #[non_exhaustive] pub enum Error { @@ -23,4 +23,4 @@ impl fmt::Debug for Error { } } -impl std::error::Error for Error {} +impl core::error::Error for Error {} diff --git a/src/histogram.rs b/src/histogram.rs index 7eebeb4..8d4de15 100644 --- a/src/histogram.rs +++ b/src/histogram.rs @@ -1,5 +1,9 @@ +use core::hash::{BuildHasher, Hasher}; + +#[cfg(feature = "std")] use std::collections::HashMap; -use std::hash::{BuildHasher, Hasher}; +#[cfg(not(feature = "std"))] +use hashbrown::HashMap; use crate::image::Image; diff --git a/src/lib.rs b/src/lib.rs index afd758e..c94cb73 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,8 @@ //! Fast library for conversion of RGBA images to 8-bit paletted images. //! +//! This crate supports `no_std` environments with the `alloc` crate. +//! Disable the default `std` feature to use in `no_std` mode. +//! //! ### Quantizing an image //! //! ``` @@ -54,6 +57,10 @@ //! save_image2(palette, indexes2, width2, height2); //! ``` +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + mod cluster; mod colormap; mod error; diff --git a/src/ord_float.rs b/src/ord_float.rs index 0472ce6..cf9e022 100644 --- a/src/ord_float.rs +++ b/src/ord_float.rs @@ -1,4 +1,4 @@ -use std::cmp::Ordering; +use core::cmp::Ordering; #[derive(Debug, Copy, Clone)] #[repr(transparent)] diff --git a/src/palette.rs b/src/palette.rs index e2d6737..4e50030 100644 --- a/src/palette.rs +++ b/src/palette.rs @@ -1,3 +1,6 @@ +#[cfg(not(feature = "std"))] +use num_traits::Float; + /// RGBA color #[repr(C)] #[derive(Clone, Copy, Default)] diff --git a/src/quantize.rs b/src/quantize.rs index 4b4a7d4..377022a 100644 --- a/src/quantize.rs +++ b/src/quantize.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use core::mem; + use crate::cluster::Cluster; use crate::colormap::Colormap; use crate::error::Error; @@ -200,7 +203,7 @@ impl QuantizeResult { err[3] += err_a * 7.0; } - std::mem::swap(&mut error_curr, &mut error_next); + mem::swap(&mut error_curr, &mut error_next); error_next.fill_with(|| [0f32; 4]); } } diff --git a/src/vpsearch.rs b/src/vpsearch.rs index 1f04fd9..6dea8f7 100644 --- a/src/vpsearch.rs +++ b/src/vpsearch.rs @@ -1,3 +1,8 @@ +use alloc::boxed::Box; +use alloc::vec::Vec; +#[cfg(not(feature = "std"))] +use num_traits::Float; + use crate::ord_float::OrdFloat32; #[derive(Clone)] @@ -115,19 +120,19 @@ impl SearchNode { if let Some(near) = &self.near { near.visit(pin, nearest); } - if distance_sq.sqrt() >= self.radius - nearest.distance { - if let Some(far) = &self.far { - far.visit(pin, nearest); - } + if distance_sq.sqrt() >= self.radius - nearest.distance + && let Some(far) = &self.far + { + far.visit(pin, nearest); } } else { if let Some(far) = &self.far { far.visit(pin, nearest); } - if distance_sq.sqrt() <= self.radius + nearest.distance { - if let Some(near) = &self.near { - near.visit(pin, nearest); - } + if distance_sq.sqrt() <= self.radius + nearest.distance + && let Some(near) = &self.near + { + near.visit(pin, nearest); } } } @@ -177,7 +182,7 @@ impl SearchTree { #[inline(always)] fn dist(c1: &[f32; 4], c2: &[f32; 4]) -> f32 { unsafe { - use std::arch::x86_64::*; + use core::arch::x86_64::*; let pc1 = _mm_loadu_ps(c1.as_ptr()); let pc2 = _mm_loadu_ps(c2.as_ptr()); @@ -196,7 +201,7 @@ fn dist(c1: &[f32; 4], c2: &[f32; 4]) -> f32 { #[inline(always)] fn dist(c1: &[f32; 4], c2: &[f32; 4]) -> f32 { unsafe { - use std::arch::aarch64::*; + use core::arch::aarch64::*; let pc1 = vld1q_f32(c1.as_ptr()); let pc2 = vld1q_f32(c2.as_ptr());