Skip endianess swap for SGI compression

This commit is contained in:
A. Molzer committed 2026-02-14 18:04:07 +01:00
1 parent 983c5baea0
commit c81d0a9c94
2 files changed
+23 -6

No files matched your search

+22 -6
View File
@@ -4,8 +4,8 @@ use super::tag_reader::TagReader;
use super::ChunkType; use super::ChunkType;
use super::{predict_f16, predict_f32, predict_f64, ValueReader}; use super::{predict_f16, predict_f32, predict_f64, ValueReader};
use crate::tags::{ use crate::tags::{
CompressionMethod, ExtraSamples, PhotometricInterpretation, PlanarConfiguration, Predictor, ByteOrder, CompressionMethod, ExtraSamples, PhotometricInterpretation, PlanarConfiguration,
SampleFormat, Tag, Predictor, SampleFormat, Tag,
}; };
use crate::{ use crate::{
ColorType, Directory, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError, UsageError, ColorType, Directory, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError, UsageError,
@@ -86,6 +86,13 @@ pub(crate) struct Image {
pub chunk_offsets: Vec<u64>, pub chunk_offsets: Vec<u64>,
pub chunk_bytes: Vec<u64>, pub chunk_bytes: Vec<u64>,
pub chroma_subsampling: (u16, u16), pub chroma_subsampling: (u16, u16),
/// Will decompression yield host-endian samples?
///
/// Standard compression algorithms run on pure bytes, taking the sample slice as it would be
/// encoded in the file. However some compression algorithms (currently only SGILog/SGILog24)
/// run on samples directly and thus skip the outer byte order entirely, except potentially
/// they have interior byte order treatment.
pub decompression_to_host_endian: bool,
} }
/// Describes how to read a tile-aligned portion of the image. /// Describes how to read a tile-aligned portion of the image.
@@ -447,6 +454,10 @@ impl Image {
chunk_offsets, chunk_offsets,
chunk_bytes, chunk_bytes,
chroma_subsampling, chroma_subsampling,
decompression_to_host_endian: matches!(
compression_method,
CompressionMethod::SgiLog | CompressionMethod::SgiLog24
),
}) })
} }
@@ -928,7 +939,12 @@ impl Image {
limits, limits,
} = reader; } = reader;
let byte_order = reader.byte_order; let decompressed_byte_order = if self.decompression_to_host_endian {
ByteOrder::native()
} else {
// Convert from the byte order of the file.
reader.byte_order
};
// Validate that the color type is supported. // Validate that the color type is supported.
let color_type = layout.color; let color_type = layout.color;
@@ -1044,7 +1060,7 @@ impl Image {
row, row,
color_type.bit_depth(), color_type.bit_depth(),
samples, samples,
byte_order, decompressed_byte_order,
predictor, predictor,
); );
} }
@@ -1090,7 +1106,7 @@ impl Image {
row, row,
color_type.bit_depth(), color_type.bit_depth(),
samples, samples,
byte_order, decompressed_byte_order,
predictor, predictor,
); );
@@ -1131,7 +1147,7 @@ impl Image {
row, row,
color_type.bit_depth(), color_type.bit_depth(),
samples, samples,
byte_order, decompressed_byte_order,
predictor, predictor,
); );
+1
View File
@@ -862,6 +862,7 @@ impl<R: Read + Seek> Decoder<R> {
chunk_offsets: Vec::new(), chunk_offsets: Vec::new(),
chunk_bytes: Vec::new(), chunk_bytes: Vec::new(),
chroma_subsampling: (2, 2), chroma_subsampling: (2, 2),
decompression_to_host_endian: false,
}, },
}; };
decoder.next_image()?; decoder.next_image()?;