Skip to content

Commit df407ba

Browse files
committed
improved tests, fixed some bugs
1 parent d49342c commit df407ba

File tree

1 file changed

+167
-101
lines changed

1 file changed

+167
-101
lines changed

src/predictor.rs

Lines changed: 167 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
///
1616
///
1717
///
18-
pub struct RevPredictorRegistry(HashMap<Predictor, Box<dyn RevPredictor>>);
18+
pub struct RevPredictorRegistry(HashMap<Predictor, Box<dyn RevPredict>>);
1919

2020
impl RevPredictorRegistry {
2121
/// create a new predictor registry with no predictors registered
@@ -24,8 +24,8 @@ impl RevPredictorRegistry {
2424
}
2525
}
2626

27-
impl AsRef<HashMap<Predictor, Box<dyn RevPredictor>>> for RevPredictorRegistry {
28-
fn as_ref(&self) -> &HashMap<Predictor, Box<dyn RevPredictor>> {
27+
impl AsRef<HashMap<Predictor, Box<dyn RevPredict>>> for RevPredictorRegistry {
28+
fn as_ref(&self) -> &HashMap<Predictor, Box<dyn RevPredict>> {
2929
&self.0
3030
}
3131
}
@@ -46,7 +46,7 @@ impl Default for RevPredictorRegistry {
4646
/// Trait for reverse predictors to implement
4747
///
4848
///
49-
pub trait RevPredictor: Debug + Send + Sync {
49+
pub trait RevPredict: Debug + Send + Sync {
5050
/// reverse predict the decompressed bytes and fix endianness on the output
5151
///
5252
///
@@ -63,7 +63,7 @@ pub trait RevPredictor: Debug + Send + Sync {
6363
#[derive(Debug)]
6464
pub struct NoPredictor;
6565

66-
impl RevPredictor for NoPredictor {
66+
impl RevPredict for NoPredictor {
6767
fn rev_predict_fix_endianness(
6868
&self,
6969
buffer: Bytes,
@@ -85,7 +85,7 @@ impl RevPredictor for NoPredictor {
8585
#[derive(Debug)]
8686
pub struct RevHorizontalPredictor;
8787

88-
impl RevPredictor for RevHorizontalPredictor {
88+
impl RevPredict for RevHorizontalPredictor {
8989
fn rev_predict_fix_endianness(
9090
&self,
9191
buffer: Bytes,
@@ -98,12 +98,10 @@ impl RevPredictor for RevHorizontalPredictor {
9898
let bit_depth = predictor_info.bits_per_sample[0];
9999

100100
let mut res = BytesMut::from(buffer);
101+
fix_endianness(&mut res[..], predictor_info.endianness, bit_depth);
101102
for buf in res.chunks_mut(output_row_stride) {
102-
// this is rev_hpredict_nsamp from image-tiff
103103
rev_hpredict_nsamp(buf, bit_depth, samples);
104-
// end rev_hpredict_nsamp
105104
}
106-
fix_endianness(&mut res[..], predictor_info.endianness, bit_depth);
107105
Ok(res.into())
108106
}
109107
}
@@ -181,7 +179,7 @@ pub fn fix_endianness(buf: &mut [u8], byte_order: Endianness, bit_depth: u16) {
181179
#[derive(Debug)]
182180
pub struct RevFloatingPointPredictor;
183181

184-
impl RevPredictor for RevFloatingPointPredictor {
182+
impl RevPredict for RevFloatingPointPredictor {
185183
fn rev_predict_fix_endianness(
186184
&self,
187185
buffer: Bytes,
@@ -312,6 +310,8 @@ pub fn rev_predict_f64(input: &mut [u8], output: &mut [u8], samples: usize) {
312310

313311
#[cfg(test)]
314312
mod test {
313+
use std::vec;
314+
315315
use bytes::Bytes;
316316

317317
use crate::{
@@ -321,64 +321,48 @@ mod test {
321321
tile::PredictorInfo,
322322
};
323323

324-
use super::{NoPredictor, RevHorizontalPredictor, RevPredictor};
324+
use super::{NoPredictor, RevHorizontalPredictor, RevPredict};
325325

326326
const PRED_INFO: PredictorInfo = PredictorInfo {
327327
endianness: Endianness::LittleEndian,
328-
image_width: 15,
329-
image_height: 15,
330-
chunk_width: 8,
331-
chunk_height: 8,
328+
image_width: 7,
329+
image_height: 7,
330+
chunk_width: 4,
331+
chunk_height: 4,
332332
bits_per_sample: &[8],
333333
samples_per_pixel: 1,
334334
sample_format: &[SampleFormat::Uint],
335335
planar_configuration: crate::tiff::tags::PlanarConfiguration::Chunky,
336336
};
337337
#[rustfmt::skip]
338-
const RES: [u8;64] = [
339-
0,1,2,3, 4,5,6,7,
340-
1,0,1,2, 3,4,5,6,
341-
2,1,0,1, 2,3,4,5,
342-
3,2,1,0, 1,2,3,4,
343-
344-
4,3,2,1, 0,1,2,3,
345-
5,4,3,2, 1,0,1,2,
346-
6,5,4,3, 2,1,0,1,
347-
7,6,5,4, 3,2,1,0,
338+
const RES: [u8;16] = [
339+
0,1, 2,3,
340+
1,0, 1,2,
341+
342+
2,1, 0,1,
343+
3,2, 1,0,
348344
];
349345
#[rustfmt::skip]
350-
const RES_RIGHT: [u8;56] = [
351-
0,1,2,3, 4,5,6,
352-
1,0,1,2, 3,4,5,
353-
2,1,0,1, 2,3,4,
354-
3,2,1,0, 1,2,3,
355-
356-
4,3,2,1, 0,1,2,
357-
5,4,3,2, 1,0,1,
358-
6,5,4,3, 2,1,0,
359-
7,6,5,4, 3,2,1,
346+
const RES_RIGHT: [u8;12] = [
347+
0,1, 2,
348+
1,0, 1,
349+
350+
2,1, 0,
351+
3,2, 1,
360352
];
361353
#[rustfmt::skip]
362-
const RES_BOT: [u8;56] = [
363-
0,1,2,3, 4,5,6,7,
364-
1,0,1,2, 3,4,5,6,
365-
2,1,0,1, 2,3,4,5,
366-
3,2,1,0, 1,2,3,4,
367-
368-
4,3,2,1, 0,1,2,3,
369-
5,4,3,2, 1,0,1,2,
370-
6,5,4,3, 2,1,0,1,
354+
const RES_BOT: [u8;12] = [
355+
0,1,2, 3,
356+
1,0,1, 2,
357+
358+
2,1,0, 1,
371359
];
372360
#[rustfmt::skip]
373-
const RES_BOT_RIGHT: [u8;49] = [
374-
0,1,2,3, 4,5,6,
375-
1,0,1,2, 3,4,5,
376-
2,1,0,1, 2,3,4,
377-
3,2,1,0, 1,2,3,
378-
379-
4,3,2,1, 0,1,2,
380-
5,4,3,2, 1,0,1,
381-
6,5,4,3, 2,1,0,
361+
const RES_BOT_RIGHT: [u8;9] = [
362+
0,1, 2,
363+
1,0, 1,
364+
365+
2,1, 0,
382366
];
383367

384368
#[rustfmt::skip]
@@ -400,57 +384,139 @@ mod test {
400384
#[test]
401385
fn test_hpredict() {
402386
let p = RevHorizontalPredictor;
387+
let mut predictor_info = PRED_INFO.clone();
403388
let cases = [
404-
(0,0, Bytes::from_static(&[
405-
0, 1, 1, 1, 1, 1, 1, 1,
406-
1,255, 1, 1, 1, 1, 1, 1,
407-
2,255,255, 1, 1, 1, 1, 1,
408-
3,255,255,255, 1, 1, 1, 1,
409-
410-
4,255,255,255, 255, 1, 1, 1,
411-
5,255,255,255, 255,255, 1, 1,
412-
6,255,255,255, 255,255,255, 1,
413-
7,255,255,255, 255,255,255,255,
414-
]), Bytes::from_static(&RES[..]) ),
415-
(0,1, Bytes::from_static(&[
416-
0, 1, 1, 1, 1, 1, 1, 1,
417-
1,255, 1, 1, 1, 1, 1, 1,
418-
2,255,255, 1, 1, 1, 1, 1,
419-
3,255,255,255, 1, 1, 1, 1,
420-
421-
4,255,255,255, 255, 1, 1, 1,
422-
5,255,255,255, 255,255, 1, 1,
423-
6,255,255,255, 255,255,255, 1,
424-
]), Bytes::from_static(&RES_BOT[..]) ),
425-
(1,0, Bytes::from_static(&[
426-
0, 1, 1, 1, 1, 1, 1,
427-
1,255, 1, 1, 1, 1, 1,
428-
2,255,255, 1, 1, 1, 1,
429-
3,255,255,255, 1, 1, 1,
430-
431-
4,255,255,255, 255, 1, 1,
432-
5,255,255,255, 255,255, 1,
433-
6,255,255,255, 255,255,255,
434-
7,255,255,255, 255,255,255,
435-
]), Bytes::from_static(&RES_RIGHT[..]) ),
436-
(1,1, Bytes::from_static(&[
437-
0, 1, 1, 1, 1, 1, 1,
438-
1,255, 1, 1, 1, 1, 1,
439-
2,255,255, 1, 1, 1, 1,
440-
3,255,255,255, 1, 1, 1,
441-
442-
4,255,255,255, 255, 1, 1,
443-
5,255,255,255, 255,255, 1,
444-
6,255,255,255, 255,255,255,
445-
]), Bytes::from_static(&RES_BOT_RIGHT[..]))
389+
(0,0, vec![
390+
0i32, 1, 1, 1,
391+
1,-1, 1, 1,
392+
2,-1,-1, 1,
393+
3,-1,-1,-1,
394+
], Vec::from(&RES[..])),
395+
(0,1, vec![
396+
0, 1, 1, 1,
397+
1,-1, 1, 1,
398+
2,-1,-1, 1,
399+
], Vec::from(&RES_BOT[..])),
400+
(1,0, vec![
401+
0, 1, 1,
402+
1,-1, 1,
403+
2,-1,-1,
404+
3,-1,-1,
405+
], Vec::from(&RES_RIGHT[..])),
406+
(1,1, vec![
407+
0, 1, 1,
408+
1,-1, 1,
409+
2,-1,-1,
410+
], Vec::from(&RES_BOT_RIGHT[..])),
446411
];
447412
for (x,y, input, expected) in cases {
448-
let res = p.rev_predict_fix_endianness(input.clone(), &PRED_INFO, x, y).unwrap();
449-
println!("testing ({x},{y}): {:?}?={:?}", &res[..], &expected[..]);
450-
assert_eq!(res, expected);
451-
452-
// also errors shouldn't crash
453-
// p.rev_predict_fix_endianness(input, &PRED_INFO, x+1, y+1).unwrap_err();
413+
println!("uints littleendian");
414+
predictor_info.endianness = Endianness::LittleEndian;
415+
predictor_info.sample_format = &[SampleFormat::Uint];
416+
predictor_info.bits_per_sample = &[8];
417+
assert_eq!(-1i32 as u8, 255);
418+
println!("testing u8");
419+
let buffer = Bytes::from(input.iter().map(|v| *v as u8).collect::<Vec<_>>());
420+
let res = Bytes::from(expected.clone());
421+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
422+
assert_eq!(-1i32 as u16, u16::MAX);
423+
println!("testing u16");
424+
predictor_info.bits_per_sample = &[16];
425+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u16).to_le_bytes()).collect::<Vec<_>>());
426+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u16).to_ne_bytes()).collect::<Vec<_>>());
427+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
428+
assert_eq!(-1i32 as u32, u32::MAX);
429+
println!("testing u32");
430+
predictor_info.bits_per_sample = &[32];
431+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u32).to_le_bytes()).collect::<Vec<_>>());
432+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u32).to_ne_bytes()).collect::<Vec<_>>());
433+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
434+
assert_eq!(-1i32 as u64, u64::MAX);
435+
println!("testing u64");
436+
predictor_info.bits_per_sample = &[64];
437+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u64).to_le_bytes()).collect::<Vec<_>>());
438+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u64).to_ne_bytes()).collect::<Vec<_>>());
439+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
440+
441+
println!("ints littleendian");
442+
predictor_info.sample_format = &[SampleFormat::Int];
443+
predictor_info.bits_per_sample = &[8];
444+
println!("testing i8");
445+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i8).to_le_bytes()).collect::<Vec<_>>());
446+
println!("{:?}", &buffer[..]);
447+
let res = Bytes::from(expected.clone());
448+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap()[..], res[..]);
449+
println!("testing i16");
450+
predictor_info.bits_per_sample = &[16];
451+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i16).to_le_bytes()).collect::<Vec<_>>());
452+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i16).to_ne_bytes()).collect::<Vec<_>>());
453+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
454+
println!("testing i32");
455+
predictor_info.bits_per_sample = &[32];
456+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i32).to_le_bytes()).collect::<Vec<_>>());
457+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i32).to_ne_bytes()).collect::<Vec<_>>());
458+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
459+
println!("testing i64");
460+
predictor_info.bits_per_sample = &[64];
461+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i64).to_le_bytes()).collect::<Vec<_>>());
462+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i64).to_ne_bytes()).collect::<Vec<_>>());
463+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
464+
465+
println!("uints bigendian");
466+
predictor_info.endianness = Endianness::BigEndian;
467+
predictor_info.sample_format = &[SampleFormat::Uint];
468+
predictor_info.bits_per_sample = &[8];
469+
assert_eq!(-1i32 as u8, 255);
470+
println!("testing u8");
471+
let buffer = Bytes::from(input.iter().map(|v| *v as u8).collect::<Vec<_>>());
472+
let res = Bytes::from(expected.clone());
473+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
474+
assert_eq!(-1i32 as u16, u16::MAX);
475+
println!("testing u16");
476+
predictor_info.bits_per_sample = &[16];
477+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u16).to_be_bytes()).collect::<Vec<_>>());
478+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u16).to_ne_bytes()).collect::<Vec<_>>());
479+
println!("buffer: {:?}", &buffer[..]);
480+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap()[..], res[..]);
481+
assert_eq!(-1i32 as u32, u32::MAX);
482+
println!("testing u32");
483+
predictor_info.bits_per_sample = &[32];
484+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u32).to_be_bytes()).collect::<Vec<_>>());
485+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u32).to_ne_bytes()).collect::<Vec<_>>());
486+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
487+
assert_eq!(-1i32 as u64, u64::MAX);
488+
println!("testing u64");
489+
predictor_info.bits_per_sample = &[64];
490+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as u64).to_be_bytes()).collect::<Vec<_>>());
491+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as u64).to_ne_bytes()).collect::<Vec<_>>());
492+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
493+
494+
println!("ints bigendian");
495+
predictor_info.sample_format = &[SampleFormat::Int];
496+
predictor_info.bits_per_sample = &[8];
497+
assert_eq!(-1i32 as u8, 255);
498+
println!("testing i8");
499+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i8).to_be_bytes()).collect::<Vec<_>>());
500+
let res = Bytes::from(expected.clone());
501+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
502+
assert_eq!(-1i32 as u16, u16::MAX);
503+
println!("testing i16");
504+
predictor_info.bits_per_sample = &[16];
505+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i16).to_be_bytes()).collect::<Vec<_>>());
506+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i16).to_ne_bytes()).collect::<Vec<_>>());
507+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
508+
assert_eq!(-1i32 as u32, u32::MAX);
509+
println!("testing i32");
510+
predictor_info.bits_per_sample = &[32];
511+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i32).to_be_bytes()).collect::<Vec<_>>());
512+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i32).to_ne_bytes()).collect::<Vec<_>>());
513+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
514+
assert_eq!(-1i32 as u64, u64::MAX);
515+
println!("testing i64");
516+
predictor_info.bits_per_sample = &[64];
517+
let buffer = Bytes::from(input.iter().flat_map(|v| (*v as i64).to_be_bytes()).collect::<Vec<_>>());
518+
let res = Bytes::from(expected.iter().flat_map(|v| (*v as i64).to_ne_bytes()).collect::<Vec<_>>());
519+
assert_eq!(p.rev_predict_fix_endianness(buffer, &predictor_info, x, y).unwrap(), res);
454520
}
455521
}
456522

0 commit comments

Comments
 (0)