Skip to content

Commit

Permalink
feat(codi-core): no_std support
Browse files Browse the repository at this point in the history
Add [no_std] support using "libm" crate, which implements all the
necessary functions for float operations like sqrt, pow, hypot, etc.
Add build for the "thumbv6m-none-eabi" target to CI, although I'm still
not 100% sure that no_std will work. This is first time I did this.
  • Loading branch information
woojiq committed Apr 7, 2024
1 parent 38b21d6 commit 4606881
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 27 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,3 @@ $ nix develop ./nix # devShell
$ direnv allow # direnv with devShell
$ nix flake check ./nix # run CI locally
```

## TODO
- [ ] No-std support: not easy because no_std doesn't have common float operations (thumbv6m-none-eabi target)
7 changes: 6 additions & 1 deletion codi-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ description.workspace = true
readme.workspace = true

[dependencies]
ordered-float = { version = "4.2.0" }
libm = "0.2.8"
ordered-float = { version = "4.2.0", default-features = false }

[features]
default = ["std"]
std = []

[lints]
workspace = true
26 changes: 13 additions & 13 deletions codi-core/src/color_dist.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use libm::{hypotf, powf, sqrtf};
use ordered_float::NotNan;

use crate::color_space::{Cielab, Rgb};
Expand Down Expand Up @@ -30,9 +31,9 @@ pub struct Euclidean;

impl ColorDistance for Euclidean {
fn dist(&self, c1: Rgb, c2: Rgb) -> NotNan<f32> {
let dist = (f32::from(c1.r) - f32::from(c2.r)).powi(2)
+ (f32::from(c1.g) - f32::from(c2.g)).powi(2)
+ (f32::from(c1.b) - f32::from(c2.b)).powi(2);
let dist = powf(f32::from(c1.r) - f32::from(c2.r), 2.0)
+ powf(f32::from(c1.g) - f32::from(c2.g), 2.0)
+ powf(f32::from(c1.b) - f32::from(c2.b), 2.0);
NotNan::new(dist).unwrap()
}
}
Expand All @@ -55,9 +56,9 @@ impl ColorDistance for EuclideanImproved {
(f32::from(c1.g) - f32::from(c2.g)),
(f32::from(c1.b) - f32::from(c2.b)),
);
let dist: f32 = (2.0 + red_mean / 256.0) * d_r.powi(2)
+ 4.0 * d_g.powi(2)
+ (2.0 + (255.0 - red_mean) / 256.0) * d_b.powi(2);
let dist: f32 = powf((2.0 + red_mean / 256.0) * d_r, 2.0)
+ 4.0 * powf(d_g, 2.0)
+ powf((2.0 + (255.0 - red_mean) / 256.0) * d_b, 2.0);
NotNan::new(dist).unwrap()
}
}
Expand All @@ -81,20 +82,19 @@ impl ColorDistance for CIE94 {

let (delta_l, delta_a, delta_b) = (lab1.l - lab2.l, lab1.a - lab2.a, lab1.b - lab2.b);

let C1 = lab1.a.hypot(lab1.b.into_inner());
let C2 = lab2.a.hypot(lab2.b.into_inner());
let C1 = hypotf(*lab1.a, *lab1.b);
let C2 = hypotf(*lab2.a, *lab2.b);

let Cab = C1 - C2;
let Sl = 1.0;
let Sc = 1.0 + K1 * C1;
let Sh = 1.0 + K2 * C1;
// https://github.com/zschuessler/DeltaE/issues/9
let Hab = (delta_a.powi(2) + delta_b.powi(2) - Cab.powi(2))
.max(0.0)
.sqrt();
let Hab = sqrtf((powf(*delta_a, 2.0) + powf(*delta_b, 2.0) - powf(Cab, 2.0)).max(0.0));

let dist =
(delta_l / (kL * Sl)).powi(2) + (Cab / (kC * Sc)).powi(2) + (Hab / (kH * Sh)).powi(2);
let dist = powf(*delta_l / (kL * Sl), 2.0)
+ powf(Cab / (kC * Sc), 2.0)
+ powf(Hab / (kH * Sh), 2.0);
NotNan::new(dist).unwrap()
}
}
Expand Down
18 changes: 10 additions & 8 deletions codi-core/src/color_space.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use libm::{cbrtf, powf, roundf};
use ordered_float::NotNan;

const HEX_COLOR_LEN: usize = 6;
Expand Down Expand Up @@ -33,6 +34,7 @@ impl core::fmt::Display for Error {
}
}

#[cfg(feature = "std")]
impl std::error::Error for Error {}

type Result<T> = core::result::Result<T, Error>;
Expand Down Expand Up @@ -134,7 +136,7 @@ impl From<Xyz> for Rgb {
if col <= 0.003_130_8 {
col * 12.92
} else {
col.powf(1.0 / 2.4) * 1.055 - 0.055
powf(col, 1.0 / 2.4) * 1.055 - 0.055
}
};

Expand All @@ -147,9 +149,9 @@ impl From<Xyz> for Rgb {
);

Self {
r: (corrected.0).round() as u8,
g: (corrected.1).round() as u8,
b: (corrected.2).round() as u8,
r: roundf(corrected.0) as u8,
g: roundf(corrected.1) as u8,
b: roundf(corrected.2) as u8,
}
}
}
Expand Down Expand Up @@ -203,7 +205,7 @@ impl From<Rgb> for Xyz {
if col <= 0.04045 {
col / 12.92
} else {
((col + 0.055) / 1.055).powf(2.4)
powf((col + 0.055) / 1.055, 2.4)
}
};

Expand Down Expand Up @@ -231,7 +233,7 @@ impl From<Cielab> for Xyz {
fn from(value: Cielab) -> Self {
let f_inv = |t: f32| {
if t > LAB_XYZ_DELTA {
t.powi(3)
powf(t, 3.0)
} else {
3.0 * LAB_XYZ_DELTA_POW2 * (t - 4.0 / 29.0)
}
Expand Down Expand Up @@ -265,9 +267,9 @@ impl From<Xyz> for Cielab {
fn from(value: Xyz) -> Self {
let f = |t: f32| {
if t > LAB_XYZ_DELTA_POW3 {
t.cbrt()
cbrtf(t)
} else {
1.0 / 3.0 * t * LAB_XYZ_DELTA.powi(-2) + 4.0 / 29.0
1.0 / 3.0 * t * powf(LAB_XYZ_DELTA, -2.0) + 4.0 / 29.0
}
};

Expand Down
2 changes: 2 additions & 0 deletions codi-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub mod color_dist;
pub mod color_space;
pub mod html_color;
Expand Down
2 changes: 1 addition & 1 deletion codi-core/src/math_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub fn matrix_mul<T, const I: usize, const J: usize, const K: usize>(
m2: &[[T; J]; K],
) -> [[T; J]; I]
where
T: std::ops::Mul<Output = T> + std::ops::Add<Output = T> + Default + Copy,
T: core::ops::Mul<Output = T> + core::ops::Add<Output = T> + Default + Copy,
{
let mut res: [[T; J]; I] = [[T::default(); J]; I];

Expand Down
4 changes: 3 additions & 1 deletion nix/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
rust =
(pkgs.rust-bin.fromRustupToolchainFile ../rust-toolchain.toml)
.override {
targets = [];
targets = ["thumbv6m-none-eabi"];
extensions = [];
};
rust-nightly = pkgs.rust-bin.nightly."2024-02-01".default;
Expand Down Expand Up @@ -66,6 +66,8 @@
doCheck = true;

postCheck = ''
cargo build -p codi-core --target thumbv6m-none-eabi --no-default-features
cargo clippy --all-targets
cargo fmt --check
cargo doc
Expand Down

0 comments on commit 4606881

Please sign in to comment.