lofty-rs/CHANGELOG.md
2024-11-20 01:22:12 -05:00

59 KiB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

Added

  • ItemKey: ItemKey::TrackArtists, available for ID3v2, Vorbis Comments, APE, and MP4 Ilst (PR)
  • UnsynchronizedStream: UnsynchronizedStream::get_ref() (PR)
  • Ilst (PR):
    • Methods to quickly set/check boolean flags:
      • Ilst::set_flag
      • Ilst::is_podcast
      • Ilst::is_compilation
      • Ilst::is_gapless
      • Ilst::is_show_work
      • Ilst::is_hd_video
    • DataType enum
      • Previously, atom data types were stored as a u32, with their names being available in mp4::constants. Now, instead of mp4::constants::BE_SIGNED_INTEGER, you can use DataType::BeSignedInteger, for example.
      • It can be converted to and from a u32
    • AtomData::data_type() to get the data type code of the atom content.

Changed

  • Ilst: Add new rules for gnre atom upgrades (issue) (PR)
    • In the case that a ©gen and gnre atom are present in a file, there was no way to tell which ©gen atoms were upgraded. the new rules are:
      • gnre present + no ©gen present, gnre gets upgraded as normal
      • gnre present + ©gen present, ©gen takes precedence and gnre is discarded

Fixed

  • MusePack: Fix potential panic when the beginning silence makes up the entire sample count (PR)
  • Timestamp:
    • Support timestamps without separators (ex. "20240906" vs "2024-09-06") (issue) (PR)
    • Timestamp::parse will now short-circuit when possible in ParsingMode::{BestAttempt, Relaxed} (issue) (PR)
      • For example, the timestamp "2024-06-03 14:08:49" contains a space instead of the required "T" marker. In ParsingMode::Strict, this would be an error. Otherwise, the parser will just stop once it hits the space and return the timestamp up to that point.
  • ID3v2:
    • ItemKey::Director will now be written correctly as a TXXX frame (PR)
    • When skipping invalid frames in ParsingMode::{BestAttempt, Relaxed}, the parser will no longer be able to go out of the bounds of the frame content (issue) (PR)
  • MP4: Support for flag items (ex. cpil) of any size (not just 1 byte) (issue) (PR)
  • Fuzzing (Thanks @qarmin!) (PR) (PR) (PR):
    • MusePack: Fix panic when ID3v2 tag sizes exceed the stream length (issue)
    • WAV: Fix panic when calculating bit depth with abnormally large bytes_per_sample (issue)
    • WavPack*: Fix panic when encountering wrongly sized blocks (issue) (issue)
    • WavPack*: Fix panic when encountering zero-sized blocks (issue)
    • MPEG: Fix panic when APE tags are incorrectly sized (issue)
    • ID3v2: Fix panic when parsing non-ASCII TDAT and TIME frames in TDRC conversion (issue)
    • APE: Fix panic when parsing incorrectly sized header APE tags (issue)

0.21.1 - 2024-08-28

Changed

  • FLAC: Vendor strings are now retained when writing tags (PR)
    • This behavior already exists for OGG formats.

Fixed

  • FLAC: Stop writing invalid PADDING blocks (issue) (PR)
    • If a PADDING block existed in the original file, and it wasn't placed at the end of the header, it would be moved without setting the Last-metadata-block flag. This would cause decoders to believe that the file was corrupted.
  • Fuzzing (Thanks @qarmin!) (PR):
    • MusePack: Fix panic when tag sizes exceed the stream length (issue)
    • AAC: Fix panic when tag sizes exceed the stream length (issue)

0.21.0 - 2024-07-29

Added

  • ParseOptions:
    • ParseOptions::read_tags to skip the parsing of tags (issue) (PR)
    • ParseOptions::read_cover_art (issue) (PR)
      • As cover art can be large, it is now possible to disable reading it when parsing a file.
    • ParseOptions::implicit_conversions to prevent automatic data conversions (PR)
      • Be sure to read the warnings in the docs to understand what this means.
  • ID3v2: Support writing ID3v2.3 tags (issue) (PR)
    • This can be done by setting WriteOptions::use_id3v23 to true.
  • Tag: Tag::take_filter (PR)
    • This is like Tag::take, but allows for per-TagItem filtering.
    • This is useful for TagType::Id3v2, as it allows specifying descriptions and languages for frames. See the docs and PR description for more details.

Changed

  • Timestamp: Timestamp::parse with empty inputs will return None when not using ParsingMode::Strict (PR)
  • MP4: Atoms with sizes greater than the remaining file size will be ignored with ParsingMode::Relaxed (PR)
  • ID3v2 (PR):
    • PopularimeterFrame::as_bytes() is now fallible
    • PrivateFrame::as_bytes() is now fallible

Fixed

  • Fuzzing (Thanks @qarmin!) (PR) (PR):
    • MP4:
      • Fix panic when reading properties of a file with no timescale specified (issue)
      • Fix panics when reading improperly sized freeform atom identifiers (issue) (issue)
      • Fix panic when data atom length is less than 16 bytes (issue)
      • Fix panic with improperly sized freeform identifiers (issue)
      • Fix panic when hdlr atom is an unexpected length (issue)
      • Fix panic when stts atom has an unrealistically large entry count (issue) (PR)
    • WAV:
      • Fix panic when reading properties with large written bytes per second (issue)
      • Fix panic when reading an improperly sized INFO LIST (issue)
      • Fix panic when reading a fmt chunk with an invalid bits_per_sample field (issue)
    • Vorbis:
      • Fix panic when reading properties of a file with large absolute granule positions (issue)
      • Fix attempted large allocations with invalid comment counts (issue)
    • FLAC: Fix panic when reading properties of a file with incorrect block sizes (issue)
    • AIFF: Fix panic when reading properties of a file with invalid f80 sample rate (issue)

0.20.1 - 2024-07-02

Fixed

  • MPEG: Fix durations being slightly off (issue) (PR)

0.20.0 - 2024-06-06

Added

  • Tag:
    • Support ItemKey::ParentalAdvisory for Ilst and Id3v2Tag (issue) (PR)
    • New tag::items module for generic representations of complex tag items
    • New Timestamp item for ISO 8601 timestamps (PR)
  • ID3v2: Special handling for frames with timestamps with Frame::Timestamp (PR)
  • GlobalOptions: preserve_format_specific_items() (issue) (PR)
    • This will allow for the preservation of format-specific items when converting between tag types.
    • Previously, these items would be discarded when converting to the generic Tag. Now they are stored in an immutable container, and silently rejoined with the tag when converting back to the original format or when writing.
  • TagItem: set_lang and set_description to allow for generic conversions of additional ID3v2 frames (such as comments) (issue) (PR)
  • BoundTaggedFile: BoundTaggedFile::into_inner to get the original file handle (PR)

Changed

  • VorbisComments/ApeTag: Verify contents of ItemKey::FlagCompilation during Tag merge (PR)
  • ID3v2:
    • ⚠️ Important ⚠️: Frame has been converted to an enum (PR):
      • This makes it easier to validate frame contents, as one can no longer make an AttachedPictureFrame with the ID "TALB", for example. See the PR for a full description of the changes.
      // Old:
      let frame = Frame::new(
          "TALB",
          FrameType::Text(TextInformationFrame {
              TextEncoding::UTF8,
              value: String::from("Foo album"),
          }),
          FrameFlags::default(),
      ).unwrap();
      
      // New:
      let frame = Frame::Text(TextInformationFrame::new(
          FrameId::new("TALB").unwrap(),
          FrameFlags::default(),
          TextEncoding::UTF8,
          String::from("Foo album"),
      ));
      
    • Renamed Popularimeter -> PopularimeterFrame
    • Renamed SynchronizedText -> SynchronizedTextFrame

Fixed

  • ID3v2: Disallow 4 character TXXX/WXXX frame descriptions from being converted to ItemKey (issue) (PR)
  • MPEG: Durations estimated by bitrate are more accurate (PR)
  • MP4:
    • Bitrate calculation is now more accurate (PR)
    • Existing tags will no longer be overridden if another udta atom is encountered (PR)
  • WAV: Bitrate calculation is now more accurate (PR)
  • MusePack: Overall improved audio properties (PR)

0.19.2 - 2024-04-26

Added

  • Length: impl<T: Length> Truncate for &mut T

0.19.1 - 2024-04-26 (YANKED)

Added

  • Truncate: impl<T: Truncate> Truncate for &mut T (PR)
  • Length: impl<T: Length> Truncate for &T (PR)

Changed

  • MP4: All surrounding free atoms will be used when writing ilst tags (issue) (PR)
    • Previously, only the free atoms immediately surrounding the ilst atom were used.

0.19.0 - 2024-04-21

Added

  • WriteOptions (issue) (PR):
    • ⚠️ Important ⚠️: This update introduces WriteOptions to allow for finer grained control over how Lofty writes tags. These are best used as global user-configurable options, as most options will not apply to all files. The defaults are set to be as safe as possible, see here.
  • Generic Writes (PR):
    • ⚠️ Important ⚠️: This update introduces FileLike, which is a combination of the Truncate + Length traits that allows one to write to more than just Files. In short, Cursor<Vec<u8>> can now be written to.
  • ChannelMask
    • BitAnd and BitOr implementations (PR)
    • Associated constants for common channels, ex. ChannelMask::FRONT_LEFT (PR)
    • ChannelMask::from_{mp4, opus}_channels
  • Opus: OpusProperties now contains the channel mask
  • AAC: AacProperties now contains the channel mask
  • Prelude: lofty::prelude module to make trait imports easier (PR)

Changed

  • ID3v2: Ignore empty duplicate frames (PR)
    • Some software will apparently write an empty duplicate frame after the actual frame. As the latest frame is the only one that gets preserved, we now check if the frame is empty before replacing.
  • Properties: FileProperties and ChannelMask have been moved from the root to the new lofty::properties module (PR)
  • ParseOptions/WriteOptions/GlobalOptions:
    • ⚠️ Important ⚠️: Moved to lofty::config (PR)
  • AudioFile/TaggedFileExt/TaggedFile/BoundTaggedFile/FileType:
    • ⚠️ Important ⚠️: Moved to lofty::file (PR)
  • Tag:
    • ⚠️ Important ⚠️- The following items have been moved to lofty::tag (PR):
      • Tag
      • Accessor
      • TagType
      • TagItem
      • ItemKey
      • ItemValue
  • Probe:
    • ⚠️ Important ⚠️- Moved to lofty::probe (PR):
  • Picture:
    • ⚠️ Important ⚠️- The following items have been moved to lofty::picture (PR):
      • Picture
      • PictureType
      • PictureInformation
      • MimeType
  • IFF (PR):
    • AIFF: AIFFTextChunks renamed to AiffTextChunks
    • RIFF: RIFFInfoList renamed to RiffInfoList

Fixed

  • Vorbis: Fix panic when reading properties of zero-length files (issue) (PR)
  • ID3v2:
    • Fix panic when reading a UTF-16 with no BOM (issue) (PR)
    • Fix panic when reading an RVA2 frame with a peak larger than 248 bits (issue) (PR)
  • WAV: Length and bitrate values are properly rounded (PR)
  • ParseOptions: No longer derives {PartialOrd, Ord} (PR)

ogg_pager

See ogg_pager's changelog.

0.18.2 - 2024-01-23

Fixed

  • MP4: Padding for shrinking tags will no longer overwrite unrelated data (PR)

0.18.1 - 2024-01-20 (YANKED)

Fixed

  • ID3v2: Fix panic in UTF-16 parsing when BOM is missing (issue) (PR)
  • MP4:
    • Properly handle track/disc numbers greater than 16 bits (PR)
    • Atom offset updates will now be properly handled for shrinking tags (PR)

0.18.0 - 2024-01-12

Added

  • MP4: Check if audio streams are DRM protected, exposed as Mp4Properties::is_drm_protected() (PR)
  • ID3v2:
    • Add Id3v2ErrorKind::EmptyFrame (PR)
    • Support converting some TIPL frame values into generic TagItems (PR)
      • Supported TIPL keys are: "producer", "arranger", "engineer", "DJ-mix", "mix".
  • GlobalOptions: Options local to the thread that persist between reads and writes (PR)
  • ItemKey: ItemKey::IntegerBpm (issue) (PR)

Changed

  • ID3v1: Renamed GENRES[14] to "R&B" (Previously "Rhythm & Blues") (PR)
  • MP4: Duration milliseconds are now rounded to the nearest whole number (PR)
  • ID3v2:
    • Stop erroring on empty frames when not using ParsingMode::Strict (PR)
    • Verify contents of flag items (ItemKey::FlagCompilation, ItemKey::FlagPodcast) (PR)
    • Id3v2Tag::get_text() will now return the raw, unedited string (PR)
      • Previously, all null separators were replaced with "/" to make the string easier to display. Now, null separators are only replaced in Accessor methods. It is up to the caller to decide how to handle all other strings.
  • resolve: Custom resolvers will now be checked before the default resolvers (PR)
  • MPEG: Up to max_junk_bytes will now be searched for tags between the start of the file and the first MPEG frame (PR)
    • This allows us to read and write ID3v2 tags that are preceeded by junk
  • ItemKey:
    • Renamed ItemKey::PodcastReleaseDate to ItemKey::ReleaseDate (PR)
    • Renamed ItemKey::{PodcastURL, PoddcastGlobalUniqueID} to ItemKey::{PodcastUrl, PoddcastGlobalUniqueId} (issue) (PR)

Fixed

  • MP4:
    • The dfLa atom for FLAC streams will now be found, providing better properties (PR)
    • Offset atoms (stco, co64, and tfhd) will now be updated when writing (issue) (PR)
    • ItemKey::FlagPodcast will be checked in Tag -> Ilst conversion (PR)
  • ID3v2: Support UTF-16 encoded TIPL frames with a single BOM (issue) (PR)
  • Speex: Estimate bitrate when the nominal bitrate is not available (PR)
    • When no nominal bitrate was provided, the bitrate was previously set to 0. Now we will give an estimate based on the stream length, which may or may not be entirely accurate.

Removed

  • ItemKey: ItemKey::InvolvedPeople
  • MimeType: MimeType::None, Picture now stores an Option<MimeType>.
  • ID3v2: TextSizeRestrictions::None and ImageSizeRestrictions::None
    • TagRestrictions now stores an Option<TextSizeRestrictions> and Option<ImageSizeRestrictions>.
  • MPEG: Emphasis::None, MpegProperties now stores an Option<Emphasis>.

0.17.1 - 2023-11-26

Changed

  • MP4: Skip over invalid ilst atoms by default (issue) (PR)

0.17.0 - 2023-11-14

Added

  • ParseOptions: ParseOptions::allocation_limit to change the default allocation limit. (PR)
  • ID3v2: Id3v2Tag::genres to handle all the ways genres can be stored in TCON frames. (PR)

Changed

  • VorbisComments: When converting from Tag to VorbisComments, ItemKey::Unknowns will be checked for spec compliance. (PR)
  • ID3v2: Any trailing null terminators will be trimmed when reading Comment, Text, UserText, UserUrl, and UnsynchronizedText frames. (PR)
  • Alloc: The default allocation limit for any single tag item is now 16MB. (PR)
  • Probe: Probe::set_file_type() will return the Probe to allow for builder-style usage. (PR)

Fixed

  • MP4: Verify atom identifiers fall within a subset of characters (PR)
    • For a multitude of reasons, garbage data can be left at the end of an atom, resulting in Lofty attempting to parse it as another atom definition. As the specification is broad, there is no way for us to say with certainty that an identifier is invalid. Now we unfortunately have to guess the validity based on the commonly known atoms. For this, we follow TagLib's checks.
  • ID3v1: No longer error on inputs shorter than 128 bytes (the length of an ID3v1 tag). (PR)
  • ID3v2: No longer error on multi-value UTF-16 encoded text frames (issue) (PR)

Removed

  • MP4: Ilst::{track_total, disc_number, disc_total} (PR)
    • These existed prior to the methods on Accessor. There is no need to keep them around, as they behave the same.

0.16.1 - 2023-10-15

Fixed

  • MP4: Skip unexpected or empty data atoms in ilst (PR)
    • It is possible for an ilst item to have both empty data atoms and unexpected (likely vendor-specific) atoms other than data. These are both cases we can safely ignore unless using ParsingMode::Strict.

0.16.0 - 2023-10-01

Added

  • ID3v2:
    • Support for "RVA2", "OWNE", "ETCO", and "PRIV" frames through id3::v2::{RelativeVolumeAdjustmentFrame, OwnershipFrame, EventTimingCodesFrame, PrivateFrame} (PR)
    • FrameId now implements Display (PR)
    • Id3v2Tag::get_texts for multi-value text frames (PR)
  • MP4 (PR):
    • Atom::into_data
    • Atom::merge
  • OGG: Support for reading "COVERART" fields, an old deprecated image storage format. (issue) (PR)

Changed

  • ID3v2:
    • Tag header parsing errors will be ignored unless using ParsingMode::Strict (PR)
    • For spec compliance, Id3v2Tag::insert will now check for frames that are only meant to appear in a tag once and remove them. Those frames are: "MCDI", "ETCO", "MLLT", "SYTC", "RVRB", "PCNT", "RBUF", "POSS", "OWNE", "SEEK", and "ASPI". (PR)
    • Id3v2Tag::remove will now take a FrameId rather than &str (PR)
    • FrameId now implements Into<Cow<'_, str>>, making it possible to use it in Frame::new (PR)
    • Id3v2Tag getters will now use &FrameId instead of &str for IDs (PR)
  • MP4 (PR):
    • Ilst::remove will now return all of the removed atoms
    • Ilst::insert_picture will now combine all pictures into a single covr atom
    • Ilst::insert will now merge atoms with the same identifier into a single atom
  • FLAC:
    • Allow multiple Vorbis Comment blocks when not using ParsingMode::Strict (PR)
      • This is not allowed by spec, but is still possible to encounter in the wild. Now we will just take whichever tag happens to be latest in the stream and use it, they will not be merged.
    • Allow picture types greater than 255 when not using ParsingMode::Strict (issue) (PR)
      • This is not allowed by spec, but has been encountered in the wild. Now we will just cap the picture type at 255.

Fixed

  • WavPack: Custom sample rates will no longer be overwritten (PR)
    • When a custom sample rate (or multiplier) was encountered, it would accidentally be overwritten with 0, causing incorrect duration and bitrate values.
  • APE: Reading properties on older files will no longer error (PR)
    • Older APE stream versions were not properly handled, leading to incorrect properties and errors.
  • ID3v2: Don't expect text frames to be null terminated (issue) (PR)

0.15.0 - 2023-07-11

Added

  • ID3v2:
    • Id3v2ErrorKind::UnsupportedFrameId (PR)
    • FrameValue::KeyValue for TIPL/TMCL frames (PR)
    • Id3v2Tag::get_user_text, Id3v2Tag::insert_user_text, and Id3v2Tag::remove_user_text for working with TXXX frames (PR)
  • ParseOptions: ParseOptions::max_junk_bytes, allowing the parser to sift through junk bytes to find required information, rather than immediately declare a file invalid. (discussion) (PR)
  • WavPack: WavPackProperties now contains the channel mask, accessible through WavPackProperties::channel_mask() (PR)
  • AIFF:
    • AiffProperties to hold additional AIFF-specific information
    • AIFC compression types are now exposed through AiffCompressionType

Changed

  • ID3v2:
    • Id3v2ErrorKind::BadFrameId now contains the frame ID (PR)
    • Bad frame IDs will no longer error when using ParsingMode::{Relaxed, BestAttempt}. The parser will now just move on to the next frame. (PR)
  • APE: The default track/disk number is now 0 to line up with ID3v2. This is only used when set_{track, disk}_total is used without a corresponding set_{track, disk}.
  • VorbisComments: When writing, items larger than u32::MAX will throw ErrorKind::TooMuchData, rather than be silently discarded.
  • AIFF: AiffFile will no longer use FileProperties. It now uses AiffProperties.

Fixed

  • APE: Track/Disk number pairs are properly converted when writing (issue) (PR)
  • ID3v2: TIPL/TMCL frames will no longer be read as a single terminated string (issue) (PR)
  • WavPack: Multichannel files will no longer be marked as mono, supporting up to 4095 channels (PR)

0.14.0 - 2023-06-08

Added

  • ParsingMode: A new variant, BestAttempt will attempt to fill holes in otherwise valid tag items (PR)
  • 🎉 Support for Musepack files (issue) (PR)

Changed

  • Probe: The default ParsingMode is now ParsingMode::BestAttempt (It was previously ParsingMode::Strict)
  • Alloc:
    • ⚠️ Important ⚠️: The allocation limit for any single tag item is now 8MB (PR). This is not configurable yet (issue).

Fixed

  • MP4: Fixed potential panic with malformed plID atoms (issue) (PR)

Removed

  • ID3v2: Removed id3::util::synchsafe::unsynch_content. This has been replaced with UnsynchronizedStream.

0.13.0 - 2023-05-08

Added

  • Tag/ItemValue: Tag::remove_empty/ItemValue::is_empty (PR)
  • ItemKey: Variants for MusicBrainz Release group/Artist/Release artist/Work IDs (PR)
  • ID3v2:
    • ItemKey::{Barcode, CatalogNumber} mappings (PR)
    • SynchsafeInteger trait to convert multiple integer types to/from their unsynchronized variants (PR)
    • Concrete types for all FrameValue variants (PR)
    • Support for the audio-text accessibility (ATXT) frame (PR)
  • VorbisComments: ItemKey::Barcode mapping (PR)

Changed

  • ID3v1: ID3v1Tag -> Id3v1Tag
  • ID3v2:
    • SyncTextInformation no longer uses a String for its language (PR)
    • FrameID -> FrameId
    • ID3v2Version -> Id3v2Version
    • ID3v2TagFlags -> Id3v2TagFlags
    • ID3v2Tag -> Id3v2Tag
    • There are fewer redundant, intermediate allocations (PR)
  • FileType/TagType/ItemKey: All variants have been changed to UpperCamelCase (PR)
  • MPEG:
    • MPEGFile -> MpegFile
    • MPEGProperties -> MpegProperties

Fixed

  • ID3v2: Compressed frames are now properly handled (PR)

Removed

  • ID3v2:
    • All uses of ID3v2ErrorKind::Other have been replaced with concrete errors
    • SyncTextInformation and GEOBInformation have been flattened into their respective items (PR)

0.12.1 - 2023-04-10

Fixed

  • WAV: Fix division by zero when reading the properties of an empty stream (issue) (PR)
  • ID3v2 (PR):
    • Export id3::v2::UniqueFileIdentifierFrame
    • Export id3::v2::Popularimeter

0.12.0 - 2023-04-04

Added

  • Properties: Expose channel mask (only supported for WAV and MPEG for now) (PR)
  • ItemKey: InitialKey mapping for Vorbis Comments (PR)
  • VorbisComments: VorbisComments::push to allow for a non-replacing insertion (PR)
  • Tags: <Tag>::new() as an alias for <Tag>::default() (PR)
  • Picture: Picture::into_data() (PR)

Changed

  • APE/ID3v1/ID3v2/Tag:
    • Allow empty strings as values instead of removing the corresponding item when empty (PR)
    • Separated the trait SplitAndMergeTag into SplitTag and MergeTag to prevent any unexpected or undefined behavior at runtime (PR)
  • VorbisComments (PR):
    • Keys will now be verified according to spec before insertion
    • Getters will now case-insensitively search for keys
    • TRACKNUM will now be considered in the Accessor::*track methods
  • Tags: Method names are more consistent (PR)

Fixed

  • ID3v2:
    • Fix conversion of user defined frames when using Tag writing interface (issue) (PR)
    • Fix writing of tag/disk numbers when using Tag writing interface (issue) (PR)
  • MP4 (PR):
    • Fix the incorrect size being written for newly created moov.udta.meta atoms
      • Previously, the 8 bytes for the size and identifier were not accounted for
    • The parser has been further restricted to avoid going out of bounds
      • This was only an issue if there was garbage data after the moov item and the parser had not yet found the moov.udta atom.
  • WavPack (PR):
    • Fewer errors are suppressed
    • Metadata sub-blocks are now properly parsed
    • Bitrate calculation will now properly round down

0.11.0 - 2023-01-29

Added

  • MP4:
    • The InitialKey, ReplayGain*, and "precise BPM" identifiers now have ItemKey mappings (PR)
    • AtomIdent now implements TryFrom<ItemKey> (PR)
    • Added support for the vendor-supplied XID in files from the Apple iTunes store as ItemKey::AppleXid. (PR)
    • Added support for ItemKey::FlagCompilation (PR)
  • Vorbis Comments:
    • Additional mappings for the Label, Remixer, and EncodedBy ItemKey variants (PR)
  • ID3v2: A new id3v2_compression_support feature to optionally depend on flate2 for decompressing frames
  • ItemKey:
    • New Variants: AppleXid, Director, Color
  • AudioFile: AudioFile::save_to{_path} (PR)
  • Files: <File>::set_{tag}
  • FLAC: FlacProperties
    • Previously, FLAC files used FileProperties. FlacProperties was added to support getting the MD5 signature of the audio data.
  • OGG: OggPictureStorage
    • This was added to cover the overlap in functionality between VorbisComments and FlacFile in that they both store (Picture, PictureInformation).
  • TagExt: TagExt::len

Changed

  • MP4: AtomIdent stores freeform identifiers as Cow<str> opposed to String (PR)
    • This allows freeform identifiers to be constructed in a const context.
  • ID3v2: FrameID now uses Cow<str> opposed to String (PR)
  • FLAC: FlacFile now stores pictures separately from its VorbisComments tag

Removed

  • Metadata format features (PR):
    • All of the format-specific features have been removed, as they served no purpose. They used to bring in optional dependencies, but they have long since been removed.

Fixed

  • Tag: Handling of the Year tag has been improved.
    • Previously, setting a year with Tag::set_year required a RecordingDate. Now it will check if the format supports the Year tag, and if not, then it will set a RecordingDate.
  • OGG: Writing of large packets would corrupt the stream (issue) (PR)

ogg_pager

See ogg_pager's changelog.

0.10.0 - 2022-12-27

Added

  • TagExt: TagExt::contains
  • Ilst: AtomData::Bool for the various flag atoms such as cpil, pcst, etc.
  • BoundTaggedFile: A TaggedFile variant bound to a File handle. (issue) (PR)

Changed

  • Files: Return the removed tag from <File>::remove(TagType) (PR)
    • Previously, the only way to remove and take ownership of a tag was through TaggedFile::take. This was not possible when using a concrete type, such as OpusFile.
  • TaggedFile: Renamed TaggedFile::take to TaggedFile::remove (PR)
  • lofty_attr: The lofty_attr::LoftyFile derive proc macro is now exported as lofty::LoftyFile.
  • TaggedFile: All methods have been split out into a new trait, TaggedFileExt. (PR)
  • Accessor: All methods returning string values now return Cow<str>. (PR)
    • This is an unfortunate change that needed to be made in order to accommodate the handling of the different possible text separators between ID3v2 versions.
  • ID3v2: Support reading of duplicate tags (issue) (PR)
    • Previously, if we were reading a file and encountered an ID3v2 tag after having already read one, we would overwrite the last one, losing all of its information. Now we preserve all of the information, overwriting frames as necessary.

Fixed

  • ID3v2: The '/' character is no longer used as a separator (issue)
  • MP4: Stopped expecting certain flags for the gnre atom prior to upgrading it (issue) (PR)

ogg_pager

See ogg_pager's changelog.

0.9.0 - 2022-10-30

Added

  • ParseOptions (issue) (PR):
    • ⚠️ Important ⚠️: This update introduces ParseOptions to allow for finer grained control over error eagerness and other settings. Previously, when reading a file the only option available was read_properties, specified with a bool in read_from{_path}. This will now default to true, and can be overridden when using Probe.
  • 🎉 Support for AAC (ADTS) files (issue) (PR)
  • FileProperties: FileProperties::new
  • Debug logging via the log crate for exposing recoverable errors.
  • Error: ErrorKind::SizeMismatch

Changed

  • ID3v2:
    • Frame/tag flags with optional additional data are now Option<T> instead of (bool, T)
    • id3::v2::TextEncoding is now exported as lofty::TextEncoding
  • read_from{_path} will no longer take a bool for reading properties, and will do it by default. To change this behavior, you must now use Probe.
  • FileType: primary_tag_type will no longer change its return depending on the enabled features.
  • lofty_attr: Simplified the file_type attribute:
    • Before, you had to specify custom file types as #[lofty(file_type = "Custom(\"MyFile\")")]. Now you can simply do #[lofty(file_type = "MyFile")] and it will infer the rest.
  • IFF: WAV and AIFF items are no longer combined in the iff module. They are now separated into their own modules at iff::wav and iff::aiff respectively.

Fixed

  • ID3v2: Populate the Populatimeter field in the ID3v2 -> Tag conversion (issue) (PR)

Removed

  • lofty_attr: The #[lofty(always_present)] attribute has been removed, and is now inferred.

0.8.1 - 2022-09-09

Added

  • VorbisComments: VorbisComments::get_all, same as Tag::get_strings (issue)

Fixed

  • ID3v2: Handle tag-wide unsynchronisation flag (amberol#235)
  • MP3: Stop using partial frame headers (PR)

0.8.0 - 2022-08-10

Added

  • A new file resolver system:
    • New module: lofty::resolve
    • With this, you will be able to create your own FileTypes, while continuing to use lofty's traditional API. Read the module docs for more info.
  • A proc macro for file creation:
    • With the new lofty_attr crate, file creation has been simplified significantly. It is available for both internal and external usage.
  • ID3v2: Exposed internal functions id3::v2::util::{synch_u32, unsynch_u32}
  • MP4: Atom::push_data

Changed

  • TaggedFile: tag{_mut} no longer takes a reference to TagType
  • ID3v2: LanguageFrame's lang field has changed type - String -> [u8; 3]
  • MP3:
    • Renamed lofty::mp3 -> lofty::mpeg
    • Renamed MP3File -> MPEGFile
    • Renamed MP3Properties -> MPEGProperties
  • MP4: Atom::data will now return all values
  • Vorbis Comments: Recognize lowercase METADATA_BLOCK_PICTURE as a picture (issue)

Fixed

  • ID3v2: ItemKey::InitialKey now maps to TKEY (PR)

0.7.3 - 2022-07-22

Added

  • FileType: FileType::from_ext detects MP1/MP2 as FileType::MP3, allowing these files to be read with read_from_path/Probe::open.
  • ItemKey: ItemKey::{REPLAYGAIN_ALBUM_GAIN, REPLAYGAIN_ALBUM_PEAK, REPLAYGAIN_TRACK_GAIN, REPLAYGAIN_TRACK_PEAK}

Changed

  • ID3v2:
    • TXXX/WXXX frames will be stored by their descriptions in ID3v2Tag -> Tag conversions
    • Stopped allowing empty strings in Accessor::set_*

Fixed

  • Tag: The Accessor::set_* methods will stop falling through, and adding empty strings

0.7.2 - 2022-07-13

This release mostly addresses issues uncovered by fuzzing, thanks to @5225225!

Changed

  • Tag: The Accessor::set_* methods will now remove the item when given an empty string

Fixed

  • AIFF/WAV: Stop relying on the file-provided size when reading (Fixes OOM)
  • MP3/APE: Stop trusting the lengths of APE tag items (Fixes OOM)
  • PictureInformation: Fix potential integer overflow in {from_jpeg, from_png}
  • MP4: The parser has received a major facelift, and shouldn't be so eager to allocate or trust user data (Fixes OOM)
  • FLAC: Return early when encountering invalid zero-sized blocks
  • FLAC/Opus/Vorbis/Speex: Add better length validity checks while reading Vorbis Comments (Fixes OOM)

0.7.1 - 2022-07-08

Added

  • Vorbis Comments: VorbisComments::{pictures, set_picture, remove_picture}
  • Tag: Tag::{set_picture, remove_picture}
  • MP4: Support property reading for files with FLAC audio

Changed

  • ID3v2: ID3v2Tag now derives Eq

0.7.0 - 2022-06-27

Added

  • WavPack support
  • Accessor:
    • The following new accessor methods have been added:
      • track
      • track_total
      • disk
      • disk_total
      • year
      • comment

Changed

  • Bitrates in properties will be rounded up, similar to FFmpeg and TagLib
  • ID3v1: Renamed Id3v1Tag -> ID3v1Tag
  • ID3v2:
    • Insert multi-value frames separately when converting to Tag
      • E.g. An artist of "foo/bar/baz" will become 3 different TagItems with ItemKey::TrackArtist
    • Join multiple artists with "/" during Tag -> Id3v2Tag conversion
      • Inverse of the previous entry
    • Properly capitalized the following:
      • Id3v2Error -> ID3v2Error
      • Id3v2ErrorKind -> ID3v2ErrorKind
      • ErrorKind::Id3v2 -> ErrorKind::ID3v2
      • Id3v2TagFlags -> ID3v2TagFlags
      • Id3v2Version -> ID3v2Version
      • Id3v2Tag -> ID3v2Tag
  • Properly capitalized the variants of TagType
    • Ape -> APE
    • Id3v1 -> ID3v1
    • Id3v2 -> ID3v2
    • Mp4Ilst -> MP4ilst
    • RiffInfo -> RIFFInfo
    • AiffText -> AIFFText
  • All types implementing PartialEq now implement Eq
  • MP4: Ilst::track_number has been moved to the Accessor::track implementation
  • Tag: Renamed Tag::get_texts to Tag::get_strings
  • AIFF: Renamed AiffTextChunks -> AIFFTextChunks
  • WAV: Renamed RiffInfoList -> RIFFInfoList

Fixed

  • AIFF: Fixed division by zero panic during property reading (issue)
  • ID3v2: Support decoding UTF-16 T/WXXX frames with missing content BOM (issue)

0.6.3 - 2022-05-18

Added

  • MP4:
    • Support atoms with multiple values (issue)
    • Atom::from_collection

Changed

  • ID3v2: Discard empty frames, rather than error
  • APE: Allow empty tag items
    • Rather than error on empty items, they will just be discarded

Fixed

  • Pictures: Treat "image/jpg" as MimeType::Jpeg (PR)
  • MP3:
    • Properly validate the contents of Xing/LAME/VBRI headers (issue)
      • A header with any field zeroed out would result in a division by zero panic
    • Fix duration estimation for files with Xing headers without the necessary flags
  • FLAC: Fix property reading of zero-length files (issue)
  • Vorbis Comments: Fix reading of vendor strings with invalid mixed UTF-8 and UTF-16 encodings
  • ID3v2:
    • Fix reading of zero-size tags
    • Attempt to read invalid v2 frame IDs in v3 tags
      • For some reason, some apps write v2 frame IDs in otherwise valid v3 frames
    • Attempt to decode invalid COMM languages
  • MP4:
    • Fix hang when reading invalid padding (issue)
      • If invalid padding was encountered at the end of the file, the reader would get stuck in an infinite loop attempting to read zero size atoms
    • Fallback to bitrate calculation from mdat when necessary (issue)
      • When reading a file that doesn't provide a valid bitrate or duration, a division by zero panic would occur. Now, it attempts to calculate the bitrate from the mdat atom.

0.6.2 - 2022-04-24

Fixed

  • MP3: Fix panic when reading files with no MPEG frames (issue)
    • Attempting to read an MP3 file with read_properties = true would result in a panic if the file contained no MPEG frames

0.6.1 - 2022-04-09

Fixed

  • MP3: Fix reading of ID3v2 tags with an extended header
    • Restrictions were unnecessarily put on the reader, keeping it from continuing to read into the extended header if it was present
  • ID3v2: Fix reading of tags with an extended header
    • The size of the extended header was not being subtracted from the total tag size, causing the reading to continue outside the tag boundaries

0.6.0 - 2022-04-05

Added

  • TagItem::{into_key, into_value, consume}
  • MP4: Mp4Codec::MP3
  • MP4: mp4::AudioObjectType
    • This new type is used in mp4::Mp4Properties, accessible with Mp4Properties::audio_object_type. This provides additional information for the type of audio being dealt with.
  • TagExt::clear
    • This allows tags to be cleared of any items or pictures, while retaining any flags (if applicable)
  • ID3v2: Respect Id3v2TagFlags::crc when writing
    • Previously, this flag was ignored, but it will now calculate a CRC for the extended header
  • ID3v2: FrameValue::Popularimeter
  • ItemValue::{into_string, into_binary}
  • Tag::take_strings
  • TaggedFile now implements AudioFile

Changed

  • MP4: Sample rates and channels are now retrieved from the audio specific config (if possible). If the information is invalid or unavailable, the existing value from the mp4a box will be used instead.
  • Vorbis Comments: Support non-PNG/JPEG images in PictureInformation::from_picture
    • The method still only supports PNG and JPEG, but rather than error when it encounters an unknown image, it will return PictureInformation::default
  • lofty::read_from will now wrap the File in a BufReader
  • FLAC: FLAC now has its own module at lofty::flac
  • ID3v2: FrameValue is now #[non_exhaustive]
  • TagType::remove_from now works for ID3v2 tags in APE and FLAC files
    • This previously verified that the FileType supported the tag. It now has special exceptions for these formats to allow stripping out these unsupported tags
  • MP4: Renamed AdvisoryRating::None to AdvisoryRating::Inoffensive
  • Renamed TaggedFile::remove_tag to TaggedFile::take
  • Vorbis Comments: VorbisComments::insert_picture now accepts a user provided PictureInformation
  • Vorbis Comments: Rename VorbisComments::{get_item, insert_item, remove_key} to VorbisComments::{get, insert, remove}
  • Vorbis Comments: VorbisComments::remove now returns an iterator over the removed items

Fixed

  • MP4: Non-full meta atoms are now properly handled.
  • MP4: Properly search for soun atom
    • The search wasn't adding read bytes correctly, but tests passed due to the atom being immediately available. It would attempt to read until it reached an EOF if it managed to make it through multiple iterations.
  • FLAC: Support files with an ID3v2 tag
    • This will be read only just like APE, but will allow such files to be read
  • ID3v2: Fix writing certain proprietary Apple frames
    • When writing, frame IDs are verified with their content. The Apple specific frames "MVNM" and "MVIN" were missing, causing an error if they were written with their proper type (FrameValue::Text)
  • ID3v2: Stop writing a BOM for TextEncoding::UTF16BE

0.5.3 - 2022-03-03

ogg_pager

See ogg_pager's changelog.

0.5.2 - 2022-02-26

Added

  • MP4: Ilst::{atoms, retain}

Fixed

  • ID3v2: The footer flag is written to the tag
  • ID3v2: Pictures are written when using Tag

0.5.1 - 2022-02-21

Changed

  • MP4: Padding atoms (free) are used when writing
  • Opus: Channel count is verified in accordance to the channel mapping family

Fixed

  • MP4: meta atoms are written correctly

0.5.0 - 2022-02-20

Added

  • Support for Speex files
  • TagExt trait to unify tag behavior
  • doc_cfg feature for docs.rs
  • Fallible allocation with ErrorKind::Alloc to help prevent OOM
  • New dependency: cfg-if
  • MP3: Emphasis struct (mp3::Emphasis) for use in Mp3Properties
  • ID3v2: Respect the footer flag (id3::v2::Id3v2TagFlags::footer) when writing
  • MP4: Constants for all well-known data types (mp4::constants)
  • MP4: Support rtng (Parental advisory) atom, with corresponding mp4::AdvisoryRating enum

Changed

  • Added #[non_exhaustive] to MimeType
  • Added #[non_exhaustive] to PictureType
  • Added #[non_exhaustive] to Mp4Codec
  • APE: Clarify why ID3v2 is read only
  • MP3: No longer error on missing Xing/VBRI header when reading properties
  • MP3: Read the entire MPEG frame header, which is exposed in Mp3Properties
  • AudioFile now requires Into<TaggedFile>
  • MP4: Empty atoms are discarded
  • MP4: Variable-size integers are shrunk when writing

Fixed

  • MP4: Panic in Mp4File::read_from (commit)
  • WAV/AIFF: Chunk reading now makes use of fallible allocation, preventing OOM
  • ID3v2: Text is properly encoded when writing
  • ID3v2: MVNM and MVIN frames are now treated as text frames
  • ID3v2: Text encodings are verified for V2 tags
  • MP4: plID atom is properly treated as a 64-bit signed integer (issue)
  • MP4: rate and rtng now map to the correct ItemKey
  • MP4: Integer pairs are now written correctly
  • TagType and FileType are no longer taken by reference in any method

Removed

  • ErrorKind::BadExtension