Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 8 additions & 28 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -969,48 +969,28 @@ pub(crate) trait Invert {
/// Inverts a color in-place.
fn invert(&mut self);
}

impl<T: Primitive> Invert for LumaA<T> {
fn invert(&mut self) {
let l = self.0;
let max = T::DEFAULT_MAX_VALUE;

*self = LumaA([max - l[0], l[1]]);
let [l, a] = self.0;
*self = LumaA([l.invert_range(), a]);
}
}

impl<T: Primitive> Invert for Luma<T> {
fn invert(&mut self) {
let l = self.0;

let max = T::DEFAULT_MAX_VALUE;
let l1 = max - l[0];

*self = Luma([l1]);
let [l] = self.0;
*self = Luma([l.invert_range()]);
}
}

impl<T: Primitive> Invert for Rgba<T> {
fn invert(&mut self) {
let rgba = self.0;

let max = T::DEFAULT_MAX_VALUE;

*self = Rgba([max - rgba[0], max - rgba[1], max - rgba[2], rgba[3]]);
let [r, g, b, a] = self.0;
*self = Rgba([r.invert_range(), g.invert_range(), b.invert_range(), a]);
}
}

impl<T: Primitive> Invert for Rgb<T> {
fn invert(&mut self) {
let rgb = self.0;

let max = T::DEFAULT_MAX_VALUE;

let r1 = max - rgb[0];
let g1 = max - rgb[1];
let b1 = max - rgb[2];

*self = Rgb([r1, g1, b1]);
let [r, g, b] = self.0;
*self = Rgb([r.invert_range(), g.invert_range(), b.invert_range()]);
}
}

Expand Down
34 changes: 33 additions & 1 deletion src/primitive_sealed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::imageops::fast_blur::BlurAccumulator;
/// this crate.
#[allow(private_bounds)]
pub trait PrimitiveSealed:
Sized + NearestFrom<f32> + WithBlurAcc + BgraSwizzle + RgbToLuma
Sized + NearestFrom<f32> + WithBlurAcc + BgraSwizzle + RgbToLuma + InvertRange
{
}

Expand Down Expand Up @@ -229,3 +229,35 @@ impl RgbToLuma for f32 {
}
}
impl RgbToLuma for f64 {}

pub(crate) trait InvertRange {
/// Inverts the default range of this value.
///
/// This has the following properties:
/// - `self.invert_range().invert_range() == self`
/// - `T::DEFAULT_MIN_VALUE.invert_range() == T::DEFAULT_MAX_VALUE` and
/// `T::DEFAULT_MAX_VALUE.invert_range() == T::DEFAULT_MIN_VALUE`
///
/// For floats, this is `1.0 - self`. For integers, this is `!self`.
fn invert_range(self) -> Self;
}
impl InvertRange for f32 {
fn invert_range(self) -> Self {
1.0 - self
}
}
impl InvertRange for f64 {
fn invert_range(self) -> Self {
1.0 - self
}
}
macro_rules! impl_invert_range_for_ints {
($($t:ty),+) => { $(
impl InvertRange for $t {
fn invert_range(self) -> Self {
!self
}
}
)+ };
}
impl_invert_range_for_ints!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
2 changes: 1 addition & 1 deletion src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ pub trait Pixel: Copy + Clone {
where
F: FnMut(Self::Subpixel, Self::Subpixel) -> Self::Subpixel;

/// Invert this pixel
/// Invert the color channels of this pixel. Alpha channels are *not* inverted.
fn invert(&mut self);

/// Blend the color of a given pixel into ourself, taking into account alpha channels
Expand Down
Loading