diff --git a/NEWS b/CHANGELOG.md
similarity index 73%
rename from NEWS
rename to CHANGELOG.md
index b1c25da0e..c9dac2f54 100644
--- a/NEWS
+++ b/CHANGELOG.md
@@ -3,6 +3,117 @@ TagLib 2.0 (Jan 24, 2024)
* New major version, binary incompatible, but source-compatible with the
latest 1.x release if no deprecated features are used.
+ * Requires a C++17 compiler and uses features of C++17.
+ * Major code cleanup, fixed warnings issued by compilers and static analyzers.
+ * Made methods virtual which should have been virtual but could not be
+ changed to keep binary compatibility, remove related workarounds.
+ * Removed deprecated functions:
+ - APE::Item::Item(const String &, const String &)
+ - APE::Item::toStringList(): Use values()
+ - APE::Item::value(): Use binaryData()
+ - ASF::Properties::setLength()
+ - ByteVector::checksum()
+ - ByteVector::isNull(): Use isEmpty()
+ - ByteVector::null
+ - FLAC::File::setID3v2FrameFactory()
+ - FLAC::File::streamInfoData()
+ - FLAC::File::streamLength()
+ - FLAC::Properties::Properties(File *, ReadStyle)
+ - FLAC::Properties::sampleWidth(): Use bitsPerSample()
+ - File::isReadable(): Use system functions
+ - File::isWritable(): Use system functions
+ - FileName::str()
+ - FileRef::create(): Use constructor
+ - MP4::Tag::itemListMap(): Use itemMap()
+ - MPC::File::remove(): Use strip()
+ - MPC::Properties::Properties(const ByteVector &, long, ReadStyle)
+ - MPEG::File::save(int, ...): Use overload
+ - MPEG::File::setID3v2FrameFactory(): Use constructor
+ - MPEG::ID3v2::Frame::Header::Header(const ByteVector &, bool)
+ - MPEG::ID3v2::Frame::Header::frameAlterPreservation(): Use
+ fileAlterPreservation()
+ - MPEG::ID3v2::Frame::Header::setData(const ByteVector &, bool)
+ - MPEG::ID3v2::Frame::Header::size(unsigned int): Use size()
+ - MPEG::ID3v2::Frame::Header::unsycronisation(): use unsynchronisation()
+ - MPEG::ID3v2::Frame::checkEncoding(const StringList &, String::Type): Use
+ checkTextEncoding(const StringList &, String::Type)
+ - MPEG::ID3v2::Frame::headerSize(): Use Header::size()
+ - MPEG::ID3v2::Frame::headerSize(unsigned int): Use
+ Header::size(unsigned int)
+ - MPEG::ID3v2::FrameFactory::createFrame(const ByteVector &, bool)
+ - MPEG::ID3v2::FrameFactory::createFrame(const ByteVector &, unsigned int):
+ Use createFrame(const ByteVector &, const Header *)
+ - MPEG::ID3v2::RelativeVolumeFrame::channelType()
+ - MPEG::ID3v2::RelativeVolumeFrame::peakVolume(): Use peakVolume(ChannelType)
+ - MPEG::ID3v2::RelativeVolumeFrame::setChannelType()
+ - MPEG::ID3v2::RelativeVolumeFrame::setPeakVolume(const PeakVolume &): Use
+ setPeakVolume(const PeakVolume &, ChannelType)
+ - MPEG::ID3v2::RelativeVolumeFrame::setVolumeAdjustment(float): Use
+ setVolumeAdjustment(float, ChannelType)
+ - MPEG::ID3v2::RelativeVolumeFrame::setVolumeAdjustmentIndex(short): Use
+ setVolumeAdjustmentIndex(short, ChannelType)
+ - MPEG::ID3v2::RelativeVolumeFrame::volumeAdjustment(): Use
+ volumeAdjustment(ChannelType)
+ - MPEG::ID3v2::RelativeVolumeFrame::volumeAdjustmentIndex(): Use
+ volumeAdjustmentIndex(ChannelType)
+ - MPEG::ID3v2::Tag::footer()
+ - MPEG::ID3v2::Tag::render(int): Use render(Version)
+ - MPEG::XingHeader::xingHeaderOffset()
+ - Ogg::Page::getCopyWithNewPageSequenceNumber()
+ - Ogg::XiphComment::removeField(): Use removeFields()
+ - PropertyMap::unsupportedData(): Returns now const reference, use
+ addUnsupportedData() to add keys
+ - RIFF::AIFF::Properties::Properties(const ByteVector &, ReadStyle)
+ - RIFF::AIFF::Properties::Properties(const ByteVector &, int, ReadStyle)
+ - RIFF::AIFF::Properties::sampleWidth(): Use bitsPerSample()
+ - RIFF::WAV::File::save(TagTypes, bool, int): Use
+ save(TagTypes, StripTags, Version)
+ - RIFF::WAV::File::tag(): Returns now a TagUnion, use ID3v2Tag() to get an
+ ID3v2::Tag
+ - String::isNull(): Use isEmpty()
+ - String::null
+ - TrueAudio::File::setID3v2FrameFactory(): Use constructor
+ - WavPack::Properties::Properties(const ByteVector &, long, ReadStyle)
+* Behavioral changes:
+ - The basic tag methods (e.g. genre()) separate multiple values with " / "
+ instead of " ".
+ - The stream operator for String uses UTF-8 instead of ISO-8859-1 encoding.
+ - MP4 property ORIGINALDATE is mapped to "----:com.apple.iTunes:ORIGINALDATE"
+ instead of "----:com.apple.iTunes:originaldate".
+ * Unified interface for complex properties like pictures.
+ * Simplified the unified properties interface by providing its methods on
+ FileRef.
+ * C bindings: Support for properties (taglib_property_...) and complex
+ properties like cover art (taglib_complex_property_...), memory I/O streams.
+ * Support for Direct Stream Digital (DSD) stream files (DSF) and interchange
+ file format (DSDIFF, DFF), ADTS (AAC) files.
+ * The runtime version can be queried.
+ * Additional utility functions ByteVector::fromUShort(),
+ ByteVector::fromULongLong(), ByteVector::toULongLong(),
+ ByteVector::toULongLong(), List::sort().
+ * Fixed List::setAutoDelete() affecting implicitly shared copies.
+ * Build system: Direct support for CMake, find_package(TagLib) exports target
+ TagLib::tag.
+ * Build system: Fixed PackageConfig to support both relative and absolute paths.
+ * Build system: utf8cpp is no longer included, it can be provided via a system
+ package or a Git submodule.
+ * ASF: Support additional properties ARTISTWEBPAGE, ENCODING, INITIALKEY,
+ ORIGINALALBUM, ORIGINALARTIST, ORIGINALFILENAME, ORIGINALLYRICIST.
+ * ID3v2: Fixed extensibility of FrameFactory, use it also for WAV and AIFF
+ files.
+ * MP4: Support additional properties OWNER, RELEASEDATE.
+ * MP4: Introduced ItemFactory allowing clients to support new atom types.
+ * MP4: Detect duration from mvhd atom if not present in mdhd atom.
+ * MP4: Fixed type of hdvd atom to be integer instead of boolean.
+ * MP4: Tolerate trailing garbage in M4A files.
+ * MPC: Fixed content check in presence of an ID3v2 tag.
+ * MPEG: Do not scan full file for ID3v2 tag when ReadStyle Fast is used.
+ * RIFF: Support properties ALBUM, ARRANGER, ARTIST, ARTISTWEBPAGE, BPM,
+ COMMENT, COMPOSER, COPYRIGHT, DATE, DISCSUBTITLE, ENCODEDBY, ENCODING,
+ ENCODINGTIME, GENRE, ISRC, LABEL, LANGUAGE, LYRICIST, MEDIA, PERFORMER,
+ RELEASECOUNTRY, REMIXER, TITLE, TRACKNUMBER.
+ * WAV: Fixed crash with files having the "id3 " chunk as the only valid chunk.
+ * Windows: Fixed support for files larger than 2GB.
TagLib 1.13.1 (Jul 1, 2023)
===========================
diff --git a/Doxyfile.cmake b/Doxyfile.cmake
index ce2147844..3c955f2a7 100644
--- a/Doxyfile.cmake
+++ b/Doxyfile.cmake
@@ -122,7 +122,8 @@ INPUT = @CMAKE_SOURCE_DIR@/taglib
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.h \
*.hh \
- *.H
+ *.H \
+ *.dox
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
diff --git a/INSTALL.md b/INSTALL.md
index 48c9f6fb9..1d9862f97 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1,5 +1,4 @@
-TagLib Installation
-===================
+# TagLib Installation
TagLib uses the CMake build system. As a user, you will most likely want to
build TagLib in release mode and install it into a system-wide location.
@@ -19,16 +18,182 @@ If you want to build TagLib without ZLib, you can use
make
sudo make install
-See http://www.cmake.org/cmake/help/runningcmake.html for generic help on
-running CMake.
-
-Mac OS X
---------
-
-On Mac OS X, you might want to build a framework that can be easily integrated
+See [cmake(1)](https://cmake.org/cmake/help/latest/manual/cmake.1.html) for
+generic help on running CMake.
+
+## Build Options
+
+These are the most important build options. For details, have a look into the
+CMakeLists.txt file.
+
+| Option | Description |
+| ----------------------- | ------------------------------------------ |
+| `BUILD_SHARED_LIBS` | Build shared libraries |
+| `CMAKE_BUILD_TYPE` | Debug, Release, RelWithDebInfo, MinSizeRel |
+| `BUILD_EXAMPLES` | Build examples |
+| `BUILD_BINDINGS` | Build C bindings |
+| `BUILD_TESTING` | Build unit tests |
+| `TRACE_IN_RELEASE` | Enable debug output in release builds |
+| `WITH_ZLIB` | Whether to build with ZLib (default ON) |
+| `ZLIB_ROOT` | Where to find ZLib's root directory |
+| `ZLIB_INCLUDE_DIR` | Where to find ZLib's include directory |
+| `ZLIB_LIBRARY` | Where to find ZLib's library |
+| `CMAKE_INSTALL_PREFIX` | Where to install Taglib |
+| `ENABLE_STATIC_RUNTIME` | Link with MSVC runtime statically |
+| `BUILD_FRAMEWORK` | Build a macOS framework |
+
+## Dependencies
+
+A required dependency is [utf8cpp](https://github.com/nemtrif/utfcpp). You can
+install the corresponding package (libutfcpp-dev on Ubuntu, utf8cpp in Homebrew,
+utfcpp in vcpkg) or fetch the Git submodule with `git submodule update --init`.
+
+Optional dependencies are
+- [zlib](https://www.zlib.net/): You can disable it with `-DWITH_ZLIB=OFF`,
+ build and install it from the sources or use a package (zlib1g-dev on Ubuntu,
+ zlib in vcpkg). It is needed for compressed ID3v2 frames.
+- [CppUnit](https://wiki.documentfoundation.org/Cppunit): Is required for unit
+ tests, which are disabled by default. If you enable them with
+ `-DBUILD_TESTING=ON`, you can build and install it from the sources or use a
+ package (libcppunit-dev on Ubuntu, cppunit in Homebrew, cppunit in vcpkg).
+ If the unit tests are enabled, you can run them with your build tool
+ (`make check`, `ninja check`) or via CMake
+ `cmake --build /path/to/build-dir --target check`.
+
+## UNIX (Including Linux, BSD and macOS)
+
+#### Building TagLib
+
+On Linux, you can install the dependencies using the package manager of your
+distribution. On macOS with Homebrew, you can use `brew install cppunit utf8cpp`
+to install the dependencies.
+
+```
+# Adapt these environment variables to your directories
+TAGLIB_SRC_DIR=$HOME/projects/taglib/src/taglib
+TAGLIB_DST_DIR=$HOME/projects/taglib/src/build
+cd $TAGLIB_SRC_DIR
+cmake -B $TAGLIB_DST_DIR -DBUILD_SHARED_LIBS=ON -DVISIBILITY_HIDDEN=ON \
+ -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON \
+ -DCMAKE_BUILD_TYPE=Release
+cmake --build $TAGLIB_DST_DIR --config Release
+cmake --build $TAGLIB_DST_DIR --config Release --target check
+
+# Install to ~/pkg folder
+cmake --install $TAGLIB_DST_DIR --config Release --prefix $HOME/pkg --strip
+
+# Run example from installed package
+LD_LIBRARY_PATH=$HOME/pkg/lib $HOME/pkg/bin/tagreader /path/to/audio-file
+```
+
+#### Building a Project Using TagLib
+
+As an example for an external application using TagLib, we create a folder
+taglib-client and copy the file tagreader.cpp from the examples folder
+of the TagLib sources into it. We then add this simple CMakeLists.txt.
+
+```
+cmake_minimum_required(VERSION 3.5.0)
+project(taglib-client)
+set(CMAKE_CXX_STANDARD 17)
+find_package(ZLIB)
+find_package(TagLib 2.0.0 REQUIRED)
+add_executable(tagreader tagreader.cpp)
+target_link_libraries(tagreader TagLib::tag)
+```
+
+To build into a folder `build` inside this directory, just run
+
+```
+# Set this to the path where TagLib is installed
+TAGLIB_PREFIX=$HOME/pkg
+cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TAGLIB_PREFIX
+cmake --build build --config Release
+
+build/tagreader /path/to/audio-file
+```
+
+If TagLib is installed in a standard location (e.g. /usr, /usr/local), its CMake
+configuration is found without setting CMAKE_INSTALL_PREFIX (or alternatives
+like CMAKE_PREFIX_PATH, CMAKE_SYSTEM_PREFIX_PATH).
+
+To use the C-bindings with tagreader_c.c, you can change the last two lines in
+CMakeLists.txt to
+
+```
+add_executable(tagreader_c tagreader_c.c)
+target_link_libraries(tagreader_c TagLib::tag_c)
+```
+
+#### Building a Project Using pkg-config
+
+Before version 2.0, TagLib did not export CMake configuration, therefore
+`pkg-config` could be used. This is still possible.
+
+Note, however, that `pkg-config` makes it more difficult to use packages which
+are not installed in a standard location. You can point `pkg-config` to search
+in non-standard locations for .pc-files, but they still contain the install
+locations defined when building TagLib. Since we did not give a
+`CMAKE_INSTALL_PREFIX` in the example above, the default `/usr/local/` is used.
+
+```
+PKG_CONFIG_PATH=$HOME/pkg/lib/pkgconfig pkg-config --libs --cflags taglib
+-I/usr/local/include -I/usr/local/include/taglib -L/usr/local/lib -ltag -lz
+```
+
+The following examples use the same build example with additional CMake
+parameters affecting the installation location.
+
+- Using the default prefix `-DCMAKE_INSTALL_PREFIX=/usr/local`:
+ ```
+ -I/usr/local/include -I/usr/local/include/taglib -L/usr/local/lib -ltag -lz
+ ```
+- Using an absolute prefix `-DCMAKE_INSTALL_PREFIX=/usr`:
+ ```
+ -I/usr/include/taglib -ltag -lz
+ ```
+- Using absolute lib and include directories
+ `-DCMAKE_INSTALL_LIBDIR=/abs-lib -DCMAKE_INSTALL_INCLUDEDIR=/abs-include -DCMAKE_INSTALL_PREFIX=/usr`:
+ ```
+ -I/abs-include -I/abs-include/taglib -L/abs-lib -ltag -lz
+ ```
+- Using relative lib and include directories
+ `-DCMAKE_INSTALL_LIBDIR=rel-lib -DCMAKE_INSTALL_INCLUDEDIR=rel-include -DCMAKE_INSTALL_PREFIX=/usr`:
+ ```
+ -I/usr/rel-include -I/usr/rel-include/taglib -L/usr/rel-lib -ltag -lz
+ ```
+ This is the output of
+ ```
+ PKG_CONFIG_PATH=$HOME/pkg/rel-lib/pkgconfig pkg-config --libs --cflags taglib
+ ```
+ You could add `--define-prefix` to the `pkg-config` arguments to have the
+ effective location `$HOME/pkg/` instead of `/usr/` in the output.
+
+Therefore, the correct paths for our example package would be given when using
+the `--define-prefix` feature.
+
+```
+PKG_CONFIG_PATH=$HOME/pkg/lib/pkgconfig pkg-config --define-prefix --libs --cflags taglib
+```
+
+You can use pkg-config from CMake, however, relocation with `--define-prefix`
+is not supported.
+
+```
+cmake_minimum_required(VERSION 3.6.0)
+project(taglib-client)
+find_package(PkgConfig)
+pkg_check_modules(TAGLIB REQUIRED IMPORTED_TARGET taglib)
+add_executable(tagreader tagreader.cpp)
+target_link_libraries(tagreader PkgConfig::TAGLIB)
+```
+
+#### Framework on macOS
+
+On macOS, you might want to build a framework that can be easily integrated
into your application. If you set the BUILD_FRAMEWORK option on, it will compile
TagLib as a framework. For example, the following command can be used to build
-a framework with Mac OS X 10.10 as the deployment target:
+a framework with macOS 10.10 as the deployment target:
mkdir build; cd build
cmake .. -DCMAKE_BUILD_TYPE=Release \
@@ -51,176 +216,217 @@ For a 10.10 static library, use:
After `make`, and `make install`, add `libtag.` to your XCode project, and add
the include folder to the project's User Header Search Paths.
-Windows
--------
-
-It's Windows ... Systems vary!
-This means you need to adjust things to suit your system, especially paths.
-
-Tested with:
-* Microsoft Visual Studio 2010, 2015, 2017
-* Microsoft C++ Build Tools 2015, 2017 (standalone packages not requiring Visual Studio)
-* GCC by mingw-w64.sf.net v4.6.3 (Strawberry Perl 32b)
-* MinGW32-4.8.0
-
-Requirements:
-* Tool chain, build environment, whatever ya want to call it ...
- Installed and working.
-* CMake program (available at: www.cmake.org).
- Installed and working.
-
-Optional:
-* Zlib library.
- Available in some tool chains, not all.
- Search the web, take your choice.
-
- Useful configuration options used with CMake (GUI and/or command line):
- Any of the `ZLIB_` variables may be used at the command line, `ZLIB_ROOT` is only
- available on the command line.
-
- | option | description |
- | ----------------------- | ----------- |
- | `WITH_ZLIB=` | Whether to build with ZLib |
- | `ZLIB_ROOT=` | Where to find ZLib's root directory. Assumes parent of: `\include` and `\lib.`|
- | `ZLIB_INCLUDE_DIR=` | Where to find ZLib's Include directory.|
- | `ZLIB_LIBRARY=` | Where to find ZLib's Library.|
- | `ZLIB_SOURCE=` | Where to find ZLib's Source Code. Alternative to `ZLIB_INCLUDE_DIR` and `ZLIB_LIBRARY`.|
- | `CMAKE_INSTALL_PREFIX=` | Where to install Taglib. |
- | `CMAKE_BUILD_TYPE=` | Release, Debug, etc ... (Not available in MSVC) |
-
-The easiest way is at the command prompt (Visual C++ command prompt for MSVS users – batch file and/or shortcuts are your friends).
-
-1. **Build the Makefiles:**
-
- Replace "GENERATOR" with your needs.
- * For MSVS: `Visual Studio XX YYYY`, e.g. `Visual Studio 14 2015`.
-
- **Note**: As Visual Studio 2017 supports CMake, you can skip this step and open the taglib
- folder in VS instead.
- * For MinGW: `MinGW Makefiles`
-
- C:\GitRoot\taglib> cmake -G "GENERATOR" -DCMAKE_INSTALL_PREFIX=C:\Libraries\taglib
-
- Or use the CMake GUI:
- 1. Open CMake GUI.
- 2. Set paths: *Where is the source code* and *Where to build the binaries*.
-
- In the example, both would be: `C:\GitRoot\taglib`
- 3. Tick: Advanced
- 4. Select: Configure
- 5. Select: Generator
- 6. Tick: Use default native compilers
- 7. Select: Finish
- Wait until done.
- 8. If using ZLib, Scroll down.
- (to the bottom of the list of options ... should go over them all)
- 1. Edit: `ZLIB_INCLUDE_DIR`
- 2. Edit: `ZLIB_LIBRARY`
- 9. Select: Generate
-
-2. **Build the project**
- * MSVS:
-
- C:\GitRoot\taglib> msbuild all_build.vcxproj /p:Configuration=Release
- OR (Depending on MSVS version or personal choice)
-
- C:\GitRoot\taglib> devenv all_build.vcxproj /build Release
- OR in the MSVS GUI:
- 1. Open MSVS.
- 2. Open taglib solution.
- 3. Set build type to: Release (look in the toolbars)
- 4. Hit F7 to build the solution. (project)
- * MinGW:
-
- C:\GitRoot\taglib> gmake
-
- OR (Depending on MinGW install)
-
- C:\GitRoot\taglib> mingw32-make
-
-3. **Install the project**
-
- (Change `install` to `uninstall` to uninstall the project)
- * MSVS:
-
- C:\GitRoot\taglib> msbuild install.vcxproj
- OR (Depending on MSVC version or personal choice)
-
- C:\GitRoot\taglib> devenv install.vcxproj
-
- Or in the MSVS GUI:
- 1. Open project.
- 2. Open Solution Explorer.
- 3. Right Click: INSTALL
- 4. Select: Project Only
- 5. Select: Build Only INSTALL
- * MinGW:
-
- C:\GitRoot\taglib> gmake install
- OR (Depending on MinGW install)
-
- C:\GitRoot\taglib> mingw32-make install
-
-
-To build a static library, set the following two options with CMake:
-
- -DBUILD_SHARED_LIBS=OFF -DENABLE_STATIC_RUNTIME=ON
+## Windows
+
+### Using Visual Studio Build Tools
+
+For this example, we assume that you have the Visual Studio Build Tools 2022
+installed. Additionally, you need [cmake](https://cmake.org/), which can be
+installed for example using [scoop](https://scoop.sh/) with
+`scoop install cmake`.
+
+#### Building TagLib (MSVC)
+
+You can build and install the dependencies
+[utf8cpp](https://github.com/nemtrif/utfcpp) and optionally
+[zlib](https://www.zlib.net/) and
+[CppUnit](https://wiki.documentfoundation.org/Cppunit) yourself, but it is
+probably easier using a package manager such as [vcpkg](https://vcpkg.io/),
+which can be installed using `scoop install vcpkg` and then install the
+dependencies using `vcpkg install utfcpp zlib cppunit`.
+
+Now you can build TagLib from PowerShell.
+
+```
+# Adapt these environment variables to your directories
+$env:TAGLIB_SRC_DIR = "${env:HOMEDRIVE}${env:HOMEPATH}/projects/taglib/src/taglib"
+$env:TAGLIB_DST_DIR = "${env:HOMEDRIVE}${env:HOMEPATH}/projects/taglib/src/msvs_vcpkg_build"
+cd $env:TAGLIB_SRC_DIR
+cmake -B $env:TAGLIB_DST_DIR -DBUILD_SHARED_LIBS=ON -DVISIBILITY_HIDDEN=ON `
+ -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON `
+ -DCMAKE_BUILD_TYPE=Release `
+ -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
+ -G "Visual Studio 17 2022"
+cmake --build $env:TAGLIB_DST_DIR --config Release
+
+# Add directories containing DLL dependencies to path
+$env:Path += -join(";$env:TAGLIB_DST_DIR\taglib\Release;",
+"$env:TAGLIB_DST_DIR\bindings\c\Release;",
+"$env:VCPKG_ROOT\packages\cppunit_x64-windows\bin;",
+"$env:VCPKG_ROOT\packages\utfcpp_x64-windows\bin;",
+"$env:VCPKG_ROOT\packages\zlib_x64-windows\bin")
+cmake --build $env:TAGLIB_DST_DIR --config Release --target check
+
+# Install to \pkg folder on current drive
+cmake --install $env:TAGLIB_DST_DIR --config Release --prefix /pkg --strip
+
+# Static library
+$env:TAGLIB_DST_DIR = "C:/Users/fle/projects/taglib/src/msvs_vcpkg_static_build"
+cmake -B $env:TAGLIB_DST_DIR -DBUILD_SHARED_LIBS=OFF -DVISIBILITY_HIDDEN=ON `
+ -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON `
+ -DCMAKE_BUILD_TYPE=Release `
+ -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
+ -G "Visual Studio 17 2022"
+cmake --build $env:TAGLIB_DST_DIR --config Release
+
+cmake --build $env:TAGLIB_DST_DIR --config Release --target check
+
+# Install to \pkg_static folder on current drive
+cmake --install $env:TAGLIB_DST_DIR --config Release --prefix /pkg_static --strip
+```
Including `ENABLE_STATIC_RUNTIME=ON` indicates you want TagLib built using the
static runtime library, rather than the DLL form of the runtime.
-Unit Tests
-----------
-
-If you want to run the test suite to make sure TagLib works properly on your
-system, you need to have cppunit installed. To build the tests, include
-the option `-DBUILD_TESTING=ON` when running cmake.
-
-The test suite has a custom target in the build system, so you can run
-the tests using make:
-
- make check
-
-Windows MinGW:
-
-* Get cppunit from https://www.freedesktop.org/wiki/Software/cppunit/
-* Build it for MinGW:
- - `./autogen.sh`
- - `./configure --disable-shared`
- - `mingw32-make; mingw32-make install DESTDIR=/path/to/install/dir`
-* Build TagLib with testing enabled:
- - ```
- cmake -G "MinGW Makefiles" -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_SHARED_LIBS=OFF \
- -DCPPUNIT_INCLUDE_DIR=/path/to/cppunit/include \
- -DCPPUNIT_LIBRARIES=/path/to/cppunit/lib/libcppunit.a \
- -DCPPUNIT_INSTALLED_VERSION=1.15.1
- ```
- - `mingw32-make`
- - `mingw32-make check`
-
-Windows MSVS:
-
-* Get cppunit from https://www.freedesktop.org/wiki/Software/cppunit/
-* Build it in Visual Studio:
- - Open examples/examples2008.sln, convert all, do not overwrite.
- - Set architecture to x64, build configuration, e.g. Debug DLL.
- - It may fail, but the needed libraries should be available in src\cppunit\DebugDll.
-* Build TagLib with testing enabled:
- - ```
- cmake -G "Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON
- -DBUILD_SHARED_LIBS=OFF -DENABLE_STATIC_RUNTIME=ON
- -DCPPUNIT_INCLUDE_DIR=\path\to\cppunit\include
- -DCPPUNIT_LIBRARIES=\path\to\cppunit\DebugDll\cppunitd_dll.lib
- -DCPPUNIT_INSTALLED_VERSION=1.15.1
- ```
- - `msbuild all_build.vcxproj /p:Configuration=Debug`
- - `path %path%;\path\to\cppunit\DebugDll`
- - `tests\Debug\test_runner.exe`
-
-macOS:
-
-* Install cppunit using a package manager, e.g. `brew install cppunit`
-* Build TagLib with testing enabled:
- - `cmake -DBUILD_TESTS=ON -DBUILD_EXAMPLES=ON -DBUILD_SHARED_LIBS=OFF`
- - `make`
- - `make check`
+#### Building a Project Using TagLib (MSVC)
+
+As an example for an external application using TagLib, we create a folder
+taglib-client and copy the file tagreader.cpp from the examples folder
+of the TagLib sources into it. We then add this simple CMakeLists.txt.
+
+```
+cmake_minimum_required(VERSION 3.5.0)
+project(taglib-client)
+set(CMAKE_CXX_STANDARD 17)
+find_package(ZLIB)
+find_package(TagLib 2.0.0 REQUIRED)
+add_executable(tagreader tagreader.cpp)
+target_link_libraries(tagreader TagLib::tag)
+```
+
+To build into a folder build inside this directory, just run
+
+```
+# Set this to the path where TagLib is installed
+$env:TAGLIB_PREFIX = "/pkg"
+cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$env:TAGLIB_PREFIX" `
+ -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
+ -G "Visual Studio 17 2022"
+cmake --build build --config Release
+
+# Add directories containing DLL dependencies to path
+$env:Path += ";$env:TAGLIB_PREFIX\bin;$env:VCPKG_ROOT\packages\zlib_x64-windows\bin"
+build\Release\tagreader /path/to/audio-file
+```
+
+To use the C-bindings with tagreader_c.c, you can change the last two lines in
+CMakeLists.txt to
+
+```
+add_executable(tagreader_c tagreader_c.c)
+target_link_libraries(tagreader_c TagLib::tag_c)
+```
+
+If you link against a static TagLib, you have to adapt the installation path
+(e.g. "/pkg_static") and add the following line to CMakeLists.txt
+
+```
+target_compile_definitions(tagreader_c PRIVATE TAGLIB_STATIC)
+```
+
+### Using MSYS2
+
+#### Building TagLib (MSYS2)
+
+To build TagLib using Clang from MSYS, install [msys2](https://www.msys2.org/),
+then start the MSYS CLANG64 shell and install the dependencies as they are
+specified in the [MSYS recipe for TagLib](
+https://packages.msys2.org/package/mingw-w64-clang-x86_64-taglib?repo=clang64).
+
+```
+pacman -Suy
+pacman -S mingw-w64-clang-x86_64-gcc-libs mingw-w64-clang-x86_64-zlib \
+ mingw-w64-clang-x86_64-cc mingw-w64-clang-x86_64-cmake \
+ mingw-w64-clang-x86_64-cppunit mingw-w64-clang-x86_64-ninja
+```
+
+Then you can build TagLib from the MSYS CLANG64 Bash.
+
+```
+# Adapt these environment variables to your directories
+TAGLIB_SRC_DIR=$HOME/projects/taglib/src/taglib
+TAGLIB_DST_DIR=$HOME/projects/taglib/src/msys_build
+cd $TAGLIB_SRC_DIR
+cmake -B $TAGLIB_DST_DIR -DBUILD_SHARED_LIBS=ON -DVISIBILITY_HIDDEN=ON \
+ -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON \
+ -DCMAKE_BUILD_TYPE=Release -G Ninja
+cmake --build $TAGLIB_DST_DIR --config Release
+
+PATH=$PATH:/clang64/bin:$TAGLIB_DST_DIR/taglib:$TAGLIB_DST_DIR/bindings/c \
+ cmake --build $TAGLIB_DST_DIR --config Release --target check
+
+# Install to /pkg_msys folder inside MSYS root (e.g. C:/msys64/pkg_msys/)
+cmake --install $TAGLIB_DST_DIR --config Release --prefix /pkg_msys --strip
+```
+
+#### Building a Project Using TagLib (MSYS2)
+
+As an example for an external application using TagLib, we create a folder
+taglib-client and copy the file tagreader.cpp from the examples folder
+of the TagLib sources into it. We then add this simple CMakeLists.txt.
+
+```
+cmake_minimum_required(VERSION 3.5.0)
+project(taglib-client)
+set(CMAKE_CXX_STANDARD 17)
+find_package(ZLIB)
+find_package(TagLib 2.0.0 REQUIRED)
+add_executable(tagreader tagreader.cpp)
+target_link_libraries(tagreader TagLib::tag)
+```
+
+To build into a folder build_msys inside this directory, just run
+
+```
+# Set this to the path where TagLib is installed
+TAGLIB_PREFIX=/pkg_msys
+cmake -B build_msys -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_INSTALL_PREFIX=$TAGLIB_PREFIX -G Ninja
+cmake --build build_msys --config Release
+
+PATH=$PATH:$TAGLIB_PREFIX/bin
+ build_msys/tagreader /path/to/audio-file
+```
+
+To use the C-bindings with tagreader_c.c, you can change the last two lines in
+CMakeLists.txt to
+
+```
+add_executable(tagreader_c tagreader_c.c)
+target_link_libraries(tagreader_c TagLib::tag_c)
+```
+
+### Using MinGW
+
+The instructions for MSYS2 can also be used to build with MinGW. You could use
+Git Bash together with the MinGW provided by Qt.
+
+```
+# Adapt these environment variables to your directories
+PATH=$PATH:/c/Qt/Tools/mingw1120_64/bin
+TAGLIB_SRC_DIR=$HOME/projects/taglib/src/taglib
+TAGLIB_DST_DIR=$HOME/projects/taglib/src/mingw_build
+cd $TAGLIB_SRC_DIR
+cmake -B $TAGLIB_DST_DIR -DBUILD_SHARED_LIBS=ON -DVISIBILITY_HIDDEN=ON \
+ -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON -DWITH_ZLIB=OFF \
+ -DCMAKE_BUILD_TYPE=Release -G 'MinGW Makefiles'
+cmake --build $TAGLIB_DST_DIR --config Release
+
+PATH=$PATH:$TAGLIB_DST_DIR/taglib \
+ $TAGLIB_DST_DIR/examples/tagreader /path/to/audio-file
+
+# Install to C:\pkg_mingw
+cmake --install $TAGLIB_DST_DIR --config Release --prefix /c/pkg_mingw --strip
+```
+
+The installed package can then be used by other projects.
+
+```
+TAGLIB_PREFIX=/c/pkg_mingw
+cmake -B build_mingw -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_INSTALL_PREFIX=$TAGLIB_PREFIX -G 'MinGW Makefiles'
+cmake --build build_mingw --config Release
+
+PATH=$PATH:$TAGLIB_PREFIX/bin
+ build_mingw/tagreader /path/to/audio-file
+```
diff --git a/taglib/toolkit/propertymapping.dox b/taglib/toolkit/propertymapping.dox
new file mode 100644
index 000000000..7a87f612c
--- /dev/null
+++ b/taglib/toolkit/propertymapping.dox
@@ -0,0 +1,112 @@
+/*!
+\page p_propertymapping Mapping of Properties to Various Formats
+
+- If no mapping is given for an %ID3v2 tag, a TXXX frame will be used with the
+ key as a description.
+- Vorbis Comments are not included in the table because they use the names from
+ the *Key* column.
+- %APE tags will also use these keys unless another name can be found in its column.
+
+| Key | %ID3v2 | %RIFF | %MP4 | %APE | %ASF |
+| -------------------------- | ------ | ----- | -------------------------------------------------------- | ----------------------- | --------------------------------- |
+| ACOUSTID_FINGERPRINT | | | | | Acoustid/Fingerprint |
+| ACOUSTID_ID | | | | | Acoustid/Id |
+| ALBUM | TALB | IPRD | ©alb | | WM/AlbumTitle |
+| ALBUMARTIST | TPE2 | | aART | ALBUM ARTIST | WM/AlbumArtist |
+| ALBUMARTISTSORT | TSO2 | | soaa | | WM/AlbumArtistSortOrder |
+| ALBUMSORT | TSOA | | soal | | WM/AlbumSortOrder |
+| ARRANGER | | IENG | | | |
+| ARTIST | TPE1 | IART | ©ART | | |
+| ARTISTS | | | \----:com.apple.iTunes:ARTISTS | | WM/ARTISTS |
+| ARTISTSORT | TSOP | | soar | | WM/ArtistSortOrder |
+| ARTISTWEBPAGE | WOAR | IBSU | | | WM/AuthorURL |
+| ASIN | | | \----:com.apple.iTunes:ASIN | | |
+| AUDIOSOURCEWEBPAGE | WOAS | | | | ASIN |
+| BARCODE | | | \----:com.apple.iTunes:BARCODE | | WM/Barcode |
+| BPM | TBPM | IBPM | tmpo | | WM/BeatsPerMinute |
+| CATALOGNUMBER | | | \----:com.apple.iTunes:CATALOGNUMBER | | WM/CatalogNo |
+| COMMENT | COMM | ICMT | ©cmt | | |
+| COMPILATION | TCMP | | cpil | | |
+| COMPOSER | TCOM | IMUS | ©wrt | | WM/Composer |
+| COMPOSERSORT | TSOC | | soco | | |
+| CONDUCTOR | TPE3 | | \----:com.apple.iTunes:CONDUCTOR | | WM/Conductor |
+| COPYRIGHT | TCOP | ICOP | cprt | | |
+| COPYRIGHTURL | WCOP | | | | |
+| DATE | TDRC | ICRD | ©day | YEAR | WM/Year |
+| DISCNUMBER | TPOS | | disk | DISC | WM/PartOfSet |
+| DISCSUBTITLE | TSST | PRT1 | \----:com.apple.iTunes:DISCSUBTITLE | | WM/SetSubTitle |
+| DJMIXER | | | \----:com.apple.iTunes:DJMIXER | | |
+| ENCODEDBY | TENC | ITCH | ©too | | WM/EncodedBy |
+| ENCODING | TSSE | ISFT | | | WM/EncodingSettings |
+| ENCODINGTIME | TDEN | IDIT | | | |
+| ENGINEER | | | \----:com.apple.iTunes:ENGINEER | | |
+| FILETYPE | TFLT | | | | |
+| FILEWEBPAGE | WOAF | | | | |
+| GAPLESSPLAYBACK | | | pgap | | |
+| GENRE | TCON | IGNR | ©gen | | WM/Genre |
+| GROUPING | GRP1 | | ©grp | | |
+| INITIALKEY | TKEY | | | | WM/InitialKey |
+| INVOLVEDPEOPLE | TIPL | | | | |
+| ISRC | TSRC | ISRC | \----:com.apple.iTunes:ISRC | | WM/ISRC |
+| LABEL | TPUB | IPUB | \----:com.apple.iTunes:LABEL | | WM/Publisher |
+| LANGUAGE | TLAN | ILNG | \----:com.apple.iTunes:LANGUAGE | | WM/Language |
+| LENGTH | TLEN | | \----:com.apple.iTunes:LYRICIST | | |
+| LICENSE | | | \----:com.apple.iTunes:LICENSE | | |
+| LYRICIST | TEXT | IWRI | | | WM/Writer |
+| LYRICS | USLT | | ©lyr | | WM/Lyrics |
+| MEDIA | TMED | IMED | \----:com.apple.iTunes:MEDIA | | WM/Media |
+| MIXER | | | \----:com.apple.iTunes:MIXER | | |
+| MOOD | TMOO | | \----:com.apple.iTunes:MOOD | | WM/Mood |
+| MOVEMENTCOUNT | | | ©mvc | | |
+| MOVEMENTNAME | MVNM | | ©mvn | | |
+| MOVEMENTNUMBER | MVIN | | ©mvi | | |
+| MUSICBRAINZ_ALBUMID | | | \----:com.apple.iTunes:MusicBrainz Album Id | | MusicBrainz/Album Id |
+| MUSICBRAINZ_ALBUMARTISTID | | | \----:com.apple.iTunes:MusicBrainz Album Artist Id | | MusicBrainz/Album Artist Id |
+| MUSICBRAINZ_ARTISTID | | | \----:com.apple.iTunes:MusicBrainz Artist Id | | MusicBrainz/Artist Id |
+| MUSICBRAINZ_RELEASEGROUPID | | | \----:com.apple.iTunes:MusicBrainz Release Group Id | | MusicBrainz/Release Group Id |
+| MUSICBRAINZ_RELEASETRACKID | | | \----:com.apple.iTunes:MusicBrainz Release Track Id | | MusicBrainz/Release Track Id |
+| MUSICBRAINZ_TRACKID | | | \----:com.apple.iTunes:MusicBrainz Track Id | | MusicBrainz/Track Id |
+| MUSICBRAINZ_WORKID | | | \----:com.apple.iTunes:MusicBrainz Work Id | | MusicBrainz/Work Id |
+| MUSICIANCREDITS | TMCL | | | | |
+| MUSICIP_PUID | | | | | MusicIP/PUID |
+| ORIGINALALBUM | TOAL | | | | WM/OriginalAlbumTitle |
+| ORIGINALARTIST | TOPE | | | | WM/OriginalArtist |
+| ORIGINALDATE | TDOR | | \----:com.apple.iTunes:ORIGINALDATE | | WM/OriginalReleaseYear |
+| ORIGINALFILENAME | TOFN | | | | WM/OriginalFilename |
+| ORIGINALLYRICIST | TOLY | | | | WM/OriginalLyricist |
+| OWNER | TOWN | | ownr | | |
+| PAYMENTWEBPAGE | WPAY | | | | |
+| PERFORMER | | ISTR | | | |
+| PLAYLISTDELAY | TDLY | | | | |
+| PODCAST | PCST | | pcst | | |
+| PODCASTCATEGORY | TCAT | | catg | | |
+| PODCASTDESC | TDES | | desc | | |
+| PODCASTID | TGID | | egid | | |
+| PODCASTURL | WFED | | purl | | |
+| PRODUCEDNOTICE | TPRO | | | | |
+| PRODUCER | | | \----:com.apple.iTunes:PRODUCER | | WM/Producer |
+| PUBLISHERWEBPAGE | WPUB | | | | |
+| RADIOSTATION | TRSN | | | | |
+| RADIOSTATIONOWNER | TRSO | | | | |
+| RADIOSTATIONWEBPAGE | WORS | | | | |
+| RELEASECOUNTRY | | ICNT | \----:com.apple.iTunes:MusicBrainz Album Release Country | | MusicBrainz/Album Release Country |
+| RELEASEDATE | TDRL | | \----:com.apple.iTunes:RELEASEDATE | | |
+| RELEASESTATUS | | | \----:com.apple.iTunes:MusicBrainz Album Status | MUSICBRAINZ_ALBUMSTATUS | MusicBrainz/Album Status |
+| RELEASETYPE | | | \----:com.apple.iTunes:MusicBrainz Album Type | MUSICBRAINZ_ALBUMTYPE | MusicBrainz/Album Type |
+| REMIXER | TPE4 | IEDT | \----:com.apple.iTunes:REMIXER | MIXARTIST | WM/ModifiedBy |
+| SCRIPT | | | \----:com.apple.iTunes:SCRIPT | | WM/Script |
+| SHOWSORT | | | sosn | | |
+| SHOWWORKMOVEMENT | | | shwm | | |
+| SUBTITLE | TIT3 | | \----:com.apple.iTunes:SUBTITLE | | WM/SubTitle |
+| TAGGINGDATE | TDTG | | | | |
+| TITLE | TIT2 | INAM | ©nam | | |
+| TITLESORT | TSOT | | sonm | | WM/TitleSortOrder |
+| TRACKNUMBER | TRCK | IPRT | trkn | TRACK | WM/TrackNumber |
+| TVEPISODE | | | tves | | |
+| TVEPISODEID | | | tven | | |
+| TVNETWORK | | | tvnn | | |
+| TVSEASON | | | tvsn | | |
+| TVSHOW | | | tvsh | | |
+| URL | WXXX | | | | |
+| WORK | TIT1 | | ©wrk | | WM/ContentGroupDescription |
+*/
diff --git a/taglib/toolkit/taglib.h b/taglib/toolkit/taglib.h
index c212968ff..8d65c1ea0 100644
--- a/taglib/toolkit/taglib.h
+++ b/taglib/toolkit/taglib.h
@@ -95,7 +95,7 @@ namespace TagLib {
* - A clean, high level, C++ API to handling audio meta data.
* - Format specific APIs for advanced API users.
* - ID3v1, ID3v2, APE, FLAC, Xiph, iTunes-style MP4 and WMA tag formats.
- * - MP3, MPC, FLAC, MP4, ASF, AIFF, WAV, TrueAudio, WavPack, Ogg FLAC, Ogg Vorbis, Speex and Opus file formats.
+ * - MP3, MPC, FLAC, MP4, ASF, AIFF, WAV, DSF, DFF, TrueAudio, WavPack, Ogg FLAC, Ogg Vorbis, Speex and Opus file formats.
* - Basic audio file properties such as length, sample rate, etc.
* - Long term binary and source compatibility.
* - Extensible design, notably the ability to add other formats or extend current formats as a library user.
@@ -126,10 +126,14 @@ namespace TagLib {
* Please see the TagLib website for the latest
* downloads.
*
- * TagLib can be built using the CMake build system. TagLib installs a taglib-config and pkg-config file to
+ * TagLib can be built using the CMake build system. TagLib installs a CMake
+ * configuration and a taglib-config and pkg-config file to
* make it easier to integrate into various build systems. Note that TagLib's include install directory \e must
* be included in the header include path. Simply adding will \e not work.
*
+ * Detailed instructions about building TagLib itself and building with TagLib
+ * can be found in INSTALL.md
+ *
* \section start Getting Started
*
* TagLib provides both simple, abstract APIs which make it possible to ignore the differences between tagging
@@ -146,8 +150,7 @@ namespace TagLib {
*
* Here's a very simple example with TagLib:
*
- * \code
- *
+ * \code {.cpp}
* TagLib::FileRef f("Latex Solar Beef.mp3");
* TagLib::String artist = f.tag()->artist(); // artist == "Frank Zappa"
*
@@ -159,10 +162,63 @@ namespace TagLib {
*
* g.tag()->setTrack(1);
* g.save();
+ * \endcode
+ *
+ * If the basic tag interface, which provides methods like
+ * \link TagLib::Tag::title() title() \endlink,
+ * \link TagLib::Tag::artist() artist() \endlink,
+ * \link TagLib::Tag::album() album() \endlink,
+ * \link TagLib::Tag::comment() comment() \endlink,
+ * \link TagLib::Tag::genre() genre() \endlink,
+ * \link TagLib::Tag::year() year() \endlink,
+ * \link TagLib::Tag::track() track() \endlink
+ * and the corresponding setters, is not enough, the
+ * \link TagLib::PropertyMap PropertyMap \endlink interface
+ * offers a flexible abstraction for textual metadata.
+ * See \ref p_propertymapping for details about the mapping of tags to properties.
+ *
+ * \code {.cpp}
+ * TagLib::PropertyMap props = f.properties();
+ * TagLib::StringList artists = props["ARTIST"];
+ * artists.append("Jim Pons");
+ * props["ARTIST"] = artists;
+ * f.setProperties(props);
+ * f.save();
+ * \endcode
+ *
+ * An additional \link FileRef::complexProperties() abstraction \endlink is
+ * provided to handle complex (i.e. non textual) properties.
+ *
+ * \code {.cpp}
+ * TagLib::ByteVector data = ...;
+ * f.setComplexProperties("PICTURE", {
+ * {
+ * {"data", data},
+ * {"pictureType", "Front Cover"},
+ * {"mimeType", "image/jpeg"}
+ * }
+ * });
+ * \endcode
*
+ * Finally, for full control, there are specific types for all supported metadata formats.
+ *
+ * \code {.cpp}
+ * if(auto file = dynamic_cast(f.file())) {
+ * if(auto id3v2Tag = file->ID3v2Tag()) {
+ * auto frames = id3v2Tag->frameList("SYLT");
+ * if(!frames.isEmpty()) {
+ * if(auto syltFrame = dynamic_cast(
+ * frames.front())) {
+ * auto text = syltFrame->synchedText();
+ * // ...
+ * }
+ * }
+ * }
+ * }
* \endcode
*
- * More examples can be found in the \e examples directory of the source distribution.
+ * More examples can be found in the
+ * examples directory of the source distribution.
*
* \section Contact
*
diff --git a/taglib/toolkit/tpropertymap.h b/taglib/toolkit/tpropertymap.h
index 5030176df..5f2768228 100644
--- a/taglib/toolkit/tpropertymap.h
+++ b/taglib/toolkit/tpropertymap.h
@@ -46,6 +46,9 @@ namespace TagLib {
* and a nonempty list of corresponding values, each value being an arbitrary
* unicode String.
*
+ * See \ref p_propertymapping for the mapping of the different formats to
+ * properties.
+ *
* Note that most metadata formats pose additional conditions on the tag keys. The
* most popular ones (Vorbis, APE, ID3v2) should support all ASCII only words of
* length between 2 and 16.