From b0cc095724d2af7100f26af16e2430efc9c10534 Mon Sep 17 00:00:00 2001 From: Lukasz Anforowicz Date: Mon, 29 Jan 2024 19:11:19 +0000 Subject: [PATCH] Change `TransformFn` to allow memoization in the future This commit changes the `TransformFn` type alias from `fn(...)` into `Box`. This allows the `TransformFn` to have store some precomputer, memoized state that we plan to add in follow-up commits. In theory this commit may have negative performance impact, but in the grand scheme of things it disappears into the measurement noise. In particular, when there is no state, then `Box` shouldn't allocate. --- src/decoder/mod.rs | 2 +- src/decoder/transform.rs | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 21d51a66..676e04f3 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -638,7 +638,7 @@ impl Reader { if self.transform_fn.is_none() { self.transform_fn = Some(create_transform_fn(self.info(), self.transform)?); } - self.transform_fn.unwrap() + self.transform_fn.as_deref().unwrap() }; transform_fn(row, output_buffer, self.info()); diff --git a/src/decoder/transform.rs b/src/decoder/transform.rs index cc89ac99..43da0dc3 100644 --- a/src/decoder/transform.rs +++ b/src/decoder/transform.rs @@ -12,7 +12,7 @@ use super::stream::FormatErrorInner; /// /// TODO: If some precomputed state is needed (e.g. to make `expand_paletted...` /// faster) then consider changing this into `Box`. -pub type TransformFn = fn(&[u8], &mut [u8], &Info); +pub type TransformFn = Box; /// Returns a transformation function that should be applied to image rows based /// on 1) decoded image metadata (`info`) and 2) the transformations requested @@ -43,36 +43,36 @@ pub fn create_transform_fn( .into(), )); } else { - if trns { - Ok(palette::expand_paletted_into_rgba8) + Ok(Box::new(if trns { + palette::expand_paletted_into_rgba8 } else { - Ok(palette::expand_paletted_into_rgb8) - } + palette::expand_paletted_into_rgb8 + })) } } ColorType::Grayscale | ColorType::GrayscaleAlpha if bit_depth < 8 && expand => { - if trns { - Ok(expand_gray_u8_with_trns) + Ok(Box::new(if trns { + expand_gray_u8_with_trns } else { - Ok(expand_gray_u8) - } + expand_gray_u8 + })) } ColorType::Grayscale | ColorType::Rgb if expand && trns => { - if bit_depth == 8 { - Ok(expand_trns_line) + Ok(Box::new(if bit_depth == 8 { + expand_trns_line } else if strip16 { - Ok(expand_trns_and_strip_line16) + expand_trns_and_strip_line16 } else { assert_eq!(bit_depth, 16); - Ok(expand_trns_line16) - } + expand_trns_line16 + })) } ColorType::Grayscale | ColorType::GrayscaleAlpha | ColorType::Rgb | ColorType::Rgba if strip16 => { - Ok(transform_row_strip16) + Ok(Box::new(transform_row_strip16)) } - _ => Ok(copy_row), + _ => Ok(Box::new(copy_row)), } }