Skip to content

Commit 5c1b253

Browse files
committed
Tile request multiplexing
1 parent 1e3b388 commit 5c1b253

File tree

3 files changed

+45
-12
lines changed

3 files changed

+45
-12
lines changed

src/cog.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ mod test {
6767

6868
#[tokio::test]
6969
async fn tmp() {
70-
let folder = "/Users/kyle/github/developmentseed/aiocogeo-rs/";
70+
let folder = "/Users/kyle/github/developmentseed/async-tiff/";
7171
let path = object_store::path::Path::parse("m_4007307_sw_18_060_20220803.tif").unwrap();
7272
let store = Arc::new(LocalFileSystem::new_with_prefix(folder).unwrap());
7373
let reader = ObjectReader::new(store, path);
@@ -81,8 +81,7 @@ mod test {
8181

8282
#[test]
8383
fn tmp_tiff_example() {
84-
let path =
85-
"/Users/kyle/github/developmentseed/aiocogeo-rs/m_4007307_sw_18_060_20220803.tif";
84+
let path = "/Users/kyle/github/developmentseed/async-tiff/m_4007307_sw_18_060_20220803.tif";
8685
let reader = std::fs::File::open(path).unwrap();
8786
let mut decoder = tiff::decoder::Decoder::new(BufReader::new(reader))
8887
.unwrap()

src/geo/affine.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#[derive(Debug)]
12
pub struct AffineTransform(f64, f64, f64, f64, f64, f64);
23

34
impl AffineTransform {

src/ifd.rs

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::collections::HashMap;
22
use std::io::{Cursor, Read};
3+
use std::ops::Range;
34

45
use byteorder::{LittleEndian, ReadBytesExt};
56
use bytes::{Buf, Bytes};
@@ -528,20 +529,22 @@ impl ImageFileDirectory {
528529
}
529530
}
530531

532+
fn get_tile_byte_range(&self, x: usize, y: usize) -> Range<usize> {
533+
let idx = (y * self.tile_count().0) + x;
534+
let offset = self.tile_offsets[idx] as usize;
535+
// TODO: aiocogeo has a -1 here, but I think that was in error
536+
let byte_count = self.tile_byte_counts[idx] as usize;
537+
offset..offset + byte_count
538+
}
539+
531540
pub async fn get_tile(
532541
&self,
533542
x: usize,
534543
y: usize,
535-
reader: Box<dyn AsyncFileReader>,
544+
mut reader: Box<dyn AsyncFileReader>,
536545
) -> Result<Bytes> {
537-
let mut cursor = AsyncCursor::new(reader);
538-
539-
let idx = (y * self.tile_count().0) + x;
540-
let offset = self.tile_offsets[idx] as usize;
541-
// TODO: aiocogeo has a -1 here, but I think that was in error
542-
let byte_count = self.tile_byte_counts[idx] as usize;
543-
let range = offset..offset + byte_count;
544-
let buf = cursor.get_range(range).await?;
546+
let range = self.get_tile_byte_range(x, y);
547+
let buf = reader.get_bytes(range).await?;
545548
decode_tile(
546549
buf,
547550
self.photometric_interpretation,
@@ -550,6 +553,36 @@ impl ImageFileDirectory {
550553
)
551554
}
552555

556+
pub async fn get_tiles(
557+
&self,
558+
x: &[usize],
559+
y: &[usize],
560+
mut reader: Box<dyn AsyncFileReader>,
561+
) -> Result<Vec<Bytes>> {
562+
// 1: Get all the byte ranges for all tiles
563+
let byte_ranges: Vec<_> = x
564+
.iter()
565+
.zip(y)
566+
.map(|(x, y)| self.get_tile_byte_range(*x, *y))
567+
.collect();
568+
569+
// 2: Fetch using `get_ranges
570+
let buffers = reader.get_byte_ranges(byte_ranges).await?;
571+
572+
// 3: Decode tiles (in the future, separate API)
573+
let mut decoded_tiles = vec![];
574+
for buf in buffers {
575+
let decoded = decode_tile(
576+
buf,
577+
self.photometric_interpretation,
578+
self.compression,
579+
self.jpeg_tables.as_ref(),
580+
)?;
581+
decoded_tiles.push(decoded);
582+
}
583+
Ok(decoded_tiles)
584+
}
585+
553586
/// Return the number of x/y tiles in the IFD
554587
pub fn tile_count(&self) -> (usize, usize) {
555588
let x_count = (self.image_width as f64 / self.tile_width as f64).ceil();

0 commit comments

Comments
 (0)