images
Decode scan files to frames and build the scan-image cache layers.
Datasource-free: DICOM/Zeiss frames come from dicom_extract, native vendor
formats (Heidelberg/Topcon/Zeiss) from the vendored private_eye parser. The
frames layer is a ZIP containing frame_NNN.webp plus a manifest.json; the
masks layer is a ZIP of per-class PNGs plus its own index. assemble_archive
stitches cache layers into the archive served to a caller.
Module
Functions
assemble_archive
def assemble_archive( frames_zip: bytes, *, mask_zip: bytes | None = None, segmentations_json: str | None = None,) ‑> bytes:Stitch cache layers into the archive served to the caller.
Members are copied rather than re-encoded: every layer is ZIP_STORED and
its contents (WebP, PNG, JSON) are already in final form.
A layer's own index (masks_index.json) is deliberately not copied — it is
internal to the layer, and the caller receives the merged
segmentations.json instead.
Arguments
frames_zip: The frames layer value.mask_zip: The masks layer value, or None when masks were not requested.segmentations_json: The merged overlay index, or None when no overlay was requested or none could be built.
Returns
The application/zip archive bytes. The frames layer's own bytes when
there is no overlay to attach, rather than a copy of them.
decode_scan
def decode_scan( path: str, *, modality: str | None = None, laterality: str | None = None,) ‑> DecodedScan:Decode a scan file to an ordered list of frames.
Arguments
path: Absolute path to the scan file.modality: Optional series selector for multi-series files (e.g..e2e).laterality: Optional "L"/"R" series selector.
Returns
The selected series' ordered FrameData and its acquisition datetime.
Raises
UnsupportedScanError: If the file type is unknown or cannot be decoded.
read_frame_dims
def read_frame_dims( frames_zip: bytes,) ‑> list[FrameDims]:Return each frame's dimensions from a frames cache layer.
Arguments
frames_zip: A layer value produced byrender_frames_zip.
Returns
One FrameDims per frame, in serving order.
Raises
UnsupportedScanError: The layer's manifest is missing or malformed, which means the entry cannot be used to build overlays.
render_frames_zip
def render_frames_zip( frames: list[FrameData], *, width: int, quality: int, acquisition_datetime: datetime | None = None,) ‑> bytes:Render frames to the frames cache layer: scaled WebP plus a manifest.
Arguments
frames: The decoded frames.width: Target output width (px), clamped per-frame to source width.quality: WebP quality 0-100.acquisition_datetime: When the series was acquired, fromDecodedScan.acquisition_datetime. Written as an explicitnullwhenNone, so a consumer can tell "this scan states no date" from "this archive predates the field".
Returns
The layer's ZIP bytes, holding frame_NNN.webp per frame and
manifest.json.
render_masks_zip
def render_masks_zip(segmentations: SegmentationPayload) ‑> bytes:Render the masks cache layer: one PNG per class mask, plus its index.
Arguments
segmentations: The overlay payload the masks were built into.
Returns The layer's ZIP bytes.
Classes
DecodedScan
class DecodedScan(frames: list[FrameData], acquisition_datetime: datetime | None):One decoded series: its frames plus the metadata that describes the series.
Series-level metadata is held here rather than on FrameData so a value that
describes the whole acquisition cannot be read as a per-frame one.
Arguments
frames: The series' frames, in serving order.acquisition_datetime: When the series was acquired, orNonewhen the file states nothing. Tz-aware only where the source stated an offset (a DICOMAcquisitionDateTimecan; a date/time pair cannot).
FrameData
class FrameData( array: NDArray[Any], modality: OphthalmologyModalityType, series_modality: str | None, laterality: str | None, source_width: int, source_height: int,):One decoded scan frame plus the metadata the manifest needs.
Arguments
array: The frame pixel data (HxW grayscale or HxWxC colour).modality: The frame's modality in the SDK's vocabulary —"OCT","SLO", orNonewhen the source states none (an absent DICOM acquisition-device-type tag) or states something that is neither.series_modality: The source's own, finer modality label, kept because the normalisation above is lossy: which SLO channel a frame came from, and what a non-OCT/SLO series actually is, are only legible here. The lower-casedprivate_eyemodality description ("slo - red","colour photo");Noneon the DICOM path, which has no per-series label to report.laterality: The series' detected laterality ("L"/"R"/"B"/"U"), or None when unknown.source_width: The frame's native width in pixels.source_height: The frame's native height in pixels.
Variables
- static
array : numpy.ndarray[typing.Any, numpy.dtype[typing.Any]]
- static
laterality : str | None
- static
modality : Literal['OCT', 'SLO', None]
- static
series_modality : str | None
- static
source_height : int
- static
source_width : int
FrameDims
class FrameDims( index: int, filename: str, modality: str, laterality: str | None, source_width: int, source_height: int, width: int, height: int,):A served frame's identity and dimensions, as recorded in the manifest.
Overlay building needs each frame's native and served dimensions but none
of its pixels, so it consumes this rather than FrameData. Reading these
back out of a cached frames archive is what lets a warm frames layer serve
a cold overlay build without decoding the scan again.
Arguments
index: The frame's index in serving order.filename: The frame's filename within the archive.modality: The frame's modality (e.g. "oct", "slo"), lower-cased.laterality: "L"/"R" if known, else None.source_width: The frame's native width in pixels.source_height: The frame's native height in pixels.width: The width the frame was encoded at.height: The height the frame was encoded at.
Variables
- static
filename : str
- static
height : int
- static
index : int
- static
laterality : str | None
- static
modality : str
- static
source_height : int
- static
source_width : int
- static
width : int
UnsupportedScanError
class UnsupportedScanError(*args, **kwargs):Raised when a scan file cannot be decoded to image frames.