refactor: simplify hash computation and remove unused benchmark
Address PR review feedback: - Remove benches/decode.rs which referenced non-existent gen_bench_tiff.c - Simplify compute_tiff_hash: replace 66-line match block with as_buffer().as_bytes() + ByteOrder::convert for LE normalization - Use TIFF Type repr(u16) as hash discriminant instead of ad-hoc u8 - Rename all 74 seq test images to match updated hashes
This commit is contained in:
1 parent
3434d0220b
commit
2d6d92e81d
77 files changed
+23
-111
No files matched your search
@@ -54,9 +54,6 @@ harness = false
|
|||||||
name = "encode"
|
name = "encode"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "decode"
|
|
||||||
harness = false
|
|
||||||
|
|
||||||
[[test]]
|
[[test]]
|
||||||
name = "decode_libtiffpic"
|
name = "decode_libtiffpic"
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
extern crate criterion;
|
|
||||||
extern crate tiff;
|
|
||||||
|
|
||||||
use criterion::{black_box, Criterion, Throughput};
|
|
||||||
use tiff::decoder::Decoder;
|
|
||||||
|
|
||||||
fn decode_image(data: &[u8]) {
|
|
||||||
let image = std::io::Cursor::new(data);
|
|
||||||
let mut reader = Decoder::open(black_box(image)).unwrap();
|
|
||||||
reader.next_image().unwrap();
|
|
||||||
reader.read_image().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut c = Criterion::default().configure_from_args();
|
|
||||||
|
|
||||||
// Check if large bench images exist
|
|
||||||
let bench_dir = std::path::Path::new("/tmp/bench-tiff");
|
|
||||||
if !bench_dir.is_dir() {
|
|
||||||
eprintln!("Skipping large image benchmarks: /tmp/bench-tiff/ not found");
|
|
||||||
eprintln!("Generate with: cc -O2 -o /tmp/gen_bench_tiff /tmp/gen_bench_tiff.c -ltiff -lm && /tmp/gen_bench_tiff");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut group = c.benchmark_group("decode-1024x1024");
|
|
||||||
group.sample_size(30);
|
|
||||||
|
|
||||||
for depth in [3, 5, 7, 8, 10, 12, 14, 16, 24] {
|
|
||||||
let path = bench_dir.join(format!("bench-1c-{depth}b.tiff"));
|
|
||||||
if !path.exists() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let data = std::fs::read(&path).unwrap();
|
|
||||||
group
|
|
||||||
.throughput(Throughput::Bytes(data.len() as u64))
|
|
||||||
.bench_function(format!("{depth}b"), |b| b.iter(|| decode_image(&data)));
|
|
||||||
}
|
|
||||||
|
|
||||||
group.finish();
|
|
||||||
}
|
|
||||||
+23
-68
@@ -1,6 +1,7 @@
|
|||||||
extern crate tiff;
|
extern crate tiff;
|
||||||
|
|
||||||
use tiff::decoder::{ifd, Decoder, DecodingResult};
|
use tiff::decoder::{ifd, Decoder, DecodingResult};
|
||||||
|
use tiff::tags::{ByteOrder, Type};
|
||||||
use tiff::ColorType;
|
use tiff::ColorType;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
@@ -83,7 +84,7 @@ fn compute_tiff_hash<R: Read + Seek>(reader: R) -> u32 {
|
|||||||
decoder.next_image().expect("Cannot read image IFD");
|
decoder.next_image().expect("Cannot read image IFD");
|
||||||
let (width, height) = decoder.dimensions().unwrap();
|
let (width, height) = decoder.dimensions().unwrap();
|
||||||
let color_type = decoder.colortype().unwrap();
|
let color_type = decoder.colortype().unwrap();
|
||||||
let result = decoder.read_image().unwrap();
|
let mut result = decoder.read_image().unwrap();
|
||||||
|
|
||||||
// Hash page index + dimensions
|
// Hash page index + dimensions
|
||||||
hasher.update(&page.to_le_bytes());
|
hasher.update(&page.to_le_bytes());
|
||||||
@@ -111,73 +112,27 @@ fn compute_tiff_hash<R: Read + Seek>(reader: R) -> u32 {
|
|||||||
other => panic!("compute_tiff_hash: unhandled ColorType {other:?}"),
|
other => panic!("compute_tiff_hash: unhandled ColorType {other:?}"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash decoded data with type discriminant + LE sample bytes
|
// Hash decoded data: TIFF type tag (u16 repr) + LE sample bytes.
|
||||||
match result {
|
// Map each variant to the corresponding TIFF Type for byte-order normalization.
|
||||||
DecodingResult::U8(ref data) => {
|
let sample_type = match &result {
|
||||||
hasher.update(&[0]);
|
DecodingResult::U8(_) => Type::BYTE,
|
||||||
hasher.update(data);
|
DecodingResult::I8(_) => Type::SBYTE,
|
||||||
}
|
DecodingResult::U16(_) => Type::SHORT,
|
||||||
DecodingResult::U16(ref data) => {
|
DecodingResult::I16(_) => Type::SSHORT,
|
||||||
hasher.update(&[1]);
|
DecodingResult::U32(_) => Type::LONG,
|
||||||
for v in data {
|
DecodingResult::I32(_) => Type::SLONG,
|
||||||
hasher.update(&v.to_le_bytes());
|
DecodingResult::F32(_) => Type::FLOAT,
|
||||||
}
|
DecodingResult::U64(_) => Type::LONG8,
|
||||||
}
|
DecodingResult::I64(_) => Type::SLONG8,
|
||||||
DecodingResult::U32(ref data) => {
|
DecodingResult::F64(_) => Type::DOUBLE,
|
||||||
hasher.update(&[2]);
|
DecodingResult::F16(_) => Type::SHORT, // f16 is 2 bytes like SHORT
|
||||||
for v in data {
|
};
|
||||||
hasher.update(&v.to_le_bytes());
|
hasher.update(&sample_type.to_u16().to_le_bytes());
|
||||||
}
|
|
||||||
}
|
let mut buf = result.as_buffer(0);
|
||||||
DecodingResult::U64(ref data) => {
|
let bytes = buf.as_bytes_mut();
|
||||||
hasher.update(&[3]);
|
ByteOrder::native().convert(sample_type, bytes, ByteOrder::LittleEndian);
|
||||||
for v in data {
|
hasher.update(bytes);
|
||||||
hasher.update(&v.to_le_bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DecodingResult::F16(ref data) => {
|
|
||||||
hasher.update(&[4]);
|
|
||||||
for v in data {
|
|
||||||
hasher.update(&v.to_le_bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DecodingResult::F32(ref data) => {
|
|
||||||
hasher.update(&[5]);
|
|
||||||
for v in data {
|
|
||||||
hasher.update(&v.to_le_bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DecodingResult::F64(ref data) => {
|
|
||||||
hasher.update(&[6]);
|
|
||||||
for v in data {
|
|
||||||
hasher.update(&v.to_le_bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DecodingResult::I8(ref data) => {
|
|
||||||
hasher.update(&[7]);
|
|
||||||
for v in data {
|
|
||||||
hasher.update(&v.to_le_bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DecodingResult::I16(ref data) => {
|
|
||||||
hasher.update(&[8]);
|
|
||||||
for v in data {
|
|
||||||
hasher.update(&v.to_le_bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DecodingResult::I32(ref data) => {
|
|
||||||
hasher.update(&[9]);
|
|
||||||
for v in data {
|
|
||||||
hasher.update(&v.to_le_bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DecodingResult::I64(ref data) => {
|
|
||||||
hasher.update(&[10]);
|
|
||||||
for v in data {
|
|
||||||
hasher.update(&v.to_le_bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
page += 1;
|
page += 1;
|
||||||
if !decoder.more_images() {
|
if !decoder.more_images() {
|
||||||
|
|||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user