Releases: OxideAV/oxideav-id3
Releases · OxideAV/oxideav-id3
v0.0.6
Other
- TKEY initial-key typed accessor (spec §4.2.1 / §4.2.3)
- ID3v2.2 write support — frame-id demotion + 6-byte header + PIC layout (spec id3v2-00 §3.2/§4.15)
- typed TFLT file-type accessor file_type() + FileType enum
- typed language accessor + Language enum for COMM/USLT/USER/SYLT (spec v2.3/v2.4 structure §3)
- typed TMED media-type accessor + MediaType enum (spec v2.3 §4.6.3 / v2.4 §4.2.3)
- complete ID3v2.2.0 §4 frame-table read support + §3.1 compression-bit fix
- add the compression dimension to the write-options matrix
- frame-level zlib compression both directions + v2.3 format-flag additions (spec v2.3 §3.3 / v2.4 §4.1.2)
- typed TCON content-type accessor + ContentType enum (v2.3 §4.2.1 / v2.4 §4.2.3)
- typed SYTC tempo accessor + SytcTempo enum (spec v2.4 §4.7)
- drop release-plz.toml — use release-plz defaults across the workspace
- typed ETCO event-type accessor (spec v2.3 §4.6 / v2.4 §4.5)
- Add typed Equ2Interpolation accessor for EQU2 interpolation method
- typed RVA2 channel_type accessor (spec v2.4 §4.11)
- typed SYLT content-type + COMR received-as accessors (spec §4.9 / §4.24)
- surface v2.4 §4.2 text frames in to_key_value_pairs mapping
- typed TIPL/TMCL/IPLS pair-list accessors (spec §4.2.2)
- Round 209: Criterion bench harness for parse/write hot paths
- surface v2.4 extended-header is_update + restrictions sub-fields
- structural IPLS involved-people-list frame (spec v2.3 §4.4)
- structural EQUA equalisation frame (spec v2.3 §4.13)
- structural RVAD relative volume adjustment frame (spec v2.3 §4.12)
- Add structured RVRB reverb frame (spec v2.3 §4.13 / v2.4 §4.13)
- structural MLLT MPEG location lookup table frame
- ID3v2.4 footer emission + parse validation (spec §3.4)
- cover extended-header CRC × unsync combinations
- extended-header CRC-32 verification + emission (spec §3.2)
- drop enumerated reader names from fuzz.yml comment
- daily CI workflow + curated ID3 seed corpus for parse target
- writer-side unsynchronisation (WholeTag + v2.4 PerFrame)
- cargo-fuzz target driving panic-freedom over the ID3 parser
- typed TimestampUnit accessor for ETCO/SYTC/SYLT/POSS
- add ASPI audio seek point index frame (v2.4 §4.30)
- add ENCR encryption method registration frame
- add GRID group identification registration frame
- structural MCDI/ETCO/SYLT/POSS/RBUF/SEEK/SIGN/AENC/LINK frames
- structural USER/OWNE/COMR/SYTC/RVA2/EQU2 frames
- structural POPM / PCNT / PRIV / GEOB / UFID frames
- replace never-match regex with semver_check = false
- drop enable_miri input (miri now manual-only via workflow_dispatch)
- grant release-plz shim contents+pull-requests write
- migrate to OxideAV/.github reusable workflows
- pin release-plz to patch-only bumps
Added
- Typed
TKEYinitial-key accessorId3Frame::initial_key()+ the
MusicalKey/KeyAccidentalenums (spec v2.3 §4.2.1 / v2.4 §4.2.3).
The frame "contains the musical key in which the sound starts",
"represented as a string with a maximum length of three characters";
the ground keys areA..G, the halfkeysb/#, minorm, and
"off key is represented with anoonly" (e.g. the spec example
Dbm). The accessor decodes that grammar toMusicalKey::Key { tonic, accidental, minor },MusicalKey::OffKey, orMusicalKey::Customfor
any value outside the grammar (tonic not inA..G, unknown / out-of-
order trailing character, or a value past the three-character maximum)
so a forward-compatible or non-conforming source surfaces structurally
rather than being dropped, matching the posture offile_type()/
media_type(). The grammar paragraph is identical across v2.2 (TKE),
v2.3, and v2.4 so the accessor is version-independent; the raw
Id3Frame::Text::valuesis unchanged and round-trips losslessly
throughwrite_tag. Three new lib tests (spec-example grammar coverage
for natural / minor / flat / sharp keys and theooff-key; non-
conforming inputs collapsing toCustom; accessorNoneon non-TKEY
frames) plus one integration round-trip test (write → parse under both
v2.3 and v2.4 envelopes preserving both the typed view and the raw
value) cover the matrix. - ID3v2.2 write support (
write_tag(&tag, Id3Version::V2_2)/ the
write_tag_with_optionspath), completing the v2.2 round-trip — the
format was previously parse-only. Each four-char id is demoted to its
three-character v2.2 id (the inverse of the existing v2.2→v2.3
promotion table), the six-byte v2.2 frame header (3-char id + 3-byte
big-endian size, no flags; specid3v2-00§3.2) is emitted, and the
v2.2 PIC layout is reconstructed (fixed three-character image-format
code per §4.15 in place of v2.3 APIC's NUL-terminated MIME). The §4
frame set is closed, so a frame with no v2.2 equivalent (a v2.4-only
addition or an unrecognisedUnknownid) is skipped rather than
emitted under an id a conformant v2.2 reader could not interpret. v2.2
predates the extended header, footer, and per-frame flags byte, so the
writer rejectswith_crc/with_footer/with_update/
with_restrictions/with_compressionunder a v2.2 target;
UnsyncMode::WholeTagis supported via the header bit-7 unsync flag
andPerFramecollapses to whole-tag as it does for v2.3. Six new
round-trip tests cover text/comment/lyrics/URL/picture frames, the PIC
three-char image format, whole-tag unsync over a false-sync payload,
v2.4-only-frame skipping, the post-v2.2 option rejections, and a
structuredPOPMframe; the fuzz target now also drives the v2.2
write+reparse path for panic-freedom. - Typed
TFLTfile-type accessorId3Frame::file_type()+FileType
enum (spec v2.3 §4.2.1 / v2.4 §4.2.3). The frame "indicates which type
of audio this tag defines" via a predefined code optionally followed by
/-separated refinements, "in a similar way to the predefined types in
theTMEDframe, but without parentheses". Because the wire form is
identical in both versions (MPG/3→code="MPG",refinements=["3"])
and carries no parentheses or v2.3 free-text refinement, a single bare
grammar covers both dialects; the only version difference is the
v2.4-addedMIMEtop-level code, which the predefined table resolves
under either envelope. The four predefined codes (MIME/MPG/VQF/PCM)
resolve to their spec descriptions; an out-of-table code surfaces as
FileType::Predefined { name: None, .. }so a forward-compatible
reference is preserved structurally rather than dropped, and a value
with an empty top-level segment surfaces asFileType::Custom. The raw
Id3Frame::Text::valuesis unchanged and round-trips losslessly,
mirroring theTMEDmedia_type()accessor. - Typed
TMEDmedia-type accessorId3Frame::media_type()+MediaType
enum (spec v2.3 §4.6.3 / v2.4 §4.2.3). The frame "describes from which
media the sound originated — either a text string or a reference to the
predefined media types found in the list below." The accessor
normalises both version dialects onto one vocabulary, mirroring the
TCONcontent_types()accessor: v2.3 wraps a reference in(...)
optionally followed by a free-text refinement ((MC) with four channels→media="MC",text=" with four channels";(VID/PAL/VHS)
→media="VID",refinements=["PAL","VHS"]) with a((escape for a
literal-(free-text name, while v2.4 drops the parentheses (the spec
exampleVID/PAL/VHSparses to the same reference). The 15 predefined
top-level codes (DIG/ANA/CD/LD/TT/MD/DAT/DCC/DVD/TV/VID/RAD/TEL/MC/REE)
resolve to their spec descriptions; an out-of-table code surfaces as
MediaType::Predefined { name: None, .. }so a forward-compatible
reference is preserved rather than dropped. The raw text value is
unchanged and round-trips losslessly throughwrite_tag. - Complete ID3v2.2.0 §4 frame-table read support. The v2.2 walker
(3-char ids, 3-byte sizes, no frame flags) previously dispatched
only text / URL /COM/ULT/PIC/REV/EQU; it now maps
every declared v2.2 frame onto the crate's typed surface:UFI§4.1
→Ufid,IPL§4.4 →Ipls,MCI§4.5 →MusicCdId,ETC§4.6
→EventTimingCodes,MLL§4.7 →MpegLocationLookup,STC§4.8
→SyncedTempo,SLT§4.10 →SyncedLyrics,GEO§4.16 →Geob,
CNT§4.17 →PlayCounter,POP§4.18 →Popularimeter,BUF
§4.19 →RecommendedBuffer,CRA§4.21 →AudioEncryption(all
byte-identical to their v2.3 descendants' payload layouts), plus two
v2.2-specific walkers —RVA§4.12 (right/left volume-change fields
are unconditional; presence is not keyed on the inc/dec sign bits
the way v2.3RVADgates its front block, so a both-decrement frame
keeps its data) andLNK§4.22 (the linked frame identifier is
always exactly 3 bytes, so a URL whose first byte is an uppercase
id-class character can never be folded into the identifier the way
the v2.3/v2.4 3-vs-4-byte heuristic would).CRM§4.20 (encrypted
meta frame) has no v2.3/v2.4 descendant and is preserved verbatim
viaId3Frame::Unknown. Thev22_promoteconversion table now
covers the full §4 id list so pass-through writes promote correctly. - Frame-level zlib compression, both directions (spec v2.3 §3.3
format flagi/ v2.4 §4.1.2 format flagk).parse_tagnow
inflates compressed frames transparently in both dialects — v2.3's
4-byte big-endian decompressed-size header addition and v2.4's
mandatory data-length indicator (a compressed v2.4 frame without
the DLI bit is rejected per the spec's "requires the 'Data Length
Indicator' bit to be set as well") — and dispatches the recovered
payload structurally. The announced decompressed size is
authoritative: an inflate-length mismatch drops the frame (earlier
frames survive, matching the corrupted-frame posture), and the
announce doubles as the allocation cap under a 64 MiB per-frame
ceiling so a zlib bomb can't force a...
v0.0.5
Other
- 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"