Skip to content

Commit

Permalink
Merge pull request #2 from spoutn1k/revert-1-spoutn1k-predictor
Browse files Browse the repository at this point in the history
Revert "Avoid per-row allocations"
  • Loading branch information
spoutn1k authored Sep 20, 2024
2 parents 9a349fe + 90b5624 commit 5b3ac29
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 37 deletions.
43 changes: 16 additions & 27 deletions src/encoder/colortype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,16 @@ use crate::tags::{PhotometricInterpretation, SampleFormat};

macro_rules! integer_horizontal_predict {
() => {
fn horizontal_predict(row: &[Self::Inner], result: &mut Vec<Self::Inner>) {
fn horizontal_predict(row: &[Self::Inner]) -> Vec<Self::Inner> {
let sample_size = Self::SAMPLE_FORMAT.len();
if row.len() < sample_size {
debug_assert!(false);
return;
}
let (start, rest) = row.split_at(sample_size);

result.clear();
if result.capacity() - result.len() < row.len() {
return;
}
result.extend_from_slice(start);
if result.capacity() - result.len() < rest.len() {
return;
}
let mut result = Vec::with_capacity(row.len());

result.extend_from_slice(&row[0..=sample_size - 1]);
result.extend(
row.into_iter()
.zip(rest)
.map(|(prev, current)| current.wrapping_sub(*prev)),
(sample_size..row.len()).map(|i| row[i].wrapping_sub(row[i - sample_size])),
);

result
}
};
}
Expand All @@ -38,7 +27,7 @@ pub trait ColorType {
/// The value of the tiff tag `SampleFormat`
const SAMPLE_FORMAT: &'static [SampleFormat];

fn horizontal_predict(row: &[Self::Inner], result: &mut Vec<Self::Inner>);
fn horizontal_predict(row: &[Self::Inner]) -> Vec<Self::Inner>;
}

pub struct Gray8;
Expand Down Expand Up @@ -108,7 +97,7 @@ impl ColorType for Gray32Float {
const BITS_PER_SAMPLE: &'static [u16] = &[32];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::IEEEFP];

fn horizontal_predict(_: &[Self::Inner], _: &mut Vec<Self::Inner>) {
fn horizontal_predict(_: &[Self::Inner]) -> Vec<Self::Inner> {
unreachable!()
}
}
Expand Down Expand Up @@ -140,7 +129,7 @@ impl ColorType for Gray64Float {
const BITS_PER_SAMPLE: &'static [u16] = &[64];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::IEEEFP];

fn horizontal_predict(_: &[Self::Inner], _: &mut Vec<Self::Inner>) {
fn horizontal_predict(_: &[Self::Inner]) -> Vec<Self::Inner> {
unreachable!()
}
}
Expand Down Expand Up @@ -181,7 +170,7 @@ impl ColorType for RGB32Float {
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::RGB;
const BITS_PER_SAMPLE: &'static [u16] = &[32, 32, 32];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::IEEEFP; 3];
fn horizontal_predict(_: &[Self::Inner], _: &mut Vec<Self::Inner>) {
fn horizontal_predict(_: &[Self::Inner]) -> Vec<Self::Inner> {
unreachable!()
}
}
Expand All @@ -202,7 +191,7 @@ impl ColorType for RGB64Float {
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::RGB;
const BITS_PER_SAMPLE: &'static [u16] = &[64, 64, 64];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::IEEEFP; 3];
fn horizontal_predict(_: &[Self::Inner], _: &mut Vec<Self::Inner>) {
fn horizontal_predict(_: &[Self::Inner]) -> Vec<Self::Inner> {
unreachable!()
}
}
Expand Down Expand Up @@ -243,7 +232,7 @@ impl ColorType for RGBA32Float {
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::RGB;
const BITS_PER_SAMPLE: &'static [u16] = &[32, 32, 32, 32];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::IEEEFP; 4];
fn horizontal_predict(_: &[Self::Inner], _: &mut Vec<Self::Inner>) {
fn horizontal_predict(_: &[Self::Inner]) -> Vec<Self::Inner> {
unreachable!()
}
}
Expand All @@ -264,7 +253,7 @@ impl ColorType for RGBA64Float {
const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::RGB;
const BITS_PER_SAMPLE: &'static [u16] = &[64, 64, 64, 64];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::IEEEFP; 4];
fn horizontal_predict(_: &[Self::Inner], _: &mut Vec<Self::Inner>) {
fn horizontal_predict(_: &[Self::Inner]) -> Vec<Self::Inner> {
unreachable!()
}
}
Expand Down Expand Up @@ -306,7 +295,7 @@ impl ColorType for CMYK32Float {
const BITS_PER_SAMPLE: &'static [u16] = &[32, 32, 32, 32];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::IEEEFP; 4];

fn horizontal_predict(_: &[Self::Inner], _: &mut Vec<Self::Inner>) {
fn horizontal_predict(_: &[Self::Inner]) -> Vec<Self::Inner> {
unreachable!()
}
}
Expand All @@ -328,7 +317,7 @@ impl ColorType for CMYK64Float {
const BITS_PER_SAMPLE: &'static [u16] = &[64, 64, 64, 64];
const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::IEEEFP; 4];

fn horizontal_predict(_: &[Self::Inner], _: &mut Vec<Self::Inner>) {
fn horizontal_predict(_: &[Self::Inner]) -> Vec<Self::Inner> {
unreachable!()
}
}
Expand Down
20 changes: 10 additions & 10 deletions src/encoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,16 +480,16 @@ impl<'a, W: 'a + Write + Seek, T: ColorType, K: TiffKind> ImageEncoder<'a, W, T,
// Write the (possible compressed) data to the encoder.
let offset = match self.predictor {
Predictor::None => self.encoder.write_data(value)?,
Predictor::Horizontal => {
let mut row_result = Vec::with_capacity(self.row_samples as _);
let mut offset = 0;
for row in value.chunks_exact(self.row_samples as usize) {
T::horizontal_predict(row, &mut row_result);
offset += self.encoder.write_data(row_result.as_slice())?;
}
offset
}
_ => unimplemented!(),
Predictor::Horizontal => value
.chunks(self.row_samples as usize)
.map(|row| {
self.encoder
.write_data(T::horizontal_predict(row).as_slice())
})
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.sum(),
_ => unreachable!(),
};

let byte_count = self.encoder.last_written() as usize;
Expand Down

0 comments on commit 5b3ac29

Please sign in to comment.