Skip to content

Commit 8978a5d

Browse files
authored
Vendor image-tiff tests (#28)
* Vendor image-tiff tests * Don't fail on decoding metadata for strip images * sample format default * Fix parsing big-endian ifds * Allow planar configuration to be inferred * Add tif files
1 parent 4b3f2b2 commit 8978a5d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1453
-118
lines changed

src/async_reader.rs

Lines changed: 146 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
use std::io::Cursor;
1+
use std::fmt::Debug;
2+
use std::io::Read;
23
use std::ops::Range;
34
use std::sync::Arc;
45

56
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
6-
use bytes::Bytes;
7+
use bytes::buf::Reader;
8+
use bytes::{Buf, Bytes};
79
use futures::future::{BoxFuture, FutureExt, TryFutureExt};
810
use object_store::ObjectStore;
911

@@ -25,7 +27,7 @@ use crate::error::{AiocogeoError, Result};
2527
/// [`ObjectStore`]: object_store::ObjectStore
2628
///
2729
/// [`tokio::fs::File`]: https://docs.rs/tokio/latest/tokio/fs/struct.File.html
28-
pub trait AsyncFileReader: Send + Sync {
30+
pub trait AsyncFileReader: Debug + Send + Sync {
2931
/// Retrieve the bytes in `range`
3032
fn get_bytes(&mut self, range: Range<u64>) -> BoxFuture<'_, Result<Bytes>>;
3133

@@ -57,7 +59,9 @@ impl AsyncFileReader for Box<dyn AsyncFileReader + '_> {
5759
}
5860

5961
#[cfg(feature = "tokio")]
60-
impl<T: tokio::io::AsyncRead + tokio::io::AsyncSeek + Unpin + Send + Sync> AsyncFileReader for T {
62+
impl<T: tokio::io::AsyncRead + tokio::io::AsyncSeek + Unpin + Debug + Send + Sync> AsyncFileReader
63+
for T
64+
{
6165
fn get_bytes(&mut self, range: Range<u64>) -> BoxFuture<'_, Result<Bytes>> {
6266
use tokio::io::{AsyncReadExt, AsyncSeekExt};
6367

@@ -114,6 +118,7 @@ impl AsyncFileReader for ObjectReader {
114118
}
115119
}
116120

121+
#[derive(Debug)]
117122
pub struct PrefetchReader {
118123
reader: Box<dyn AsyncFileReader>,
119124
buffer: Bytes,
@@ -161,25 +166,13 @@ pub enum Endianness {
161166

162167
/// A wrapper around an [ObjectStore] that provides a seek-oriented interface
163168
// TODO: in the future add buffering to this
169+
#[derive(Debug)]
164170
pub(crate) struct AsyncCursor {
165171
reader: Box<dyn AsyncFileReader>,
166172
offset: usize,
167173
endianness: Endianness,
168174
}
169175

170-
/// Macro to generate functions to read scalar values from the cursor
171-
macro_rules! impl_read_byteorder {
172-
($method_name:ident, $typ:ty) => {
173-
pub(crate) async fn $method_name(&mut self) -> Result<$typ> {
174-
let mut buf = Cursor::new(self.read(<$typ>::BITS as usize / 8).await?);
175-
match self.endianness {
176-
Endianness::LittleEndian => Ok(buf.$method_name::<LittleEndian>()?),
177-
Endianness::BigEndian => Ok(buf.$method_name::<BigEndian>()?),
178-
}
179-
}
180-
};
181-
}
182-
183176
impl AsyncCursor {
184177
/// Create a new AsyncCursor from a reader and endianness.
185178
pub(crate) fn new(reader: Box<dyn AsyncFileReader>, endianness: Endianness) -> Self {
@@ -196,6 +189,7 @@ impl AsyncCursor {
196189
// Initialize with default endianness and then set later
197190
let mut cursor = Self::new(reader, Default::default());
198191
let magic_bytes = cursor.read(2).await?;
192+
let magic_bytes = magic_bytes.as_ref();
199193

200194
// Should be b"II" for little endian or b"MM" for big endian
201195
if magic_bytes == Bytes::from_static(b"II") {
@@ -212,59 +206,80 @@ impl AsyncCursor {
212206
}
213207

214208
/// Consume self and return the underlying [`AsyncFileReader`].
209+
#[allow(dead_code)]
215210
pub(crate) fn into_inner(self) -> Box<dyn AsyncFileReader> {
216211
self.reader
217212
}
218213

219214
/// Read the given number of bytes, advancing the internal cursor state by the same amount.
220-
pub(crate) async fn read(&mut self, length: usize) -> Result<Bytes> {
215+
pub(crate) async fn read(&mut self, length: usize) -> Result<EndianAwareReader> {
221216
let range = self.offset as _..(self.offset + length) as _;
222217
self.offset += length;
223-
self.reader.get_bytes(range).await
218+
let bytes = self.reader.get_bytes(range).await?;
219+
Ok(EndianAwareReader {
220+
reader: bytes.reader(),
221+
endianness: self.endianness,
222+
})
224223
}
225224

226225
/// Read a u8 from the cursor, advancing the internal state by 1 byte.
227226
pub(crate) async fn read_u8(&mut self) -> Result<u8> {
228-
let buf = self.read(1).await?;
229-
Ok(Cursor::new(buf).read_u8()?)
227+
self.read(1).await?.read_u8()
230228
}
231229

232230
/// Read a i8 from the cursor, advancing the internal state by 1 byte.
233231
pub(crate) async fn read_i8(&mut self) -> Result<i8> {
234-
let buf = self.read(1).await?;
235-
Ok(Cursor::new(buf).read_i8()?)
232+
self.read(1).await?.read_i8()
233+
}
234+
235+
/// Read a u16 from the cursor, advancing the internal state by 2 bytes.
236+
pub(crate) async fn read_u16(&mut self) -> Result<u16> {
237+
self.read(2).await?.read_u16()
238+
}
239+
240+
/// Read a i16 from the cursor, advancing the internal state by 2 bytes.
241+
pub(crate) async fn read_i16(&mut self) -> Result<i16> {
242+
self.read(2).await?.read_i16()
243+
}
244+
245+
/// Read a u32 from the cursor, advancing the internal state by 4 bytes.
246+
pub(crate) async fn read_u32(&mut self) -> Result<u32> {
247+
self.read(4).await?.read_u32()
248+
}
249+
250+
/// Read a i32 from the cursor, advancing the internal state by 4 bytes.
251+
pub(crate) async fn read_i32(&mut self) -> Result<i32> {
252+
self.read(4).await?.read_i32()
253+
}
254+
255+
/// Read a u64 from the cursor, advancing the internal state by 8 bytes.
256+
pub(crate) async fn read_u64(&mut self) -> Result<u64> {
257+
self.read(8).await?.read_u64()
236258
}
237259

238-
impl_read_byteorder!(read_u16, u16);
239-
impl_read_byteorder!(read_u32, u32);
240-
impl_read_byteorder!(read_u64, u64);
241-
impl_read_byteorder!(read_i16, i16);
242-
impl_read_byteorder!(read_i32, i32);
243-
impl_read_byteorder!(read_i64, i64);
260+
/// Read a i64 from the cursor, advancing the internal state by 8 bytes.
261+
pub(crate) async fn read_i64(&mut self) -> Result<i64> {
262+
self.read(8).await?.read_i64()
263+
}
244264

245265
pub(crate) async fn read_f32(&mut self) -> Result<f32> {
246-
let mut buf = Cursor::new(self.read(4).await?);
247-
let out = match self.endianness {
248-
Endianness::LittleEndian => buf.read_f32::<LittleEndian>()?,
249-
Endianness::BigEndian => buf.read_f32::<BigEndian>()?,
250-
};
251-
Ok(out)
266+
self.read(4).await?.read_f32()
252267
}
253268

254269
pub(crate) async fn read_f64(&mut self) -> Result<f64> {
255-
let mut buf = Cursor::new(self.read(8).await?);
256-
let out = match self.endianness {
257-
Endianness::LittleEndian => buf.read_f64::<LittleEndian>()?,
258-
Endianness::BigEndian => buf.read_f64::<BigEndian>()?,
259-
};
260-
Ok(out)
270+
self.read(8).await?.read_f64()
261271
}
262272

263273
#[allow(dead_code)]
264274
pub(crate) fn reader(&self) -> &dyn AsyncFileReader {
265275
&self.reader
266276
}
267277

278+
#[allow(dead_code)]
279+
pub(crate) fn endianness(&self) -> Endianness {
280+
self.endianness
281+
}
282+
268283
/// Advance cursor position by a set amount
269284
pub(crate) fn advance(&mut self, amount: usize) {
270285
self.offset += amount;
@@ -278,3 +293,93 @@ impl AsyncCursor {
278293
self.offset
279294
}
280295
}
296+
297+
pub(crate) struct EndianAwareReader {
298+
reader: Reader<Bytes>,
299+
endianness: Endianness,
300+
}
301+
302+
impl EndianAwareReader {
303+
/// Read a u8 from the cursor, advancing the internal state by 1 byte.
304+
pub(crate) fn read_u8(&mut self) -> Result<u8> {
305+
Ok(self.reader.read_u8()?)
306+
}
307+
308+
/// Read a i8 from the cursor, advancing the internal state by 1 byte.
309+
pub(crate) fn read_i8(&mut self) -> Result<i8> {
310+
Ok(self.reader.read_i8()?)
311+
}
312+
313+
pub(crate) fn read_u16(&mut self) -> Result<u16> {
314+
match self.endianness {
315+
Endianness::LittleEndian => Ok(self.reader.read_u16::<LittleEndian>()?),
316+
Endianness::BigEndian => Ok(self.reader.read_u16::<BigEndian>()?),
317+
}
318+
}
319+
320+
pub(crate) fn read_i16(&mut self) -> Result<i16> {
321+
match self.endianness {
322+
Endianness::LittleEndian => Ok(self.reader.read_i16::<LittleEndian>()?),
323+
Endianness::BigEndian => Ok(self.reader.read_i16::<BigEndian>()?),
324+
}
325+
}
326+
327+
pub(crate) fn read_u32(&mut self) -> Result<u32> {
328+
match self.endianness {
329+
Endianness::LittleEndian => Ok(self.reader.read_u32::<LittleEndian>()?),
330+
Endianness::BigEndian => Ok(self.reader.read_u32::<BigEndian>()?),
331+
}
332+
}
333+
334+
pub(crate) fn read_i32(&mut self) -> Result<i32> {
335+
match self.endianness {
336+
Endianness::LittleEndian => Ok(self.reader.read_i32::<LittleEndian>()?),
337+
Endianness::BigEndian => Ok(self.reader.read_i32::<BigEndian>()?),
338+
}
339+
}
340+
341+
pub(crate) fn read_u64(&mut self) -> Result<u64> {
342+
match self.endianness {
343+
Endianness::LittleEndian => Ok(self.reader.read_u64::<LittleEndian>()?),
344+
Endianness::BigEndian => Ok(self.reader.read_u64::<BigEndian>()?),
345+
}
346+
}
347+
348+
pub(crate) fn read_i64(&mut self) -> Result<i64> {
349+
match self.endianness {
350+
Endianness::LittleEndian => Ok(self.reader.read_i64::<LittleEndian>()?),
351+
Endianness::BigEndian => Ok(self.reader.read_i64::<BigEndian>()?),
352+
}
353+
}
354+
355+
pub(crate) fn read_f32(&mut self) -> Result<f32> {
356+
match self.endianness {
357+
Endianness::LittleEndian => Ok(self.reader.read_f32::<LittleEndian>()?),
358+
Endianness::BigEndian => Ok(self.reader.read_f32::<BigEndian>()?),
359+
}
360+
}
361+
362+
pub(crate) fn read_f64(&mut self) -> Result<f64> {
363+
match self.endianness {
364+
Endianness::LittleEndian => Ok(self.reader.read_f64::<LittleEndian>()?),
365+
Endianness::BigEndian => Ok(self.reader.read_f64::<BigEndian>()?),
366+
}
367+
}
368+
369+
#[allow(dead_code)]
370+
pub(crate) fn into_inner(self) -> (Reader<Bytes>, Endianness) {
371+
(self.reader, self.endianness)
372+
}
373+
}
374+
375+
impl AsRef<[u8]> for EndianAwareReader {
376+
fn as_ref(&self) -> &[u8] {
377+
self.reader.get_ref().as_ref()
378+
}
379+
}
380+
381+
impl Read for EndianAwareReader {
382+
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
383+
self.reader.read(buf)
384+
}
385+
}

src/cog.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use crate::error::Result;
33
use crate::ifd::ImageFileDirectories;
44
use crate::AsyncFileReader;
55

6+
#[derive(Debug)]
67
pub struct COGReader {
78
#[allow(dead_code)]
8-
reader: Box<dyn AsyncFileReader>,
9+
cursor: AsyncCursor,
910
ifds: ImageFileDirectories,
1011
}
1112

@@ -21,8 +22,7 @@ impl COGReader {
2122

2223
let ifds = ImageFileDirectories::open(&mut cursor, first_ifd_location as usize).await?;
2324

24-
let reader = cursor.into_inner();
25-
Ok(Self { reader, ifds })
25+
Ok(Self { cursor, ifds })
2626
}
2727

2828
pub fn ifds(&self) -> &ImageFileDirectories {

0 commit comments

Comments
 (0)