From 0a878888dbf07c103f559fdbe636ea1a36682a49 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Tue, 3 Mar 2026 14:36:16 +0100 Subject: [PATCH 1/2] More optimal code gen for `invert_colors` --- src/decoder/mod.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index ef0d183..0dc99a5 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -730,33 +730,33 @@ fn invert_colors( } } (ColorType::Gray(16), SampleFormat::Uint) => { - for x in buf.chunks_mut(2) { - let v = u16::from_ne_bytes(x.try_into().unwrap()); - x.copy_from_slice(&(0xffff - v).to_ne_bytes()); + for x in buf.as_chunks_mut::<2>().0 { + let v = u16::from_ne_bytes(*x); + *x = (0xffff - v).to_ne_bytes(); } } (ColorType::Gray(32), SampleFormat::Uint) => { - for x in buf.chunks_mut(4) { - let v = u32::from_ne_bytes(x.try_into().unwrap()); - x.copy_from_slice(&(0xffff_ffff - v).to_ne_bytes()); + for x in buf.as_chunks_mut::<4>().0 { + let v = u32::from_ne_bytes(*x); + *x = (0xffff_ffff - v).to_ne_bytes(); } } (ColorType::Gray(64), SampleFormat::Uint) => { - for x in buf.chunks_mut(8) { - let v = u64::from_ne_bytes(x.try_into().unwrap()); - x.copy_from_slice(&(0xffff_ffff_ffff_ffff - v).to_ne_bytes()); + for x in buf.as_chunks_mut::<8>().0 { + let v = u64::from_ne_bytes(*x); + *x = (0xffff_ffff_ffff_ffff - v).to_ne_bytes(); } } (ColorType::Gray(32), SampleFormat::IEEEFP) => { - for x in buf.chunks_mut(4) { - let v = f32::from_ne_bytes(x.try_into().unwrap()); - x.copy_from_slice(&(1.0 - v).to_ne_bytes()); + for x in buf.as_chunks_mut::<4>().0 { + let v = f32::from_ne_bytes(*x); + *x = (1.0 - v).to_ne_bytes(); } } (ColorType::Gray(64), SampleFormat::IEEEFP) => { - for x in buf.chunks_mut(8) { - let v = f64::from_ne_bytes(x.try_into().unwrap()); - x.copy_from_slice(&(1.0 - v).to_ne_bytes()); + for x in buf.as_chunks_mut::<8>().0 { + let v = f64::from_ne_bytes(*x); + *x = (1.0 - v).to_ne_bytes(); } } _ => { From d872ff8751bd140e97ede49e31bd8a2e26020a82 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Tue, 3 Mar 2026 14:54:32 +0100 Subject: [PATCH 2/2] Unify grayscale integer code paths --- src/decoder/mod.rs | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 0dc99a5..b2885be 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -717,36 +717,19 @@ fn invert_colors( sample_format: SampleFormat, ) -> TiffResult<()> { match (color_type, sample_format) { - // Where pixels do not cross a byte boundary - (ColorType::Gray(1 | 2 | 4 | 8), SampleFormat::Uint) => { + (ColorType::Gray(1 | 2 | 4 | 8 | 16 | 32 | 64), SampleFormat::Uint) => { + // It's guaranteed that pixels do not cross a byte boundary. + // To invert a single N-bit pixel, we can calculate: + // (2^N - 1) - x = (2^N - 1) + !x + 1 (because -x = !x + 1) + // = 2^n + !x + // = !x (because modular arithmetic) + // + // Further, since !x operates on bits independently, negating bytes + // also works for multi-byte pixels. for x in buf { - // Equivalent to both of the following: - // - // *x = 0xff - *x - // *x = !*x - // - // since -x = !x+1 *x = !*x; } } - (ColorType::Gray(16), SampleFormat::Uint) => { - for x in buf.as_chunks_mut::<2>().0 { - let v = u16::from_ne_bytes(*x); - *x = (0xffff - v).to_ne_bytes(); - } - } - (ColorType::Gray(32), SampleFormat::Uint) => { - for x in buf.as_chunks_mut::<4>().0 { - let v = u32::from_ne_bytes(*x); - *x = (0xffff_ffff - v).to_ne_bytes(); - } - } - (ColorType::Gray(64), SampleFormat::Uint) => { - for x in buf.as_chunks_mut::<8>().0 { - let v = u64::from_ne_bytes(*x); - *x = (0xffff_ffff_ffff_ffff - v).to_ne_bytes(); - } - } (ColorType::Gray(32), SampleFormat::IEEEFP) => { for x in buf.as_chunks_mut::<4>().0 { let v = f32::from_ne_bytes(*x);