openSvsFile function

Future<SvsFile?> openSvsFile(
  1. String path, {
  2. int maxConcurrency = 4,
})

Opens an SVS file at the specified path and reads its TIFF/BigTIFF header.

Supports both standard TIFF (Magic 42) and BigTIFF (Magic 43, 64-bit offsets). maxConcurrency defines the maximum number of concurrent file handles in the pool used for parallel tile reading (default is 4). For slow mechanical HDDs or resource-constrained environments, set to 1 or 2 to avoid seek thrashing. For fast SSDs/NVMe, higher values (e.g. 4 to 8) maximize read throughput. Returns an SvsFile instance if the file is a valid SVS/TIFF file, or null if opening or validation fails.

Implementation

Future<SvsFile?> openSvsFile(String path, {int maxConcurrency = 4}) async {
  final file = File(path);
  if (!await file.exists()) return null;

  final raf = await file.open();
  try {
    final headerBytes = await raf.read(16);
    if (headerBytes.length < 8) {
      await raf.close();
      return null;
    }

    final bd = ByteData.sublistView(headerBytes);
    Endian endian;
    final byteOrder = String.fromCharCodes(headerBytes.sublist(0, 2));
    if (byteOrder == 'II') {
      endian = Endian.little;
    } else if (byteOrder == 'MM') {
      endian = Endian.big;
    } else {
      await raf.close();
      return null;
    }

    final magic = bd.getUint16(2, endian);
    if (magic == 42) {
      // Standard TIFF (32-bit offsets)
      final ifdOffset = bd.getUint32(4, endian);
      return SvsFile(raf, endian, ifdOffset, false, path, maxConcurrency);
    } else if (magic == 43) {
      // BigTIFF (64-bit offsets)
      if (headerBytes.length < 16) {
        await raf.close();
        return null;
      }
      final offsetByteSize = bd.getUint16(4, endian);
      final unused = bd.getUint16(6, endian);
      if (offsetByteSize != 8 || unused != 0) {
        await raf.close();
        return null;
      }
      final ifdOffset = bd.getUint64(8, endian);
      return SvsFile(raf, endian, ifdOffset, true, path, maxConcurrency);
    } else {
      await raf.close();
      return null;
    }
  } catch (e) {
    await raf.close();
    return null;
  }
}