Skip to content

Commit 958e0d0

Browse files
committed
Allow HSV, HSL and HWB to represent nonlinear RGB
1 parent 71b1434 commit 958e0d0

File tree

13 files changed

+364
-393
lines changed

13 files changed

+364
-393
lines changed

palette/examples/hue.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use palette::{FromColor, Hsl, Hue, IntoColor, Lch, Pixel, Srgb};
1+
use palette::{FromColor, Hsl, Hue, Lch, Pixel, Srgb};
22

33
fn main() {
44
let mut image = image::open("res/fruits.png")
@@ -12,15 +12,11 @@ fn main() {
1212
let color = Srgb::from_raw(&pixel.0).into_format();
1313

1414
pixel.0 = if x < y {
15-
let saturated = Hsl::from_color(color).shift_hue(180.0);
16-
Srgb::from_linear(saturated.into_color())
17-
.into_format()
18-
.into_raw()
15+
let hue_shifted = Hsl::from_color(color).shift_hue(180.0);
16+
Srgb::from_color(hue_shifted).into_format().into_raw()
1917
} else {
20-
let saturated = Lch::from_color(color).shift_hue(180.0);
21-
Srgb::from_linear(saturated.into_color())
22-
.into_format()
23-
.into_raw()
18+
let hue_shifted = Lch::from_color(color).shift_hue(180.0);
19+
Srgb::from_color(hue_shifted).into_format().into_raw()
2420
};
2521
}
2622

palette/examples/saturate.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use palette::{Hsl, IntoColor, Lch, Pixel, Saturate, Srgb};
1+
use palette::{FromColor, Hsl, IntoColor, Lch, Pixel, Saturate, Srgb};
22

33
use image::{GenericImage, GenericImageView};
44

@@ -19,18 +19,13 @@ fn main() {
1919
for y in 0..height {
2020
let color: Hsl = Srgb::from_raw(&sub_image.get_pixel(x, y).0)
2121
.into_format()
22-
.into_linear()
2322
.into_color();
2423

2524
let saturated = color.saturate(0.8);
2625
sub_image.put_pixel(
2726
x,
2827
y,
29-
image::Rgb(
30-
Srgb::from_linear(saturated.into_color())
31-
.into_format()
32-
.into_raw(),
33-
),
28+
image::Rgb(Srgb::from_color(saturated).into_format().into_raw()),
3429
);
3530
}
3631
}
@@ -43,18 +38,13 @@ fn main() {
4338
for y in 0..height {
4439
let color: Lch = Srgb::from_raw(&sub_image.get_pixel(x, y).0)
4540
.into_format()
46-
.into_linear()
4741
.into_color();
4842

4943
let saturated = color.saturate(0.8);
5044
sub_image.put_pixel(
5145
x,
5246
y,
53-
image::Rgb(
54-
Srgb::from_linear(saturated.into_color())
55-
.into_format()
56-
.into_raw(),
57-
),
47+
image::Rgb(Srgb::from_color(saturated).into_format().into_raw()),
5848
);
5949
}
6050
}

palette/src/convert.rs

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,39 @@
1515
//! They can be attached to either the item itself, or to the fields.
1616
//!
1717
//! ```
18-
//! # use palette::rgb::RgbSpace;
18+
//! # use palette::rgb::{RgbStandard, RgbSpace};
1919
//! # use palette::convert::FromColorUnclamped;
2020
//! # use palette::{Xyz, Component, FloatComponent};
2121
//! #
2222
//! #[palette(
2323
//! component = "T",
24-
//! rgb_space = "S",
25-
//! white_point = "S::WhitePoint",
24+
//! rgb_standard = "S",
25+
//! white_point = "<S::Space as RgbSpace>::WhitePoint",
2626
//! )]
2727
//! #[derive(FromColorUnclamped)]
2828
//! #[repr(C)]
29-
//! struct ExampleType<S: RgbSpace, T: Component> {
29+
//! struct ExampleType<S: RgbStandard, T: Component> {
3030
//! // ...
3131
//! #[palette(alpha)]
3232
//! alpha: T,
33-
//! space: std::marker::PhantomData<S>,
33+
//! standard: std::marker::PhantomData<S>,
3434
//! }
3535
//!
36-
//! # impl<S: RgbSpace, T: FloatComponent> FromColorUnclamped<Xyz<S::WhitePoint, T>> for ExampleType<S, T> {
37-
//! # fn from_color_unclamped(color: Xyz<S::WhitePoint, T>) -> Self {
38-
//! # ExampleType {alpha: T::max_intensity(), space: std::marker::PhantomData}
36+
//! # impl<S, T> FromColorUnclamped<Xyz<<S::Space as RgbSpace>::WhitePoint, T>> for ExampleType<S, T>
37+
//! # where
38+
//! # S: RgbStandard,
39+
//! # T: FloatComponent
40+
//! # {
41+
//! # fn from_color_unclamped(color: Xyz<<S::Space as RgbSpace>::WhitePoint, T>) -> Self {
42+
//! # ExampleType {alpha: T::max_intensity(), standard: std::marker::PhantomData}
3943
//! # }
4044
//! # }
4145
//! #
42-
//! # impl<S: RgbSpace, T: FloatComponent> FromColorUnclamped<ExampleType<S, T>> for Xyz<S::WhitePoint, T> {
46+
//! # impl<S, T> FromColorUnclamped<ExampleType<S, T>> for Xyz<<S::Space as RgbSpace>::WhitePoint, T>
47+
//! # where
48+
//! # S: RgbStandard,
49+
//! # T: FloatComponent
50+
//! # {
4351
//! # fn from_color_unclamped(color: ExampleType<S, T>) -> Self {
4452
//! # Xyz::default()
4553
//! # }
@@ -60,9 +68,9 @@
6068
//! component type that should be used when deriving. The default is `f32`, but
6169
//! it may be any other type, including type parameters.
6270
//!
63-
//! * `rgb_space = "some::rgb_space::Type"`: Sets the RGB space
71+
//! * `rgb_standard = "some::rgb_standard::Type"`: Sets the RGB standard
6472
//! type that should be used when deriving. The default is to either use `Srgb`
65-
//! or a best effort to convert between spaces, so sometimes it has to be set
73+
//! or a best effort to convert between standards, but sometimes it has to be set
6674
//! to a specific type. This also accepts type parameters.
6775
//!
6876
//! ## Field Attributes
@@ -138,7 +146,7 @@
138146
//! #[palette(
139147
//! skip_derives(Rgb),
140148
//! component = "T",
141-
//! rgb_space = "palette::encoding::Srgb"
149+
//! rgb_standard = "palette::encoding::Srgb"
142150
//! )]
143151
//! #[derive(Copy, Clone, Pixel, FromColorUnclamped)]
144152
//! #[repr(C)] // Makes sure the memory layout is as we want it.
@@ -185,8 +193,8 @@
185193
//! 0.0,
186194
//! 0.0,
187195
//! 0.0,
188-
//! 0.7353569830524495,
189-
//! 0.5370987304831942,
196+
//! 0.5,
197+
//! 0.25,
190198
//! ];
191199
//! let hsv: Hsv<_, f64> = Bgr::from_raw_slice(&buffer)[1].into_color();
192200
//!
@@ -209,7 +217,7 @@
209217
//! /// CSS style sRGB.
210218
//! #[palette(
211219
//! skip_derives(Rgb),
212-
//! rgb_space = "palette::encoding::Srgb"
220+
//! rgb_standard = "palette::encoding::Srgb"
213221
//! )]
214222
//! #[derive(PartialEq, Debug, FromColorUnclamped, WithAlpha)]
215223
//! struct CssRgb {
@@ -528,7 +536,7 @@ mod tests {
528536
skip_derives(Xyz, Luma),
529537
white_point = "S::WhitePoint",
530538
component = "f64",
531-
rgb_space = "S",
539+
rgb_standard = "Linear<S>",
532540
palette_internal,
533541
palette_internal_not_base_type
534542
)]
@@ -597,7 +605,7 @@ mod tests {
597605
skip_derives(Lch, Luma),
598606
white_point = "crate::white_point::E",
599607
component = "T",
600-
rgb_space = "(crate::encoding::Srgb, crate::white_point::E)",
608+
rgb_standard = "Linear<(crate::encoding::Srgb, crate::white_point::E)>",
601609
palette_internal,
602610
palette_internal_not_base_type
603611
)]
@@ -667,7 +675,7 @@ mod tests {
667675
let lch: Lch<_, f64> = Default::default();
668676
WithXyz::<crate::encoding::Srgb>::from_color(lch);
669677

670-
let rgb: Rgb<crate::encoding::Srgb, f64> = Default::default();
678+
let rgb: Rgb<_, f64> = Default::default();
671679
WithXyz::<crate::encoding::Srgb>::from_color(rgb);
672680

673681
let hsl: Hsl<_, f64> = Default::default();
@@ -701,8 +709,7 @@ mod tests {
701709
let lch: Alpha<Lch<_, f64>, u8> = Alpha::from(Lch::default());
702710
WithXyz::<crate::encoding::Srgb>::from_color(lch);
703711

704-
let rgb: Alpha<Rgb<crate::encoding::Srgb, f64>, u8> =
705-
Alpha::from(Rgb::<crate::encoding::Srgb, f64>::default());
712+
let rgb: Alpha<Rgb<_, f64>, u8> = Alpha::from(Rgb::default());
706713
WithXyz::<crate::encoding::Srgb>::from_color(rgb);
707714

708715
let hsl: Alpha<Hsl<_, f64>, u8> = Alpha::from(Hsl::default());
@@ -736,7 +743,7 @@ mod tests {
736743
let lch: Lch<_, f64> = Default::default();
737744
Alpha::<WithXyz<crate::encoding::Srgb>, u8>::from_color(lch);
738745

739-
let rgb: Rgb<crate::encoding::Srgb, f64> = Default::default();
746+
let rgb: Rgb<_, f64> = Default::default();
740747
Alpha::<WithXyz<crate::encoding::Srgb>, u8>::from_color(rgb);
741748

742749
let hsl: Hsl<_, f64> = Default::default();
@@ -770,7 +777,7 @@ mod tests {
770777
let lch: Lch<_, f64> = Default::default();
771778
Alpha::<WithXyz<crate::encoding::Srgb>, u8>::from_color(lch);
772779

773-
let rgb: Rgb<crate::encoding::Srgb, f64> = Default::default();
780+
let rgb: Rgb<_, f64> = Default::default();
774781
Alpha::<WithXyz<crate::encoding::Srgb>, u8>::from_color(rgb);
775782

776783
let hsl: Hsl<_, f64> = Default::default();
@@ -795,7 +802,7 @@ mod tests {
795802
let _yxy: Yxy<_, f64> = color.into_color();
796803
let _lab: Lab<_, f64> = color.into_color();
797804
let _lch: Lch<_, f64> = color.into_color();
798-
let _rgb: Rgb<crate::encoding::Srgb, f64> = color.into_color();
805+
let _rgb: Rgb<_, f64> = color.into_color();
799806
let _hsl: Hsl<_, f64> = color.into_color();
800807
let _hsv: Hsv<_, f64> = color.into_color();
801808
let _hwb: Hwb<_, f64> = color.into_color();
@@ -812,7 +819,7 @@ mod tests {
812819
let _yxy: Yxy<_, f64> = color.into_color();
813820
let _lab: Lab<_, f64> = color.into_color();
814821
let _lch: Lch<_, f64> = color.into_color();
815-
let _rgb: Rgb<crate::encoding::Srgb, f64> = color.into_color();
822+
let _rgb: Rgb<_, f64> = color.into_color();
816823
let _hsl: Hsl<_, f64> = color.into_color();
817824
let _hsv: Hsv<_, f64> = color.into_color();
818825
let _hwb: Hwb<_, f64> = color.into_color();
@@ -828,7 +835,7 @@ mod tests {
828835
let _yxy: Alpha<Yxy<_, f64>, u8> = color.into_color();
829836
let _lab: Alpha<Lab<_, f64>, u8> = color.into_color();
830837
let _lch: Alpha<Lch<_, f64>, u8> = color.into_color();
831-
let _rgb: Alpha<Rgb<crate::encoding::Srgb, f64>, u8> = color.into_color();
838+
let _rgb: Alpha<Rgb<_, f64>, u8> = color.into_color();
832839
let _hsl: Alpha<Hsl<_, f64>, u8> = color.into_color();
833840
let _hsv: Alpha<Hsv<_, f64>, u8> = color.into_color();
834841
let _hwb: Alpha<Hwb<_, f64>, u8> = color.into_color();
@@ -845,7 +852,7 @@ mod tests {
845852
let _yxy: Alpha<Yxy<_, f64>, u8> = color.into_color();
846853
let _lab: Alpha<Lab<_, f64>, u8> = color.into_color();
847854
let _lch: Alpha<Lch<_, f64>, u8> = color.into_color();
848-
let _rgb: Alpha<Rgb<crate::encoding::Srgb, f64>, u8> = color.into_color();
855+
let _rgb: Alpha<Rgb<_, f64>, u8> = color.into_color();
849856
let _hsl: Alpha<Hsl<_, f64>, u8> = color.into_color();
850857
let _hsv: Alpha<Hsv<_, f64>, u8> = color.into_color();
851858
let _hwb: Alpha<Hwb<_, f64>, u8> = color.into_color();
@@ -869,7 +876,7 @@ mod tests {
869876
let lch: Lch<crate::white_point::E, f64> = Default::default();
870877
WithoutXyz::<f64>::from_color(lch);
871878

872-
let rgb: Rgb<(_, crate::encoding::Srgb), f64> = Default::default();
879+
let rgb: Rgb<_, f64> = Default::default();
873880
WithoutXyz::<f64>::from_color(rgb);
874881

875882
let hsl: Hsl<_, f64> = Default::default();
@@ -894,7 +901,7 @@ mod tests {
894901
let _yxy: Yxy<crate::white_point::E, f64> = color.into_color();
895902
let _lab: Lab<crate::white_point::E, f64> = color.into_color();
896903
let _lch: Lch<crate::white_point::E, f64> = color.into_color();
897-
let _rgb: Rgb<(_, crate::encoding::Srgb), f64> = color.into_color();
904+
let _rgb: Rgb<_, f64> = color.into_color();
898905
let _hsl: Hsl<_, f64> = color.into_color();
899906
let _hsv: Hsv<_, f64> = color.into_color();
900907
let _hwb: Hwb<_, f64> = color.into_color();

0 commit comments

Comments
 (0)