Skip to content

1.3.1 — Scan Type resolution + parser hardening

Choose a tag to compare

@aagedal aagedal released this 23 Apr 23:40
· 143 commits to main since this release

Added

  • VideoScanType + scanType / scanOrder helpers on VideoMetadata
    and VideoStream — derive MediaInfo-style "Scan Type" (Progressive /
    Interlaced / Unknown) and "Scan Order" (TFF / BFF) UI columns without
    enumerating every VideoFieldOrder case. fieldOrder still encodes
    both values in one enum and remains the ground truth.
  • MXF FieldDominance parsing (0x3212) — SMPTE 377-1 §G.2.51 tag now
    resolves TFF vs BFF for interlaced essence descriptors that carry it.

Fixed

  • fieldOrder now resolves for every supported container. Previously,
    MP4 / MOV without a fiel atom, Matroska / WebM without FlagInterlaced,
    and MXF with FrameLayout=1 (separated fields) all returned nil or
    .unknown, leaving downstream "Scan Type" UIs blank for the majority
    of real-world files. New behaviour:
    • MP4 / MOV: absence of fiel defaults to .progressive (matches
      ffmpeg's mov demuxer and iPhone / camera convention).
    • Matroska / WebM: absence of FlagInterlaced / FieldOrder
      defaults to .progressive for video essence (cover-art MJPEG tracks
      keep nil). VP8 / VP9 / AV1 have no interlaced coding mode; HEVC /
      H.264 writers only emit these elements for genuinely interlaced
      source.
    • MXF: FrameLayout=1 (separated fields) and FrameLayout=3
      (mixed) now resolve to .topFieldFirst (the broadcast convention and
      what MediaInfo / ffprobe report for untagged interlaced essence).
      FieldDominance=2 overrides to .bottomFieldFirst. Previously these
      returned .unknown.

Security

  • Int-overflow hardening across binary parsers — malformed input can
    no longer trap the process via arithmetic overflow on 32-bit lengths,
    offsets, or sub-block sizes. Affected paths: ICC profile, IPTC IIM,
    MPF, XMP, PNG, PSD, and the shared Data slicing helpers.
  • MP4 chapter allocation cap — chpl (Nero) and udta > chap
    readers refuse chapter counts that would allocate more than a sane
    ceiling, stopping a malformed count field from triggering
    gigabyte-scale Array.reserveCapacity on import.
  • GIF sub-block overrun fix — application-extension sub-block reader
    no longer walks past the declared data length when a truncated stream
    omits its terminator.
  • Video-read memory cap — the MKV / WebM front-end limits aggregate
    bytes buffered for a single import, keeping multi-file scans (batch
    imports, folder-watch) well under 1 GB resident even when fed
    unusually large Matroska clusters.
  • CBOR decoder overflow guard — string and byte-string readers
    reject lengths that would overflow Int, preventing a crafted C2PA
    manifest from crashing the CBOR front-end.
  • zlib deflate-bomb cap — PNG / ICC / XMP inflate paths stop
    producing output once a generous decompressed-size ceiling is
    reached, so a tiny deflate stream can no longer expand to gigabytes
    and exhaust memory.

Validation

Audited against a 22-file video fixture set (H.264, HEVC, VVC, AV1,
VP8/VP9, ProRes, ProRes RAW, APV, AVC-Intra, MXF broadcast):

  • All 20 modern MP4 / MOV / MKV / WebM files now resolve Scan Type to
    Progressive (previously nil for 6 of them).
  • Both broadcast MXF files (AVC-Intra 50) now resolve to Scan Type =
    Interlaced, Scan Order = TFF — matches MediaInfo output.