Merge pull request #346 from RunDevelopment/invert-color-as-chunks
More optimal code gen for `invert_colors`
This commit is contained in:
1 file changed
+15
-32
+15
-32
@@ -717,46 +717,29 @@ fn invert_colors(
|
|||||||
sample_format: SampleFormat,
|
sample_format: SampleFormat,
|
||||||
) -> TiffResult<()> {
|
) -> TiffResult<()> {
|
||||||
match (color_type, sample_format) {
|
match (color_type, sample_format) {
|
||||||
// Where pixels do not cross a byte boundary
|
(ColorType::Gray(1 | 2 | 4 | 8 | 16 | 32 | 64), SampleFormat::Uint) => {
|
||||||
(ColorType::Gray(1 | 2 | 4 | 8), 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 {
|
for x in buf {
|
||||||
// Equivalent to both of the following:
|
|
||||||
//
|
|
||||||
// *x = 0xff - *x
|
|
||||||
// *x = !*x
|
|
||||||
//
|
|
||||||
// since -x = !x+1
|
|
||||||
*x = !*x;
|
*x = !*x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(ColorType::Gray(32), SampleFormat::IEEEFP) => {
|
(ColorType::Gray(32), SampleFormat::IEEEFP) => {
|
||||||
for x in buf.chunks_mut(4) {
|
for x in buf.as_chunks_mut::<4>().0 {
|
||||||
let v = f32::from_ne_bytes(x.try_into().unwrap());
|
let v = f32::from_ne_bytes(*x);
|
||||||
x.copy_from_slice(&(1.0 - v).to_ne_bytes());
|
*x = (1.0 - v).to_ne_bytes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(ColorType::Gray(64), SampleFormat::IEEEFP) => {
|
(ColorType::Gray(64), SampleFormat::IEEEFP) => {
|
||||||
for x in buf.chunks_mut(8) {
|
for x in buf.as_chunks_mut::<8>().0 {
|
||||||
let v = f64::from_ne_bytes(x.try_into().unwrap());
|
let v = f64::from_ne_bytes(*x);
|
||||||
x.copy_from_slice(&(1.0 - v).to_ne_bytes());
|
*x = (1.0 - v).to_ne_bytes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|||||||
Reference in new issue
Block a user