IFE resolution: read the Iris scale-relative convention, no vendor override (#81)
IFE Magnification/MPP read the Iris scale-relative convention — verified against the
Iris-Codec encoder source, with no per-vendor override (#81 follow-up).
Fixed
- IFE
Metadata.Magnification/Metadata.MPPread the Iris resolution convention.
v0.54.0 mis-framed the root cause as "an encoder stamped a downsampled level's value
into the header" and special-casedaperio.AppMag/aperio.MPP. The actual Iris
convention — confirmed against the Iris-Codec encoder source
(Iris-Codec/src/IrisCodecEncoder.cpp,READ_OPENSLIDE_METADATA, which writes
micronsPerPixel = MPP_finest × max_scaleandmagnification = objective / max_scale,
front().downsample == max_scale) — is that theMETADATAheader stores
scale-relative quantities:magnificationis a coefficient andmicronsPerPixel
is anchored at the lowest-resolution layer. opentile-go inverts that:
Magnification = magnification × max_scaleandMPP = micronsPerPixel / max_scale
(max_scale= the finest layer's scale). The raw header values stay in
MagnificationFromHeader/MPPFromHeader.
Removed
- The
aperio.*override is gone. v0.54.0/first-cut-v0.54.1 special-cased the
source scanner'saperio.AppMag/aperio.MPP(orImageDescriptionbanner) to
"correct" a header that disagreed with the convention. That existed solely to prop up
one fixture (cervix_2x_jpeg.iris) whose header is stale — computed for a 4-layer
max_scale = 64pyramid but the file ships a 9-layermax_scale = 256ladder, so the
convention at its realmax_scale = 256would give an impossible160×. The
convention is the spec; a disagreeing header is a bug in the file, so the override
(aperioL0Resolution+ helpers) was removed and the fixture's header is corrected at
the source instead (see Added).aperio.*values remain available via
Properties["iris.aperio.*"].
Added
cmd/ifefixheader— a small utility that rewrites an.irisMETADATA header's
scale-relative resolution fields to be conformant with the file's own pyramid. It
readsmax_scalefromLAYER_EXTENTSand writes
magnification = appmag / max_scale,micronsPerPixel = mpp × max_scalefrom the
supplied true L0 objective / MPP. Used to fix the publiccervix_2x_jpeg.iris
fixture's stale header:go run ./cmd/ifefixheader -appmag 40 -mpp 0.262968 ….
Documentation
docs/formats/ife.md— documents the reversed Iris layer numbering, the
scale-relative header semantics, the× / ÷ max_scalederivation (cited to the
encoder source), the no-override stance +cmd/ifefixheaderworkflow, and corrects an
earlier "cervix is a 2× downsample of a 253,952 × 177,152 original" note (the embedded
Aperio metadata reports native126940×88416@0.262968= the finest layer). The
public425248_JPEG/AVIF.irisreferences carry no resolution metadata at all. The
localsample_files/ife/ife-format-spec-for-opentile-go.mdreference gains a matching
note.