Simplify and avoid allocation in jpeg decompression
This commit is contained in:
1 parent
289fab2fcd
commit
24d203c7c3
2 files changed
+27
-105
No files matched your search
+26
-5
@@ -1,5 +1,5 @@
|
||||
use super::ifd::{Directory, Value};
|
||||
use super::stream::{ByteOrder, DeflateReader, JpegReader, LZWReader, PackBitsReader};
|
||||
use super::stream::{ByteOrder, DeflateReader, LZWReader, PackBitsReader};
|
||||
use super::tag_reader::TagReader;
|
||||
use super::{fp_predict_f32, fp_predict_f64, DecodingBuffer, Limits};
|
||||
use super::{stream::SmartReader, ChunkType};
|
||||
@@ -326,7 +326,7 @@ impl Image {
|
||||
photometric_interpretation: PhotometricInterpretation,
|
||||
compression_method: CompressionMethod,
|
||||
compressed_length: u64,
|
||||
jpeg_tables: Option<Arc<Vec<u8>>>,
|
||||
jpeg_tables: Option<&[u8]>,
|
||||
) -> TiffResult<Box<dyn Read + 'r>> {
|
||||
Ok(match compression_method {
|
||||
CompressionMethod::None => Box::new(reader),
|
||||
@@ -344,7 +344,29 @@ impl Image {
|
||||
));
|
||||
}
|
||||
|
||||
let jpeg_reader = JpegReader::new(reader, compressed_length, jpeg_tables)?;
|
||||
// Construct new jpeg_reader wrapping a SmartReader.
|
||||
//
|
||||
// JPEG compression in TIFF allows saving quantization and/or huffman tables in one
|
||||
// central location. These `jpeg_tables` are simply prepended to the remaining jpeg image data.
|
||||
// Because these `jpeg_tables` start with a `SOI` (HEX: `0xFFD8`) or __start of image__ marker
|
||||
// which is also at the beginning of the remaining JPEG image data and would
|
||||
// confuse the JPEG renderer, one of these has to be taken off. In this case the first two
|
||||
// bytes of the remaining JPEG data is removed because it follows `jpeg_tables`.
|
||||
// Similary, `jpeg_tables` ends with a `EOI` (HEX: `0xFFD9`) or __end of image__ marker,
|
||||
// this has to be removed as well (last two bytes of `jpeg_tables`).
|
||||
let jpeg_reader = match jpeg_tables {
|
||||
Some(jpeg_tables) => {
|
||||
let mut reader = reader.take(compressed_length);
|
||||
reader.read_exact(&mut [0; 2])?;
|
||||
|
||||
Box::new(
|
||||
Cursor::new(&jpeg_tables[..jpeg_tables.len() - 2])
|
||||
.chain(reader.take(compressed_length)),
|
||||
) as Box<dyn Read>
|
||||
}
|
||||
None => Box::new(reader.take(compressed_length)),
|
||||
};
|
||||
|
||||
let mut decoder = jpeg::Decoder::new(jpeg_reader);
|
||||
|
||||
match photometric_interpretation {
|
||||
@@ -522,13 +544,12 @@ impl Image {
|
||||
|
||||
let padding_right = chunk_dims.0 - data_dims.0;
|
||||
|
||||
let jpeg_tables = self.jpeg_tables.clone();
|
||||
let mut reader = Self::create_reader(
|
||||
reader,
|
||||
photometric_interpretation,
|
||||
compression_method,
|
||||
*compressed_bytes,
|
||||
jpeg_tables,
|
||||
self.jpeg_tables.as_deref().map(|a| &**a),
|
||||
)?;
|
||||
|
||||
if output_width == data_dims.0 as usize && padding_right == 0 {
|
||||
|
||||
Reference in new issue
Block a user