openSvsFile function
Opens an SVS, Hamamatsu NDPI, VMS or VMU file at the specified path.
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.
virtualTiling controls whether to aggregate micro-tiles in Hamamatsu slides.
virtualTileWidth and virtualTileHeight configure virtual tile dimensions (e.g. 256x256 or 512x512).
mcuRowsPerTile configures the number of MCU rows per virtual tile (e.g. 32 or 64).
Returns an SvsFile instance if the file is valid, or null if opening or validation fails.
Implementation
Future<SvsFile?> openSvsFile(
String path, {
int maxConcurrency = 4,
bool? virtualTiling,
int? virtualTileWidth,
int? virtualTileHeight,
int? mcuRowsPerTile,
}) 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 {
return await openHamamatsuSet(
raf,
path,
maxConcurrency,
virtualTiling: virtualTiling,
virtualTileWidth: virtualTileWidth,
virtualTileHeight: virtualTileHeight,
mcuRowsPerTile: mcuRowsPerTile,
);
}
final magic = bd.getUint16(2, endian);
if (magic == 42) {
// Standard TIFF (32-bit offsets)
final ifdOffset = bd.getUint32(4, endian);
final ndpiOffset = headerBytes.length >= 12 ? bd.getUint64(4, endian) : 0;
if (await isNdpi(raf, ndpiOffset, endian)) {
return await openNdpi(
raf,
path,
endian,
ndpiOffset,
maxConcurrency,
virtualTiling: virtualTiling,
virtualTileWidth: virtualTileWidth,
virtualTileHeight: virtualTileHeight,
mcuRowsPerTile: mcuRowsPerTile,
);
}
if (ifdOffset != 0) {
final length = await raf.length();
if (ifdOffset > length - 2) throw const FormatException('Invalid TIFF IFD offset');
await raf.setPosition(ifdOffset);
final countBytes = await raf.read(2);
if (countBytes.length != 2) throw const FormatException('Truncated TIFF IFD');
final count = ByteData.sublistView(countBytes).getUint16(0, endian);
if (ifdOffset + 2 + count * 12 + 4 > length) {
throw const FormatException('Truncated TIFF directory');
}
}
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;
}
}