Commit Graph
111 Commits
Author SHA1 Message Date
Ryan FrancesconiandGitHub 3ace0483c0 RIFF: support RF64 and BW64 (#1412)
RF64 and BW64 are the long forms of WAVE, used past 4 GB: each 32-bit
size field holds a 0xffffffff sentinel and the real sizes live in a
leading ds64 chunk. RIFF::WAV::File::isSupported() rejected them, but
FileRef reaches the class by extension for any .wav and RIFF::File::read()
never inspected the magic, so these files opened as valid.

updateGlobalSize() then wrote a real 32-bit total over the sentinel at
offset 4. Readers stop consulting ds64 once that field holds a number, so
a 4.8 GB file measured 0.005958 sec and 1144 audio bytes after a tag save
that returned true. Below 4 GB the tags were lost instead: the appended
LIST landed inside the region read() had clamped the sentinel data chunk
to, and a re-read found no properties.

Worse, the append offset is last.offset + last.size with size truncated to
0xffffffff, so on a long file the new chunk was spliced into the middle of
the audio — measured at offset 4294971392 on that same file, 4 GiB past
the data chunk's start, displacing everything after it.

Accept both magics, take the riff and data sizes from ds64, and write the
sentinel back on save. Writing it unconditionally is what the format
requires and also repairs a file an earlier version damaged: the same
4.8 GB file, clobbered and then saved through this path, read back at
25000.000000 sec and 4,800,000,000 bytes.

The ds64 table of additional oversized chunks is not parsed — the data
chunk has its own dedicated field and is the only one that is ever large —
so any chunk listed there stays on the clamping path added in #1329, which
this leaves untouched.

Chunk::size becomes offset_t so the append offset is computed correctly.
The struct is file-scope in rifffile.cpp and FilePrivate is only
forward-declared, so no protected signature changes and no ABI break.
chunkDataSize() still returns unsigned int, saturating rather than
truncating; a new chunkDataSize64() carries the real value to
WAV::Properties, which otherwise reports 0 s for a long file.

AIFF is big-endian and has no long form, so RIFF::File's only other
subclass cannot reach the new branch.

tests/data/rf64.wav is 9,680 bytes and built by construction, not by an
encoder; Core Audio reads it as RF64 at 0.050000 sec. The sentinels behave
identically at any size, so a small fixture covers the detection failure,
the sentinel overwrite and the repair.
2026-08-14 06:47:05 +02:00
0836f213e7 ASF: Improve PropertyMap interface (#1401)
Support more property keys, also with numeric and Guid types.

---------

Co-authored-by: Urs Fleisch <[email protected]>
2026-08-09 15:44:18 +02:00
Urs FleischandGitHub 2a5fc12b68 Support additional MP4 codecs (#1293, #1338)
Adds MP4::Properties::Codec enum values AC3, EAC3, FLAC, DTS, Opus and a
MP4::Properties::codecId() method.
Parse high-res FLAC bitrate from MP4 dfLa box.
Parse E-AC-3 bitrate from MP4 dec3 box.

The test files were generated using ffmpeg:

ffmpeg -hide_banner -y -f lavfi \
  -i "sine=frequency=440:sample_rate=48000:duration=1" \
  -c:a flac -ac 2 -flags +bitexact -fflags +bitexact \
  -metadata:s:a:0 encoder= -metadata encoder= \
  -f mp4 tests/data/flac.m4a

ffmpeg -hide_banner -y -f lavfi \
  -i "sine=frequency=440:sample_rate=48000:duration=1" \
  -c:a libopus -ac 2 -flags +bitexact -fflags +bitexact \
  -metadata:s:a:0 encoder= -metadata encoder= \
  -f mp4 tests/data/opus.m4a

ffmpeg -hide_banner -y -f lavfi \
  -i "sine=frequency=440:sample_rate=48000:duration=1" \
  -c:a ac3 -b:a 128k -ac 2 -strict experimental \
  -flags +bitexact -fflags +bitexact \
  -metadata:s:a:0 encoder= -metadata encoder= \
  -f mp4 tests/data/ac3.m4a

ffmpeg -hide_banner -y -f lavfi \
  -i "sine=frequency=440:sample_rate=48000:duration=1" \
  -c:a eac3 -b:a 128k -ac 2 -strict experimental \
  -flags +bitexact -fflags +bitexact \
  -metadata:s:a:0 encoder= -metadata encoder= \
  -f mp4 tests/data/eac3.m4a

ffmpeg -hide_banner -y -f lavfi \
  -i "sine=frequency=440:sample_rate=96000:duration=1" \
  -c:a flac -sample_fmt s32 -ac 2 -flags +bitexact -fflags +bitexact \
  -metadata:s:a:0 encoder= -metadata encoder= \
  -f mp4 tests/data/flac96.m4a
2026-08-07 14:54:50 +02:00
Urs FleischandGitHub e547578ae8 Support Vorbis comments from a multiplexed Ogg stream (#1370)
Ogg::File::readPages() read pages from all logical bitstreams and
indexed their packets into one global list. In a multiplexed file the
Theora and Vorbis packets got interleaved, so packet 0 was a Theora
header rather than the expected Vorbis type-3 comment header.

Before reading packets, the Vorbis reader now selects the Vorbis
logical bitstream (the one whose first packet is the Vorbis
identification header), so it reads the correct stream regardless of
position. Packet parsing is scoped to the selected bitstream, so
packets from other codecs in the same file are ignored.

tests/data/multiplex.ogg is generated using

ffmpeg -hide_banner -y \
  -f lavfi -i "color=c=navy:s=500x500:r=1:d=2" \
  -f lavfi -i "sine=frequency=440:sample_rate=48000:duration=2" \
  -map 0:v -map 1:a \
  -c:v libtheora -q:v 3 \
  -c:a libvorbis -ac 2 -q:a 2 \
  -flags +bitexact -fflags +bitexact \
  -metadata:s:a:0 TITLE="Paper Lights" \
  -metadata:s:a:0 encoder= -metadata:s:v:0 encoder= \
  -f ogg tests/data/multiplex.ogg
2026-08-05 20:57:29 +02:00
Thomas BergwinklandGitHub 5530420d08 Fix ID3v2 frame data length check for per-frame unsynchronised ID3v2.4 frames (#1385)
Frame::fieldData() (taglib/mpeg/id3v2/id3v2frame.cpp) discarded any
ID3v2.4 frame whose declared size (from the header) no longer matched
its actual buffer size after per-frame unsynchronisation was decoded by
FrameFactory::prepareFrameHeader(), silently emptying frames like
TIT2/TPE1/TALB. Clamp the declared length to what's actually available
instead of discarding the frame, only bailing out if the frame's data
offset itself doesn't fit.

Adds testUnsynchDecodeID3v24Frame() to tests/test_id3v2.cpp, covering a
frame with its own per-frame Unsynchronisation flag (as opposed to the
tag-wide flag already covered by testUnsynchDecode()), using new fixture
tests/data/unsynch24.id3.
2026-08-01 07:53:53 +02:00
Urs FleischandGitHub fa189f6cf7 Fix data length indicator check for compressed ID3v2 frames (#1371) 2026-06-26 09:39:27 +02:00
DanielandGitHub 49510e7d5a Move MPEG check to end of content-based detection (#1319)
MPEG::File::isSupported() scans for frame sync bytes that can appear
in other files, causing them to be misidentified as MP3.

This also includes a test with such a file.
2026-04-04 08:01:41 +02:00
Urs Fleisch d2bf7e72d2 Unit tests for Matroska 2026-01-24 14:59:10 +01:00
648f5e5882 Add Shorten (SHN) support (#1257)
* Add Shorten (SHN) support

* Add `<cmath>` include and use `std::log2`

* Use `uintptr_t` for buffer size calculations

* Work around `byteSwap` not using fixed width types

* Remove four-character codes

* Attempt to fix `static_assert`

* Revert previous commit

* Update `read_uint`* functions

* Use ByteVector for byte swaps

* Use different ByteVector ctor

* Rework variable-length input to use ByteVector

* Rename some variables

* Naming and formatting cleanup

* Add basic Shorten tests

* Rename a constant

* Rename `internalFileType` to `fileType`

* Add documentation on `fileType` meaning

* Add DO_NOT_DOCUMENT guard

* Fix shadowVariable issues reported by cppcheck

cppcheck --enable=all --inline-suppr \
  --suppress=noExplicitConstructor --suppress=unusedFunction \
  --suppress=missingIncludeSystem --project=compile_commands.json

* Formatting cleanup

* More explicit types

Reason for these changes: getRiceGolombCode(k, uInt32CodeSize) was
called with int k for uint32_t& argument.
There was also a warning from MSVC for line 299:
warning C4267: 'argument': conversion from 'size_t' to 'int'

* Additional explicit types

* Rename `SHN` namespace to `Shorten`

Also rename files to match

---------

Co-authored-by: Urs Fleisch <[email protected]>
2024-12-30 07:23:11 -06:00
Stephen BoothandGitHub f3fb4d83a4 Skip unknown MP4 boxes (#1231) 2024-05-18 06:45:10 +02:00
Urs Fleisch 3d4428726e Fix parsing of ID3v2.2 frames (#1228) 2024-05-18 06:43:00 +02:00
Urs FleischandGitHub dfa33bec08 Fix crash with invalid WAV files (#1163) (#1164)
With specially crafted WAV files having the "id3 " chunk as the
only valid chunk, when trying to write the tags, the existing
"id3 " chunk is removed, and then vector::front() is called on
the now empty chunks vector.
Now it is checked if the vector is empty to avoid the crash.
2023-11-05 14:40:18 +01:00
3869aa189f Raw AAC (ADTS) support (#508)
Detect ADTS MPEG header to use it also for AAC.

The test file empty1s.aac was generated using
ffmpeg -f lavfi -i anullsrc=r=11025:cl=mono -t 1 -acodec aac empty1s.aac

---------

Co-authored-by: Nick Shaforostov <[email protected]>
Co-authored-by: Urs Fleisch <[email protected]>
2023-11-03 05:17:39 +01:00
Stephen F. BoothandUrs Fleisch 19cceab211 DSDIFF support, add tests, fix formatting 2023-10-23 06:06:05 +02:00
Stephen F. BoothandUrs Fleisch 39d1d68237 DSD Stream File (DSF) support 2023-09-26 16:23:03 +02:00
Urs FleischandGitHub 97203503b0 Do not miss frames when an extended header is present (#1081) 2023-03-18 08:08:37 +01:00
Urs FleischandGitHub e21640bf10 MP4: Detect atoms with invalid length or type (#1077) 2023-03-18 08:07:46 +01:00
Urs Fleisch 197d2a684b Correctly parse MP4 non-full meta atoms (#1041)
There are m4a files with regular (non-full) meta atoms. When such
a meta atom is not correctly parsed, the subsequent atoms are not
recognized and offsets will not be adjusted when atoms are added,
which will corrupt the MP4 file.

This change will look behind the meta atom to check if the next
atom follows directly, i.e. without the four bytes with version
and flags as they exist in full atoms. In such a case, these
four bytes will not be skipped.

Witnesses of this strange format specification are
https://leo-van-stee.github.io/
https://github.com/axiomatic-systems/Bento4/blob/v1.6.0-639/Source/C%2B%2B/Core/Ap4ContainerAtom.cpp#L60
2022-03-12 07:33:32 +01:00
Urs Fleisch f3bdd416da Remove some DSF and DSDIFF leftovers
These can be merged back into master from the branch
add_dsf_and_dsdiff_file_formats.
2021-01-02 10:50:52 +01:00
Urs Fleisch 1a2e1d08ac Merge pull request #986 from ufleisch/ufleisch/wav-extensible-subformat
WAV: Support subformat in WAVE_FORMAT_EXTENSIBLE (#850)
2021-01-01 11:48:06 +01:00
Urs Fleisch a00b3499b4 WavPack: Add test with non-standard sample rate 2020-12-23 07:04:51 +01:00
Urs Fleisch 1332d44ff6 WAV: Test properties of file with WAVE_FORMAT_EXTENSIBLE
uint8we.wav: http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples/AFsp/M1F1-uint8WE-AFsp.wav
2020-12-21 15:42:13 +01:00
David Bryant ec9c49b964 add test for WavPack DSD (issue #962) 2020-07-01 08:35:20 -07:00
Jonas KvingeandStephen F. Booth d71398c953 Add DSF and DSDIFF file types management (#878)
* Add DSF and DSDIFF file types management

* Fixes for some build chains

* unit64_t replaced by unsigned long long, warning fixes

* Remove C++11 extension incompatible with some build chains (enumeration in a nested name specifier)

* Change typedef types (uint, ulong, ...) to standard types
remove BUILD_FRAMEWORK changes from this pull request

* Replace deprecated String::null and ByteVector::null by String() and ByteVector()
Styling update, thanks to FestusHagen

* Restyling

* Restyling to reduce length of excessively long lines

* Add to detectByExtension

* Added `isSupported(IOStream *stream)` to `DSF::File` and `DSDIFF::File`
2018-10-26 19:45:49 -05:00
Tsuda Kageyu 3d14ff74b1 Remove a duplicate test file. 2017-01-27 22:10:02 +09:00
Tsuda Kageyu 6bb92c34fa Ignore fake MPEG frame headers when seeking them. 2017-01-20 22:38:25 +09:00
Tsuda Kageyu 13be28a52c Be tolerant of empty FLAC seektable blocks. 2017-01-10 00:11:13 +09:00
Ramesh Shanmugasundaram 83c72518ab Renamed unsupported-extension.xxx and modified test
The file name unsupported-extension.xxx causes issue when unpacked
taglib-xxx.gz over an NFS partition. The file extension ".xxx" is the
one NFS uses for its own purpose and hence it will not allow creation
of this file.

Hence renamed the file and modified the test cases that checks for this
file.

Signed-off-by: Ramesh Shanmugasundaram <[email protected]>
2016-12-22 15:19:45 +00:00
Tsuda Kageyu b98a984b66 Fix handling of lowercase 'metadata_block_picture' fields in Vorbis comments.
Also refactored some redundant code for parsing pictures.
2016-11-11 00:07:32 +09:00
Tsuda Kageyu f5ca097379 Proper handling of MP4 atoms with zero length.
If the size of an atom is 0, it designates the last atom which extends to the end of the file.
2016-11-02 15:44:50 +09:00
Tsuda Kageyu 6a96a6426a Replace a possibly non-free file in the test suite. 2016-10-22 02:11:16 +09:00
Tsuda Kageyu 9b995544e4 Fix reading table of contents frames with a lot of children. 2016-05-14 09:58:19 +09:00
Tsuda Kageyu 9976155aa9 Ignore 'fact' chunk of WAV files if their format is PCM.
TagLib reports wrong length of some PCM files with a 'fact' chunk.
2016-01-30 00:51:28 +09:00
Tsuda Kageyu fe92f3dffe Add a test for broken MPEG audio frames. 2016-01-09 13:30:00 +09:00
Tsuda Kageyu 081d6eaf76 More robust checks for invalid MPEG frame headers. (again) 2015-12-22 14:57:23 +09:00
Tsuda Kageyu be9b5cc93a More robust checks for invalid MPEG frame headers. 2015-12-08 11:20:51 +09:00
Tsuda Kageyu 59088096e6 Add some tests for M4V files. 2015-11-30 17:18:50 +09:00
Tsuda Kageyu 11f4e4e1ca Merge pull request #567 from TsudaKageyu/audioprop-wv
(wishlist) WavPack: AudioProperties improvements
2015-08-01 01:30:19 +09:00
Tsuda Kageyu 9759bd2dd7 Merge pull request #566 from TsudaKageyu/audioprop-tta
(wishlist) TrueAudio: AudioProperties improvements
2015-08-01 01:30:12 +09:00
Tsuda Kageyu b28784538a Merge pull request #565 from TsudaKageyu/audioprop-wav
(wishlist) WAV: AudioProperties improvements
2015-08-01 01:30:03 +09:00
Tsuda Kageyu 6a778751ee Merge pull request #560 from TsudaKageyu/audioprop-mpeg
(wishlist) MPEG: AudioProperties improvements
2015-08-01 01:29:06 +09:00
Tsuda Kageyu 692ce897cb Merge pull request #557 from TsudaKageyu/audioprop-flac
(wishlist) FLAC: AudioProperties improvements
2015-08-01 01:27:06 +09:00
Tsuda Kageyu 0ed1c29acc Merge pull request #556 from TsudaKageyu/audioprop-asf
(wishlist) ASF: AudioProperties improvements
2015-08-01 01:26:52 +09:00
Tsuda Kageyu 3c59b7858a Merge pull request #555 from TsudaKageyu/audioprop-ape
(wishlist) APE: AudioProperties improvements
2015-08-01 01:21:59 +09:00
Tsuda Kageyu 21412e2ba2 FLAC: AudioProperties improvements
Add lengthInSeconds(), lengthInMilliseconds() properties. (#503)
Add bitsPerSample() property besides sampleWidth(). (#360)
Remove some data members which are not needed to carry.
Add some tests for audio properties.
Add some supplementary comments.
2015-08-01 00:49:21 +09:00
Tsuda Kageyu 6f944b0291 Make FLAC::File tolerant to zero-sized padding blocks. 2015-07-29 20:52:56 +09:00
Tsuda Kageyu 91ed3548f1 ASF: Enable ASF::Properties to get the audio codec information. 2015-06-21 02:42:47 +09:00
Tsuda Kageyu 2155b4fd50 TrueAudio: A bit more accurate calculation of the stream length. 2015-06-20 17:36:00 +09:00
Tsuda Kageyu 8f6af3f020 WavPack: A bit more accurate calculation of the stream length. 2015-06-18 18:00:03 +09:00
Tsuda Kageyu 22f250eaa4 WavPack: AudioProperties improvements
Add lengthInSeconds(), lengthInMilliseconds() properties. (#503)
Add isLossless() property.
Support multi channel. (#92)
Remove some data members which are not needed to carry.
Add some tests for audio properties.
Add some supplementary comments.
2015-06-18 17:59:06 +09:00