decodeAsync static method
Decodes from a TiffAsyncByteSource — storage that can only be read
asynchronously, such as a browser File/Blob or an HTTP server
answering Range requests (see package:tiff/tiff_web.dart).
Only the header and IFDs are read here, in a few reads of at least 64 KiB each. Pixel data is then read per call — and only the strips/tiles that call needs — by the pages' async methods (TiffImage.decodeRegionAsync, TiffImage.decodeRegionRgba8Async, TiffImage.readTileJpegAsync, ...), so the file can be far larger than memory. Their synchronous counterparts throw a TiffException on these pages, since there is nothing loaded for them to read.
Implementation
static Future<TiffDocument> decodeAsync(TiffAsyncByteSource source) async {
const readAhead = 64 * 1024;
const carriedBytes = 1024 * 1024;
final prefetch = PrefetchByteSource(source);
final session = PrefetchSession();
final header = await prefetch.run(
[(0, 16)],
() => TiffHeader.parse(prefetch),
session: session,
readAhead: readAhead,
);
final reader = TiffByteReader(prefetch, header.byteOrder.endian);
final images = <TiffImage>[];
var nextIfdOffset = header.firstIfdOffset;
while (nextIfdOffset != 0) {
// Consecutive IFDs are often close together, so the latest reads are
// kept for the next page; older ones are dropped to bound memory on a
// file with thousands of pages.
session.keepRecent(carriedBytes);
final offset = nextIfdOffset;
final (image, next) = await prefetch.run(
const [],
() => _readPage(reader, offset, header.isBigTiff),
session: session,
readAhead: readAhead,
);
images.add(image);
nextIfdOffset = next;
}
return _document(images, header, prefetch);
}