Skip to content

Releases: OxideAV/oxideav-iff

v0.0.9

15 Jun 05:10
27b95df

Choose a tag to compare

Added

  • (aiff) fold oxideav-aiff into oxideav-iff::aiff

Other

  • add SSND (Sound Data) chunk writer — §5.0 block-aligning body encoder
  • frame_chunk framing helper + write_fver_chunk (FVER) writer
  • ANIM op-1 (XOR ILBM mode) full-frame decode + encode
  • COMM chunk writer + public 80-bit extended sample-rate encoder (§2.1/§3.2)
  • ANIM op-4 (Generalized short/long Delta) decode + encode
  • op-2/op-3 Long/Short Delta mode decode + encode (spec §1.2.2-§1.2.3, §2.2.1)
  • EA IFF 85 §5 LIST/CAT group-children walker
  • surface chunk::ReservedId §3 reserved-ckID classifier
  • surface EA IFF 85 §3 universally-reserved ckID classifier
  • generic top-level group probe primitive (FORM/LIST/CAT envelope)
  • typed PCHG header surface + derived-hint consistency check
  • typed Sham row-palette accessors mirroring Pchg::palette_at_line
  • drop release-plz.toml — use release-plz defaults across the workspace
  • cargo-fuzz harness — aiff_decode + anim_decode + pchg_parse
  • §14 chunk-precedence surface (ChunkClass + Form helpers)
  • structured SPRT (sprite-precedence) chunk surfacing
  • structured DEST (destination-merge) chunk surfacing
  • structured SAXL (Sound Accelerator) chunk surfacing
  • structured §13.0 text chunks (NAME / AUTH / (c) / ANNO)
  • structured MIDI (MIDI Data) chunk surfacing
  • ANIM op-7 encoder + AIFF COMT/AESD/APPL surfacing + MARK/INST write
  • structured INST (Instrument) chunk parsing
  • structured MARK (Marker) chunk parsing

Added

  • AIFF/AIFF-C SSND (Sound Data) chunk writer
    (docs/audio/aiff/aiff-c.txt §5.0). aiff::write_sound_data(&SoundData)
    emits the §5.0 SoundDataChunk data portion — offset (u32) +
    blockSize (u32) + offset bytes of block-alignment padding +
    soundData — completing the AIFF round-trip story: SSND was the
    one read-path chunk class (Form::sound) without a body writer. Per
    §5.0 "offset determines where the first sample frame in the soundData
    starts", a non-zero offset inserts that many zero alignment bytes
    before the samples (the §5.0 "Block-Aligning Sound Data" mechanism),
    so the result round-trips through the SSND reader, whose samples
    slice begins at byte 8 + offset. The common case
    (§5.0 "Applications that don't care about block alignment should set
    blockSize and offset to zero") emits eight zero header bytes followed
    by the raw samples. Like every other aiff::write_* helper it emits a
    chunk body; pair it with aiff::frame_chunk(b"SSND", body) for the
    full header + odd-length pad. Covered by 4 new unit tests in
    src/aiff/form.rs (zero-offset layout, full-FORM parse round-trip,
    non-zero-offset alignment-gap round-trip, and a frame_chunk
    ChunkIter framing round-trip).

  • AIFF/AIFF-C frame_chunk framing helper + write_fver_chunk
    (FVER) writer
    (docs/audio/aiff/aiff-aifc-format.md §1 / §3.1).
    Every per-chunk aiff::write_* helper emits a chunk body and
    leaves the 8-byte ckID + ckSize header and the odd-length pad byte
    to the caller. aiff::frame_chunk(id, body) factors that into one
    place — the exact inverse of aiff::ChunkIter: it prepends the
    4-byte ckID + big-endian int32 ckSize header and appends a
    single 0x00 pad byte iff the body length is odd (the §1 16-bit
    alignment rule; the pad is not counted in ckSize), returning
    AiffError::OversizedChunk when the body exceeds u32::MAX. This
    closes the last write-side gap: FVER was the one read-path chunk
    class (Form::fver_timestamp) without a body writer.
    aiff::write_fver_chunk(timestamp) emits the 4-byte big-endian
    timestamp, and aiff::AIFC_VERSION_1 (0xA280_5140) is the §3.1
    AIFF-C v1 spec timestamp every AIFC file carries. Covered by 6 new
    unit tests in src/aiff/chunk.rs (even/odd/empty framing, pad
    transparency through a frame_chunkChunkIter round-trip, and an
    FVER framed round-trip).

  • ANIM op-1 (XOR ILBM mode) decode + encode for the full-frame
    case (docs/image/iff/anim.txt §1.2.1 / §1.3 / §2.1). op-1 is the
    original ANIM compression method: the encoder XORs every byte of the
    new frame against the previous frame's planar bitmap, producing a
    bitmap that is 0 where the frames agreed, and stores it
    run-length-encoded (anim::encode_op1_body / anim::encode_anim_op1,
    honouring BMHD.compression for ByteRun1 or uncompressed BODY). The
    decoder (apply_op1, wired into parse_anim via ANHD.operation = 1) expands the BODY and XORs it into the running planar state — a
    zero byte in the XOR bitmap leaves the running state unchanged per
    §1.3. The §2.1 "XOR mode only" mask / w / h / x / y ANHD
    fields narrow the BODY to a plane subset / sub-rectangle "to
    eliminate unnecessary un-changed data"; the staged spec gives no wire
    description of that partial-BODY layout, so a plane-masked or
    partial-rectangle ANHD is rejected with Error::unsupported and the
    full-frame case (all planes, whole bitmap) is decoded. Covered by
    tests/anim_op1.rs (8 tests: ByteRun1 + uncompressed round-trips,
    sparse / 2-plane / multi-frame sequences, all-plane-mask tagging,
    no-op-XOR on identical planar buffers, partial-rectangle rejection).

  • AIFF / AIFF-C COMM chunk writer + 80-bit extended sample-rate
    encoder
    (docs/audio/aiff/aiff-aifc-format.md §2.1, §3.2). Adds
    aiff::write_common_chunk, the round-trip inverse of
    parse_common: it emits the fixed 18-byte AIFF body
    (numChannels / numSampleFrames / sampleSize / 10-byte
    sampleRate) and, when the CommonChunk carries a
    compression_type, the AIFF-C extension — the 4-byte
    compressionType FourCC followed by the compressionName Pascal
    string padded so its total length (length byte + chars) is even per
    §3.2. A None compression name collapses to the canonical
    zero-length pstring. The writer follows the body-only convention of
    the other write_*_chunk functions (the FORM header / whole-chunk
    pad byte are the muxer's job). Backing this, the 80-bit IEEE-754
    extended encoder previously available only to the test suite was
    promoted to the public aiff::encode_extended (the exact inverse
    of decode_extended for finite normalised values) plus
    aiff::encode_sample_rate, the validating wrapper that rejects
    NaN / infinite / non-positive rates with InvalidSampleRate so a
    writer can never emit a COMM the parser would refuse. With this the
    required COMM chunk joins the existing optional-chunk writers, so
    every AIFF chunk class except the top-level FORM/SSND muxer now has
    symmetric read + write paths.

  • ANIM op-4 (Generalized short/long Delta mode) decode + encode
    (spec §1.2.4, wire format §2.2.2). Implemented from the §2.2.2
    SetDLTAshort reference routine, the only normative description of
    the op-4 wire format. The DLTA opens with 16 big-endian u32
    pointers — 8 data-list pointers then 8 op-list pointers — and these
    pointers (plus the per-op column offsets) are measured in 16-bit
    words
    , not bytes, because the reference routine performs WORD*
    pointer arithmetic (data = deltaword + deltadata[i], dest = planeptr + *ptr); this is the key behavioural difference from the
    byte-offset ops 5 / 7. Each plane's op list is a flat run of
    (offset, size) pairs terminated by 0xFFFF: offset is the
    absolute word position where the run begins (non-cumulative),
    size > 0 copies size data words one-per-row (Uniq) and
    size < 0 copies one data word to |size| rows (Same), with the
    dest stepping nw = row_bytes / word_size words per row down each
    vertical column. ANHD.bits selects the variant — bit 0
    short/long data, bit 2 separate-vs-shared info list (both
    supported), bit 5 short/long op offsets — while the XOR (bit 1) and
    horizontal (bit 4 clear) variants and any reserved high bit are
    rejected with Error::Unsupported since the spec gives them no
    separate wire format (§2.1 directs players to verify undefined bits
    are zero). parse_anim / the iff_anim demuxer now accept
    ANHD.operation = 4; the write-side surface is
    [anim::encode_anim_op4] (container-level) plus the lower-level
    [anim::encode_op4_body], both emitting the short/long-data,
    vertical, RLC, separate-info, non-XOR configuration the reference
    routine reads. Covered by tests/anim_op4.rs (10 tests:
    hand-built Same / Uniq decode in short + long data modes, word-unit
    pointer semantics, shared-info-list, unsupported-variant rejection,
    and encode→decode + full-container round-trips).

  • ANIM op-2 / op-3 (Long / Short Delta mode) decode + encode
    (spec §1.2.2 / §1.2.3, wire format §2.2.1). The DLTA opens with 8
    big-endian u32 plane pointers (0 = plane unchanged; the §2.2.1
    worked value for the first list is 32); each plane's payload is a
    list of groups whose offsets and counts are big-endian shorts and
    whose data words are longs (op 2) or shorts (op 3). A word cursor
    starts at the plane's first word; a positive offset advances the
    cursor and places one data word, a negative offset (absolute value
    = offset + 2) advances the cursor and a count short introduces that
    many contiguous data words, and 0xFFFF terminates the plane's
    list. The bitplane is addressed as the contiguous height × row_bytes byte array it occupies in memory, so op-2 long words may
    straddle row boundaries — the decoder gathers each plane into a
    contiguous buffer, applies the groups, and scatters the rows back.
    parse_anim / the iff_anim demuxer now accept ANHD.operation
    2 and 3; the new write-side surface is [anim::encode_anim_op2] /
    [anim::encode_anim_op3] (container-level, mirroring the op-5 /
    op-7 encoders) plus the lower-level [anim::encode_op23_body].
    The encoder collapses runs of ≥ 2 changed words into a
    negative-offset group per §1.2.2 ¶ "Strings of 2 or more long-words
    in a row which change can be run together", emits single-word
    groups otherwise, and bridges offsets wider than ...

Read more

v0.0.8

30 May 02:51
81d9866

Choose a tag to compare

Other

  • ANIM op-7 (Short / Long Vertical Delta) decode
  • palette-cycling step helpers + per-line PCHG palette resolver
  • 24-bit literal-RGB true-colour decode + encode
  • DRNG DPaint IV extended range cycling chunk
  • CRNG (DPaint colour-range) + CCRT (Graphicraft) chunks
  • ANIM op-5 Byte Vertical Delta encoder
  • add Demuxer::seek_to — sample-exact O(1) cursor reset

Added

  • ANIM op-7 (Short / Long Vertical Delta) decode. When a delta
    frame carries ANHD.operation = 7, the running planar state is
    patched in place by walking the DLTA chunk's 16 big-endian u32
    pointer table (8 opcode-list pointers + 8 data-list pointers, one
    pair per plane; a 0 pointer marks the plane unchanged). Per plane
    the bitplane is split into vertical columns of width data_size,
    controlled by ANHD.bits bit 0 (0 = short 2-byte items, 1 =
    long 4-byte items); column count = row_bytes / data_size. Each
    column starts with an op_count byte (0 = column unchanged)
    followed by op_count opcode bytes; the three opcode classes are
    Skip (hi bit clear, non-zero — forward the dest cursor by N rows,
    no data consumed), Uniq (hi bit set — copy byte & 0x7F data
    items literally from the data list, one per consecutive row) and
    Same (0x00 byte followed by a count byte — copy one data item
    count times to consecutive rows). Advancing one row adds
    row_bytes (NOT data_size) to the byte offset within the
    bitplane. Tested in tests/anim_op7_decode.rs (6 tests): short
    Skip + Uniq + Same exercise across all 4 columns of a 1-plane
    64×4 image, long-data (4-byte item) exercise across a 1-plane
    64×3 image, all-zero pointer table leaves state untouched,
    truncated pointer table errors, out-of-range opcode pointer
    errors, two-plane independent pointer-pair lookup. Op-7 encode +
    op-8 decode/encode remain open follow-ups.

  • ILBM palette-cycling step helpers + per-scanline PCHG resolver.
    Crng::cycle_step(palette, steps), Ccrt::cycle_step(palette, steps)
    and Drng::cycle_step(palette, steps) rotate the closed range
    ([low..=high] for CRNG, [start..=end] for CCRT,
    [min..=max] for DRNG) in place by steps ticks. Crng and
    Ccrt honour their reverse-direction flag (CRNG's FLAG_REVERSE,
    CCRT's direction < 0); DRNG cycles forward only (its wire format
    has no direction flag) and the in-tree DRNG spec material does not
    define per-tick semantics for the optional DrngTrueCell /
    DrngRegCell lists, so the cell list is left untouched and callers
    layer their own splice on top after the rotation. Each helper takes
    steps modulo the range length so feeding an accumulated tick
    counter into it is O(range) regardless of how large steps grows;
    inactive cycles, malformed ranges (low > high), ranges that extend
    past the palette tail, single-slot ranges, and steps == 0 mod range_len are all no-ops and the helper returns false to signal
    "palette unchanged." Pchg::palette_at_line(base, y) returns the
    cumulative PCHG-overridden palette at the start of scanline y by
    folding every PCHG entry whose line <= y over base; out-of-range
    register indices are skipped silently to match the parser's
    tolerance. A free palette_for_line(image, y) convenience wraps the
    Option<Pchg> plumbing so animation consumers can write a uniform
    per-row "give me the active palette" call without branching on
    whether the file carried a PCHG chunk. Tested in
    tests/ilbm_palette_cycle.rs (28 tests): forward / reverse single
    ticks against synthesised palettes, full-revolution identity, large
    modulo step counts, inactive / single-slot / inverted-range / past-
    palette no-ops, zero-step no-op, fwd-then-reverse round-trip,
    CCRT-direction-zero no-op, DRNG cell-list preservation across the
    rotation, PCHG before-first-override / mid-override / past-image-
    height resolution, PCHG out-of-range-index tolerance, and an
    end-to-end "PCHG override + CRNG rotation on top" composition test
    showing the two helpers compose without interfering.

  • ILBM 24-bit true-colour (literal-RGB) decode + encode. When
    BMHD.n_planes == 24 the BODY carries 8 red bitplanes (LSB-first),
    then 8 green, then 8 blue per scanline with no CMAP chunk, per the
    EGFF / fileformat.info §3.3.4 description of NewTek / LightWave Toaster
    IFF24 files. Both Compression::None and Compression::ByteRun1 are
    supported (per-plane-per-row, identical to the indexed planar path);
    Compression::Auto picks the shorter of the two. Masking::HasMask
    is undefined for literal-RGB and is rejected at decode/encode time;
    the HAM / EHB CAMG flags are also rejected because they describe
    6/8-plane indexed viewports. Alpha is dropped on encode (always
    0xFF on decode) — 24-bit ILBM has no transparent-colour key. New
    MuxerMode::TrueColor24 reaches the encoder through the streaming
    IlbmMuxer API; the muxer emits a CAMG-free, CMAP-free ILBM file
    with n_planes = 24. Tested in tests/ilbm_truecolor24.rs
    (12 tests): raw + ByteRun1 + Auto round-trips, Auto beats raw on a
    solid fill, no-CMAP emit, full 256-value sweep per channel,
    HasMask + n_planes=24 decode rejection, HAM/EHB + n_planes=24 encode
    rejection, alpha-dropped-to-opaque, redundant-CMAP-tolerated decode,
    indexed-encode-without-palette still rejected, end-to-end through
    the streaming muxer.

  • ilbm::Drng (DeluxePaint IV extended range cycling, variable-length
    chunk: 8-byte header min, max, rate, flags, ntrue, nregs followed
    by ntrue × DrngTrueCell (cell, r, g, b) and nregs ×
    DrngRegCell (cell, index)). A super-set of CRNG that lets the
    cycle window step through true-colour RGB samples and/or follow live
    palette registers at arbitrary positions inside [min, max].
    parse_ilbm collects every DRNG chunk into IlbmImage::drngs
    (order preserved); encode_ilbm re-emits them right after the
    CCRT block so a parse → encode is byte-stable. Accessors:
    Drng::cycles_per_second() (same rate / 16384 × 60 Hz as Crng),
    Drng::is_active(), Drng::has_true_cells() /
    Drng::has_reg_cells() (honour both the cell list and the DP_RGB
    / DP_REGS flag bits — robust against generators that set the flag
    without writing any cells), Drng::range_len(). Cell-list lengths
    are clamped to u8::MAX on encode; the parser rejects truncated
    payloads and short headers (< 8 bytes) rather than tolerating
    malformed input. Tested in tests/ilbm_drng.rs (13 tests): empty
    cell lists, true-cell-only, reg-cell-only, both lists together,
    multi-chunk order preservation, byte-stable re-encode, accessor
    corner cases (inactive, zero rate, inverted range, flag-without-
    cells), short / truncated payload rejection, and a mixed
    CRNG + CCRT + DRNG single-file round-trip.

  • ilbm::Crng (DeluxePaint colour-range cycling, 8-byte chunk:
    pad1, rate, flags, low, high) and ilbm::Ccrt (Commodore
    Graphicraft colour-cycling timing, 14-byte chunk: direction, start, end, seconds, micros, pad) parse/round-trip support.
    parse_ilbm collects every CRNG / CCRT chunk it sees into
    IlbmImage::crngs / IlbmImage::ccrts (order preserved);
    encode_ilbm re-emits them between PCHG and BODY so a parse →
    encode is byte-stable. Each struct exposes spec-derived accessors
    Crng::cycles_per_second() (rate / 16384 × 60 Hz),
    Crng::is_active(), Crng::is_reverse(), Crng::range_len();
    Ccrt::delay_seconds() (seconds + micros/1e6), Ccrt::is_active(),
    Ccrt::is_reverse(), Ccrt::range_len(). Inverted ranges
    (low > high / start > end) and out-of-spec negative timing
    components clamp to safe defaults rather than wrap. Tested in
    tests/ilbm_crng_ccrt.rs (13 tests): single-chunk round-trip,
    multi-chunk order preservation, byte-stable re-encode, inactive /
    reversed flags, short-payload rejection, mixed CRNG+CCRT,
    unknown-chunk skipping. No animation is performed; consumers
    walk image.crngs / image.ccrts to apply their own palette
    rotation.

  • anim::encode_anim_op5(frames) and anim::encode_op5_body(prev, cur, bmhd) — ANIM op-5 (Byte Vertical Delta) encoder. Walks each
    plane's columns top-to-bottom; emits skip ops (1..=0x7F rows
    unchanged), repeat ops (0x80, cnt, v for 3..=0xFF same bytes), or
    literal ops (0x80 | cnt, then cnt bytes for 1..=0x7F differing
    bytes), splitting at run-length caps. Pointer table populates only
    the plane slots that actually carry deltas; identical frames yield
    a 32-byte BODY (just the empty table). Tested in
    tests/anim_op5_encode.rs (10 tests): identical-frame trivial
    case, sparse 4×4-corner delta round-trip, sparse-delta byte-count
    beats op-0 by ≥ 20 % on 64×64, long skip-run (300 rows) crosses
    the 0x7F cap correctly, long repeat-run (300 rows) crosses the
    0xFF cap correctly, 2-bitplane indexed round-trip, 4-frame
    bouncing-dot sequence pixel-exact, encode_op5_body pointer-table
    has slot 0 = 32 + slots 1..=7 = 0 when only plane 0 dirty,
    encode_op5_body rejects > 8 colour planes with Unsupported.

  • SvxDemuxer::seek_to(stream_index, pts) — sample-exact seek across
    FORM / 8SVX bodies. 8SVX is keyframe-only pcm_s8 (Fibonacci-delta
    is decompressed at open()), so seek is a constant-time cursor
    reset over the in-memory interleaved frame buffer; the returned pts
    equals pts.clamp(0, total_frames) with no keyframe quantisation.
    Works uniformly across raw and Fibonacci-compressed bodies.
    Integration tests in tests/seek.rs cover seek-to-zero, half-second
    exact landing, past-EOF clamping, invalid stream index, and seek
    through a Fibonacci body against the demuxer-decoded reference.

v0.0.7

10 May 03:36
c29b03e

Choose a tag to compare

Other

  • round-4 — IlbmMuxer mode select + masking + ImageMagick cross-decode
  • drop stale REGISTRARS / with_all_features intra-doc links
  • drop dead linkme dep
  • round-3 — Compression::Auto RDO picker + encoder refactor
  • auto-register via oxideav_core::register! macro (linkme distributed slice)
  • round 2 — PBM, GRAB, SHAM, PCHG, HAM/EHB encode, ANIM op-0/op-5

Added

  • ilbm round-4 features:

    • IlbmMuxer::with_mode — new MuxerMode enum
      (IndexedAuto / Ham6 / Ham8 / Ehb / Pbm) lets callers
      request any of the five encoder modes through the streaming
      container API. Previously only indexed planar was reachable;
      HAM/EHB/PBM were encode_ilbm-only. The muxer auto-builds the
      correct CAMG flags + plane count + palette cap (16 / 64 / 32 /
      256) for each mode and rejects illegal combinations (e.g. PBM
      with HasMask plane).
    • IlbmMuxer::with_masking — set Masking::HasMask or
      Masking::HasTransparentColor plus the keyed transparent index
      on muxer-side encodes.
    • Indexed + PBM HasTransparentColor encode path — when
      bmhd.masking == HasTransparentColor and a source pixel's
      alpha is < 0x80, the encoder writes bmhd.transparent_color
      directly instead of nearest-palette-matching the source RGB,
      so the decoder produces alpha-0 for those indices on read.
    • 13 new tests in tests/ilbm_round4.rs: 5 mux-mode round-trips
      (HAM6 grey, HAM8 grey, HAM6 colour gradient, EHB exact, PBM
      lossless uncompressed and ByteRun1), explicit HasMask +
      HasTransparentColor encoder round-trips, PBM RLE-vs-raw
      byte-savings, mode-emits-CAMG sanity, and three optional
      ImageMagick magick convert cross-decode tests (indexed + HAM6
      • PBM, gated by OXIDEAV_IFF_MAGICK_CROSS=1, silent skip when
        the binary or its ilbmtoppm delegate is unavailable). Indexed
        ByteRun1 and PBM cross-decoded pixels are bit-exact against
        magick's output; HAM6 only checks dimensions agree.
  • ilbm round-3 features:

    • Compression::Auto — encoder-only variant. encode_ilbm tries
      both uncompressed and ByteRun1 BODY for each image and emits the
      shorter result, writing the resolved mode into BMHD. IlbmMuxer
      now defaults to Auto instead of ByteRun1. Picks ByteRun1 for
      solid-colour / gradient images (typical >50 % savings) and raw for
      fully-random bitplane data.
    • pack_body_resolving internal helper — returns (Vec<u8>, Compression)
      so the BMHD compression byte always matches the actual encoding.
    • All BODY-encoder branches (indexed, ehb, ham, pbm) refactored
      into a planar-row builder + a resolving packer so Auto propagates
      through every encode path.
    • 8 new tests in tests/ilbm_round3.rs: Auto selects RLE for solid
      colour, Auto selects raw for pseudo-random data, HAM6/HAM8/EHB
      self-roundtrip under Auto compression, byte-savings sanity check,
      CAMG emission guard, IlbmMuxer end-to-end with Auto.
  • ilbm round-2 features:

    • PBM chunky variant (FORM / PBM ) — DPaint II / Brilliance
      8-bit-per-pixel sibling of ILBM. Read + write under the
      iff_ilbm container with uncompressed and ByteRun1 BODY.
    • GRAB chunk — mouse-pointer hotspot (i16 x, i16 y).
      Round-trip via IlbmImage::grab.
    • SHAM — Sliced HAM, one 16-entry RGB444 palette per
      scanline. The decoder applies the row's palette to HAM6
      op-0b00 (palette lookup); the encoder honours per-row
      palette state when quantising HAM6 BODY.
    • PCHG — Sebastiano Vigna's palette-change list. Small format
      parsed into per-line PchgLine overrides; both small and big
      formats round-trip the original raw bytes for byte-exact
      encoder output. The indexed encoder honours per-row palette
      state when quantising the BODY.
    • HAM6 / HAM8 encode — per-row state-machine encoder picks
      the cheapest of (palette lookup, modify-R, modify-G, modify-B)
      against the running channel state by squared distance.
    • EHB encode — quantise against the 64-entry expanded
      palette, emit 6 bitplanes regardless of input palette length.
  • anim module: read-only support for FORM / ANIM (DPaint III /
    Aegis Animator multi-frame container). Implements ANHD op 0
    (literal full BODY) and op 5 (Byte Vertical Delta). Op-0 muxer
    helper encode_anim_op0 available for round-trip testing.

  • New container registration "iff_anim" with .anim extension and
    a FORM....ANIM probe; demuxer emits one keyframe packet per
    decoded frame through a rawvideo / Rgba stream.

v0.0.6

05 May 08:38

Choose a tag to compare

Other

  • add FORM/ILBM read + round-trip support
  • replace never-match regex with semver_check = false
  • migrate to centralized OxideAV/.github reusable workflows
  • pin release-plz to patch-only bumps

Added

  • ilbm module: read/round-trip support for FORM/ILBM (Amiga
    InterLeaved BitMap, 1986 Jerry Morrison spec). BMHD / CMAP / CAMG /
    BODY chunks; uncompressed and ByteRun1 (PackBits) BODY; 1..=8
    colour bitplanes; EHB (32→64-entry palette mirroring); HAM6 and HAM8
    with running-state channel modify ops; Masking::HasMask plane and
    Masking::HasTransparentColor alpha. Public API:
    parse_ilbm / encode_ilbm / IlbmImage / Bmhd / Camg /
    byterun1_{decode,encode}_row / expand_ham_row /
    expand_ehb_palette.
  • New container registration "iff_ilbm" with .ilbm / .lbm
    extensions and a FORM....ILBM probe; demuxer emits one keyframe
    packet of RGBA pixels through a rawvideo stream.

v0.0.5

25 Apr 06:42
4933921

Choose a tag to compare

Other

  • drop oxideav-codec/oxideav-container shims, import from oxideav-core

v0.0.4

19 Apr 17:54
23dfd66

Choose a tag to compare

Other

  • bump oxideav-container dep to "0.1"
  • drop Cargo.lock — this crate is a library
  • bump oxideav-core / oxideav-codec dep examples to "0.1"
  • bump to oxideav-core 0.1.1 + codec 0.1.1
  • bump oxideav-core + oxideav-codec deps to "0.1"
  • thread &dyn CodecResolver through open()
  • iff / 8svx: round-trip (c) copyright chunk, rewrite README

v0.0.3

17 Apr 18:14

Choose a tag to compare

chore: Release package oxideav-iff version 0.0.3