11use std:: collections:: HashMap ;
22use std:: io:: { Cursor , Read } ;
3+ use std:: ops:: Range ;
34
45use byteorder:: { LittleEndian , ReadBytesExt } ;
56use 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,38 @@ 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+ 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+
553588 /// Return the number of x/y tiles in the IFD
554589 pub fn tile_count ( & self ) -> ( usize , usize ) {
555590 let x_count = ( self . image_width as f64 / self . tile_width as f64 ) . ceil ( ) ;
0 commit comments