Merge pull request #90 from image-rs/weezl
Replace lzw decoder with weezl
This commit is contained in:
8 files changed
+105
-7
No files matched your search
+9
-1
@@ -17,7 +17,15 @@ repository = "https://github.com/image-rs/image-tiff"
|
|||||||
exclude = ["tests/images/*", "tests/fuzz_images/*"]
|
exclude = ["tests/images/*", "tests/fuzz_images/*"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lzw = "0.10"
|
weezl = "0.1.0"
|
||||||
|
|
||||||
[dependencies.miniz_oxide]
|
[dependencies.miniz_oxide]
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
features = ["no_extern_crate_alloc"]
|
features = ["no_extern_crate_alloc"]
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
criterion = "0.3.1"
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "lzw"
|
||||||
|
harness = false
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
extern crate criterion;
|
||||||
|
extern crate tiff;
|
||||||
|
|
||||||
|
use criterion::{black_box, BenchmarkId, BenchmarkGroup, Criterion, Throughput, measurement::Measurement};
|
||||||
|
use tiff::decoder::Decoder;
|
||||||
|
|
||||||
|
fn read_image(image: &[u8]) {
|
||||||
|
let image = std::io::Cursor::new(image);
|
||||||
|
let decoder = Decoder::new(black_box(image));
|
||||||
|
let mut reader = decoder.unwrap();
|
||||||
|
|
||||||
|
while {
|
||||||
|
reader.read_image().unwrap();
|
||||||
|
reader.more_images()
|
||||||
|
} {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
struct BenchDef {
|
||||||
|
data: &'static [u8],
|
||||||
|
id: &'static str,
|
||||||
|
sample_size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_bench_def<M: Measurement>(group: &mut BenchmarkGroup<M>, def: BenchDef) {
|
||||||
|
group
|
||||||
|
.sample_size(def.sample_size)
|
||||||
|
.throughput(Throughput::Bytes(def.data.len() as u64))
|
||||||
|
.bench_with_input(
|
||||||
|
BenchmarkId::new(def.id, def.data.len()),
|
||||||
|
def.data,
|
||||||
|
|b, input| {
|
||||||
|
b.iter(|| read_image(input))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut c = Criterion::default().configure_from_args();
|
||||||
|
let mut group = c.benchmark_group("tiff-lzw");
|
||||||
|
|
||||||
|
/*
|
||||||
|
run_bench_def(&mut group, BenchDef {
|
||||||
|
data: include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/images/quad-lzw-compat.tiff")),
|
||||||
|
id: "quad-lzw.tif",
|
||||||
|
sample_size: 500,
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
run_bench_def(&mut group, BenchDef {
|
||||||
|
data: include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/images/issue_69_lzw.tiff")),
|
||||||
|
id: "issue-69-lzw.tif",
|
||||||
|
sample_size: 500,
|
||||||
|
});
|
||||||
|
|
||||||
|
run_bench_def(&mut group, BenchDef {
|
||||||
|
data: include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/benches/kodim02-lzw.tif")),
|
||||||
|
id: "kodim02-lzw.tif",
|
||||||
|
sample_size: 20,
|
||||||
|
});
|
||||||
|
|
||||||
|
run_bench_def(&mut group, BenchDef {
|
||||||
|
data: include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/benches/kodim07-lzw.tif")),
|
||||||
|
id: "kodim07-lzw.tif",
|
||||||
|
sample_size: 20,
|
||||||
|
});
|
||||||
|
|
||||||
|
run_bench_def(&mut group, BenchDef {
|
||||||
|
data: include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/benches/Transparency-lzw.tif")),
|
||||||
|
id: "Transparency-lzw.tif",
|
||||||
|
sample_size: 20,
|
||||||
|
});
|
||||||
|
}
|
||||||
+19
-5
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
use crate::bytecast;
|
use crate::bytecast;
|
||||||
use crate::error::{TiffError, TiffResult};
|
use crate::error::{TiffError, TiffResult};
|
||||||
use lzw;
|
|
||||||
use miniz_oxide::inflate;
|
use miniz_oxide::inflate;
|
||||||
use std::io::{self, Read, Seek};
|
use std::io::{self, Read, Seek};
|
||||||
|
|
||||||
@@ -244,12 +243,27 @@ impl LZWReader {
|
|||||||
let mut compressed = vec![0; compressed_length as usize];
|
let mut compressed = vec![0; compressed_length as usize];
|
||||||
reader.read_exact(&mut compressed[..])?;
|
reader.read_exact(&mut compressed[..])?;
|
||||||
let mut uncompressed = Vec::with_capacity(max_uncompressed_length);
|
let mut uncompressed = Vec::with_capacity(max_uncompressed_length);
|
||||||
let mut decoder = lzw::DecoderEarlyChange::new(lzw::MsbReader::new(), 8);
|
let mut decoder = weezl::decode::Decoder::with_tiff_size_switch(weezl::BitOrder::Msb, 8);
|
||||||
let mut bytes_read = 0;
|
let mut bytes_read = 0;
|
||||||
while bytes_read < compressed_length && uncompressed.len() < max_uncompressed_length {
|
while bytes_read < compressed_length && uncompressed.len() < max_uncompressed_length {
|
||||||
let (len, bytes) = decoder.decode_bytes(&compressed[bytes_read..])?;
|
let bytes_written = uncompressed.len();
|
||||||
bytes_read += len;
|
uncompressed.reserve(1 << 12);
|
||||||
uncompressed.extend_from_slice(bytes);
|
let buffer_space = uncompressed.capacity();
|
||||||
|
uncompressed.resize(buffer_space, 0u8);
|
||||||
|
|
||||||
|
let result = decoder.decode_bytes(&compressed[bytes_read..], &mut uncompressed[bytes_written..]);
|
||||||
|
bytes_read += result.consumed_in;
|
||||||
|
uncompressed.truncate(bytes_written + result.consumed_out);
|
||||||
|
|
||||||
|
match result.status {
|
||||||
|
Ok(weezl::LzwStatus::Ok) => {},
|
||||||
|
Ok(weezl::LzwStatus::Done) => break,
|
||||||
|
Ok(weezl::LzwStatus::NoProgress) => return Err(io::Error::new(
|
||||||
|
io::ErrorKind::UnexpectedEof,
|
||||||
|
"no lzw end code found",
|
||||||
|
)),
|
||||||
|
Err(err) => return Err(io::Error::new(io::ErrorKind::InvalidData, err)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let bytes = uncompressed.len();
|
let bytes = uncompressed.len();
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
//! # Related Links
|
//! # Related Links
|
||||||
//! * <https://www.adobe.io/open/standards/TIFF.html> - The TIFF specification
|
//! * <https://www.adobe.io/open/standards/TIFF.html> - The TIFF specification
|
||||||
|
|
||||||
extern crate lzw;
|
extern crate weezl;
|
||||||
extern crate miniz_oxide;
|
extern crate miniz_oxide;
|
||||||
|
|
||||||
mod bytecast;
|
mod bytecast;
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Copyrights:
|
||||||
|
|
||||||
|
kodim*.png: Eastman Kodak Company, released for unrestricted use
|
||||||
|
Transparency.png: Public Domain, according to Wikimedia
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user