mirror of
https://github.com/taglib/taglib.git
synced 2026-06-13 09:49:18 -04:00
Compare commits
84 Commits
v1.12-beta
...
v1.13.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c840222a39 | ||
|
|
39e712796f | ||
|
|
97203503b0 | ||
|
|
e21640bf10 | ||
|
|
a31356e330 | ||
|
|
9ef9514bfa | ||
|
|
967c0eefed | ||
|
|
abbf880872 | ||
|
|
e49724ae5f | ||
|
|
9427d8f3ba | ||
|
|
f40290dcaf | ||
|
|
983a35f5ae | ||
|
|
4dc6bdcd28 | ||
|
|
c963d1189a | ||
|
|
1ac61ffe19 | ||
|
|
a564d743f8 | ||
|
|
8c4d663393 | ||
|
|
bc5e56d3eb | ||
|
|
8aa7dd81d8 | ||
|
|
15ff32b685 | ||
|
|
084108a908 | ||
|
|
decc0fa50a | ||
|
|
02c7e34681 | ||
|
|
5f079d6992 | ||
|
|
2e90ec0ef0 | ||
|
|
9914519d43 | ||
|
|
f80d11ed2a | ||
|
|
4e7f844ea6 | ||
|
|
50b89ad19a | ||
|
|
0470c2894d | ||
|
|
10721b4b41 | ||
|
|
cebaf9a8e2 | ||
|
|
197d2a684b | ||
|
|
e255e749e8 | ||
|
|
a7eb7735ee | ||
|
|
0de8b45612 | ||
|
|
bdd8ff2af0 | ||
|
|
82964ba176 | ||
|
|
f7887e7235 | ||
|
|
8ab618da18 | ||
|
|
c98fba7cc4 | ||
|
|
52bf85f8ca | ||
|
|
a4bb904a01 | ||
|
|
05486d00bf | ||
|
|
c4a0855f42 | ||
|
|
2cb7973162 | ||
|
|
ff8a9ea831 | ||
|
|
fd66b0d3b6 | ||
|
|
f581615110 | ||
|
|
07eb81e88a | ||
|
|
c6f1e2750e | ||
|
|
a8884c2b17 | ||
|
|
76f00c5a8a | ||
|
|
68ac7c3106 | ||
|
|
38d1d4c21c | ||
|
|
b77e828d4b | ||
|
|
17e299350a | ||
|
|
1d24bd3399 | ||
|
|
4971f8fb03 | ||
|
|
d74689cb93 | ||
|
|
51ae5748cb | ||
|
|
f2eb331696 | ||
|
|
5f6bbb20e7 | ||
|
|
03d03f782e | ||
|
|
1d3e080f04 | ||
|
|
3391bd80c4 | ||
|
|
1644c0dd87 | ||
|
|
85cc41082c | ||
|
|
b5cd4c40e2 | ||
|
|
932d45259c | ||
|
|
844f07d32d | ||
|
|
304ab20174 | ||
|
|
243dd863d7 | ||
|
|
d77e2aee0b | ||
|
|
1e636957ab | ||
|
|
507a42871c | ||
|
|
01348fb619 | ||
|
|
9e0a7f7adb | ||
|
|
340ec9932a | ||
|
|
c8b39449c3 | ||
|
|
bd254654bc | ||
|
|
fbc3f9bbec | ||
|
|
99ad01e12f | ||
|
|
83aa01c6af |
54
.github/workflows/build.yml
vendored
Normal file
54
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: Build
|
||||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
include:
|
||||
- os: windows-latest
|
||||
cmake_extra_args: '-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake"'
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Ubuntu
|
||||
run: sudo apt install -y libcppunit-dev zlib1g-dev
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
|
||||
- name: Set up macOS
|
||||
run: brew install cppunit
|
||||
if: matrix.os == 'macos-latest'
|
||||
|
||||
- name: Set up Windows
|
||||
run: vcpkg install cppunit --triplet x64-windows
|
||||
if: matrix.os == 'windows-latest'
|
||||
|
||||
- name: Configure
|
||||
run: >
|
||||
cmake -B${{github.workspace}}/build
|
||||
-DBUILD_SHARED_LIBS=ON -DVISIBILITY_HIDDEN=ON
|
||||
-DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||
${{ matrix.cmake_extra_args }}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: ctest -C ${{env.BUILD_TYPE}} -V --no-tests=error
|
||||
if: matrix.os != 'windows-latest'
|
||||
|
||||
- name: Test Windows
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: |
|
||||
$env:Path += ";$env:VCPKG_INSTALLATION_ROOT\packages\cppunit_x64-windows\bin;$PWD\taglib\Release"
|
||||
ctest -C ${{env.BUILD_TYPE}} -V --no-tests=error
|
||||
if: matrix.os == 'windows-latest'
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -3,6 +3,7 @@ cmake_uninstall.cmake
|
||||
Makefile
|
||||
CTestTestfile.cmake
|
||||
CMakeFiles/
|
||||
CMakeLists.txt.user*
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
@@ -12,6 +13,7 @@ CMakeFiles/
|
||||
*.suo
|
||||
*.user
|
||||
.*
|
||||
!.github/workflows/
|
||||
*~
|
||||
/CMakeCache.txt
|
||||
/Doxyfile
|
||||
@@ -47,3 +49,9 @@ CMakeFiles/
|
||||
taglib.h.stamp
|
||||
taglib.xcodeproj
|
||||
CMakeScripts
|
||||
/.clang-format
|
||||
/compile_commands.json
|
||||
/build/
|
||||
.clangd
|
||||
.cache
|
||||
.idea
|
||||
|
||||
32
.travis.yml
32
.travis.yml
@@ -1,32 +0,0 @@
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
dist: trusty
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
arch:
|
||||
- ppc64le
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcppunit-dev
|
||||
- zlib1g-dev
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
|
||||
install:
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install cppunit; fi
|
||||
|
||||
script: cmake -DBUILD_TESTS=ON -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON -DCMAKE_CXX_FLAGS="-std=c++11" . && make && make check
|
||||
2
AUTHORS
2
AUTHORS
@@ -16,6 +16,8 @@ Mathias Panzenböck <grosser.meister.morti@gmx.net>
|
||||
Mod, S3M, IT and XM metadata implementations
|
||||
Damien Plisson <damien78@audirvana.com>
|
||||
DSDIFF metadata implementation
|
||||
Urs Fleisch <ufleisch@users.sourceforge.net>
|
||||
Bug fixes, maintainer.
|
||||
|
||||
Please send all patches and questions to taglib-devel@kde.org rather than to
|
||||
individual developers!
|
||||
|
||||
@@ -2,11 +2,11 @@ cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
|
||||
|
||||
project(taglib)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
|
||||
|
||||
if(DEFINED ENABLE_STATIC)
|
||||
message(FATAL_ERROR "This option is no longer available, use BUILD_SHARED_LIBS instead")
|
||||
endif()
|
||||
include(CTest)
|
||||
include(FeatureSummary)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||
if(APPLE)
|
||||
@@ -32,7 +32,6 @@ if(ENABLE_CCACHE)
|
||||
endif()
|
||||
|
||||
option(VISIBILITY_HIDDEN "Build with -fvisibility=hidden" OFF)
|
||||
option(BUILD_TESTS "Build the test suite" OFF)
|
||||
option(BUILD_EXAMPLES "Build the examples" OFF)
|
||||
option(BUILD_BINDINGS "Build the bindings" ON)
|
||||
|
||||
@@ -46,22 +45,25 @@ endif()
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
set(TESTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests/")
|
||||
|
||||
## the following are directories where stuff will be installed to
|
||||
set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)")
|
||||
set(EXEC_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Base directory for executables and libraries")
|
||||
set(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "The subdirectory to the binaries prefix (default prefix/bin)")
|
||||
set(LIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})")
|
||||
set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The subdirectory to the header prefix")
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
endif()
|
||||
|
||||
if(MSVC AND ENABLE_STATIC_RUNTIME)
|
||||
foreach(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
if(MSVC)
|
||||
if(ENABLE_STATIC_RUNTIME)
|
||||
foreach(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
# Disable warnings for internal invocations of API functions
|
||||
# that have been marked with TAGLIB_DEPRECATED
|
||||
# https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4996
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4996")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996")
|
||||
endif()
|
||||
|
||||
# Read version information from file taglib/toolkit/taglib.h into variables
|
||||
@@ -90,9 +92,9 @@ endif()
|
||||
# 2. If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0.
|
||||
# 3. If any interfaces have been added since the last public release, then increment age.
|
||||
# 4. If any interfaces have been removed since the last public release, then set age to 0.
|
||||
set(TAGLIB_SOVERSION_CURRENT 19)
|
||||
set(TAGLIB_SOVERSION_REVISION 0)
|
||||
set(TAGLIB_SOVERSION_AGE 18)
|
||||
set(TAGLIB_SOVERSION_CURRENT 20)
|
||||
set(TAGLIB_SOVERSION_REVISION 1)
|
||||
set(TAGLIB_SOVERSION_AGE 19)
|
||||
|
||||
math(EXPR TAGLIB_SOVERSION_MAJOR "${TAGLIB_SOVERSION_CURRENT} - ${TAGLIB_SOVERSION_AGE}")
|
||||
math(EXPR TAGLIB_SOVERSION_MINOR "${TAGLIB_SOVERSION_AGE}")
|
||||
@@ -100,40 +102,46 @@ math(EXPR TAGLIB_SOVERSION_PATCH "${TAGLIB_SOVERSION_REVISION}")
|
||||
|
||||
include(ConfigureChecks.cmake)
|
||||
|
||||
if(${ZLIB_FOUND})
|
||||
set(ZLIB_LIBRARIES_FLAGS -lz)
|
||||
# Determine whether zlib is installed.
|
||||
option(WITH_ZLIB "Build with ZLIB" ON)
|
||||
|
||||
if(WITH_ZLIB)
|
||||
if(NOT ZLIB_SOURCE)
|
||||
find_package(ZLIB)
|
||||
if(ZLIB_FOUND)
|
||||
set(HAVE_ZLIB 1)
|
||||
set(ZLIB_LIBRARIES_FLAGS -lz)
|
||||
else()
|
||||
set(HAVE_ZLIB 0)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_ZLIB AND ZLIB_SOURCE)
|
||||
set(HAVE_ZLIB 1)
|
||||
set(HAVE_ZLIB_SOURCE 1)
|
||||
endif()
|
||||
else()
|
||||
set(HAVE_ZLIB 0)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/taglib-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/taglib-config" @ONLY)
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/taglib-config" DESTINATION "${BIN_INSTALL_DIR}")
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/taglib-config" DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/taglib-config.cmd.cmake" "${CMAKE_CURRENT_BINARY_DIR}/taglib-config.cmd")
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/taglib-config.cmd" DESTINATION "${BIN_INSTALL_DIR}")
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/taglib-config.cmd" DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_FRAMEWORK)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/taglib.pc.cmake" "${CMAKE_CURRENT_BINARY_DIR}/taglib.pc" @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/taglib.pc" DESTINATION "${LIB_INSTALL_DIR}/pkgconfig")
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_ZLIB AND ZLIB_SOURCE)
|
||||
set(HAVE_ZLIB 1)
|
||||
set(HAVE_ZLIB_SOURCE 1)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/taglib.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
configure_file(config.h.cmake "${CMAKE_CURRENT_BINARY_DIR}/config.h")
|
||||
|
||||
if(WITH_ASF)
|
||||
set(TAGLIB_WITH_ASF TRUE)
|
||||
endif()
|
||||
if(WITH_MP4)
|
||||
set(TAGLIB_WITH_MP4 TRUE)
|
||||
endif()
|
||||
|
||||
option(TRACE_IN_RELEASE "Output debug messages even in release mode" OFF)
|
||||
if(TRACE_IN_RELEASE)
|
||||
set(TRACE_IN_RELEASE TRUE)
|
||||
@@ -147,9 +155,13 @@ if(BUILD_BINDINGS)
|
||||
add_subdirectory(bindings)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTS AND NOT BUILD_SHARED_LIBS)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
if(BUILD_TESTING)
|
||||
find_package(CppUnit)
|
||||
if(CppUnit_FOUND)
|
||||
add_subdirectory(tests)
|
||||
else()
|
||||
message(WARNING "BUILD_TESTING requested, but CppUnit not found, skipping tests.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_EXAMPLES)
|
||||
@@ -157,7 +169,6 @@ if(BUILD_EXAMPLES)
|
||||
endif()
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.cmake" "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
|
||||
file(COPY doc/taglib.png DESTINATION doc)
|
||||
add_custom_target(docs doxygen)
|
||||
|
||||
# uninstall target
|
||||
@@ -166,3 +177,5 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" "${CMAKE_C
|
||||
if(NOT TARGET uninstall)
|
||||
add_custom_target(uninstall COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
endif()
|
||||
|
||||
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||
|
||||
@@ -176,27 +176,6 @@ check_cxx_source_compiles("
|
||||
}
|
||||
" HAVE_ISO_STRDUP)
|
||||
|
||||
# Determine whether zlib is installed.
|
||||
|
||||
if(NOT ZLIB_SOURCE)
|
||||
find_package(ZLIB)
|
||||
if(ZLIB_FOUND)
|
||||
set(HAVE_ZLIB 1)
|
||||
else()
|
||||
set(HAVE_ZLIB 0)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Determine whether CppUnit is installed.
|
||||
|
||||
if(BUILD_TESTS AND NOT BUILD_SHARED_LIBS)
|
||||
find_package(CppUnit)
|
||||
if(NOT CppUnit_FOUND)
|
||||
message(STATUS "CppUnit not found, disabling tests.")
|
||||
set(BUILD_TESTS OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Detect WinRT mode
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
|
||||
set(PLATFORM WINRT 1)
|
||||
|
||||
261
Doxyfile.cmake
261
Doxyfile.cmake
@@ -1,37 +1,79 @@
|
||||
# Doxyfile 1.3.4
|
||||
# Doxyfile 1.9.1
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = TagLib
|
||||
PROJECT_NUMBER = ${TAGLIB_LIB_VERSION_STRING}
|
||||
PROJECT_BRIEF =
|
||||
PROJECT_LOGO = @CMAKE_SOURCE_DIR@/doc/taglib.svg
|
||||
OUTPUT_DIRECTORY = doc
|
||||
CREATE_SUBDIRS = NO
|
||||
ALLOW_UNICODE_NAMES = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
USE_WINDOWS_ENCODING = NO
|
||||
OUTPUT_TEXT_DIRECTION = None
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
JAVADOC_BANNER = NO
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = NO
|
||||
PYTHON_DOCSTRING = YES
|
||||
INHERIT_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 4
|
||||
ALIASES =
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
OPTIMIZE_OUTPUT_SLICE = NO
|
||||
EXTENSION_MAPPING =
|
||||
MARKDOWN_SUPPORT = YES
|
||||
TOC_INCLUDE_HEADINGS = 5
|
||||
AUTOLINK_SUPPORT = YES
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
GROUP_NESTED_COMPOUNDS = NO
|
||||
SUBGROUPING = YES
|
||||
INLINE_GROUPED_CLASSES = NO
|
||||
INLINE_SIMPLE_STRUCTS = NO
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
LOOKUP_CACHE_SIZE = 0
|
||||
NUM_PROC_THREADS = 1
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_PRIV_VIRTUAL = NO
|
||||
EXTRACT_PACKAGE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = NO
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
RESOLVE_UNNAMED_PARAMS = YES
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
@@ -39,172 +81,267 @@ HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = YES
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
HIDE_COMPOUND_REFERENCE= NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
SHOW_GROUPED_MEMB_INC = NO
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_MEMBERS_CTORS_1ST = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
STRICT_PROTO_MATCHING = NO
|
||||
GENERATE_TODOLIST = NO
|
||||
GENERATE_TESTLIST = NO
|
||||
GENERATE_BUGLIST = NO
|
||||
GENERATE_DEPRECATEDLIST= NO
|
||||
ENABLED_SECTIONS =
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
LAYOUT_FILE =
|
||||
CITE_BIB_FILES =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
# Configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_AS_ERROR = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
# Configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = @CMAKE_SOURCE_DIR@/taglib
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS = *.h \
|
||||
*.hh \
|
||||
*.H
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
USE_MDFILE_AS_MAINPAGE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
# Configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
SOURCE_TOOLTIPS = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
CLANG_ASSISTED_PARSING = NO
|
||||
CLANG_ADD_INC_PATHS = YES
|
||||
CLANG_OPTIONS =
|
||||
CLANG_DATABASE_PATH =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
# Configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
# Configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER = @CMAKE_SOURCE_DIR@/doc/api-header.html
|
||||
HTML_FOOTER = @CMAKE_SOURCE_DIR@/doc/api-footer.html
|
||||
HTML_STYLESHEET = @CMAKE_SOURCE_DIR@/doc/taglib-api.css
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
HTML_STYLESHEET =
|
||||
HTML_EXTRA_STYLESHEET =
|
||||
HTML_EXTRA_FILES =
|
||||
HTML_COLORSTYLE_HUE = 220
|
||||
HTML_COLORSTYLE_SAT = 100
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
HTML_TIMESTAMP = NO
|
||||
HTML_DYNAMIC_MENUS = YES
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
HTML_INDEX_NUM_ENTRIES = 100
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||
DOCSET_PUBLISHER_NAME = Publisher
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
CHM_INDEX_ENCODING =
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = YES
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_QHP = NO
|
||||
QCH_FILE =
|
||||
QHP_NAMESPACE = org.doxygen.Project
|
||||
QHP_VIRTUAL_FOLDER = doc
|
||||
QHP_CUST_FILTER_NAME =
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
QHG_LOCATION =
|
||||
GENERATE_ECLIPSEHELP = NO
|
||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
DISABLE_INDEX = NO
|
||||
GENERATE_TREEVIEW = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
TREEVIEW_WIDTH = 250
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
HTML_FORMULA_FORMAT = png
|
||||
FORMULA_FONTSIZE = 10
|
||||
FORMULA_TRANSPARENT = YES
|
||||
FORMULA_MACROFILE =
|
||||
USE_MATHJAX = NO
|
||||
MATHJAX_FORMAT = HTML-CSS
|
||||
MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2
|
||||
MATHJAX_EXTENSIONS =
|
||||
MATHJAX_CODEFILE =
|
||||
SEARCHENGINE = NO
|
||||
SERVER_BASED_SEARCH = NO
|
||||
EXTERNAL_SEARCH = NO
|
||||
SEARCHENGINE_URL =
|
||||
SEARCHDATA_FILE = searchdata.xml
|
||||
EXTERNAL_SEARCH_ID =
|
||||
EXTRA_SEARCH_MAPPINGS =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
# Configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
LATEX_MAKEINDEX_CMD = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = letter
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
LATEX_FOOTER =
|
||||
LATEX_EXTRA_STYLESHEET =
|
||||
LATEX_EXTRA_FILES =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
LATEX_SOURCE_CODE = NO
|
||||
LATEX_BIB_STYLE = plain
|
||||
LATEX_TIMESTAMP = NO
|
||||
LATEX_EMOJI_DIRECTORY =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
# Configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
RTF_SOURCE_CODE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
# Configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_SUBDIR =
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
# Configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
XML_NS_MEMB_FILE_SCOPE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
# Configuration options related to the DOCBOOK output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_DOCBOOK = NO
|
||||
DOCBOOK_OUTPUT = docbook
|
||||
DOCBOOK_PROGRAMLISTING = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
# Configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = DO_NOT_DOCUMENT \
|
||||
DOXYGEN \
|
||||
WITH_MP4 \
|
||||
WITH_ASF
|
||||
EXPAND_AS_DEFINED =
|
||||
DOXYGEN
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
# Configuration options related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
EXTERNAL_PAGES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
DIA_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = YES
|
||||
DOT_NUM_THREADS = 0
|
||||
DOT_FONTNAME = Helvetica
|
||||
DOT_FONTSIZE = 10
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
DOT_UML_DETAILS = NO
|
||||
DOT_WRAP_THRESHOLD = 17
|
||||
TEMPLATE_RELATIONS = YES
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = svg
|
||||
INTERACTIVE_SVG = NO
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MSCFILE_DIRS =
|
||||
DIAFILE_DIRS =
|
||||
PLANTUML_JAR_PATH =
|
||||
PLANTUML_CFG_FILE =
|
||||
PLANTUML_INCLUDE_PATH =
|
||||
DOT_GRAPH_MAX_NODES = 100
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
|
||||
111
INSTALL.md
111
INSTALL.md
@@ -13,6 +13,12 @@ In order to build the included examples, use the `BUILD_EXAMPLES` option:
|
||||
|
||||
cmake -DBUILD_EXAMPLES=ON [...]
|
||||
|
||||
If you want to build TagLib without ZLib, you can use
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release -DWITH_ZLIB=OFF .
|
||||
make
|
||||
sudo make install
|
||||
|
||||
See http://www.cmake.org/cmake/help/runningcmake.html for generic help on
|
||||
running CMake.
|
||||
|
||||
@@ -22,23 +28,25 @@ Mac OS X
|
||||
On Mac OS X, 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
|
||||
an Universal Binary framework with Mac OS X 10.4 as the deployment target:
|
||||
a framework with Mac OS X 10.10 as the deployment target:
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
mkdir build; cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DBUILD_FRAMEWORK=ON \
|
||||
-DCMAKE_C_COMPILER=/usr/bin/gcc-4.0 \
|
||||
-DCMAKE_CXX_COMPILER=/usr/bin/c++-4.0 \
|
||||
-DCMAKE_OSX_SYSROOT=/Developer/SDKs/MacOSX10.4u.sdk/ \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.4 \
|
||||
-DCMAKE_OSX_ARCHITECTURES="ppc;i386;x86_64"
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.10 \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"
|
||||
make
|
||||
|
||||
For a 10.6 Snow Leopard static library with both 32-bit and 64-bit code, use:
|
||||
For a 10.10 static library, use:
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.6 \
|
||||
-DCMAKE_OSX_ARCHITECTURES="i386;x86_64" \
|
||||
mkdir build; cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX="<folder you want to build to>"
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.10 \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"
|
||||
make
|
||||
|
||||
After `make`, and `make install`, add `libtag.` to your XCode project, and add
|
||||
the include folder to the project's User Header Search Paths.
|
||||
@@ -52,7 +60,7 @@ 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)
|
||||
* GCC by mingw-w64.sf.net v4.6.3 (Strawberry Perl 32b)
|
||||
* MinGW32-4.8.0
|
||||
|
||||
Requirements:
|
||||
@@ -69,15 +77,16 @@ Optional:
|
||||
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 |
|
||||
---------------------| ------------|
|
||||
`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) |
|
||||
|
||||
| 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).
|
||||
|
||||
@@ -85,11 +94,11 @@ The easiest way is at the command prompt (Visual C++ command prompt for MSVS use
|
||||
|
||||
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:
|
||||
@@ -126,13 +135,13 @@ The easiest way is at the command prompt (Visual C++ command prompt for MSVS use
|
||||
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:
|
||||
|
||||
@@ -140,7 +149,7 @@ The easiest way is at the command prompt (Visual C++ command prompt for MSVS use
|
||||
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.
|
||||
@@ -151,7 +160,7 @@ The easiest way is at the command prompt (Visual C++ command prompt for MSVS use
|
||||
|
||||
C:\GitRoot\taglib> gmake install
|
||||
OR (Depending on MinGW install)
|
||||
|
||||
|
||||
C:\GitRoot\taglib> mingw32-make install
|
||||
|
||||
|
||||
@@ -167,9 +176,53 @@ 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_TESTS=on` when running cmake.
|
||||
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`
|
||||
|
||||
40
NEWS
40
NEWS
@@ -1,4 +1,42 @@
|
||||
============================
|
||||
TagLib 1.13.1 (Jul 1, 2023)
|
||||
===========================
|
||||
|
||||
* Fixed parsing of TXXX frames without description.
|
||||
* Detect MP4 atoms with invalid length or type.
|
||||
* Do not miss ID3v2 frames when an extended header is present.
|
||||
* Use property "DISCSUBTITLE" for ID3v2 "TSST" frame.
|
||||
* Build system improvements: Use absolute path for macOS dylib install name,
|
||||
support --define-prefix when using pkg-config, fixed minimum required
|
||||
CppUnit version.
|
||||
* Code clean up using clang-tidy.
|
||||
|
||||
TagLib 1.13 (Oct 27, 2022)
|
||||
==========================
|
||||
|
||||
* Added interface StreamTypeResolver to support streams which cannot be
|
||||
fopen()'ed, e.g. network files.
|
||||
* Added MP4::File::strip() to remove meta atom from MP4 file.
|
||||
* Added Map::value() to look up without creating entry.
|
||||
* Use property "WORK" instead of "CONTENTGROUP" for ID3v2 "TIT1" frame,
|
||||
use property "WORK" for ASF "WM/ContentGroupDescription",
|
||||
use property "COMPILATION" for ID3v2 "TCMP" frame.
|
||||
* Build system improvements: option WITH_ZLIB, BUILD_TESTING instead of
|
||||
BUILD_TESTS, GNUInstallDirs, FeatureSummary, tests with BUILD_SHARED_LIBS,
|
||||
cross compilation with Buildroot, systems without HAVE_GCC_ATOMIC, Clang.
|
||||
* Fixed heap-buffer-overflows when handling ASF, APE, FLAC, ID3v2, MP4, MPC
|
||||
tags.
|
||||
* Fixed detection of invalid file by extension when correct type can be
|
||||
detected by contents.
|
||||
* Fixed unnecessary creation of map entries in APE and FLAC tags if looked up
|
||||
tag does not exist.
|
||||
* Fixed parsing of MP4 non-full meta atoms.
|
||||
* Fixed potential ID3v1 false positive in the presence of an APE tag.
|
||||
* Fixed ID3v2 version handling for frames embedded in CHAP or CTOC frames.
|
||||
* Fixed parsing of multiple strings with a single BOM in ID3v2.4.0.
|
||||
* Fixed several smaller issues reported by clang-tidy.
|
||||
|
||||
TagLib 1.12 (Feb 16, 2021)
|
||||
==========================
|
||||
|
||||
* Added support for WinRT.
|
||||
* Added support for Linux on POWER.
|
||||
|
||||
15
README.md
15
README.md
@@ -1,14 +1,14 @@
|
||||
# TagLib
|
||||
|
||||
[](https://travis-ci.org/taglib/taglib)
|
||||
[](../../actions)
|
||||
|
||||
### TagLib Audio Metadata Library
|
||||
|
||||
http://taglib.org/
|
||||
https://taglib.org/
|
||||
|
||||
TagLib is a library for reading and editing the metadata of several
|
||||
popular audio formats. Currently it supports both ID3v1 and [ID3v2][]
|
||||
for MP3 files, [Ogg Vorbis][] comments and ID3 tags
|
||||
for MP3 files, [Ogg Vorbis][] comments and ID3 tags
|
||||
in [FLAC][], MPC, Speex, WavPack, TrueAudio, WAV, AIFF, MP4, APE,
|
||||
and ASF files.
|
||||
|
||||
@@ -18,9 +18,8 @@ it may be used in proprietary applications, but if changes are made to
|
||||
TagLib they must be contributed back to the project. Please review the
|
||||
licenses if you are considering using TagLib in your project.
|
||||
|
||||
[ID3v2]: http://www.id3.org
|
||||
[Ogg Vorbis]: http://vorbis.com/
|
||||
[ID3v2]: https://id3.org/
|
||||
[Ogg Vorbis]: https://xiph.org/vorbis/
|
||||
[FLAC]: https://xiph.org/flac/
|
||||
[GNU Lesser General Public License]: http://www.gnu.org/licenses/lgpl.html
|
||||
[Mozilla Public License]: http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
|
||||
[GNU Lesser General Public License]: https://www.gnu.org/licenses/lgpl.html
|
||||
[Mozilla Public License]: https://www.mozilla.org/MPL/MPL-1.1.html
|
||||
|
||||
@@ -58,18 +58,18 @@ set_target_properties(tag_c PROPERTIES
|
||||
VERSION 0.0.0
|
||||
SOVERSION 0
|
||||
DEFINE_SYMBOL MAKE_TAGLIB_C_LIB
|
||||
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
|
||||
INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR}
|
||||
)
|
||||
install(TARGETS tag_c
|
||||
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/taglib
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/taglib
|
||||
)
|
||||
|
||||
if(NOT BUILD_FRAMEWORK)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib_c.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib_c.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc @ONLY)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace
|
||||
{
|
||||
return String(s, unicodeStrings ? String::UTF8 : String::Latin1);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void taglib_set_strings_unicode(BOOL unicode)
|
||||
{
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
prefix=${CMAKE_INSTALL_PREFIX}
|
||||
exec_prefix=${CMAKE_INSTALL_PREFIX}
|
||||
libdir=${LIB_INSTALL_DIR}
|
||||
includedir=${INCLUDE_INSTALL_DIR}
|
||||
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
|
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
||||
|
||||
Name: TagLib C Bindings
|
||||
Description: Audio meta-data library (C bindings)
|
||||
Requires: taglib
|
||||
Version: ${TAGLIB_LIB_VERSION_STRING}
|
||||
Libs: -L${LIB_INSTALL_DIR} -ltag_c
|
||||
Cflags: -I${INCLUDE_INSTALL_DIR}/taglib
|
||||
Version: @TAGLIB_LIB_VERSION_STRING@
|
||||
Libs: -L${libdir} -ltag_c
|
||||
Cflags: -I${includedir}/taglib
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
include (MacroEnsureVersion)
|
||||
|
||||
if(NOT CPPUNIT_MIN_VERSION)
|
||||
SET(CPPUNIT_MIN_VERSION 1.12.0)
|
||||
SET(CPPUNIT_MIN_VERSION 1.14.0)
|
||||
endif(NOT CPPUNIT_MIN_VERSION)
|
||||
|
||||
FIND_PROGRAM(CPPUNIT_CONFIG_EXECUTABLE cppunit-config )
|
||||
@@ -33,7 +33,7 @@ ELSE(CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
|
||||
FIND_PATH(CPPUNIT_CFLAGS cppunit/TestRunner.h PATHS /usr/include /usr/local/include )
|
||||
FIND_LIBRARY(CPPUNIT_LIBRARIES NAMES cppunit PATHS /usr/lib /usr/local/lib )
|
||||
# how can we find cppunit version?
|
||||
MESSAGE (STATUS "Ensure you cppunit installed version is at least ${CPPUNIT_MIN_VERSION}")
|
||||
MESSAGE (STATUS "Ensure your cppunit installed version is at least ${CPPUNIT_MIN_VERSION}")
|
||||
SET (CPPUNIT_INSTALLED_VERSION ${CPPUNIT_MIN_VERSION})
|
||||
ENDIF(CPPUNIT_CONFIG_EXECUTABLE)
|
||||
|
||||
@@ -56,7 +56,7 @@ IF(CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
|
||||
macro_ensure_version( ${CPPUNIT_MIN_VERSION} ${CPPUNIT_INSTALLED_VERSION} CPPUNIT_INSTALLED_VERSION_OK )
|
||||
|
||||
IF(NOT CPPUNIT_INSTALLED_VERSION_OK)
|
||||
MESSAGE ("** CppUnit version is too old: found ${CPPUNIT_INSTALLED_VERSION} installed, ${CPPUNIT_MIN_VERSION} or major is required")
|
||||
MESSAGE ("** CppUnit version is too old: found ${CPPUNIT_INSTALLED_VERSION} installed, ${CPPUNIT_MIN_VERSION} or newer is required")
|
||||
SET(CppUnit_FOUND FALSE)
|
||||
ENDIF(NOT CPPUNIT_INSTALLED_VERSION_OK)
|
||||
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,41 +1,38 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen $doxygenversion"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>$title ($projectname)</title>
|
||||
<link href="taglib-api.css" rel="stylesheet" type="text/css">
|
||||
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="$relpath^jquery.js"></script>
|
||||
<script type="text/javascript" src="$relpath^dynsections.js"></script>
|
||||
$treeview
|
||||
$search
|
||||
$mathjax
|
||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||
$extrastylesheet
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<div id="container">
|
||||
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td width="1">
|
||||
<img src="../taglib.png">
|
||||
</td>
|
||||
<td>
|
||||
<div id="intro">
|
||||
<table border="0" height="119" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr><td valign="top"><h1>TagLib $projectnumber ($title)</h1></td></tr>
|
||||
<tr>
|
||||
<td valign="bottom">
|
||||
<div id="links">
|
||||
<a href="index.html">Home</a>
|
||||
<a href="inherits.html">Class Hierarchy</a>
|
||||
<a href="namespaces.html">Namespaces</a>
|
||||
<a href="annotated.html">Classes</a>
|
||||
<a href="files.html">Headers</a>
|
||||
<a href="namespacemembers.html">Namespace Members</a>
|
||||
<a href="functions.html">Class Members</a>
|
||||
<a href="globals.html">File Members</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div id="text">
|
||||
<div id="top">
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo" width="200px"/></td>
|
||||
<td id="projectalign" style="padding-left: 0.5em;">
|
||||
<div id="projectname">$projectname
|
||||
 <span id="projectnumber">$projectnumber</span>
|
||||
</div>
|
||||
<div id="projectbrief">$projectbrief</div>
|
||||
</td>
|
||||
<td style="padding-left: 0.5em;">
|
||||
<div id="projectbrief">$projectbrief</div>
|
||||
</td>
|
||||
<td>$searchbox</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -1,395 +0,0 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
background: white;
|
||||
color: black;
|
||||
margin: 0px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
a:link {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #cccccc;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #cccccc;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/* container */
|
||||
|
||||
#container {
|
||||
position: absolute;
|
||||
border-width: thin;
|
||||
border-style: solid;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
/* intro */
|
||||
|
||||
#intro {
|
||||
padding: 5px;
|
||||
margin: 0px;
|
||||
background: #cccccc;
|
||||
border-width: medium;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
#intro h1 {
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
/* links */
|
||||
|
||||
#links {
|
||||
font-size: x-small;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
#links a {
|
||||
border-width: thin;
|
||||
border-style: dotted;
|
||||
border-color: white;
|
||||
/* margin: 0px 10px 0px 0px; */
|
||||
margin: 1px;
|
||||
padding: 3px;
|
||||
line-height: 230%
|
||||
}
|
||||
|
||||
#links a:hover {
|
||||
color: black;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#links h3 {
|
||||
outline-width: thin;
|
||||
border-style: solid;
|
||||
padding: 2px;
|
||||
margin: 3px 0px 3px 0px;
|
||||
}
|
||||
|
||||
/* menu */
|
||||
|
||||
#menu h3 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* text */
|
||||
|
||||
#text {
|
||||
margin: 0px;
|
||||
padding: 5px 5px 0px 5px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#text h3 {
|
||||
border-width: thin;
|
||||
border-style: solid;
|
||||
padding: 2px;
|
||||
margin: 3px 0px 3px 0px;
|
||||
}
|
||||
|
||||
#text li {
|
||||
margin: 0px 0px 10px 0px;
|
||||
}
|
||||
|
||||
#text ul {
|
||||
margin: 5px;
|
||||
padding: 0px 0px 0px 20px;
|
||||
}
|
||||
|
||||
#leftcolumn {
|
||||
float: left;
|
||||
width: 300px;
|
||||
margin: 0px 10px 0px 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#rightcolumn {
|
||||
float: right;
|
||||
width: 210px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
/* vspacer */
|
||||
|
||||
.vspacer {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.silver {
|
||||
border-width: thin;
|
||||
border-color: black;
|
||||
border-style: solid;
|
||||
background: #cccccc;
|
||||
}
|
||||
|
||||
a.code {
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
color: #4444ee
|
||||
}
|
||||
|
||||
a.codeRef {
|
||||
font-weight: normal;
|
||||
color: #4444ee
|
||||
}
|
||||
|
||||
div.fragment {
|
||||
width: 98%;
|
||||
border: 1px solid #CCCCCC;
|
||||
background-color: #f5f5f5;
|
||||
padding-left: 4px;
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
div.ah {
|
||||
background-color: black;
|
||||
font-weight: bold; color: #ffffff;
|
||||
margin-bottom: 3px;
|
||||
margin-top: 3px
|
||||
}
|
||||
|
||||
#text td {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
div.memdoc {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px 10px 10px 40px;
|
||||
}
|
||||
|
||||
div.memproto {
|
||||
border: thin solid black;
|
||||
background-color: #f2f2ff;
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
td.paramtype {
|
||||
color: #602020;
|
||||
}
|
||||
|
||||
table.memname {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.groupHeader {
|
||||
margin-left: 16px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 6px;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
div.groupText {
|
||||
margin-left: 16px;
|
||||
font-style: italic;
|
||||
font-size: smaller
|
||||
}
|
||||
|
||||
body {
|
||||
background: white;
|
||||
color: black;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
td.indexkey {
|
||||
background-color: #eeeeff;
|
||||
font-weight: bold;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px
|
||||
}
|
||||
|
||||
td.indexvalue {
|
||||
background-color: #eeeeff;
|
||||
font-style: italic;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px
|
||||
}
|
||||
|
||||
tr.memlist {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
p.formulaDsp {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img.formulaDsp {
|
||||
|
||||
}
|
||||
|
||||
img.formulaInl {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
span.keyword {
|
||||
color: #008000
|
||||
}
|
||||
|
||||
span.keywordtype {
|
||||
color: #604020
|
||||
}
|
||||
|
||||
span.keywordflow {
|
||||
color: #e08000
|
||||
}
|
||||
|
||||
span.comment {
|
||||
color: #800000
|
||||
}
|
||||
|
||||
span.preprocessor {
|
||||
color: #806020
|
||||
}
|
||||
|
||||
span.stringliteral {
|
||||
color: #002080
|
||||
}
|
||||
|
||||
span.charliteral {
|
||||
color: #008080
|
||||
}
|
||||
|
||||
.mdTable {
|
||||
border: 1px solid #868686;
|
||||
background-color: #f2f2ff;
|
||||
}
|
||||
|
||||
.mdRow {
|
||||
padding: 8px 20px;
|
||||
}
|
||||
|
||||
.mdescLeft {
|
||||
font-size: smaller;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
background-color: #FAFAFA;
|
||||
padding-left: 8px;
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.mdescRight {
|
||||
font-size: smaller;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-style: italic;
|
||||
background-color: #FAFAFA;
|
||||
padding-left: 4px;
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
padding-bottom: 0px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.memItemLeft {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-style: solid;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-family: Geneva, Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.memItemRight {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-style: solid;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-family: Geneva, Arial, Helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.search {
|
||||
color: #0000ee;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
form.search {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
input.search {
|
||||
font-size: 75%;
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
background-color: #eeeeff;
|
||||
}
|
||||
|
||||
td.tiny {
|
||||
font-size: 75%;
|
||||
}
|
||||
BIN
doc/taglib.png
BIN
doc/taglib.png
Binary file not shown.
|
Before Width: | Height: | Size: 2.7 KiB |
58
doc/taglib.svg
Normal file
58
doc/taglib.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 11 KiB |
@@ -38,3 +38,8 @@ target_link_libraries(framelist tag)
|
||||
add_executable(strip-id3v1 strip-id3v1.cpp)
|
||||
target_link_libraries(strip-id3v1 tag)
|
||||
|
||||
install(TARGETS tagreader tagreader_c tagwriter framelist strip-id3v1
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
@@ -14,10 +14,20 @@ EOH
|
||||
exit 1;
|
||||
}
|
||||
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
||||
libdir=@LIB_INSTALL_DIR@
|
||||
includedir=@INCLUDE_INSTALL_DIR@
|
||||
# Looks useless as it is, but could be replaced with a "pcfiledir" by Buildroot.
|
||||
prefix=
|
||||
exec_prefix=
|
||||
|
||||
if test -z "$prefix"; then
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
else
|
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
||||
fi
|
||||
if test -z "$exec_prefix"; then
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
else
|
||||
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
|
||||
fi
|
||||
|
||||
flags=""
|
||||
|
||||
@@ -38,7 +48,7 @@ do
|
||||
echo @TAGLIB_LIB_VERSION_STRING@
|
||||
;;
|
||||
--prefix)
|
||||
echo $prefix
|
||||
echo ${prefix:-@CMAKE_INSTALL_PREFIX@}
|
||||
;;
|
||||
*)
|
||||
echo "$0: unknown option $1"
|
||||
|
||||
@@ -27,8 +27,8 @@ goto theend
|
||||
* to allow for static, shared or debug builds.
|
||||
* It would be preferable if the top level CMakeLists.txt provided the library name during config. ??
|
||||
:doit
|
||||
if /i "%1#" == "--libs#" echo -L${LIB_INSTALL_DIR} -llibtag
|
||||
if /i "%1#" == "--cflags#" echo -I${INCLUDE_INSTALL_DIR} -I${INCLUDE_INSTALL_DIR}/taglib
|
||||
if /i "%1#" == "--libs#" echo -L${CMAKE_INSTALL_FULL_LIBDIR} -llibtag
|
||||
if /i "%1#" == "--cflags#" echo -I${CMAKE_INSTALL_FULL_INCLUDEDIR} -I${CMAKE_INSTALL_FULL_INCLUDEDIR}/taglib
|
||||
if /i "%1#" == "--version#" echo ${TAGLIB_LIB_VERSION_STRING}
|
||||
if /i "%1#" == "--prefix#" echo ${CMAKE_INSTALL_PREFIX}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
||||
libdir=@LIB_INSTALL_DIR@
|
||||
includedir=@INCLUDE_INSTALL_DIR@
|
||||
exec_prefix=${prefix}
|
||||
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
|
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
||||
|
||||
Name: TagLib
|
||||
Description: Audio meta-data library
|
||||
Requires:
|
||||
Requires:
|
||||
Version: @TAGLIB_LIB_VERSION_STRING@
|
||||
Libs: -L${libdir} -ltag @ZLIB_LIBRARIES_FLAGS@
|
||||
Cflags: -I${includedir} -I${includedir}/taglib
|
||||
|
||||
@@ -344,7 +344,7 @@ endif()
|
||||
set_target_properties(tag PROPERTIES
|
||||
VERSION ${TAGLIB_SOVERSION_MAJOR}.${TAGLIB_SOVERSION_MINOR}.${TAGLIB_SOVERSION_PATCH}
|
||||
SOVERSION ${TAGLIB_SOVERSION_MAJOR}
|
||||
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
|
||||
INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR}
|
||||
DEFINE_SYMBOL MAKE_TAGLIB_LIB
|
||||
LINK_INTERFACE_LIBRARIES ""
|
||||
PUBLIC_HEADER "${tag_HDRS}"
|
||||
@@ -365,8 +365,8 @@ endif()
|
||||
|
||||
install(TARGETS tag
|
||||
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/taglib
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/taglib
|
||||
)
|
||||
|
||||
@@ -49,7 +49,7 @@ using namespace TagLib;
|
||||
namespace
|
||||
{
|
||||
enum { ApeAPEIndex = 0, ApeID3v1Index = 1 };
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class APE::File::FilePrivate
|
||||
{
|
||||
|
||||
@@ -229,7 +229,7 @@ namespace TagLib {
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace APE
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -135,8 +135,7 @@ unsigned int APE::Footer::completeTagSize() const
|
||||
{
|
||||
if(d->headerPresent)
|
||||
return d->tagSize + size();
|
||||
else
|
||||
return d->tagSize;
|
||||
return d->tagSize;
|
||||
}
|
||||
|
||||
void APE::Footer::setTagSize(unsigned int s)
|
||||
@@ -158,8 +157,7 @@ ByteVector APE::Footer::renderHeader() const
|
||||
{
|
||||
if(!d->headerPresent)
|
||||
return ByteVector();
|
||||
else
|
||||
return render(true);
|
||||
return render(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace TagLib {
|
||||
FooterPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace APE
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -219,8 +219,7 @@ String APE::Item::toString() const
|
||||
{
|
||||
if(d->type == Text && !isEmpty())
|
||||
return d->text.front();
|
||||
else
|
||||
return String();
|
||||
return String();
|
||||
}
|
||||
|
||||
bool APE::Item::isEmpty() const
|
||||
@@ -229,9 +228,7 @@ bool APE::Item::isEmpty() const
|
||||
case Text:
|
||||
if(d->text.isEmpty())
|
||||
return true;
|
||||
if(d->text.size() == 1 && d->text.front().isEmpty())
|
||||
return true;
|
||||
return false;
|
||||
return d->text.size() == 1 && d->text.front().isEmpty();
|
||||
case Binary:
|
||||
case Locator:
|
||||
return d->value.isEmpty();
|
||||
@@ -260,7 +257,7 @@ void APE::Item::parse(const ByteVector &data)
|
||||
const ByteVector value = data.mid(8 + d->key.size() + 1, valueLength);
|
||||
|
||||
setReadOnly(flags & 1);
|
||||
setType(ItemTypes((flags >> 1) & 3));
|
||||
setType(static_cast<ItemTypes>((flags >> 1) & 3));
|
||||
|
||||
if(Text == d->type)
|
||||
d->text = StringList(ByteVectorList::split(value, '\0'), String::UTF8);
|
||||
|
||||
@@ -31,9 +31,7 @@
|
||||
#include "tstringlist.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace APE {
|
||||
|
||||
//! An implementation of APE-items
|
||||
|
||||
/*!
|
||||
@@ -215,10 +213,7 @@ namespace TagLib {
|
||||
class ItemPrivate;
|
||||
ItemPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace APE
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace
|
||||
|
||||
return header.toUShort(4, false);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void APE::Properties::read(File *file, long streamLength)
|
||||
{
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace TagLib {
|
||||
* Create an instance of APE::Properties with the data read from the
|
||||
* APE::File \a file.
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use Properties(File *, long, ReadStyle).
|
||||
*/
|
||||
TAGLIB_DEPRECATED Properties(File *file, ReadStyle style = Average);
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace TagLib {
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace APE
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class APE::Tag::TagPrivate
|
||||
{
|
||||
@@ -91,13 +91,11 @@ public:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
APE::Tag::Tag() :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
APE::Tag::Tag(TagLib::File *file, long footerLocation) :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
d->file = file;
|
||||
@@ -118,51 +116,44 @@ ByteVector APE::Tag::fileIdentifier()
|
||||
|
||||
String APE::Tag::title() const
|
||||
{
|
||||
if(d->itemListMap["TITLE"].isEmpty())
|
||||
return String();
|
||||
return d->itemListMap["TITLE"].values().toString();
|
||||
Item value = d->itemListMap.value("TITLE");
|
||||
return value.isEmpty() ? String() : value.values().toString();
|
||||
}
|
||||
|
||||
String APE::Tag::artist() const
|
||||
{
|
||||
if(d->itemListMap["ARTIST"].isEmpty())
|
||||
return String();
|
||||
return d->itemListMap["ARTIST"].values().toString();
|
||||
Item value = d->itemListMap.value("ARTIST");
|
||||
return value.isEmpty() ? String() : value.values().toString();
|
||||
}
|
||||
|
||||
String APE::Tag::album() const
|
||||
{
|
||||
if(d->itemListMap["ALBUM"].isEmpty())
|
||||
return String();
|
||||
return d->itemListMap["ALBUM"].values().toString();
|
||||
Item value = d->itemListMap.value("ALBUM");
|
||||
return value.isEmpty() ? String() : value.values().toString();
|
||||
}
|
||||
|
||||
String APE::Tag::comment() const
|
||||
{
|
||||
if(d->itemListMap["COMMENT"].isEmpty())
|
||||
return String();
|
||||
return d->itemListMap["COMMENT"].values().toString();
|
||||
Item value = d->itemListMap.value("COMMENT");
|
||||
return value.isEmpty() ? String() : value.values().toString();
|
||||
}
|
||||
|
||||
String APE::Tag::genre() const
|
||||
{
|
||||
if(d->itemListMap["GENRE"].isEmpty())
|
||||
return String();
|
||||
return d->itemListMap["GENRE"].values().toString();
|
||||
Item value = d->itemListMap.value("GENRE");
|
||||
return value.isEmpty() ? String() : value.values().toString();
|
||||
}
|
||||
|
||||
unsigned int APE::Tag::year() const
|
||||
{
|
||||
if(d->itemListMap["YEAR"].isEmpty())
|
||||
return 0;
|
||||
return d->itemListMap["YEAR"].toString().toInt();
|
||||
Item value = d->itemListMap.value("YEAR");
|
||||
return value.isEmpty() ? 0 : value.toString().toInt();
|
||||
}
|
||||
|
||||
unsigned int APE::Tag::track() const
|
||||
{
|
||||
if(d->itemListMap["TRACK"].isEmpty())
|
||||
return 0;
|
||||
return d->itemListMap["TRACK"].toString().toInt();
|
||||
Item value = d->itemListMap.value("TRACK");
|
||||
return value.isEmpty() ? 0 : value.toString().toInt();
|
||||
}
|
||||
|
||||
void APE::Tag::setTitle(const String &s)
|
||||
@@ -210,16 +201,18 @@ namespace
|
||||
{
|
||||
// conversions of tag keys between what we use in PropertyMap and what's usual
|
||||
// for APE tags
|
||||
// usual, APE
|
||||
const char *keyConversions[][2] = {{"TRACKNUMBER", "TRACK" },
|
||||
{"DATE", "YEAR" },
|
||||
{"ALBUMARTIST", "ALBUM ARTIST"},
|
||||
{"DISCNUMBER", "DISC" },
|
||||
{"REMIXER", "MIXARTIST" },
|
||||
{"RELEASESTATUS", "MUSICBRAINZ_ALBUMSTATUS" },
|
||||
{"RELEASETYPE", "MUSICBRAINZ_ALBUMTYPE" }};
|
||||
// usual, APE
|
||||
const std::pair<const char *, const char *> keyConversions[] = {
|
||||
std::make_pair("TRACKNUMBER", "TRACK"),
|
||||
std::make_pair("DATE", "YEAR"),
|
||||
std::make_pair("ALBUMARTIST", "ALBUM ARTIST"),
|
||||
std::make_pair("DISCNUMBER", "DISC"),
|
||||
std::make_pair("REMIXER", "MIXARTIST"),
|
||||
std::make_pair("RELEASESTATUS", "MUSICBRAINZ_ALBUMSTATUS"),
|
||||
std::make_pair("RELEASETYPE", "MUSICBRAINZ_ALBUMTYPE"),
|
||||
};
|
||||
const size_t keyConversionsSize = sizeof(keyConversions) / sizeof(keyConversions[0]);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
PropertyMap APE::Tag::properties() const
|
||||
{
|
||||
@@ -235,8 +228,8 @@ PropertyMap APE::Tag::properties() const
|
||||
else {
|
||||
// Some tags need to be handled specially
|
||||
for(size_t i = 0; i < keyConversionsSize; ++i) {
|
||||
if(tagName == keyConversions[i][1])
|
||||
tagName = keyConversions[i][0];
|
||||
if(tagName == keyConversions[i].second)
|
||||
tagName = keyConversions[i].first;
|
||||
}
|
||||
properties[tagName].append(it->second.toStringList());
|
||||
}
|
||||
@@ -257,9 +250,9 @@ PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
|
||||
|
||||
// see comment in properties()
|
||||
for(size_t i = 0; i < keyConversionsSize; ++i)
|
||||
if(properties.contains(keyConversions[i][0])) {
|
||||
properties.insert(keyConversions[i][1], properties[keyConversions[i][0]]);
|
||||
properties.erase(keyConversions[i][0]);
|
||||
if(properties.contains(keyConversions[i].first)) {
|
||||
properties.insert(keyConversions[i].second, properties[keyConversions[i].first]);
|
||||
properties.erase(keyConversions[i].first);
|
||||
}
|
||||
|
||||
// first check if tags need to be removed completely
|
||||
@@ -419,7 +412,12 @@ void APE::Tag::parse(const ByteVector &data)
|
||||
}
|
||||
|
||||
const unsigned int keyLength = nullPos - pos - 8;
|
||||
const unsigned int valLegnth = data.toUInt(pos, false);
|
||||
const unsigned int valLength = data.toUInt(pos, false);
|
||||
|
||||
if(valLength >= data.size() || pos > data.size() - valLength) {
|
||||
debug("APE::Tag::parse() - Invalid val length. Stopped parsing.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(keyLength >= MinKeyLength
|
||||
&& keyLength <= MaxKeyLength
|
||||
@@ -434,6 +432,6 @@ void APE::Tag::parse(const ByteVector &data)
|
||||
debug("APE::Tag::parse() - Skipped an item due to an invalid key.");
|
||||
}
|
||||
|
||||
pos += keyLength + valLegnth + 9;
|
||||
pos += keyLength + valLength + 9;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace TagLib {
|
||||
class TagPrivate;
|
||||
TagPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace APE
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -185,7 +185,7 @@ String ASF::Attribute::parse(ASF::File &f, int kind)
|
||||
if(kind == 0) {
|
||||
nameLength = readWORD(&f);
|
||||
name = readString(&f, nameLength);
|
||||
d->type = ASF::Attribute::AttributeTypes(readWORD(&f));
|
||||
d->type = static_cast<ASF::Attribute::AttributeTypes>(readWORD(&f));
|
||||
size = readWORD(&f);
|
||||
}
|
||||
// metadata & metadata library
|
||||
@@ -197,7 +197,7 @@ String ASF::Attribute::parse(ASF::File &f, int kind)
|
||||
}
|
||||
d->stream = readWORD(&f);
|
||||
nameLength = readWORD(&f);
|
||||
d->type = ASF::Attribute::AttributeTypes(readWORD(&f));
|
||||
d->type = static_cast<ASF::Attribute::AttributeTypes>(readWORD(&f));
|
||||
size = readDWORD(&f);
|
||||
name = readString(&f, nameLength);
|
||||
}
|
||||
@@ -312,7 +312,7 @@ ByteVector ASF::Attribute::render(const String &name, int kind) const
|
||||
|
||||
if(kind == 0) {
|
||||
data = renderString(name, true) +
|
||||
ByteVector::fromShort((int)d->type, false) +
|
||||
ByteVector::fromShort(static_cast<int>(d->type), false) +
|
||||
ByteVector::fromShort(data.size(), false) +
|
||||
data;
|
||||
}
|
||||
@@ -321,7 +321,7 @@ ByteVector ASF::Attribute::render(const String &name, int kind) const
|
||||
data = ByteVector::fromShort(kind == 2 ? d->language : 0, false) +
|
||||
ByteVector::fromShort(d->stream, false) +
|
||||
ByteVector::fromShort(nameData.size(), false) +
|
||||
ByteVector::fromShort((int)d->type, false) +
|
||||
ByteVector::fromShort(static_cast<int>(d->type), false) +
|
||||
ByteVector::fromUInt(data.size(), false) +
|
||||
nameData +
|
||||
data;
|
||||
|
||||
@@ -33,10 +33,8 @@
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
|
||||
namespace ASF
|
||||
{
|
||||
|
||||
class File;
|
||||
class Picture;
|
||||
|
||||
@@ -201,8 +199,7 @@ namespace TagLib
|
||||
class AttributePrivate;
|
||||
AttributePrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace ASF
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace
|
||||
const ByteVector contentEncryptionGuid("\xFB\xB3\x11\x22\x23\xBD\xD2\x11\xB4\xB7\x00\xA0\xC9\x55\xFC\x6E", 16);
|
||||
const ByteVector extendedContentEncryptionGuid("\x14\xE6\x8A\x29\x22\x26 \x17\x4C\xB9\x35\xDA\xE0\x7E\xE9\x28\x9C", 16);
|
||||
const ByteVector advancedContentEncryptionGuid("\xB6\x9B\x07\x7A\xA4\xDA\x12\x4E\xA5\xCA\x91\xD3\x8D\xC1\x1A\x8D", 16);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class ASF::File::FilePrivate::BaseObject
|
||||
{
|
||||
@@ -194,7 +194,7 @@ private:
|
||||
void ASF::File::FilePrivate::BaseObject::parse(ASF::File *file, unsigned int size)
|
||||
{
|
||||
data.clear();
|
||||
if(size > 24 && size <= (unsigned int)(file->length()))
|
||||
if(size > 24 && size <= static_cast<unsigned int>(file->length()))
|
||||
data = file->readBlock(size - 24);
|
||||
else
|
||||
data = ByteVector();
|
||||
@@ -384,7 +384,7 @@ void ASF::File::FilePrivate::HeaderExtensionObject::parse(ASF::File *file, unsig
|
||||
}
|
||||
bool ok;
|
||||
long long size = readQWORD(file, &ok);
|
||||
if(!ok) {
|
||||
if(!ok || size < 0 || size > dataSize - dataPos) {
|
||||
file->setValid(false);
|
||||
break;
|
||||
}
|
||||
@@ -400,7 +400,7 @@ void ASF::File::FilePrivate::HeaderExtensionObject::parse(ASF::File *file, unsig
|
||||
else {
|
||||
obj = new UnknownObject(guid);
|
||||
}
|
||||
obj->parse(file, (unsigned int)size);
|
||||
obj->parse(file, static_cast<unsigned int>(size));
|
||||
objects.append(obj);
|
||||
dataPos += size;
|
||||
}
|
||||
@@ -656,7 +656,7 @@ void ASF::File::read()
|
||||
setValid(false);
|
||||
break;
|
||||
}
|
||||
long size = (long)readQWORD(this, &ok);
|
||||
long size = static_cast<long>(readQWORD(this, &ok));
|
||||
if(!ok) {
|
||||
setValid(false);
|
||||
break;
|
||||
|
||||
@@ -33,10 +33,8 @@
|
||||
#include "asftag.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
//! An implementation of ASF (WMA) metadata
|
||||
namespace ASF {
|
||||
|
||||
/*!
|
||||
* This implements and provides an interface for ASF files to the
|
||||
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
|
||||
@@ -130,9 +128,7 @@ namespace TagLib {
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace ASF
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -137,7 +137,7 @@ ByteVector ASF::Picture::render() const
|
||||
return ByteVector();
|
||||
|
||||
return
|
||||
ByteVector((char)d->type) +
|
||||
ByteVector(static_cast<char>(d->type)) +
|
||||
ByteVector::fromUInt(d->picture.size(), false) +
|
||||
renderString(d->mimeType) +
|
||||
renderString(d->description) +
|
||||
@@ -150,7 +150,7 @@ void ASF::Picture::parse(const ByteVector& bytes)
|
||||
if(bytes.size() < 9)
|
||||
return;
|
||||
int pos = 0;
|
||||
d->type = (Type)bytes[0]; ++pos;
|
||||
d->type = static_cast<Type>(bytes[0]); ++pos;
|
||||
const unsigned int dataLen = bytes.toUInt(pos, false); pos+=4;
|
||||
|
||||
const ByteVector nullStringTerminator(2, 0);
|
||||
@@ -172,7 +172,6 @@ void ASF::Picture::parse(const ByteVector& bytes)
|
||||
|
||||
d->picture = bytes.mid(pos, dataLen);
|
||||
d->valid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ASF::Picture ASF::Picture::fromInvalid()
|
||||
|
||||
@@ -216,7 +216,7 @@ namespace TagLib
|
||||
class PicturePrivate;
|
||||
PicturePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace ASF
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ASFPICTURE_H
|
||||
|
||||
@@ -31,9 +31,7 @@
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace ASF {
|
||||
|
||||
//! An implementation of ASF audio properties
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties
|
||||
{
|
||||
@@ -86,7 +84,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
@@ -178,9 +176,6 @@ namespace TagLib {
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace ASF
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,6 @@ public:
|
||||
};
|
||||
|
||||
ASF::Tag::Tag() :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
}
|
||||
@@ -95,8 +94,7 @@ unsigned int ASF::Tag::track() const
|
||||
const ASF::Attribute attr = d->attributeListMap["WM/TrackNumber"][0];
|
||||
if(attr.type() == ASF::Attribute::DWordType)
|
||||
return attr.toUInt();
|
||||
else
|
||||
return attr.toString().toInt();
|
||||
return attr.toString().toInt();
|
||||
}
|
||||
if(d->attributeListMap.contains("WM/Track"))
|
||||
return d->attributeListMap["WM/Track"][0].toUInt();
|
||||
@@ -212,65 +210,65 @@ bool ASF::Tag::isEmpty() const
|
||||
|
||||
namespace
|
||||
{
|
||||
const char *keyTranslation[][2] = {
|
||||
{ "WM/AlbumTitle", "ALBUM" },
|
||||
{ "WM/AlbumArtist", "ALBUMARTIST" },
|
||||
{ "WM/Composer", "COMPOSER" },
|
||||
{ "WM/Writer", "LYRICIST" },
|
||||
{ "WM/Conductor", "CONDUCTOR" },
|
||||
{ "WM/ModifiedBy", "REMIXER" },
|
||||
{ "WM/Year", "DATE" },
|
||||
{ "WM/OriginalReleaseYear", "ORIGINALDATE" },
|
||||
{ "WM/Producer", "PRODUCER" },
|
||||
{ "WM/ContentGroupDescription", "GROUPING" },
|
||||
{ "WM/SubTitle", "SUBTITLE" },
|
||||
{ "WM/SetSubTitle", "DISCSUBTITLE" },
|
||||
{ "WM/TrackNumber", "TRACKNUMBER" },
|
||||
{ "WM/PartOfSet", "DISCNUMBER" },
|
||||
{ "WM/Genre", "GENRE" },
|
||||
{ "WM/BeatsPerMinute", "BPM" },
|
||||
{ "WM/Mood", "MOOD" },
|
||||
{ "WM/ISRC", "ISRC" },
|
||||
{ "WM/Lyrics", "LYRICS" },
|
||||
{ "WM/Media", "MEDIA" },
|
||||
{ "WM/Publisher", "LABEL" },
|
||||
{ "WM/CatalogNo", "CATALOGNUMBER" },
|
||||
{ "WM/Barcode", "BARCODE" },
|
||||
{ "WM/EncodedBy", "ENCODEDBY" },
|
||||
{ "WM/AlbumSortOrder", "ALBUMSORT" },
|
||||
{ "WM/AlbumArtistSortOrder", "ALBUMARTISTSORT" },
|
||||
{ "WM/ArtistSortOrder", "ARTISTSORT" },
|
||||
{ "WM/TitleSortOrder", "TITLESORT" },
|
||||
{ "WM/Script", "SCRIPT" },
|
||||
{ "WM/Language", "LANGUAGE" },
|
||||
{ "WM/ARTISTS", "ARTISTS" },
|
||||
{ "ASIN", "ASIN" },
|
||||
{ "MusicBrainz/Track Id", "MUSICBRAINZ_TRACKID" },
|
||||
{ "MusicBrainz/Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "MusicBrainz/Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MusicBrainz/Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "MusicBrainz/Album Release Country", "RELEASECOUNTRY" },
|
||||
{ "MusicBrainz/Album Status", "RELEASESTATUS" },
|
||||
{ "MusicBrainz/Album Type", "RELEASETYPE" },
|
||||
{ "MusicBrainz/Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "MusicBrainz/Release Track Id", "MUSICBRAINZ_RELEASETRACKID" },
|
||||
{ "MusicBrainz/Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "MusicIP/PUID", "MUSICIP_PUID" },
|
||||
{ "Acoustid/Id", "ACOUSTID_ID" },
|
||||
{ "Acoustid/Fingerprint", "ACOUSTID_FINGERPRINT" },
|
||||
const std::pair<const char *, const char *> keyTranslation[] = {
|
||||
std::make_pair("WM/AlbumTitle", "ALBUM"),
|
||||
std::make_pair("WM/AlbumArtist", "ALBUMARTIST"),
|
||||
std::make_pair("WM/Composer", "COMPOSER"),
|
||||
std::make_pair("WM/Writer", "LYRICIST"),
|
||||
std::make_pair("WM/Conductor", "CONDUCTOR"),
|
||||
std::make_pair("WM/ModifiedBy", "REMIXER"),
|
||||
std::make_pair("WM/Year", "DATE"),
|
||||
std::make_pair("WM/OriginalReleaseYear", "ORIGINALDATE"),
|
||||
std::make_pair("WM/Producer", "PRODUCER"),
|
||||
std::make_pair("WM/ContentGroupDescription", "WORK"),
|
||||
std::make_pair("WM/SubTitle", "SUBTITLE"),
|
||||
std::make_pair("WM/SetSubTitle", "DISCSUBTITLE"),
|
||||
std::make_pair("WM/TrackNumber", "TRACKNUMBER"),
|
||||
std::make_pair("WM/PartOfSet", "DISCNUMBER"),
|
||||
std::make_pair("WM/Genre", "GENRE"),
|
||||
std::make_pair("WM/BeatsPerMinute", "BPM"),
|
||||
std::make_pair("WM/Mood", "MOOD"),
|
||||
std::make_pair("WM/ISRC", "ISRC"),
|
||||
std::make_pair("WM/Lyrics", "LYRICS"),
|
||||
std::make_pair("WM/Media", "MEDIA"),
|
||||
std::make_pair("WM/Publisher", "LABEL"),
|
||||
std::make_pair("WM/CatalogNo", "CATALOGNUMBER"),
|
||||
std::make_pair("WM/Barcode", "BARCODE"),
|
||||
std::make_pair("WM/EncodedBy", "ENCODEDBY"),
|
||||
std::make_pair("WM/AlbumSortOrder", "ALBUMSORT"),
|
||||
std::make_pair("WM/AlbumArtistSortOrder", "ALBUMARTISTSORT"),
|
||||
std::make_pair("WM/ArtistSortOrder", "ARTISTSORT"),
|
||||
std::make_pair("WM/TitleSortOrder", "TITLESORT"),
|
||||
std::make_pair("WM/Script", "SCRIPT"),
|
||||
std::make_pair("WM/Language", "LANGUAGE"),
|
||||
std::make_pair("WM/ARTISTS", "ARTISTS"),
|
||||
std::make_pair("ASIN", "ASIN"),
|
||||
std::make_pair("MusicBrainz/Track Id", "MUSICBRAINZ_TRACKID"),
|
||||
std::make_pair("MusicBrainz/Artist Id", "MUSICBRAINZ_ARTISTID"),
|
||||
std::make_pair("MusicBrainz/Album Id", "MUSICBRAINZ_ALBUMID"),
|
||||
std::make_pair("MusicBrainz/Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID"),
|
||||
std::make_pair("MusicBrainz/Album Release Country", "RELEASECOUNTRY"),
|
||||
std::make_pair("MusicBrainz/Album Status", "RELEASESTATUS"),
|
||||
std::make_pair("MusicBrainz/Album Type", "RELEASETYPE"),
|
||||
std::make_pair("MusicBrainz/Release Group Id", "MUSICBRAINZ_RELEASEGROUPID"),
|
||||
std::make_pair("MusicBrainz/Release Track Id", "MUSICBRAINZ_RELEASETRACKID"),
|
||||
std::make_pair("MusicBrainz/Work Id", "MUSICBRAINZ_WORKID"),
|
||||
std::make_pair("MusicIP/PUID", "MUSICIP_PUID"),
|
||||
std::make_pair("Acoustid/Id", "ACOUSTID_ID"),
|
||||
std::make_pair("Acoustid/Fingerprint", "ACOUSTID_FINGERPRINT"),
|
||||
};
|
||||
const size_t keyTranslationSize = sizeof(keyTranslation) / sizeof(keyTranslation[0]);
|
||||
|
||||
String translateKey(const String &key)
|
||||
{
|
||||
for(size_t i = 0; i < keyTranslationSize; ++i) {
|
||||
if(key == keyTranslation[i][0])
|
||||
return keyTranslation[i][1];
|
||||
if(key == keyTranslation[i].first)
|
||||
return keyTranslation[i].second;
|
||||
}
|
||||
|
||||
return String();
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
PropertyMap ASF::Tag::properties() const
|
||||
{
|
||||
@@ -324,9 +322,8 @@ PropertyMap ASF::Tag::setProperties(const PropertyMap &props)
|
||||
{
|
||||
static Map<String, String> reverseKeyMap;
|
||||
if(reverseKeyMap.isEmpty()) {
|
||||
int numKeys = sizeof(keyTranslation) / sizeof(keyTranslation[0]);
|
||||
for(int i = 0; i < numKeys; i++) {
|
||||
reverseKeyMap[keyTranslation[i][1]] = keyTranslation[i][0];
|
||||
for(size_t i = 0; i < keyTranslationSize; i++) {
|
||||
reverseKeyMap[keyTranslation[i].second] = keyTranslation[i].first;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,8 @@ namespace TagLib {
|
||||
virtual bool isEmpty() const;
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use attributeListMap() const, contains(), removeItem(),
|
||||
* attribute(), setAttribute(), addAttribute().
|
||||
*/
|
||||
AttributeListMap &attributeListMap();
|
||||
|
||||
@@ -205,6 +206,6 @@ namespace TagLib {
|
||||
class TagPrivate;
|
||||
TagPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace ASF
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -95,9 +95,9 @@ namespace TagLib
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
} // namespace ASF
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -49,32 +49,31 @@ using namespace TagLib;
|
||||
#define VIRTUAL_FUNCTION_WORKAROUND(function_name, default_value) \
|
||||
if(dynamic_cast<const APE::Properties*>(this)) \
|
||||
return dynamic_cast<const APE::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const ASF::Properties*>(this)) \
|
||||
if(dynamic_cast<const ASF::Properties*>(this)) \
|
||||
return dynamic_cast<const ASF::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const FLAC::Properties*>(this)) \
|
||||
if(dynamic_cast<const FLAC::Properties*>(this)) \
|
||||
return dynamic_cast<const FLAC::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const MP4::Properties*>(this)) \
|
||||
if(dynamic_cast<const MP4::Properties*>(this)) \
|
||||
return dynamic_cast<const MP4::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const MPC::Properties*>(this)) \
|
||||
if(dynamic_cast<const MPC::Properties*>(this)) \
|
||||
return dynamic_cast<const MPC::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const MPEG::Properties*>(this)) \
|
||||
if(dynamic_cast<const MPEG::Properties*>(this)) \
|
||||
return dynamic_cast<const MPEG::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const Ogg::Opus::Properties*>(this)) \
|
||||
if(dynamic_cast<const Ogg::Opus::Properties*>(this)) \
|
||||
return dynamic_cast<const Ogg::Opus::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const Ogg::Speex::Properties*>(this)) \
|
||||
if(dynamic_cast<const Ogg::Speex::Properties*>(this)) \
|
||||
return dynamic_cast<const Ogg::Speex::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const TrueAudio::Properties*>(this)) \
|
||||
if(dynamic_cast<const TrueAudio::Properties*>(this)) \
|
||||
return dynamic_cast<const TrueAudio::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const RIFF::AIFF::Properties*>(this)) \
|
||||
if(dynamic_cast<const RIFF::AIFF::Properties*>(this)) \
|
||||
return dynamic_cast<const RIFF::AIFF::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const RIFF::WAV::Properties*>(this)) \
|
||||
if(dynamic_cast<const RIFF::WAV::Properties*>(this)) \
|
||||
return dynamic_cast<const RIFF::WAV::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const Vorbis::Properties*>(this)) \
|
||||
if(dynamic_cast<const Vorbis::Properties*>(this)) \
|
||||
return dynamic_cast<const Vorbis::Properties*>(this)->function_name(); \
|
||||
else if(dynamic_cast<const WavPack::Properties*>(this)) \
|
||||
if(dynamic_cast<const WavPack::Properties*>(this)) \
|
||||
return dynamic_cast<const WavPack::Properties*>(this)->function_name(); \
|
||||
else \
|
||||
return (default_value);
|
||||
return (default_value);
|
||||
|
||||
class AudioProperties::AudioPropertiesPrivate
|
||||
{
|
||||
|
||||
@@ -122,6 +122,6 @@ namespace TagLib {
|
||||
AudioPropertiesPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -67,8 +67,13 @@ namespace
|
||||
File *detectByResolvers(FileName fileName, bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if(::strlen(fileName) == 0 && ::wcslen(fileName) == 0)
|
||||
return 0;
|
||||
#else
|
||||
if(::strlen(fileName) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
ResolverList::ConstIterator it = fileTypeResolvers.begin();
|
||||
for(; it != fileTypeResolvers.end(); ++it) {
|
||||
File *file = (*it)->createFile(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
@@ -79,6 +84,22 @@ namespace
|
||||
return 0;
|
||||
}
|
||||
|
||||
File *detectByResolvers(IOStream* stream, bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
{
|
||||
for(ResolverList::ConstIterator it = fileTypeResolvers.begin();
|
||||
it != fileTypeResolvers.end(); ++it) {
|
||||
if(const FileRef::StreamTypeResolver *streamResolver =
|
||||
dynamic_cast<const FileRef::StreamTypeResolver*>(*it)) {
|
||||
if(File *file = streamResolver->createFileFromStream(
|
||||
stream, readAudioProperties, audioPropertiesStyle))
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Detect the file type based on the file extension.
|
||||
|
||||
File* detectByExtension(IOStream *stream, bool readAudioProperties,
|
||||
@@ -104,41 +125,51 @@ namespace
|
||||
|
||||
// .oga can be any audio in the Ogg container. So leave it to content-based detection.
|
||||
|
||||
File *file = 0;
|
||||
|
||||
if(ext == "MP3")
|
||||
return new MPEG::File(stream, ID3v2::FrameFactory::instance(), readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "OGG")
|
||||
return new Ogg::Vorbis::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "FLAC")
|
||||
return new FLAC::File(stream, ID3v2::FrameFactory::instance(), readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "MPC")
|
||||
return new MPC::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "WV")
|
||||
return new WavPack::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "SPX")
|
||||
return new Ogg::Speex::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "OPUS")
|
||||
return new Ogg::Opus::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "TTA")
|
||||
return new TrueAudio::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "M4A" || ext == "M4R" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2" || ext == "M4V")
|
||||
return new MP4::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "WMA" || ext == "ASF")
|
||||
return new ASF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "AIF" || ext == "AIFF" || ext == "AFC" || ext == "AIFC")
|
||||
return new RIFF::AIFF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "WAV")
|
||||
return new RIFF::WAV::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "APE")
|
||||
return new APE::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
file = new MPEG::File(stream, ID3v2::FrameFactory::instance(), readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "OGG")
|
||||
file = new Ogg::Vorbis::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "FLAC")
|
||||
file = new FLAC::File(stream, ID3v2::FrameFactory::instance(), readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "MPC")
|
||||
file = new MPC::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "WV")
|
||||
file = new WavPack::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "SPX")
|
||||
file = new Ogg::Speex::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "OPUS")
|
||||
file = new Ogg::Opus::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "TTA")
|
||||
file = new TrueAudio::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "M4A" || ext == "M4R" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2" || ext == "M4V")
|
||||
file = new MP4::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "WMA" || ext == "ASF")
|
||||
file = new ASF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "AIF" || ext == "AIFF" || ext == "AFC" || ext == "AIFC")
|
||||
file = new RIFF::AIFF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "WAV")
|
||||
file = new RIFF::WAV::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "APE")
|
||||
file = new APE::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
// module, nst and wow are possible but uncommon extensions
|
||||
if(ext == "MOD" || ext == "MODULE" || ext == "NST" || ext == "WOW")
|
||||
return new Mod::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "S3M")
|
||||
return new S3M::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "IT")
|
||||
return new IT::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "XM")
|
||||
return new XM::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "MOD" || ext == "MODULE" || ext == "NST" || ext == "WOW")
|
||||
file = new Mod::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "S3M")
|
||||
file = new S3M::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "IT")
|
||||
file = new IT::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "XM")
|
||||
file = new XM::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
|
||||
// if file is not valid, leave it to content-based detection.
|
||||
|
||||
if(file) {
|
||||
if(file->isValid())
|
||||
return file;
|
||||
delete file;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -184,8 +215,7 @@ namespace
|
||||
if(file) {
|
||||
if(file->isValid())
|
||||
return file;
|
||||
else
|
||||
delete file;
|
||||
delete file;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -262,13 +292,12 @@ namespace
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class FileRef::FileRefPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
FileRefPrivate() :
|
||||
RefCounter(),
|
||||
file(0),
|
||||
stream(0) {}
|
||||
|
||||
@@ -467,6 +496,12 @@ void FileRef::parse(FileName fileName, bool readAudioProperties,
|
||||
void FileRef::parse(IOStream *stream, bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
{
|
||||
// Try user-defined stream resolvers.
|
||||
|
||||
d->file = detectByResolvers(stream, readAudioProperties, audioPropertiesStyle);
|
||||
if(d->file)
|
||||
return;
|
||||
|
||||
// Try user-defined resolvers.
|
||||
|
||||
d->file = detectByResolvers(stream->name(), readAudioProperties, audioPropertiesStyle);
|
||||
|
||||
@@ -108,6 +108,16 @@ namespace TagLib {
|
||||
audioPropertiesStyle = AudioProperties::Average) const = 0;
|
||||
};
|
||||
|
||||
class TAGLIB_EXPORT StreamTypeResolver : public FileTypeResolver
|
||||
{
|
||||
TAGLIB_IGNORE_MISSING_DESTRUCTOR
|
||||
public:
|
||||
virtual File *createFileFromStream(IOStream *stream,
|
||||
bool readAudioProperties = true,
|
||||
AudioProperties::ReadStyle
|
||||
audioPropertiesStyle = AudioProperties::Average) const = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Creates a null FileRef.
|
||||
*/
|
||||
@@ -166,8 +176,8 @@ namespace TagLib {
|
||||
* \warning This pointer will become invalid when this FileRef and all
|
||||
* copies pass out of scope.
|
||||
*
|
||||
* \warning Do not cast it to any subclasses of \class Tag.
|
||||
* Use tag returning methods of appropriate subclasses of \class File instead.
|
||||
* \warning Do not cast it to any subclasses of Tag.
|
||||
* Use tag returning methods of appropriate subclasses of File instead.
|
||||
*
|
||||
* \see File::tag()
|
||||
*/
|
||||
@@ -268,7 +278,7 @@ namespace TagLib {
|
||||
* \note You generally shouldn't use this method, but instead the constructor
|
||||
* directly.
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use FileRef(FileName, bool, AudioProperties::ReadStyle).
|
||||
*/
|
||||
static File *create(FileName fileName,
|
||||
bool readAudioProperties = true,
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace
|
||||
const long MaxPaddingLegnth = 1024 * 1024;
|
||||
|
||||
const char LastBlockFlag = '\x80';
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class FLAC::File::FilePrivate
|
||||
{
|
||||
@@ -497,6 +497,11 @@ void FLAC::File::scan()
|
||||
|
||||
seek(nextBlockOffset);
|
||||
const ByteVector header = readBlock(4);
|
||||
if(header.size() != 4) {
|
||||
debug("FLAC::File::scan() -- Failed to read a block header");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Header format (from spec):
|
||||
// <1> Last-metadata-block flag
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace TagLib {
|
||||
* when
|
||||
*
|
||||
* \see ID3v2FrameFactory
|
||||
* \deprecated This value should be passed in via the constructor
|
||||
* \deprecated This value should be passed in via the constructor.
|
||||
*/
|
||||
TAGLIB_DEPRECATED void setID3v2FrameFactory(const ID3v2::FrameFactory *factory);
|
||||
|
||||
@@ -337,7 +337,7 @@ namespace TagLib {
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace FLAC
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,8 +37,8 @@ public:
|
||||
};
|
||||
|
||||
FLAC::MetadataBlock::MetadataBlock()
|
||||
: d(0)
|
||||
{
|
||||
d = 0;
|
||||
}
|
||||
|
||||
FLAC::MetadataBlock::~MetadataBlock()
|
||||
|
||||
@@ -31,9 +31,7 @@
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace FLAC {
|
||||
|
||||
class TAGLIB_EXPORT MetadataBlock
|
||||
{
|
||||
public:
|
||||
@@ -67,9 +65,6 @@ namespace TagLib {
|
||||
class MetadataBlockPrivate;
|
||||
MetadataBlockPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace FLAC
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -79,7 +79,7 @@ bool FLAC::Picture::parse(const ByteVector &data)
|
||||
}
|
||||
|
||||
unsigned int pos = 0;
|
||||
d->type = FLAC::Picture::Type(data.toUInt(pos));
|
||||
d->type = static_cast<FLAC::Picture::Type>(data.toUInt(pos));
|
||||
pos += 4;
|
||||
unsigned int mimeTypeLength = data.toUInt(pos);
|
||||
pos += 4;
|
||||
|
||||
@@ -33,9 +33,7 @@
|
||||
#include "flacmetadatablock.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace FLAC {
|
||||
|
||||
class TAGLIB_EXPORT Picture : public MetadataBlock
|
||||
{
|
||||
public:
|
||||
@@ -200,9 +198,6 @@ namespace TagLib {
|
||||
};
|
||||
|
||||
typedef List<Picture> PictureList;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace FLAC
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of bitsPerSample().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use bitsPerSample().
|
||||
*/
|
||||
TAGLIB_DEPRECATED int sampleWidth() const;
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace TagLib {
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace FLAC
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,9 +32,7 @@
|
||||
#include "flacmetadatablock.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace FLAC {
|
||||
|
||||
class TAGLIB_EXPORT UnknownMetadataBlock : public MetadataBlock
|
||||
{
|
||||
public:
|
||||
@@ -73,9 +71,6 @@ namespace TagLib {
|
||||
class UnknownMetadataBlockPrivate;
|
||||
UnknownMetadataBlockPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace FLAC
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,7 @@ class IT::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate(AudioProperties::ReadStyle propertiesStyle)
|
||||
: tag(), properties(propertiesStyle)
|
||||
: properties(propertiesStyle)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ bool IT::File::save()
|
||||
// write comment as instrument and sample names:
|
||||
StringList lines = d->tag.comment().split("\n");
|
||||
for(unsigned short i = 0; i < instrumentCount; ++ i) {
|
||||
seek(192L + length + ((long)i << 2));
|
||||
seek(192L + length + (static_cast<long>(i) << 2));
|
||||
unsigned long instrumentOffset = 0;
|
||||
if(!readU32L(instrumentOffset))
|
||||
return false;
|
||||
@@ -128,14 +128,14 @@ bool IT::File::save()
|
||||
}
|
||||
|
||||
for(unsigned short i = 0; i < sampleCount; ++ i) {
|
||||
seek(192L + length + ((long)instrumentCount << 2) + ((long)i << 2));
|
||||
seek(192L + length + (static_cast<long>(instrumentCount) << 2) + (static_cast<long>(i) << 2));
|
||||
unsigned long sampleOffset = 0;
|
||||
if(!readU32L(sampleOffset))
|
||||
return false;
|
||||
|
||||
seek(sampleOffset + 20);
|
||||
|
||||
if((unsigned int)(i + instrumentCount) < lines.size())
|
||||
if(static_cast<unsigned int>(i + instrumentCount) < lines.size())
|
||||
writeString(lines[i + instrumentCount], 25);
|
||||
else
|
||||
writeString(String(), 25);
|
||||
@@ -152,7 +152,7 @@ bool IT::File::save()
|
||||
// terminating NUL but it does not hurt to add one:
|
||||
if(message.size() > 7999)
|
||||
message.resize(7999);
|
||||
message.append((char)0);
|
||||
message.append(static_cast<char>(0));
|
||||
|
||||
unsigned short special = 0;
|
||||
unsigned short messageLength = 0;
|
||||
@@ -239,7 +239,7 @@ void IT::File::read(bool)
|
||||
seek(messageOffset);
|
||||
ByteVector messageBytes = readBlock(messageLength);
|
||||
READ_ASSERT(messageBytes.size() == messageLength);
|
||||
int index = messageBytes.find((char) 0);
|
||||
int index = messageBytes.find(static_cast<char>(0));
|
||||
if(index > -1)
|
||||
messageBytes.resize(index, 0);
|
||||
messageBytes.replace('\r', '\n');
|
||||
@@ -258,7 +258,7 @@ void IT::File::read(bool)
|
||||
// But this always gives 64 channels for all my files anyway.
|
||||
// Strangely VLC does report other values. I wonder how VLC
|
||||
// gets it's values.
|
||||
if((unsigned char) pannings[i] < 128 && volumes[i] > 0)
|
||||
if(static_cast<unsigned char>(pannings[i]) < 128 && volumes[i] > 0)
|
||||
++channels;
|
||||
}
|
||||
d->properties.setChannels(channels);
|
||||
@@ -280,7 +280,7 @@ void IT::File::read(bool)
|
||||
// e.g. VLC seems to interpret a nil as a space. I
|
||||
// don't know what is the proper behaviour.
|
||||
for(unsigned short i = 0; i < instrumentCount; ++ i) {
|
||||
seek(192L + length + ((long)i << 2));
|
||||
seek(192L + length + (static_cast<long>(i) << 2));
|
||||
READ_U32L_AS(instrumentOffset);
|
||||
seek(instrumentOffset);
|
||||
|
||||
@@ -296,7 +296,7 @@ void IT::File::read(bool)
|
||||
}
|
||||
|
||||
for(unsigned short i = 0; i < sampleCount; ++ i) {
|
||||
seek(192L + length + ((long)instrumentCount << 2) + ((long)i << 2));
|
||||
seek(192L + length + (static_cast<long>(instrumentCount) << 2) + (static_cast<long>(i) << 2));
|
||||
READ_U32L_AS(sampleOffset);
|
||||
|
||||
seek(sampleOffset);
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace TagLib {
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace IT
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace TagLib {
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace IT
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,9 +34,7 @@
|
||||
#include "modproperties.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace Mod {
|
||||
|
||||
class TAGLIB_EXPORT File : public TagLib::Mod::FileBase
|
||||
{
|
||||
public:
|
||||
@@ -106,9 +104,6 @@ namespace TagLib {
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace Mod
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@ bool Mod::FileBase::readString(String &s, unsigned long size)
|
||||
{
|
||||
ByteVector data(readBlock(size));
|
||||
if(data.size() < size) return false;
|
||||
int index = data.find((char) 0);
|
||||
int index = data.find(static_cast<char>(0));
|
||||
if(index > -1)
|
||||
{
|
||||
data.resize(index);
|
||||
|
||||
@@ -35,9 +35,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace Mod {
|
||||
|
||||
class TAGLIB_EXPORT FileBase : public TagLib::File
|
||||
{
|
||||
protected:
|
||||
@@ -58,9 +56,6 @@ namespace TagLib {
|
||||
bool readU16B(unsigned short &number);
|
||||
bool readU32B(unsigned long &number);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace Mod
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -30,9 +30,7 @@
|
||||
#include "audioproperties.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace Mod {
|
||||
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties
|
||||
{
|
||||
public:
|
||||
@@ -63,9 +61,6 @@ namespace TagLib {
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace Mod
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -44,7 +44,6 @@ public:
|
||||
};
|
||||
|
||||
Mod::Tag::Tag() :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,9 +29,7 @@
|
||||
#include "tag.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace Mod {
|
||||
|
||||
/*!
|
||||
* Tags for module files (Mod, S3M, IT, XM).
|
||||
*
|
||||
@@ -186,9 +184,6 @@ namespace TagLib {
|
||||
class TagPrivate;
|
||||
TagPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace Mod
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -31,17 +31,17 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
const char *MP4::Atom::containers[11] = {
|
||||
const char *const MP4::Atom::containers[11] = {
|
||||
"moov", "udta", "mdia", "meta", "ilst",
|
||||
"stbl", "minf", "moof", "traf", "trak",
|
||||
"stsd"
|
||||
};
|
||||
|
||||
MP4::Atom::Atom(File *file)
|
||||
: offset(file->tell())
|
||||
{
|
||||
children.setAutoDelete(true);
|
||||
|
||||
offset = file->tell();
|
||||
ByteVector header = file->readBlock(8);
|
||||
if(header.size() != 8) {
|
||||
// The atom header must be 8 bytes long, otherwise there is either
|
||||
@@ -73,7 +73,7 @@ MP4::Atom::Atom(File *file)
|
||||
}
|
||||
}
|
||||
|
||||
if(length < 8) {
|
||||
if(length < 8 || length > file->length() - offset) {
|
||||
debug("MP4: Invalid atom size");
|
||||
length = 0;
|
||||
file->seek(0, File::End);
|
||||
@@ -81,11 +81,37 @@ MP4::Atom::Atom(File *file)
|
||||
}
|
||||
|
||||
name = header.mid(4, 4);
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
const char ch = name.at(i);
|
||||
if((ch < ' ' || ch > '~') && ch != '\251') {
|
||||
debug("MP4: Invalid atom type");
|
||||
length = 0;
|
||||
file->seek(0, File::End);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < numContainers; i++) {
|
||||
if(name == containers[i]) {
|
||||
if(name == "meta") {
|
||||
file->seek(4, File::Current);
|
||||
long posAfterMeta = file->tell();
|
||||
ByteVector nextSize = file->readBlock(8).mid(4, 4);
|
||||
static const char *const metaChildrenNames[] = {
|
||||
"hdlr", "ilst", "mhdr", "ctry", "lang"
|
||||
};
|
||||
bool metaIsFullAtom = true;
|
||||
for(size_t j = 0;
|
||||
j < sizeof(metaChildrenNames) / sizeof(metaChildrenNames[0]);
|
||||
++j) {
|
||||
if(nextSize == metaChildrenNames[j]) {
|
||||
// meta is not a full atom (i.e. not followed by version, flags). It
|
||||
// is followed by the size and type of the first child atom.
|
||||
metaIsFullAtom = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Only skip next four bytes, which contain version and flags, if meta
|
||||
// is a full atom.
|
||||
file->seek(posAfterMeta + (metaIsFullAtom ? 4 : 0));
|
||||
}
|
||||
else if(name == "stsd") {
|
||||
file->seek(8, File::Current);
|
||||
|
||||
@@ -34,9 +34,7 @@
|
||||
#include "tlist.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace MP4 {
|
||||
|
||||
class Atom;
|
||||
typedef TagLib::List<Atom *> AtomList;
|
||||
|
||||
@@ -74,7 +72,7 @@ namespace TagLib {
|
||||
|
||||
typedef TagLib::List<AtomData> AtomDataList;
|
||||
|
||||
class Atom
|
||||
class TAGLIB_EXPORT Atom
|
||||
{
|
||||
public:
|
||||
Atom(File *file);
|
||||
@@ -88,11 +86,11 @@ namespace TagLib {
|
||||
AtomList children;
|
||||
private:
|
||||
static const int numContainers = 11;
|
||||
static const char *containers[11];
|
||||
static const char *const containers[11];
|
||||
};
|
||||
|
||||
//! Root-level atoms
|
||||
class Atoms
|
||||
class TAGLIB_EXPORT Atoms
|
||||
{
|
||||
public:
|
||||
Atoms(File *file);
|
||||
@@ -101,10 +99,8 @@ namespace TagLib {
|
||||
AtomList path(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0);
|
||||
AtomList atoms;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ class MP4::CoverArt::CoverArtPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
CoverArtPrivate() :
|
||||
RefCounter(),
|
||||
format(MP4::CoverArt::JPEG) {}
|
||||
|
||||
Format format;
|
||||
|
||||
@@ -32,9 +32,7 @@
|
||||
#include "mp4atom.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace MP4 {
|
||||
|
||||
class TAGLIB_EXPORT CoverArt
|
||||
{
|
||||
public:
|
||||
@@ -76,9 +74,6 @@ namespace TagLib {
|
||||
};
|
||||
|
||||
typedef List<CoverArt> CoverArtList;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class MP4::File::FilePrivate
|
||||
{
|
||||
@@ -175,6 +175,26 @@ MP4::File::save()
|
||||
return d->tag->save();
|
||||
}
|
||||
|
||||
bool
|
||||
MP4::File::strip(int tags)
|
||||
{
|
||||
if(readOnly()) {
|
||||
debug("MP4::File::strip() - Cannot strip tags from a read only file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!isValid()) {
|
||||
debug("MP4::File::strip() -- Cannot strip tags from an invalid file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(tags & MP4) {
|
||||
return d->tag->strip();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MP4::File::hasMP4Tag() const
|
||||
{
|
||||
|
||||
@@ -33,10 +33,8 @@
|
||||
#include "mp4tag.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
//! An implementation of MP4 (AAC, ALAC, ...) metadata
|
||||
namespace MP4 {
|
||||
|
||||
class Atoms;
|
||||
|
||||
/*!
|
||||
@@ -48,6 +46,19 @@ namespace TagLib {
|
||||
class TAGLIB_EXPORT File : public TagLib::File
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* This set of flags is used for strip() and is suitable for
|
||||
* being OR-ed together.
|
||||
*/
|
||||
enum TagTypes {
|
||||
//! Empty set. Matches no tag types.
|
||||
NoTags = 0x0000,
|
||||
//! Matches MP4 tags.
|
||||
MP4 = 0x0001,
|
||||
//! Matches all tag types.
|
||||
AllTags = 0xffff
|
||||
};
|
||||
|
||||
/*!
|
||||
* Constructs an MP4 file from \a file. If \a readProperties is true the
|
||||
* file's audio properties will also be read.
|
||||
@@ -114,6 +125,15 @@ namespace TagLib {
|
||||
*/
|
||||
bool save();
|
||||
|
||||
/*!
|
||||
* This will strip the tags that match the OR-ed together TagTypes from the
|
||||
* file. By default it strips all tags. It returns true if the tags are
|
||||
* successfully stripped.
|
||||
*
|
||||
* \note This will update the file immediately.
|
||||
*/
|
||||
bool strip(int tags = AllTags);
|
||||
|
||||
/*!
|
||||
* Returns whether or not the file on disk actually has an MP4 tag, or the
|
||||
* file has a Metadata Item List (ilst) atom.
|
||||
@@ -135,9 +155,6 @@ namespace TagLib {
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -34,7 +34,6 @@ class MP4::Item::ItemPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
ItemPrivate() :
|
||||
RefCounter(),
|
||||
valid(true),
|
||||
atomDataType(TypeUndefined) {}
|
||||
|
||||
|
||||
@@ -31,9 +31,7 @@
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace MP4 {
|
||||
|
||||
class TAGLIB_EXPORT Item
|
||||
{
|
||||
public:
|
||||
@@ -85,9 +83,6 @@ namespace TagLib {
|
||||
class ItemPrivate;
|
||||
ItemPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class MP4::Properties::PropertiesPrivate
|
||||
{
|
||||
@@ -188,7 +188,7 @@ MP4::Properties::read(File *file, Atoms *atoms)
|
||||
file->seek(mdhd->offset);
|
||||
data = file->readBlock(mdhd->length);
|
||||
|
||||
const unsigned int version = data[8];
|
||||
const unsigned int version = data.at(8);
|
||||
long long unit;
|
||||
long long length;
|
||||
if(version == 1) {
|
||||
@@ -222,13 +222,13 @@ MP4::Properties::read(File *file, Atoms *atoms)
|
||||
d->channels = data.toShort(40U);
|
||||
d->bitsPerSample = data.toShort(42U);
|
||||
d->sampleRate = data.toUInt(46U);
|
||||
if(data.containsAt("esds", 56) && data[64] == 0x03) {
|
||||
if(data.containsAt("esds", 56) && data.at(64) == 0x03) {
|
||||
unsigned int pos = 65;
|
||||
if(data.containsAt("\x80\x80\x80", pos)) {
|
||||
pos += 3;
|
||||
}
|
||||
pos += 4;
|
||||
if(data[pos] == 0x04) {
|
||||
if(data.at(pos) == 0x04) {
|
||||
pos += 1;
|
||||
if(data.containsAt("\x80\x80\x80", pos)) {
|
||||
pos += 3;
|
||||
|
||||
@@ -30,9 +30,7 @@
|
||||
#include "audioproperties.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace MP4 {
|
||||
|
||||
class Atoms;
|
||||
class File;
|
||||
|
||||
@@ -55,7 +53,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
@@ -112,9 +110,6 @@ namespace TagLib {
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -84,7 +84,7 @@ MP4::Tag::Tag(TagLib::File *file, MP4::Atoms *atoms) :
|
||||
if (val.type == TypeUTF8) {
|
||||
addItem(atom->name, StringList(String(val.data, String::UTF8)));
|
||||
} else {
|
||||
addItem(atom->name, (int)(val.data.toShort()));
|
||||
addItem(atom->name, static_cast<int>(val.data.toShort()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,11 +140,11 @@ MP4::Tag::parseData2(const MP4::Atom *atom, int expectedFlags, bool freeForm)
|
||||
debug("MP4: Unexpected atom \"" + name + "\", expecting \"mean\"");
|
||||
return result;
|
||||
}
|
||||
else if(i == 1 && name != "name") {
|
||||
if(i == 1 && name != "name") {
|
||||
debug("MP4: Unexpected atom \"" + name + "\", expecting \"name\"");
|
||||
return result;
|
||||
}
|
||||
result.append(AtomData(AtomDataType(flags), data.mid(pos + 12, length - 12)));
|
||||
result.append(AtomData(static_cast<AtomDataType>(flags), data.mid(pos + 12, length - 12)));
|
||||
}
|
||||
else {
|
||||
if(name != "data") {
|
||||
@@ -152,7 +152,7 @@ MP4::Tag::parseData2(const MP4::Atom *atom, int expectedFlags, bool freeForm)
|
||||
return result;
|
||||
}
|
||||
if(expectedFlags == -1 || flags == expectedFlags) {
|
||||
result.append(AtomData(AtomDataType(flags), data.mid(pos + 16, length - 16)));
|
||||
result.append(AtomData(static_cast<AtomDataType>(flags), data.mid(pos + 16, length - 16)));
|
||||
}
|
||||
}
|
||||
pos += length;
|
||||
@@ -177,7 +177,7 @@ MP4::Tag::parseInt(const MP4::Atom *atom)
|
||||
{
|
||||
ByteVectorList data = parseData(atom);
|
||||
if(!data.isEmpty()) {
|
||||
addItem(atom->name, (int)data[0].toShort());
|
||||
addItem(atom->name, static_cast<int>(data[0].toShort()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ MP4::Tag::parseGnre(const MP4::Atom *atom)
|
||||
{
|
||||
ByteVectorList data = parseData(atom);
|
||||
if(!data.isEmpty()) {
|
||||
int idx = (int)data[0].toShort();
|
||||
int idx = static_cast<int>(data[0].toShort());
|
||||
if(idx > 0) {
|
||||
addItem("\251gen", StringList(ID3v1::genre(idx - 1)));
|
||||
}
|
||||
@@ -316,7 +316,7 @@ MP4::Tag::parseCovr(const MP4::Atom *atom)
|
||||
}
|
||||
if(flags == TypeJPEG || flags == TypePNG || flags == TypeBMP ||
|
||||
flags == TypeGIF || flags == TypeImplicit) {
|
||||
value.append(MP4::CoverArt(MP4::CoverArt::Format(flags),
|
||||
value.append(MP4::CoverArt(static_cast<MP4::CoverArt::Format>(flags),
|
||||
data.mid(pos + 16, length - 16)));
|
||||
}
|
||||
else {
|
||||
@@ -541,6 +541,19 @@ MP4::Tag::save()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MP4::Tag::strip()
|
||||
{
|
||||
d->items.clear();
|
||||
|
||||
AtomList path = d->atoms->path("moov", "udta", "meta", "ilst");
|
||||
if(path.size() == 4) {
|
||||
saveExisting(ByteVector(), path);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MP4::Tag::updateParents(const AtomList &path, long delta, int ignore)
|
||||
{
|
||||
@@ -699,20 +712,40 @@ MP4::Tag::saveExisting(ByteVector data, const AtomList &path)
|
||||
}
|
||||
|
||||
long delta = data.size() - length;
|
||||
if(delta > 0 || (delta < 0 && delta > -8)) {
|
||||
data.append(padIlst(data));
|
||||
delta = data.size() - length;
|
||||
}
|
||||
else if(delta < 0) {
|
||||
data.append(padIlst(data, -delta - 8));
|
||||
delta = 0;
|
||||
}
|
||||
if(!data.isEmpty()) {
|
||||
if(delta > 0 || (delta < 0 && delta > -8)) {
|
||||
data.append(padIlst(data));
|
||||
delta = data.size() - length;
|
||||
}
|
||||
else if(delta < 0) {
|
||||
data.append(padIlst(data, -delta - 8));
|
||||
delta = 0;
|
||||
}
|
||||
|
||||
d->file->insert(data, offset, length);
|
||||
d->file->insert(data, offset, length);
|
||||
|
||||
if(delta) {
|
||||
updateParents(path, delta, 1);
|
||||
updateOffsets(delta, offset);
|
||||
if(delta) {
|
||||
updateParents(path, delta, 1);
|
||||
updateOffsets(delta, offset);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Strip meta if data is empty, only the case when called from strip().
|
||||
MP4::Atom *udta = *(--it);
|
||||
AtomList &udtaChildren = udta->children;
|
||||
AtomList::Iterator metaIt = udtaChildren.find(meta);
|
||||
if(metaIt != udtaChildren.end()) {
|
||||
offset = meta->offset;
|
||||
delta = - meta->length;
|
||||
udtaChildren.erase(metaIt);
|
||||
d->file->removeBlock(meta->offset, meta->length);
|
||||
delete meta;
|
||||
|
||||
if(delta) {
|
||||
updateParents(path, delta, 2);
|
||||
updateOffsets(delta, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,89 +904,89 @@ bool MP4::Tag::contains(const String &key) const
|
||||
|
||||
namespace
|
||||
{
|
||||
const char *keyTranslation[][2] = {
|
||||
{ "\251nam", "TITLE" },
|
||||
{ "\251ART", "ARTIST" },
|
||||
{ "\251alb", "ALBUM" },
|
||||
{ "\251cmt", "COMMENT" },
|
||||
{ "\251gen", "GENRE" },
|
||||
{ "\251day", "DATE" },
|
||||
{ "\251wrt", "COMPOSER" },
|
||||
{ "\251grp", "GROUPING" },
|
||||
{ "aART", "ALBUMARTIST" },
|
||||
{ "trkn", "TRACKNUMBER" },
|
||||
{ "disk", "DISCNUMBER" },
|
||||
{ "cpil", "COMPILATION" },
|
||||
{ "tmpo", "BPM" },
|
||||
{ "cprt", "COPYRIGHT" },
|
||||
{ "\251lyr", "LYRICS" },
|
||||
{ "\251too", "ENCODEDBY" },
|
||||
{ "soal", "ALBUMSORT" },
|
||||
{ "soaa", "ALBUMARTISTSORT" },
|
||||
{ "soar", "ARTISTSORT" },
|
||||
{ "sonm", "TITLESORT" },
|
||||
{ "soco", "COMPOSERSORT" },
|
||||
{ "sosn", "SHOWSORT" },
|
||||
{ "shwm", "SHOWWORKMOVEMENT" },
|
||||
{ "pgap", "GAPLESSPLAYBACK" },
|
||||
{ "pcst", "PODCAST" },
|
||||
{ "catg", "PODCASTCATEGORY" },
|
||||
{ "desc", "PODCASTDESC" },
|
||||
{ "egid", "PODCASTID" },
|
||||
{ "purl", "PODCASTURL" },
|
||||
{ "tves", "TVEPISODE" },
|
||||
{ "tven", "TVEPISODEID" },
|
||||
{ "tvnn", "TVNETWORK" },
|
||||
{ "tvsn", "TVSEASON" },
|
||||
{ "tvsh", "TVSHOW" },
|
||||
{ "\251wrk", "WORK" },
|
||||
{ "\251mvn", "MOVEMENTNAME" },
|
||||
{ "\251mvi", "MOVEMENTNUMBER" },
|
||||
{ "\251mvc", "MOVEMENTCOUNT" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Track Id", "MUSICBRAINZ_TRACKID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Release Track Id", "MUSICBRAINZ_RELEASETRACKID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Release Country", "RELEASECOUNTRY" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Status", "RELEASESTATUS" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Type", "RELEASETYPE" },
|
||||
{ "----:com.apple.iTunes:ARTISTS", "ARTISTS" },
|
||||
{ "----:com.apple.iTunes:originaldate", "ORIGINALDATE" },
|
||||
{ "----:com.apple.iTunes:ASIN", "ASIN" },
|
||||
{ "----:com.apple.iTunes:LABEL", "LABEL" },
|
||||
{ "----:com.apple.iTunes:LYRICIST", "LYRICIST" },
|
||||
{ "----:com.apple.iTunes:CONDUCTOR", "CONDUCTOR" },
|
||||
{ "----:com.apple.iTunes:REMIXER", "REMIXER" },
|
||||
{ "----:com.apple.iTunes:ENGINEER", "ENGINEER" },
|
||||
{ "----:com.apple.iTunes:PRODUCER", "PRODUCER" },
|
||||
{ "----:com.apple.iTunes:DJMIXER", "DJMIXER" },
|
||||
{ "----:com.apple.iTunes:MIXER", "MIXER" },
|
||||
{ "----:com.apple.iTunes:SUBTITLE", "SUBTITLE" },
|
||||
{ "----:com.apple.iTunes:DISCSUBTITLE", "DISCSUBTITLE" },
|
||||
{ "----:com.apple.iTunes:MOOD", "MOOD" },
|
||||
{ "----:com.apple.iTunes:ISRC", "ISRC" },
|
||||
{ "----:com.apple.iTunes:CATALOGNUMBER", "CATALOGNUMBER" },
|
||||
{ "----:com.apple.iTunes:BARCODE", "BARCODE" },
|
||||
{ "----:com.apple.iTunes:SCRIPT", "SCRIPT" },
|
||||
{ "----:com.apple.iTunes:LANGUAGE", "LANGUAGE" },
|
||||
{ "----:com.apple.iTunes:LICENSE", "LICENSE" },
|
||||
{ "----:com.apple.iTunes:MEDIA", "MEDIA" },
|
||||
const std::pair<const char *, const char *> keyTranslation[] = {
|
||||
std::make_pair("\251nam", "TITLE"),
|
||||
std::make_pair("\251ART", "ARTIST"),
|
||||
std::make_pair("\251alb", "ALBUM"),
|
||||
std::make_pair("\251cmt", "COMMENT"),
|
||||
std::make_pair("\251gen", "GENRE"),
|
||||
std::make_pair("\251day", "DATE"),
|
||||
std::make_pair("\251wrt", "COMPOSER"),
|
||||
std::make_pair("\251grp", "GROUPING"),
|
||||
std::make_pair("aART", "ALBUMARTIST"),
|
||||
std::make_pair("trkn", "TRACKNUMBER"),
|
||||
std::make_pair("disk", "DISCNUMBER"),
|
||||
std::make_pair("cpil", "COMPILATION"),
|
||||
std::make_pair("tmpo", "BPM"),
|
||||
std::make_pair("cprt", "COPYRIGHT"),
|
||||
std::make_pair("\251lyr", "LYRICS"),
|
||||
std::make_pair("\251too", "ENCODEDBY"),
|
||||
std::make_pair("soal", "ALBUMSORT"),
|
||||
std::make_pair("soaa", "ALBUMARTISTSORT"),
|
||||
std::make_pair("soar", "ARTISTSORT"),
|
||||
std::make_pair("sonm", "TITLESORT"),
|
||||
std::make_pair("soco", "COMPOSERSORT"),
|
||||
std::make_pair("sosn", "SHOWSORT"),
|
||||
std::make_pair("shwm", "SHOWWORKMOVEMENT"),
|
||||
std::make_pair("pgap", "GAPLESSPLAYBACK"),
|
||||
std::make_pair("pcst", "PODCAST"),
|
||||
std::make_pair("catg", "PODCASTCATEGORY"),
|
||||
std::make_pair("desc", "PODCASTDESC"),
|
||||
std::make_pair("egid", "PODCASTID"),
|
||||
std::make_pair("purl", "PODCASTURL"),
|
||||
std::make_pair("tves", "TVEPISODE"),
|
||||
std::make_pair("tven", "TVEPISODEID"),
|
||||
std::make_pair("tvnn", "TVNETWORK"),
|
||||
std::make_pair("tvsn", "TVSEASON"),
|
||||
std::make_pair("tvsh", "TVSHOW"),
|
||||
std::make_pair("\251wrk", "WORK"),
|
||||
std::make_pair("\251mvn", "MOVEMENTNAME"),
|
||||
std::make_pair("\251mvi", "MOVEMENTNUMBER"),
|
||||
std::make_pair("\251mvc", "MOVEMENTCOUNT"),
|
||||
std::make_pair("----:com.apple.iTunes:MusicBrainz Track Id", "MUSICBRAINZ_TRACKID"),
|
||||
std::make_pair("----:com.apple.iTunes:MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID"),
|
||||
std::make_pair("----:com.apple.iTunes:MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID"),
|
||||
std::make_pair("----:com.apple.iTunes:MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID"),
|
||||
std::make_pair("----:com.apple.iTunes:MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASEGROUPID"),
|
||||
std::make_pair("----:com.apple.iTunes:MusicBrainz Release Track Id", "MUSICBRAINZ_RELEASETRACKID"),
|
||||
std::make_pair("----:com.apple.iTunes:MusicBrainz Work Id", "MUSICBRAINZ_WORKID"),
|
||||
std::make_pair("----:com.apple.iTunes:MusicBrainz Album Release Country", "RELEASECOUNTRY"),
|
||||
std::make_pair("----:com.apple.iTunes:MusicBrainz Album Status", "RELEASESTATUS"),
|
||||
std::make_pair("----:com.apple.iTunes:MusicBrainz Album Type", "RELEASETYPE"),
|
||||
std::make_pair("----:com.apple.iTunes:ARTISTS", "ARTISTS"),
|
||||
std::make_pair("----:com.apple.iTunes:originaldate", "ORIGINALDATE"),
|
||||
std::make_pair("----:com.apple.iTunes:ASIN", "ASIN"),
|
||||
std::make_pair("----:com.apple.iTunes:LABEL", "LABEL"),
|
||||
std::make_pair("----:com.apple.iTunes:LYRICIST", "LYRICIST"),
|
||||
std::make_pair("----:com.apple.iTunes:CONDUCTOR", "CONDUCTOR"),
|
||||
std::make_pair("----:com.apple.iTunes:REMIXER", "REMIXER"),
|
||||
std::make_pair("----:com.apple.iTunes:ENGINEER", "ENGINEER"),
|
||||
std::make_pair("----:com.apple.iTunes:PRODUCER", "PRODUCER"),
|
||||
std::make_pair("----:com.apple.iTunes:DJMIXER", "DJMIXER"),
|
||||
std::make_pair("----:com.apple.iTunes:MIXER", "MIXER"),
|
||||
std::make_pair("----:com.apple.iTunes:SUBTITLE", "SUBTITLE"),
|
||||
std::make_pair("----:com.apple.iTunes:DISCSUBTITLE", "DISCSUBTITLE"),
|
||||
std::make_pair("----:com.apple.iTunes:MOOD", "MOOD"),
|
||||
std::make_pair("----:com.apple.iTunes:ISRC", "ISRC"),
|
||||
std::make_pair("----:com.apple.iTunes:CATALOGNUMBER", "CATALOGNUMBER"),
|
||||
std::make_pair("----:com.apple.iTunes:BARCODE", "BARCODE"),
|
||||
std::make_pair("----:com.apple.iTunes:SCRIPT", "SCRIPT"),
|
||||
std::make_pair("----:com.apple.iTunes:LANGUAGE", "LANGUAGE"),
|
||||
std::make_pair("----:com.apple.iTunes:LICENSE", "LICENSE"),
|
||||
std::make_pair("----:com.apple.iTunes:MEDIA", "MEDIA"),
|
||||
};
|
||||
const size_t keyTranslationSize = sizeof(keyTranslation) / sizeof(keyTranslation[0]);
|
||||
|
||||
String translateKey(const String &key)
|
||||
{
|
||||
for(size_t i = 0; i < keyTranslationSize; ++i) {
|
||||
if(key == keyTranslation[i][0])
|
||||
return keyTranslation[i][1];
|
||||
if(key == keyTranslation[i].first)
|
||||
return keyTranslation[i].second;
|
||||
}
|
||||
|
||||
return String();
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
PropertyMap MP4::Tag::properties() const
|
||||
{
|
||||
@@ -998,9 +1031,8 @@ PropertyMap MP4::Tag::setProperties(const PropertyMap &props)
|
||||
{
|
||||
static Map<String, String> reverseKeyMap;
|
||||
if(reverseKeyMap.isEmpty()) {
|
||||
int numKeys = sizeof(keyTranslation) / sizeof(keyTranslation[0]);
|
||||
for(int i = 0; i < numKeys; i++) {
|
||||
reverseKeyMap[keyTranslation[i][1]] = keyTranslation[i][0];
|
||||
for(size_t i = 0; i < keyTranslationSize; i++) {
|
||||
reverseKeyMap[keyTranslation[i].second] = keyTranslation[i].first;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,11 +36,9 @@
|
||||
#include "mp4item.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace MP4 {
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use ItemMap.
|
||||
*/
|
||||
TAGLIB_DEPRECATED typedef TagLib::Map<String, Item> ItemListMap;
|
||||
typedef TagLib::Map<String, Item> ItemMap;
|
||||
@@ -72,7 +70,7 @@ namespace TagLib {
|
||||
virtual bool isEmpty() const;
|
||||
|
||||
/*!
|
||||
* \deprecated Use the item() and setItem() API instead
|
||||
* \deprecated Use the item() and setItem() API instead.
|
||||
*/
|
||||
TAGLIB_DEPRECATED ItemMap &itemListMap();
|
||||
|
||||
@@ -102,6 +100,11 @@ namespace TagLib {
|
||||
*/
|
||||
bool contains(const String &key) const;
|
||||
|
||||
/*!
|
||||
* Saves the associated file with the tag stripped.
|
||||
*/
|
||||
bool strip();
|
||||
|
||||
PropertyMap properties() const;
|
||||
void removeUnsupportedProperties(const StringList& properties);
|
||||
PropertyMap setProperties(const PropertyMap &properties);
|
||||
@@ -156,9 +159,6 @@ namespace TagLib {
|
||||
class TagPrivate;
|
||||
TagPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,7 @@ using namespace TagLib;
|
||||
namespace
|
||||
{
|
||||
enum { MPCAPEIndex = 0, MPCID3v1Index = 1 };
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class MPC::File::FilePrivate
|
||||
{
|
||||
|
||||
@@ -195,7 +195,7 @@ namespace TagLib {
|
||||
void strip(int tags = AllTags);
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use strip().
|
||||
* \see strip
|
||||
*/
|
||||
TAGLIB_DEPRECATED void remove(int tags = AllTags);
|
||||
@@ -232,7 +232,7 @@ namespace TagLib {
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace MPC
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace
|
||||
// This array looks weird, but the same as original MusePack code found at:
|
||||
// https://www.musepack.net/index.php?pg=src
|
||||
const unsigned short sftable [8] = { 44100, 48000, 37800, 32000, 0, 0, 0, 0 };
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void MPC::Properties::readSV8(File *file, long streamLength)
|
||||
{
|
||||
@@ -298,6 +298,9 @@ void MPC::Properties::readSV8(File *file, long streamLength)
|
||||
void MPC::Properties::readSV7(const ByteVector &data, long streamLength)
|
||||
{
|
||||
if(data.startsWith("MP+")) {
|
||||
if(data.size() < 4)
|
||||
return;
|
||||
|
||||
d->version = data[3] & 15;
|
||||
if(d->version < 7)
|
||||
return;
|
||||
@@ -317,22 +320,22 @@ void MPC::Properties::readSV7(const ByteVector &data, long streamLength)
|
||||
|
||||
// convert gain info
|
||||
if(d->trackGain != 0) {
|
||||
int tmp = (int)((64.82 - (short)d->trackGain / 100.) * 256. + .5);
|
||||
int tmp = static_cast<int>((64.82 - static_cast<short>(d->trackGain) / 100.) * 256. + .5);
|
||||
if(tmp >= (1 << 16) || tmp < 0) tmp = 0;
|
||||
d->trackGain = tmp;
|
||||
}
|
||||
|
||||
if(d->albumGain != 0) {
|
||||
int tmp = (int)((64.82 - d->albumGain / 100.) * 256. + .5);
|
||||
int tmp = static_cast<int>((64.82 - d->albumGain / 100.) * 256. + .5);
|
||||
if(tmp >= (1 << 16) || tmp < 0) tmp = 0;
|
||||
d->albumGain = tmp;
|
||||
}
|
||||
|
||||
if (d->trackPeak != 0)
|
||||
d->trackPeak = (int)(log10((double)d->trackPeak) * 20 * 256 + .5);
|
||||
d->trackPeak = static_cast<int>(log10(static_cast<double>(d->trackPeak)) * 20 * 256 + .5);
|
||||
|
||||
if (d->albumPeak != 0)
|
||||
d->albumPeak = (int)(log10((double)d->albumPeak) * 20 * 256 + .5);
|
||||
d->albumPeak = static_cast<int>(log10(static_cast<double>(d->albumPeak)) * 20 * 256 + .5);
|
||||
|
||||
bool trueGapless = (gapless >> 31) & 0x0001;
|
||||
if(trueGapless) {
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
@@ -152,7 +152,7 @@ namespace TagLib {
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace MPC
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@ using namespace TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
const wchar_t *genres[] = {
|
||||
const wchar_t *const genres[] = {
|
||||
L"Blues",
|
||||
L"Classic Rock",
|
||||
L"Country",
|
||||
@@ -224,7 +224,7 @@ namespace
|
||||
L"Psybient"
|
||||
};
|
||||
const int genresSize = sizeof(genres) / sizeof(genres[0]);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
StringList ID3v1::genreList()
|
||||
{
|
||||
@@ -250,8 +250,7 @@ String ID3v1::genre(int i)
|
||||
{
|
||||
if(i >= 0 && i < genresSize)
|
||||
return String(genres[i]); // always make a copy
|
||||
else
|
||||
return String();
|
||||
return String();
|
||||
}
|
||||
|
||||
int ID3v1::genreIndex(const String &name)
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace TagLib {
|
||||
* will be returned.
|
||||
*/
|
||||
int TAGLIB_EXPORT genreIndex(const String &name);
|
||||
}
|
||||
}
|
||||
} // namespace ID3v1
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace
|
||||
{
|
||||
const ID3v1::StringHandler defaultStringHandler;
|
||||
const ID3v1::StringHandler *stringHandler = &defaultStringHandler;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class ID3v1::Tag::TagPrivate
|
||||
{
|
||||
@@ -76,8 +76,7 @@ ByteVector ID3v1::StringHandler::render(const String &s) const
|
||||
{
|
||||
if(s.isLatin1())
|
||||
return s.data(String::Latin1);
|
||||
else
|
||||
return ByteVector();
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -85,13 +84,11 @@ ByteVector ID3v1::StringHandler::render(const String &s) const
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ID3v1::Tag::Tag() :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
ID3v1::Tag::Tag(File *file, long tagOffset) :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
d->file = file;
|
||||
@@ -115,9 +112,9 @@ ByteVector ID3v1::Tag::render() const
|
||||
data.append(stringHandler->render(d->album).resize(30));
|
||||
data.append(stringHandler->render(d->year).resize(4));
|
||||
data.append(stringHandler->render(d->comment).resize(28));
|
||||
data.append(char(0));
|
||||
data.append(char(d->track));
|
||||
data.append(char(d->genre));
|
||||
data.append(static_cast<char>(0));
|
||||
data.append(static_cast<char>(d->track));
|
||||
data.append(static_cast<char>(d->genre));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace TagLib {
|
||||
class TagPrivate;
|
||||
TagPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace ID3v1
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -133,7 +133,7 @@ void AttachedPictureFrame::parseFields(const ByteVector &data)
|
||||
return;
|
||||
}
|
||||
|
||||
d->textEncoding = String::Type(data[0]);
|
||||
d->textEncoding = static_cast<String::Type>(data[0]);
|
||||
|
||||
int pos = 1;
|
||||
|
||||
@@ -144,7 +144,7 @@ void AttachedPictureFrame::parseFields(const ByteVector &data)
|
||||
return;
|
||||
}
|
||||
|
||||
d->type = (TagLib::ID3v2::AttachedPictureFrame::Type)data[pos++];
|
||||
d->type = static_cast<TagLib::ID3v2::AttachedPictureFrame::Type>(data[pos++]);
|
||||
d->description = readStringField(data, d->textEncoding, &pos);
|
||||
|
||||
d->data = data.mid(pos);
|
||||
@@ -156,10 +156,10 @@ ByteVector AttachedPictureFrame::renderFields() const
|
||||
|
||||
String::Type encoding = checkTextEncoding(d->description, d->textEncoding);
|
||||
|
||||
data.append(char(encoding));
|
||||
data.append(static_cast<char>(encoding));
|
||||
data.append(d->mimeType.data(String::Latin1));
|
||||
data.append(textDelimiter(String::Latin1));
|
||||
data.append(char(d->type));
|
||||
data.append(static_cast<char>(d->type));
|
||||
data.append(d->description.data(encoding));
|
||||
data.append(textDelimiter(encoding));
|
||||
data.append(d->data);
|
||||
@@ -189,7 +189,7 @@ void AttachedPictureFrameV22::parseFields(const ByteVector &data)
|
||||
return;
|
||||
}
|
||||
|
||||
d->textEncoding = String::Type(data[0]);
|
||||
d->textEncoding = static_cast<String::Type>(data[0]);
|
||||
|
||||
int pos = 1;
|
||||
|
||||
@@ -205,7 +205,7 @@ void AttachedPictureFrameV22::parseFields(const ByteVector &data)
|
||||
d->mimeType = "image/" + fixedString;
|
||||
}
|
||||
|
||||
d->type = (TagLib::ID3v2::AttachedPictureFrame::Type)data[pos++];
|
||||
d->type = static_cast<TagLib::ID3v2::AttachedPictureFrame::Type>(data[pos++]);
|
||||
d->description = readStringField(data, d->textEncoding, &pos);
|
||||
|
||||
d->data = data.mid(pos);
|
||||
|
||||
@@ -224,7 +224,7 @@ namespace TagLib {
|
||||
AttachedPictureFrameV22(const ByteVector &data, Header *h);
|
||||
friend class FrameFactory;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace ID3v2
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -124,7 +124,7 @@ void ChapterFrame::setElementID(const ByteVector &eID)
|
||||
{
|
||||
d->elementID = eID;
|
||||
|
||||
if(d->elementID.endsWith(char(0)))
|
||||
if(d->elementID.endsWith(static_cast<char>(0)))
|
||||
d->elementID = d->elementID.mid(0, d->elementID.size() - 1);
|
||||
}
|
||||
|
||||
@@ -294,8 +294,10 @@ ByteVector ChapterFrame::renderFields() const
|
||||
data.append(ByteVector::fromUInt(d->startOffset, true));
|
||||
data.append(ByteVector::fromUInt(d->endOffset, true));
|
||||
FrameList l = d->embeddedFrameList;
|
||||
for(FrameList::ConstIterator it = l.begin(); it != l.end(); ++it)
|
||||
for(FrameList::ConstIterator it = l.begin(); it != l.end(); ++it) {
|
||||
(*it)->header()->setVersion(header()->version());
|
||||
data.append((*it)->render());
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ namespace TagLib {
|
||||
class ChapterFramePrivate;
|
||||
ChapterFramePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace ID3v2
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -150,7 +150,7 @@ void CommentsFrame::parseFields(const ByteVector &data)
|
||||
return;
|
||||
}
|
||||
|
||||
d->textEncoding = String::Type(data[0]);
|
||||
d->textEncoding = static_cast<String::Type>(data[0]);
|
||||
d->language = data.mid(1, 3);
|
||||
|
||||
int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
|
||||
@@ -177,7 +177,7 @@ ByteVector CommentsFrame::renderFields() const
|
||||
encoding = checkTextEncoding(d->description, encoding);
|
||||
encoding = checkTextEncoding(d->text, encoding);
|
||||
|
||||
v.append(char(encoding));
|
||||
v.append(static_cast<char>(encoding));
|
||||
v.append(d->language.size() == 3 ? d->language : "XXX");
|
||||
v.append(d->description.data(encoding));
|
||||
v.append(textDelimiter(encoding));
|
||||
|
||||
@@ -174,6 +174,6 @@ namespace TagLib {
|
||||
CommentsFramePrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace ID3v2
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -104,7 +104,7 @@ void EventTimingCodesFrame::parseFields(const ByteVector &data)
|
||||
return;
|
||||
}
|
||||
|
||||
d->timestampFormat = TimestampFormat(data[0]);
|
||||
d->timestampFormat = static_cast<TimestampFormat>(data[0]);
|
||||
|
||||
int pos = 1;
|
||||
d->synchedEvents.clear();
|
||||
@@ -120,12 +120,12 @@ ByteVector EventTimingCodesFrame::renderFields() const
|
||||
{
|
||||
ByteVector v;
|
||||
|
||||
v.append(char(d->timestampFormat));
|
||||
v.append(static_cast<char>(d->timestampFormat));
|
||||
for(SynchedEventList::ConstIterator it = d->synchedEvents.begin();
|
||||
it != d->synchedEvents.end();
|
||||
++it) {
|
||||
const SynchedEvent &entry = *it;
|
||||
v.append(char(entry.type));
|
||||
v.append(static_cast<char>(entry.type));
|
||||
v.append(ByteVector::fromUInt(entry.time));
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +180,6 @@ namespace TagLib {
|
||||
EventTimingCodesFramePrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace ID3v2
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -142,7 +142,7 @@ void GeneralEncapsulatedObjectFrame::parseFields(const ByteVector &data)
|
||||
return;
|
||||
}
|
||||
|
||||
d->textEncoding = String::Type(data[0]);
|
||||
d->textEncoding = static_cast<String::Type>(data[0]);
|
||||
|
||||
int pos = 1;
|
||||
|
||||
@@ -163,7 +163,7 @@ ByteVector GeneralEncapsulatedObjectFrame::renderFields() const
|
||||
|
||||
ByteVector data;
|
||||
|
||||
data.append(char(encoding));
|
||||
data.append(static_cast<char>(encoding));
|
||||
data.append(d->mimeType.data(String::Latin1));
|
||||
data.append(textDelimiter(String::Latin1));
|
||||
data.append(d->fileName.data(encoding));
|
||||
|
||||
@@ -173,7 +173,7 @@ namespace TagLib {
|
||||
class GeneralEncapsulatedObjectFramePrivate;
|
||||
GeneralEncapsulatedObjectFramePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace ID3v2
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -117,8 +117,13 @@ void OwnershipFrame::parseFields(const ByteVector &data)
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
// Need at least 1 byte for the encoding
|
||||
if(data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the text encoding
|
||||
d->textEncoding = String::Type(data[0]);
|
||||
d->textEncoding = static_cast<String::Type>(data[0]);
|
||||
pos += 1;
|
||||
|
||||
// Read the price paid this is a null terminate string
|
||||
@@ -150,7 +155,7 @@ ByteVector OwnershipFrame::renderFields() const
|
||||
|
||||
ByteVector v;
|
||||
|
||||
v.append(char(encoding));
|
||||
v.append(static_cast<char>(encoding));
|
||||
v.append(d->pricePaid.data(String::Latin1));
|
||||
v.append(textDelimiter(String::Latin1));
|
||||
v.append(d->datePurchased.data(String::Latin1));
|
||||
|
||||
@@ -146,6 +146,6 @@ namespace TagLib {
|
||||
OwnershipFramePrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace ID3v2
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -77,6 +77,6 @@ namespace TagLib {
|
||||
PodcastFramePrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace ID3v2
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
@@ -102,14 +102,14 @@ void PopularimeterFrame::setCounter(unsigned int s)
|
||||
|
||||
void PopularimeterFrame::parseFields(const ByteVector &data)
|
||||
{
|
||||
int pos = 0, size = int(data.size());
|
||||
int pos = 0, size = static_cast<int>(data.size());
|
||||
|
||||
d->email = readStringField(data, String::Latin1, &pos);
|
||||
|
||||
d->rating = 0;
|
||||
d->counter = 0;
|
||||
if(pos < size) {
|
||||
d->rating = (unsigned char)(data[pos++]);
|
||||
d->rating = static_cast<unsigned char>(data[pos++]);
|
||||
if(pos < size) {
|
||||
d->counter = data.toUInt(static_cast<unsigned int>(pos));
|
||||
}
|
||||
@@ -122,7 +122,7 @@ ByteVector PopularimeterFrame::renderFields() const
|
||||
|
||||
data.append(d->email.data(String::Latin1));
|
||||
data.append(textDelimiter(String::Latin1));
|
||||
data.append(char(d->rating));
|
||||
data.append(static_cast<char>(d->rating));
|
||||
data.append(ByteVector::fromUInt(d->counter));
|
||||
|
||||
return data;
|
||||
|
||||
@@ -127,6 +127,6 @@ namespace TagLib {
|
||||
PopularimeterFramePrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace ID3v2
|
||||
} // namespace TagLib
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user