Skip to content

Commit d49342c

Browse files
committed
added predictors
1 parent c720f01 commit d49342c

File tree

8 files changed

+728
-15
lines changed

8 files changed

+728
-15
lines changed

src/cog.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ mod test {
2525

2626
use crate::decoder::DecoderRegistry;
2727
use crate::metadata::{PrefetchBuffer, TiffMetadataReader};
28+
use crate::predictor::RevPredictorRegistry;
2829
use crate::reader::{AsyncFileReader, ObjectReader};
2930

3031
use super::*;
@@ -52,8 +53,9 @@ mod test {
5253

5354
let ifd = &tiff.ifds[1];
5455
let decoder_registry = DecoderRegistry::default();
56+
let predictor_registry = RevPredictorRegistry::default();
5557
let tile = ifd.fetch_tile(0, 0, reader.as_ref()).await.unwrap();
56-
let tile = tile.decode(&decoder_registry).unwrap();
58+
let tile = tile.decode(&decoder_registry, &predictor_registry).unwrap();
5759
std::fs::write("img.buf", tile).unwrap();
5860
}
5961

src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ pub enum AsyncTiffError {
1515
#[error("General error: {0}")]
1616
General(String),
1717

18+
/// Tile index error
19+
#[error("Tile index out of bounds: {0}, {1}")]
20+
TileIndexError(u32, u32),
21+
1822
/// IO Error.
1923
#[error(transparent)]
2024
IOError(#[from] std::io::Error),

src/ifd.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ use num_enum::TryFromPrimitive;
66

77
use crate::error::{AsyncTiffError, AsyncTiffResult};
88
use crate::geo::{GeoKeyDirectory, GeoKeyTag};
9-
use crate::reader::AsyncFileReader;
9+
use crate::reader::{AsyncFileReader, Endianness};
1010
use crate::tiff::tags::{
1111
CompressionMethod, PhotometricInterpretation, PlanarConfiguration, Predictor, ResolutionUnit,
1212
SampleFormat, Tag,
1313
};
1414
use crate::tiff::{TiffError, Value};
15-
use crate::tile::Tile;
15+
use crate::tile::{PredictorInfo, Tile};
1616

1717
const DOCUMENT_NAME: u16 = 269;
1818

@@ -21,6 +21,8 @@ const DOCUMENT_NAME: u16 = 269;
2121
#[allow(dead_code)]
2222
#[derive(Debug, Clone)]
2323
pub struct ImageFileDirectory {
24+
pub(crate) endianness: Endianness,
25+
2426
pub(crate) new_subfile_type: Option<u32>,
2527

2628
/// The number of columns in the image, i.e., the number of pixels per row.
@@ -143,7 +145,10 @@ pub struct ImageFileDirectory {
143145

144146
impl ImageFileDirectory {
145147
/// Create a new ImageFileDirectory from tag data
146-
pub fn from_tags(tag_data: HashMap<Tag, Value>) -> AsyncTiffResult<Self> {
148+
pub fn from_tags(
149+
tag_data: HashMap<Tag, Value>,
150+
endianness: Endianness,
151+
) -> AsyncTiffResult<Self> {
147152
let mut new_subfile_type = None;
148153
let mut image_width = None;
149154
let mut image_height = None;
@@ -349,6 +354,7 @@ impl ImageFileDirectory {
349354
PlanarConfiguration::Chunky
350355
};
351356
Ok(Self {
357+
endianness,
352358
new_subfile_type,
353359
image_width: image_width.expect("image_width not found"),
354360
image_height: image_height.expect("image_height not found"),
@@ -675,6 +681,30 @@ impl ImageFileDirectory {
675681
Some(offset as _..(offset + byte_count) as _)
676682
}
677683

684+
fn get_predictor_info(&self) -> PredictorInfo {
685+
PredictorInfo {
686+
endianness: self.endianness,
687+
image_width: self.image_width,
688+
image_height: self.image_height,
689+
chunk_width: if self.tile_width.is_none() {
690+
// we are stripped => image_width
691+
self.image_width
692+
} else {
693+
self.tile_width.unwrap()
694+
},
695+
chunk_height: if self.tile_height.is_none() {
696+
self.rows_per_strip
697+
.expect("no tile height and no rows_per_strip")
698+
} else {
699+
self.tile_height.unwrap()
700+
},
701+
bits_per_sample: &self.bits_per_sample,
702+
samples_per_pixel: self.samples_per_pixel,
703+
sample_format: &self.sample_format,
704+
planar_configuration: self.planar_configuration,
705+
}
706+
}
707+
678708
/// Fetch the tile located at `x` column and `y` row using the provided reader.
679709
pub async fn fetch_tile(
680710
&self,
@@ -689,6 +719,8 @@ impl ImageFileDirectory {
689719
Ok(Tile {
690720
x,
691721
y,
722+
predictor: self.predictor.unwrap_or(Predictor::None),
723+
predictor_info: self.get_predictor_info(),
692724
compressed_bytes,
693725
compression_method: self.compression,
694726
photometric_interpretation: self.photometric_interpretation,
@@ -724,6 +756,8 @@ impl ImageFileDirectory {
724756
let tile = Tile {
725757
x,
726758
y,
759+
predictor: self.predictor.unwrap_or(Predictor::None),
760+
predictor_info: self.get_predictor_info(),
727761
compressed_bytes,
728762
compression_method: self.compression,
729763
photometric_interpretation: self.photometric_interpretation,

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub mod error;
99
pub mod geo;
1010
mod ifd;
1111
pub mod metadata;
12+
pub mod predictor;
1213
pub mod tiff;
1314
mod tile;
1415

src/metadata/reader.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ impl ImageFileDirectoryReader {
226226
let (tag, value) = self.read_tag(fetch, tag_idx).await?;
227227
tags.insert(tag, value);
228228
}
229-
ImageFileDirectory::from_tags(tags)
229+
ImageFileDirectory::from_tags(tags, self.endianness)
230230
}
231231

232232
/// Finish this reader, reading the byte offset of the next IFD
@@ -623,11 +623,14 @@ async fn read_tag_value<F: MetadataFetch>(
623623

624624
#[cfg(test)]
625625
mod test {
626+
use crate::{
627+
metadata::{reader::read_tag, MetadataFetch},
628+
reader::Endianness,
629+
tiff::{tags::Tag, Value},
630+
};
626631
use bytes::Bytes;
627632
use futures::FutureExt;
628633

629-
use super::*;
630-
631634
impl MetadataFetch for Bytes {
632635
fn fetch(
633636
&self,

0 commit comments

Comments
 (0)