Skip to content

Commit 2b3fe03

Browse files
committed
Remove lifetime and store a single element for bits_per_pixel
1 parent a50fb81 commit 2b3fe03

File tree

3 files changed

+61
-57
lines changed

3 files changed

+61
-57
lines changed

src/ifd.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,10 @@ impl ImageFileDirectory {
682682
}
683683

684684
fn get_predictor_info(&self) -> PredictorInfo {
685+
if !self.bits_per_sample.windows(2).all(|w| w[0] == w[1]) {
686+
panic!("bits_per_sample should be the same for all channels");
687+
}
688+
685689
PredictorInfo {
686690
endianness: self.endianness,
687691
image_width: self.image_width,
@@ -698,7 +702,7 @@ impl ImageFileDirectory {
698702
} else {
699703
self.tile_height.unwrap()
700704
},
701-
bits_per_sample: &self.bits_per_sample,
705+
bits_per_sample: self.bits_per_sample[0],
702706
samples_per_pixel: self.samples_per_pixel,
703707
planar_configuration: self.planar_configuration,
704708
}

src/predictor.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl Unpredict for NoPredictor {
3434
fix_endianness(
3535
&mut res[..],
3636
predictor_info.endianness,
37-
predictor_info.bits_per_sample[0],
37+
predictor_info.bits_per_sample,
3838
);
3939
Ok(res.into())
4040
}
@@ -54,7 +54,7 @@ impl Unpredict for HorizontalPredictor {
5454
) -> AsyncTiffResult<Bytes> {
5555
let output_row_stride = predictor_info.output_row_stride(tile_x)?;
5656
let samples = predictor_info.samples_per_pixel as usize;
57-
let bit_depth = predictor_info.bits_per_sample[0];
57+
let bit_depth = predictor_info.bits_per_sample;
5858

5959
let mut res = BytesMut::from(buffer);
6060
fix_endianness(&mut res[..], predictor_info.endianness, bit_depth);
@@ -152,7 +152,7 @@ impl Unpredict for FloatingPointPredictor {
152152
let mut res: BytesMut = BytesMut::zeroed(
153153
output_row_stride * predictor_info.chunk_height_pixels(tile_y)? as usize,
154154
);
155-
let bit_depth = predictor_info.bits_per_sample[0] as usize;
155+
let bit_depth = predictor_info.bits_per_sample;
156156
if predictor_info.chunk_width_pixels(tile_x)? == predictor_info.chunk_width {
157157
// no special padding handling
158158
let mut input = BytesMut::from(buffer);
@@ -173,7 +173,7 @@ impl Unpredict for FloatingPointPredictor {
173173
let mut input = BytesMut::from(buffer);
174174

175175
let input_row_stride =
176-
predictor_info.chunk_width as usize * predictor_info.bits_per_pixel() / 8;
176+
predictor_info.chunk_width as usize * predictor_info.bits_per_sample as usize / 8;
177177
for (in_buf, out_buf) in input
178178
.chunks_mut(input_row_stride)
179179
.zip(res.chunks_mut(output_row_stride))
@@ -297,7 +297,7 @@ mod test {
297297
image_height: 7,
298298
chunk_width: 4,
299299
chunk_height: 4,
300-
bits_per_sample: &[8],
300+
bits_per_sample: 8,
301301
samples_per_pixel: 1,
302302
planar_configuration: crate::tiff::tags::PlanarConfiguration::Chunky,
303303
};
@@ -379,104 +379,104 @@ mod test {
379379
for (x,y, input, expected) in cases {
380380
println!("uints littleendian");
381381
predictor_info.endianness = Endianness::LittleEndian;
382-
predictor_info.bits_per_sample = &[8];
382+
predictor_info.bits_per_sample = 8;
383383
assert_eq!(-1i32 as u8, 255);
384384
println!("testing u8");
385385
let buffer = Bytes::from(input.iter().map(|v| *v as u8).collect::<Vec<_>>());
386386
let res = Bytes::from(expected.clone());
387387
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
388388
assert_eq!(-1i32 as u16, u16::MAX);
389389
println!("testing u16");
390-
predictor_info.bits_per_sample = &[16];
390+
predictor_info.bits_per_sample = 16;
391391
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u16).to_le_bytes()).collect::<Vec<_>>());
392392
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u16).to_ne_bytes()).collect::<Vec<_>>());
393393
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
394394
assert_eq!(-1i32 as u32, u32::MAX);
395395
println!("testing u32");
396-
predictor_info.bits_per_sample = &[32];
396+
predictor_info.bits_per_sample = 32;
397397
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u32).to_le_bytes()).collect::<Vec<_>>());
398398
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u32).to_ne_bytes()).collect::<Vec<_>>());
399399
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
400400
assert_eq!(-1i32 as u64, u64::MAX);
401401
println!("testing u64");
402-
predictor_info.bits_per_sample = &[64];
402+
predictor_info.bits_per_sample = 64;
403403
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u64).to_le_bytes()).collect::<Vec<_>>());
404404
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u64).to_ne_bytes()).collect::<Vec<_>>());
405405
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
406406

407407
println!("ints littleendian");
408-
predictor_info.bits_per_sample = &[8];
408+
predictor_info.bits_per_sample = 8;
409409
println!("testing i8");
410410
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i8).to_le_bytes()).collect::<Vec<_>>());
411411
println!("{:?}", &buffer[..]);
412412
let res = Bytes::from(expected.clone());
413413
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap()[..], res[..]);
414414
println!("testing i16");
415-
predictor_info.bits_per_sample = &[16];
415+
predictor_info.bits_per_sample = 16;
416416
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i16).to_le_bytes()).collect::<Vec<_>>());
417417
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i16).to_ne_bytes()).collect::<Vec<_>>());
418418
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
419419
println!("testing i32");
420-
predictor_info.bits_per_sample = &[32];
420+
predictor_info.bits_per_sample = 32;
421421
let buffer = Bytes::from(input.iter().flat_map(|v| v.to_le_bytes()).collect::<Vec<_>>());
422422
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i32).to_ne_bytes()).collect::<Vec<_>>());
423423
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
424424
println!("testing i64");
425-
predictor_info.bits_per_sample = &[64];
425+
predictor_info.bits_per_sample = 64;
426426
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i64).to_le_bytes()).collect::<Vec<_>>());
427427
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i64).to_ne_bytes()).collect::<Vec<_>>());
428428
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
429429

430430
println!("uints bigendian");
431431
predictor_info.endianness = Endianness::BigEndian;
432-
predictor_info.bits_per_sample = &[8];
432+
predictor_info.bits_per_sample = 8;
433433
assert_eq!(-1i32 as u8, 255);
434434
println!("testing u8");
435435
let buffer = Bytes::from(input.iter().map(|v| *v as u8).collect::<Vec<_>>());
436436
let res = Bytes::from(expected.clone());
437437
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
438438
assert_eq!(-1i32 as u16, u16::MAX);
439439
println!("testing u16");
440-
predictor_info.bits_per_sample = &[16];
440+
predictor_info.bits_per_sample = 16;
441441
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u16).to_be_bytes()).collect::<Vec<_>>());
442442
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u16).to_ne_bytes()).collect::<Vec<_>>());
443443
println!("buffer: {:?}", &buffer[..]);
444444
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap()[..], res[..]);
445445
assert_eq!(-1i32 as u32, u32::MAX);
446446
println!("testing u32");
447-
predictor_info.bits_per_sample = &[32];
447+
predictor_info.bits_per_sample = 32;
448448
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u32).to_be_bytes()).collect::<Vec<_>>());
449449
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u32).to_ne_bytes()).collect::<Vec<_>>());
450450
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
451451
assert_eq!(-1i32 as u64, u64::MAX);
452452
println!("testing u64");
453-
predictor_info.bits_per_sample = &[64];
453+
predictor_info.bits_per_sample = 64;
454454
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u64).to_be_bytes()).collect::<Vec<_>>());
455455
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u64).to_ne_bytes()).collect::<Vec<_>>());
456456
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
457457

458458
println!("ints bigendian");
459-
predictor_info.bits_per_sample = &[8];
459+
predictor_info.bits_per_sample = 8;
460460
assert_eq!(-1i32 as u8, 255);
461461
println!("testing i8");
462462
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i8).to_be_bytes()).collect::<Vec<_>>());
463463
let res = Bytes::from(expected.clone());
464464
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
465465
assert_eq!(-1i32 as u16, u16::MAX);
466466
println!("testing i16");
467-
predictor_info.bits_per_sample = &[16];
467+
predictor_info.bits_per_sample = 16;
468468
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i16).to_be_bytes()).collect::<Vec<_>>());
469469
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i16).to_ne_bytes()).collect::<Vec<_>>());
470470
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
471471
assert_eq!(-1i32 as u32, u32::MAX);
472472
println!("testing i32");
473-
predictor_info.bits_per_sample = &[32];
473+
predictor_info.bits_per_sample = 32;
474474
let buffer = Bytes::from(input.iter().flat_map(|v| v.to_be_bytes()).collect::<Vec<_>>());
475475
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i32).to_ne_bytes()).collect::<Vec<_>>());
476476
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
477477
assert_eq!(-1i32 as u64, u64::MAX);
478478
println!("testing i64");
479-
predictor_info.bits_per_sample = &[64];
479+
predictor_info.bits_per_sample = 64;
480480
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i64).to_be_bytes()).collect::<Vec<_>>());
481481
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i64).to_ne_bytes()).collect::<Vec<_>>());
482482
assert_eq!(p.fix_endianness_and_unpredict(buffer, &predictor_info, x, y).unwrap(), res);
@@ -501,7 +501,7 @@ mod test {
501501
image_height: 4+1,
502502
chunk_width: 4,
503503
chunk_height: 4,
504-
bits_per_sample: &[16],
504+
bits_per_sample: 16,
505505
samples_per_pixel: 1,
506506
planar_configuration: PlanarConfiguration::Chunky,
507507
};
@@ -530,7 +530,7 @@ mod test {
530530
image_height: 4+1,
531531
chunk_width: 4,
532532
chunk_height: 4,
533-
bits_per_sample: &[16],
533+
bits_per_sample: 16,
534534
samples_per_pixel: 1,
535535
planar_configuration: PlanarConfiguration::Chunky,
536536
};
@@ -558,7 +558,7 @@ mod test {
558558
image_height: 2 + 1,
559559
chunk_width: 2,
560560
chunk_height: 2,
561-
bits_per_sample: &[32],
561+
bits_per_sample: 32,
562562
samples_per_pixel: 1,
563563
planar_configuration: PlanarConfiguration::Chunky,
564564
};
@@ -592,7 +592,7 @@ mod test {
592592
image_height: 2 + 1,
593593
chunk_width: 2,
594594
chunk_height: 2,
595-
bits_per_sample: &[64],
595+
bits_per_sample: 64,
596596
samples_per_pixel: 1,
597597
planar_configuration: PlanarConfiguration::Chunky,
598598
};

src/tile.rs

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::tiff::{TiffError, TiffUnsupportedError};
1717
/// Also provides convenience functions
1818
///
1919
#[derive(Debug, Clone, Copy)]
20-
pub(crate) struct PredictorInfo<'a> {
20+
pub(crate) struct PredictorInfo {
2121
/// endianness
2222
pub(crate) endianness: Endianness,
2323
/// width of the image in pixels
@@ -30,10 +30,10 @@ pub(crate) struct PredictorInfo<'a> {
3030
pub(crate) chunk_width: u32,
3131
/// chunk height in pixels
3232
pub(crate) chunk_height: u32,
33-
/// bits per sample, as an array
33+
/// bits per sample
3434
///
35-
/// Can also be a single value, in which case it applies to all samples
36-
pub(crate) bits_per_sample: &'a [u16], // maybe say that we only support a single bits_per_sample?
35+
/// We only support a single bits_per_sample across all samples
36+
pub(crate) bits_per_sample: u16,
3737
/// number of samples per pixel
3838
pub(crate) samples_per_pixel: u16,
3939
/// planar configuration
@@ -42,7 +42,7 @@ pub(crate) struct PredictorInfo<'a> {
4242
pub(crate) planar_configuration: PlanarConfiguration,
4343
}
4444

45-
impl PredictorInfo<'_> {
45+
impl PredictorInfo {
4646
/// chunk width in pixels, taking padding into account
4747
///
4848
/// strips are considered image-width chunks
@@ -125,29 +125,30 @@ impl PredictorInfo<'_> {
125125

126126
/// get the output row stride in bytes, taking padding into account
127127
pub fn output_row_stride(&self, x: u32) -> AsyncTiffResult<usize> {
128-
Ok((self.chunk_width_pixels(x)? as usize).saturating_mul(self.bits_per_pixel()) / 8)
128+
Ok((self.chunk_width_pixels(x)? as usize).saturating_mul(self.bits_per_sample as _) / 8)
129129
}
130130

131-
/// The total number of bits per pixel, taking into account possible different sample sizes
132-
///
133-
/// Technically bits_per_sample.len() should be *equal* to samples, but libtiff also allows
134-
/// it to be a single value that applies to all samples.
135-
///
136-
/// Libtiff and image-tiff do not support mixed bits per sample, but we give the possibility
137-
/// unless you also have PlanarConfiguration::Planar, at which point the first is taken
138-
pub fn bits_per_pixel(&self) -> usize {
139-
match self.planar_configuration {
140-
PlanarConfiguration::Chunky => {
141-
if self.bits_per_sample.len() == 1 {
142-
self.samples_per_pixel as usize * self.bits_per_sample[0] as usize
143-
} else {
144-
assert_eq!(self.samples_per_pixel as usize, self.bits_per_sample.len());
145-
self.bits_per_sample.iter().map(|v| *v as usize).product()
146-
}
147-
}
148-
PlanarConfiguration::Planar => self.bits_per_sample[0] as usize,
149-
}
150-
}
131+
// /// The total number of bits per pixel, taking into account possible different sample sizes
132+
// ///
133+
// /// Technically bits_per_sample.len() should be *equal* to samples, but libtiff also allows
134+
// /// it to be a single value that applies to all samples.
135+
// ///
136+
// /// Libtiff and image-tiff do not support mixed bits per sample, but we give the possibility
137+
// /// unless you also have PlanarConfiguration::Planar, at which point the first is taken
138+
// pub fn bits_per_pixel(&self) -> usize {
139+
// self.bits_per_sample
140+
// match self.planar_configuration {
141+
// PlanarConfiguration::Chunky => {
142+
// if self.bits_per_sample.len() == 1 {
143+
// self.samples_per_pixel as usize * self.bits_per_sample[0] as usize
144+
// } else {
145+
// assert_eq!(self.samples_per_pixel as usize, self.bits_per_sample.len());
146+
// self.bits_per_sample.iter().map(|v| *v as usize).product()
147+
// }
148+
// }
149+
// PlanarConfiguration::Planar => self.bits_per_sample[0] as usize,
150+
// }
151+
// }
151152

152153
/// The number of chunks in the horizontal (x) direction
153154
pub fn chunks_across(&self) -> u32 {
@@ -167,18 +168,18 @@ impl PredictorInfo<'_> {
167168
///
168169
/// This is returned by `fetch_tile`.
169170
#[derive(Debug)]
170-
pub struct Tile<'a> {
171+
pub struct Tile {
171172
pub(crate) x: usize,
172173
pub(crate) y: usize,
173174
pub(crate) predictor: Predictor,
174-
pub(crate) predictor_info: PredictorInfo<'a>,
175+
pub(crate) predictor_info: PredictorInfo,
175176
pub(crate) compressed_bytes: Bytes,
176177
pub(crate) compression_method: CompressionMethod,
177178
pub(crate) photometric_interpretation: PhotometricInterpretation,
178179
pub(crate) jpeg_tables: Option<Bytes>,
179180
}
180181

181-
impl Tile<'_> {
182+
impl Tile {
182183
/// The column index of this tile.
183184
pub fn x(&self) -> usize {
184185
self.x
@@ -268,11 +269,10 @@ mod test {
268269
image_height: 17,
269270
chunk_width: 8,
270271
chunk_height: 8,
271-
bits_per_sample: &[8],
272+
bits_per_sample: 8,
272273
samples_per_pixel: 1,
273274
planar_configuration: PlanarConfiguration::Chunky,
274275
};
275-
assert_eq!(info.bits_per_pixel(), 8);
276276
assert_eq!(info.chunks_across(), 2);
277277
assert_eq!(info.chunks_down(), 3);
278278
assert_eq!(info.chunk_width_pixels(0).unwrap(), info.chunk_width);

0 commit comments

Comments
 (0)