CCITT group 4 (Fax4) decoding support
This commit is contained in:
1 parent
85b5df7a62
commit
666f871d30
4 files changed
+28
-1
No files matched your search
@@ -20,6 +20,7 @@ exclude = ["tests/images/*", "tests/fuzz_images/*"]
|
|||||||
half = { version = "2.4.1" }
|
half = { version = "2.4.1" }
|
||||||
quick-error = "2.0.1"
|
quick-error = "2.0.1"
|
||||||
|
|
||||||
|
fax = { version = "0.2.2", optional = true }
|
||||||
flate2 = { version = "1.0.20", optional = true }
|
flate2 = { version = "1.0.20", optional = true }
|
||||||
weezl = { version = "0.1.10", optional = true }
|
weezl = { version = "0.1.10", optional = true }
|
||||||
zstd = { version = "0.13", optional = true }
|
zstd = { version = "0.13", optional = true }
|
||||||
|
|||||||
+21
-1
@@ -381,6 +381,7 @@ impl Image {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_reader<'r, R: 'r + Read>(
|
fn create_reader<'r, R: 'r + Read>(
|
||||||
|
&self,
|
||||||
reader: R,
|
reader: R,
|
||||||
compression_method: CompressionMethod,
|
compression_method: CompressionMethod,
|
||||||
compressed_length: u64,
|
compressed_length: u64,
|
||||||
@@ -452,6 +453,25 @@ impl Image {
|
|||||||
|
|
||||||
Box::new(Cursor::new(data))
|
Box::new(Cursor::new(data))
|
||||||
}
|
}
|
||||||
|
CompressionMethod::Fax4 => {
|
||||||
|
let width = u16::try_from(self.width)?;
|
||||||
|
let height = u16::try_from(self.height)?;
|
||||||
|
let mut out: Vec<u8> = Vec::with_capacity(usize::from(width) * usize::from(height));
|
||||||
|
|
||||||
|
let mut buffer = Vec::with_capacity(usize::try_from(compressed_length)?);
|
||||||
|
reader.take(compressed_length).read_to_end(&mut buffer)?;
|
||||||
|
|
||||||
|
// all extant tiff/fax4 decoders I've found always assume that the photometric interpretation
|
||||||
|
// is `WhiteIsZero`, ignoring the tag. ImageMagick appears to generate fax4-encoded tiffs
|
||||||
|
// with the tag incorrectly set to `BlackIsZero`.
|
||||||
|
fax::decoder::decode_g4(buffer.into_iter(), width, Some(height), |transitions| {
|
||||||
|
out.extend(fax::decoder::pels(transitions, width).map(|c| match c {
|
||||||
|
fax::Color::Black => 255,
|
||||||
|
fax::Color::White => 0,
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
Box::new(Cursor::new(out))
|
||||||
|
}
|
||||||
method => {
|
method => {
|
||||||
return Err(TiffError::UnsupportedError(
|
return Err(TiffError::UnsupportedError(
|
||||||
TiffUnsupportedError::UnsupportedCompressionMethod(method),
|
TiffUnsupportedError::UnsupportedCompressionMethod(method),
|
||||||
@@ -653,7 +673,7 @@ impl Image {
|
|||||||
assert!(output_row_stride >= data_row_bytes);
|
assert!(output_row_stride >= data_row_bytes);
|
||||||
assert!(buf.len() >= output_row_stride * (data_dims.1 as usize - 1) + data_row_bytes);
|
assert!(buf.len() >= output_row_stride * (data_dims.1 as usize - 1) + data_row_bytes);
|
||||||
|
|
||||||
let mut reader = Self::create_reader(
|
let mut reader = self.create_reader(
|
||||||
reader,
|
reader,
|
||||||
compression_method,
|
compression_method,
|
||||||
*compressed_bytes,
|
*compressed_bytes,
|
||||||
|
|||||||
@@ -672,3 +672,9 @@ fn bytes_gray_f32() {
|
|||||||
byte_order_u32,
|
byte_order_u32,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "fax")]
|
||||||
|
fn test_fax4() {
|
||||||
|
test_image_sum_u8("fax4.tiff", ColorType::Gray(1), 62384985);
|
||||||
|
}
|
||||||
Binary file not shown.
Reference in new issue
Block a user