1
1
use std:: collections:: HashMap ;
2
2
use std:: io:: { Cursor , Read } ;
3
+ use std:: ops:: Range ;
3
4
4
5
use byteorder:: { LittleEndian , ReadBytesExt } ;
5
6
use bytes:: { Buf , Bytes } ;
@@ -528,20 +529,22 @@ impl ImageFileDirectory {
528
529
}
529
530
}
530
531
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
+
531
540
pub async fn get_tile (
532
541
& self ,
533
542
x : usize ,
534
543
y : usize ,
535
- reader : Box < dyn AsyncFileReader > ,
544
+ mut reader : Box < dyn AsyncFileReader > ,
536
545
) -> 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 ?;
545
548
decode_tile (
546
549
buf,
547
550
self . photometric_interpretation ,
@@ -550,6 +553,38 @@ impl ImageFileDirectory {
550
553
)
551
554
}
552
555
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
+ assert_eq ! ( x. len( ) , y. len( ) , "x and y should have same len" ) ;
563
+
564
+ // 1: Get all the byte ranges for all tiles
565
+ let byte_ranges: Vec < _ > = x
566
+ . iter ( )
567
+ . zip ( y)
568
+ . map ( |( x, y) | self . get_tile_byte_range ( * x, * y) )
569
+ . collect ( ) ;
570
+
571
+ // 2: Fetch using `get_ranges
572
+ let buffers = reader. get_byte_ranges ( byte_ranges) . await ?;
573
+
574
+ // 3: Decode tiles (in the future, separate API)
575
+ let mut decoded_tiles = vec ! [ ] ;
576
+ for buf in buffers {
577
+ let decoded = decode_tile (
578
+ buf,
579
+ self . photometric_interpretation ,
580
+ self . compression ,
581
+ self . jpeg_tables . as_ref ( ) ,
582
+ ) ?;
583
+ decoded_tiles. push ( decoded) ;
584
+ }
585
+ Ok ( decoded_tiles)
586
+ }
587
+
553
588
/// Return the number of x/y tiles in the IFD
554
589
pub fn tile_count ( & self ) -> ( usize , usize ) {
555
590
let x_count = ( self . image_width as f64 / self . tile_width as f64 ) . ceil ( ) ;
0 commit comments