mirror of
https://github.com/taglib/taglib.git
synced 2026-06-13 17:59:24 -04:00
Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
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'
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -12,6 +12,7 @@ CMakeFiles/
|
||||
*.suo
|
||||
*.user
|
||||
.*
|
||||
!.github/workflows/
|
||||
*~
|
||||
/CMakeCache.txt
|
||||
/Doxyfile
|
||||
@@ -47,3 +48,8 @@ CMakeFiles/
|
||||
taglib.h.stamp
|
||||
taglib.xcodeproj
|
||||
CMakeScripts
|
||||
/.clang-format
|
||||
/compile_commands.json
|
||||
.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,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_CURRENT 20)
|
||||
set(TAGLIB_SOVERSION_REVISION 0)
|
||||
set(TAGLIB_SOVERSION_AGE 18)
|
||||
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
|
||||
|
||||
39
INSTALL.md
39
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 install 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.
|
||||
@@ -72,6 +80,7 @@ Useful configuration options used with CMake (GUI and/or command line):
|
||||
|
||||
| option | description |
|
||||
| ----------------------- | ----------- |
|
||||
| `WITH_ZLIB=` | Whether to build with ZLib |
|
||||
| `ZLIB_ROOT=` | Where to find ZLib's root directory. Assumes parent of: `\include` and `\lib.`|
|
||||
| `ZLIB_INCLUDE_DIR=` | Where to find ZLib's Include directory.|
|
||||
| `ZLIB_LIBRARY=` | Where to find ZLib's Library.
|
||||
@@ -167,7 +176,7 @@ 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 -DBUILD_SHARED_LIBS=OFF` 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:
|
||||
@@ -183,7 +192,7 @@ Windows MinGW:
|
||||
- `mingw32-make; mingw32-make install DESTDIR=/path/to/install/dir`
|
||||
* Build TagLib with testing enabled:
|
||||
- ```
|
||||
cmake -G "MinGW Makefiles" -DBUILD_TESTS=ON -DBUILD_EXAMPLES=ON -DBUILD_SHARED_LIBS=OFF \
|
||||
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
|
||||
@@ -200,7 +209,7 @@ Windows MSVS:
|
||||
- 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_TESTS=ON -DBUILD_EXAMPLES=ON
|
||||
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
|
||||
|
||||
25
NEWS
25
NEWS
@@ -1,3 +1,28 @@
|
||||
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)
|
||||
==========================
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# TagLib
|
||||
|
||||
[](https://travis-ci.org/taglib/taglib)
|
||||
[](../../actions)
|
||||
|
||||
### TagLib Audio Metadata Library
|
||||
|
||||
@@ -23,4 +23,3 @@ licenses if you are considering using TagLib in your project.
|
||||
[FLAC]: https://xiph.org/flac/
|
||||
[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_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)
|
||||
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,12 @@
|
||||
prefix=${CMAKE_INSTALL_PREFIX}
|
||||
exec_prefix=${CMAKE_INSTALL_PREFIX}
|
||||
libdir=${LIB_INSTALL_DIR}
|
||||
includedir=${INCLUDE_INSTALL_DIR}
|
||||
libdir=${CMAKE_INSTALL_FULL_LIBDIR}
|
||||
includedir=${CMAKE_INSTALL_FULL_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
|
||||
Libs: -L${CMAKE_INSTALL_FULL_LIBDIR} -ltag_c
|
||||
Cflags: -I${CMAKE_INSTALL_FULL_INCLUDEDIR}/taglib
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||
includedir=@CMAKE_INSTALL_FULL_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_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
|
||||
)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -84,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,
|
||||
@@ -109,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;
|
||||
}
|
||||
@@ -189,8 +215,7 @@ namespace
|
||||
if(file) {
|
||||
if(file->isValid())
|
||||
return file;
|
||||
else
|
||||
delete file;
|
||||
delete file;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -267,13 +292,12 @@ namespace
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class FileRef::FileRefPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
FileRefPrivate() :
|
||||
RefCounter(),
|
||||
file(0),
|
||||
stream(0) {}
|
||||
|
||||
@@ -472,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.
|
||||
*/
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -44,7 +44,6 @@ public:
|
||||
};
|
||||
|
||||
Mod::Tag::Tag() :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
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"
|
||||
@@ -85,7 +85,25 @@ MP4::Atom::Atom(File *file)
|
||||
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);
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace TagLib {
|
||||
|
||||
typedef TagLib::List<AtomData> AtomDataList;
|
||||
|
||||
class Atom
|
||||
class TAGLIB_EXPORT Atom
|
||||
{
|
||||
public:
|
||||
Atom(File *file);
|
||||
@@ -88,11 +88,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);
|
||||
|
||||
@@ -34,7 +34,6 @@ class MP4::CoverArt::CoverArtPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
CoverArtPrivate() :
|
||||
RefCounter(),
|
||||
format(MP4::CoverArt::JPEG) {}
|
||||
|
||||
Format format;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -48,6 +48,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 +127,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.
|
||||
|
||||
@@ -34,7 +34,6 @@ class MP4::Item::ItemPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
ItemPrivate() :
|
||||
RefCounter(),
|
||||
valid(true),
|
||||
atomDataType(TypeUndefined) {}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
|
||||
@@ -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,7 +140,7 @@ 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;
|
||||
}
|
||||
@@ -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)));
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace TagLib {
|
||||
namespace MP4 {
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use ItemMap.
|
||||
*/
|
||||
TAGLIB_DEPRECATED typedef TagLib::Map<String, Item> ItemListMap;
|
||||
typedef TagLib::Map<String, Item> ItemMap;
|
||||
@@ -72,7 +72,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 +102,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);
|
||||
|
||||
@@ -195,7 +195,7 @@ namespace TagLib {
|
||||
void strip(int tags = AllTags);
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use strip().
|
||||
* \see strip
|
||||
*/
|
||||
TAGLIB_DEPRECATED void remove(int tags = AllTags);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -117,6 +117,11 @@ 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]);
|
||||
pos += 1;
|
||||
|
||||
@@ -109,7 +109,7 @@ void PopularimeterFrame::parseFields(const ByteVector &data)
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ void RelativeVolumeFrame::parseFields(const ByteVector &data)
|
||||
|
||||
// Each channel is at least 4 bytes.
|
||||
|
||||
while(pos <= (int)data.size() - 4) {
|
||||
while(pos <= static_cast<int>(data.size()) - 4) {
|
||||
|
||||
ChannelType type = ChannelType(data[pos]);
|
||||
pos += 1;
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace {
|
||||
}
|
||||
return l;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public methods
|
||||
@@ -274,7 +274,7 @@ TableOfContentsFrame *TableOfContentsFrame::findTopLevel(const ID3v2::Tag *tag)
|
||||
++it)
|
||||
{
|
||||
TableOfContentsFrame *frame = dynamic_cast<TableOfContentsFrame *>(*it);
|
||||
if(frame && frame->isTopLevel() == true)
|
||||
if(frame && frame->isTopLevel())
|
||||
return frame;
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@ ByteVector TableOfContentsFrame::renderFields() const
|
||||
if(d->isOrdered)
|
||||
flags += 1;
|
||||
data.append(flags);
|
||||
data.append((char)(entryCount()));
|
||||
data.append(static_cast<char>(entryCount()));
|
||||
ByteVectorList::ConstIterator it = d->childElements.begin();
|
||||
while(it != d->childElements.end()) {
|
||||
data.append(*it);
|
||||
@@ -344,8 +344,10 @@ ByteVector TableOfContentsFrame::renderFields() const
|
||||
it++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -125,22 +125,22 @@ void TextIdentificationFrame::setTextEncoding(String::Type encoding)
|
||||
namespace
|
||||
{
|
||||
// array of allowed TIPL prefixes and their corresponding key value
|
||||
const char* involvedPeople[][2] = {
|
||||
{"ARRANGER", "ARRANGER"},
|
||||
{"ENGINEER", "ENGINEER"},
|
||||
{"PRODUCER", "PRODUCER"},
|
||||
{"DJ-MIX", "DJMIXER"},
|
||||
{"MIX", "MIXER"},
|
||||
const std::pair<const char *, const char *> involvedPeople[] = {
|
||||
std::make_pair("ARRANGER", "ARRANGER"),
|
||||
std::make_pair("ENGINEER", "ENGINEER"),
|
||||
std::make_pair("PRODUCER", "PRODUCER"),
|
||||
std::make_pair("DJ-MIX", "DJMIXER"),
|
||||
std::make_pair("MIX", "MIXER"),
|
||||
};
|
||||
const size_t involvedPeopleSize = sizeof(involvedPeople) / sizeof(involvedPeople[0]);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const KeyConversionMap &TextIdentificationFrame::involvedPeopleMap() // static
|
||||
{
|
||||
static KeyConversionMap m;
|
||||
if(m.isEmpty()) {
|
||||
for(size_t i = 0; i < involvedPeopleSize; ++i)
|
||||
m.insert(involvedPeople[i][1], involvedPeople[i][0]);
|
||||
m.insert(involvedPeople[i].second, involvedPeople[i].first);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
@@ -218,12 +218,32 @@ void TextIdentificationFrame::parseFields(const ByteVector &data)
|
||||
// append those split values to the list and make sure that the new string's
|
||||
// type is the same specified for this frame
|
||||
|
||||
unsigned short firstBom = 0;
|
||||
for(ByteVectorList::ConstIterator it = l.begin(); it != l.end(); it++) {
|
||||
if(!(*it).isEmpty()) {
|
||||
if(d->textEncoding == String::Latin1)
|
||||
if(d->textEncoding == String::Latin1) {
|
||||
d->fieldList.append(Tag::latin1StringHandler()->parse(*it));
|
||||
else
|
||||
d->fieldList.append(String(*it, d->textEncoding));
|
||||
}
|
||||
else {
|
||||
String::Type textEncoding = d->textEncoding;
|
||||
if(textEncoding == String::UTF16) {
|
||||
if(it == l.begin()) {
|
||||
firstBom = it->mid(0, 2).toUShort();
|
||||
}
|
||||
else {
|
||||
unsigned short subsequentBom = it->mid(0, 2).toUShort();
|
||||
if(subsequentBom != 0xfeff && subsequentBom != 0xfffe) {
|
||||
if(firstBom == 0xfeff) {
|
||||
textEncoding = String::UTF16BE;
|
||||
}
|
||||
else if(firstBom == 0xfffe) {
|
||||
textEncoding = String::UTF16LE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
d->fieldList.append(String(*it, textEncoding));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,8 +294,8 @@ PropertyMap TextIdentificationFrame::makeTIPLProperties() const
|
||||
for(StringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
|
||||
bool found = false;
|
||||
for(size_t i = 0; i < involvedPeopleSize; ++i)
|
||||
if(*it == involvedPeople[i][0]) {
|
||||
map.insert(involvedPeople[i][1], (++it)->split(","));
|
||||
if(*it == involvedPeople[i].first) {
|
||||
map.insert(involvedPeople[i].second, (++it)->split(","));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// static methods
|
||||
@@ -94,8 +94,7 @@ ByteVector Frame::textDelimiter(String::Type t)
|
||||
{
|
||||
if(t == String::UTF16 || t == String::UTF16BE || t == String::UTF16LE)
|
||||
return ByteVector(2, '\0');
|
||||
else
|
||||
return ByteVector(1, '\0');
|
||||
return ByteVector(1, '\0');
|
||||
}
|
||||
|
||||
const String Frame::instrumentPrefix("PERFORMER:");
|
||||
@@ -117,11 +116,11 @@ Frame *Frame::createTextualFrame(const String &key, const StringList &values) //
|
||||
TextIdentificationFrame *frame = new TextIdentificationFrame(frameID, String::UTF8);
|
||||
frame->setText(values);
|
||||
return frame;
|
||||
} else if((frameID[0] == 'W') && (values.size() == 1)){ // URL frame (not WXXX); support only one value
|
||||
} if((frameID[0] == 'W') && (values.size() == 1)){ // URL frame (not WXXX); support only one value
|
||||
UrlLinkFrame* frame = new UrlLinkFrame(frameID);
|
||||
frame->setUrl(values.front());
|
||||
return frame;
|
||||
} else if(frameID == "PCST") {
|
||||
} if(frameID == "PCST") {
|
||||
return new PodcastFrame();
|
||||
}
|
||||
}
|
||||
@@ -166,16 +165,14 @@ ByteVector Frame::frameID() const
|
||||
{
|
||||
if(d->header)
|
||||
return d->header->frameID();
|
||||
else
|
||||
return ByteVector();
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
unsigned int Frame::size() const
|
||||
{
|
||||
if(d->header)
|
||||
return d->header->frameSize();
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Frame::setData(const ByteVector &data)
|
||||
@@ -309,10 +306,8 @@ String::Type Frame::checkEncoding(const StringList &fields, String::Type encodin
|
||||
debug("Frame::checkEncoding() -- Rendering using UTF8.");
|
||||
return String::UTF8;
|
||||
}
|
||||
else {
|
||||
debug("Frame::checkEncoding() -- Rendering using UTF16.");
|
||||
return String::UTF16;
|
||||
}
|
||||
debug("Frame::checkEncoding() -- Rendering using UTF16.");
|
||||
return String::UTF16;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,120 +321,121 @@ String::Type Frame::checkTextEncoding(const StringList &fields, String::Type enc
|
||||
|
||||
namespace
|
||||
{
|
||||
const char *frameTranslation[][2] = {
|
||||
const std::pair<const char *, const char *> frameTranslation[] = {
|
||||
// Text information frames
|
||||
{ "TALB", "ALBUM"},
|
||||
{ "TBPM", "BPM" },
|
||||
{ "TCOM", "COMPOSER" },
|
||||
{ "TCON", "GENRE" },
|
||||
{ "TCOP", "COPYRIGHT" },
|
||||
{ "TDEN", "ENCODINGTIME" },
|
||||
{ "TDLY", "PLAYLISTDELAY" },
|
||||
{ "TDOR", "ORIGINALDATE" },
|
||||
{ "TDRC", "DATE" },
|
||||
// { "TRDA", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
// { "TDAT", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
// { "TYER", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
// { "TIME", "DATE" }, // id3 v2.3, replaced by TDRC in v2.4
|
||||
{ "TDRL", "RELEASEDATE" },
|
||||
{ "TDTG", "TAGGINGDATE" },
|
||||
{ "TENC", "ENCODEDBY" },
|
||||
{ "TEXT", "LYRICIST" },
|
||||
{ "TFLT", "FILETYPE" },
|
||||
//{ "TIPL", "INVOLVEDPEOPLE" }, handled separately
|
||||
{ "TIT1", "CONTENTGROUP" }, // 'Work' in iTunes
|
||||
{ "TIT2", "TITLE"},
|
||||
{ "TIT3", "SUBTITLE" },
|
||||
{ "TKEY", "INITIALKEY" },
|
||||
{ "TLAN", "LANGUAGE" },
|
||||
{ "TLEN", "LENGTH" },
|
||||
//{ "TMCL", "MUSICIANCREDITS" }, handled separately
|
||||
{ "TMED", "MEDIA" },
|
||||
{ "TMOO", "MOOD" },
|
||||
{ "TOAL", "ORIGINALALBUM" },
|
||||
{ "TOFN", "ORIGINALFILENAME" },
|
||||
{ "TOLY", "ORIGINALLYRICIST" },
|
||||
{ "TOPE", "ORIGINALARTIST" },
|
||||
{ "TOWN", "OWNER" },
|
||||
{ "TPE1", "ARTIST"},
|
||||
{ "TPE2", "ALBUMARTIST" }, // id3's spec says 'PERFORMER', but most programs use 'ALBUMARTIST'
|
||||
{ "TPE3", "CONDUCTOR" },
|
||||
{ "TPE4", "REMIXER" }, // could also be ARRANGER
|
||||
{ "TPOS", "DISCNUMBER" },
|
||||
{ "TPRO", "PRODUCEDNOTICE" },
|
||||
{ "TPUB", "LABEL" },
|
||||
{ "TRCK", "TRACKNUMBER" },
|
||||
{ "TRSN", "RADIOSTATION" },
|
||||
{ "TRSO", "RADIOSTATIONOWNER" },
|
||||
{ "TSOA", "ALBUMSORT" },
|
||||
{ "TSOC", "COMPOSERSORT" },
|
||||
{ "TSOP", "ARTISTSORT" },
|
||||
{ "TSOT", "TITLESORT" },
|
||||
{ "TSO2", "ALBUMARTISTSORT" }, // non-standard, used by iTunes
|
||||
{ "TSRC", "ISRC" },
|
||||
{ "TSSE", "ENCODING" },
|
||||
std::make_pair("TALB", "ALBUM"),
|
||||
std::make_pair("TBPM", "BPM"),
|
||||
std::make_pair("TCOM", "COMPOSER"),
|
||||
std::make_pair("TCON", "GENRE"),
|
||||
std::make_pair("TCOP", "COPYRIGHT"),
|
||||
std::make_pair("TDEN", "ENCODINGTIME"),
|
||||
std::make_pair("TDLY", "PLAYLISTDELAY"),
|
||||
std::make_pair("TDOR", "ORIGINALDATE"),
|
||||
std::make_pair("TDRC", "DATE"),
|
||||
// std::make_pair("TRDA", "DATE"), // id3 v2.3, replaced by TDRC in v2.4
|
||||
// std::make_pair("TDAT", "DATE"), // id3 v2.3, replaced by TDRC in v2.4
|
||||
// std::make_pair("TYER", "DATE"), // id3 v2.3, replaced by TDRC in v2.4
|
||||
// std::make_pair("TIME", "DATE"), // id3 v2.3, replaced by TDRC in v2.4
|
||||
std::make_pair("TDRL", "RELEASEDATE"),
|
||||
std::make_pair("TDTG", "TAGGINGDATE"),
|
||||
std::make_pair("TENC", "ENCODEDBY"),
|
||||
std::make_pair("TEXT", "LYRICIST"),
|
||||
std::make_pair("TFLT", "FILETYPE"),
|
||||
//std::make_pair("TIPL", "INVOLVEDPEOPLE"), handled separately
|
||||
std::make_pair("TIT1", "WORK"), // 'Work' in iTunes
|
||||
std::make_pair("TIT2", "TITLE"),
|
||||
std::make_pair("TIT3", "SUBTITLE"),
|
||||
std::make_pair("TKEY", "INITIALKEY"),
|
||||
std::make_pair("TLAN", "LANGUAGE"),
|
||||
std::make_pair("TLEN", "LENGTH"),
|
||||
//std::make_pair("TMCL", "MUSICIANCREDITS"), handled separately
|
||||
std::make_pair("TMED", "MEDIA"),
|
||||
std::make_pair("TMOO", "MOOD"),
|
||||
std::make_pair("TOAL", "ORIGINALALBUM"),
|
||||
std::make_pair("TOFN", "ORIGINALFILENAME"),
|
||||
std::make_pair("TOLY", "ORIGINALLYRICIST"),
|
||||
std::make_pair("TOPE", "ORIGINALARTIST"),
|
||||
std::make_pair("TOWN", "OWNER"),
|
||||
std::make_pair("TPE1", "ARTIST"),
|
||||
std::make_pair("TPE2", "ALBUMARTIST"), // id3's spec says 'PERFORMER', but most programs use 'ALBUMARTIST'
|
||||
std::make_pair("TPE3", "CONDUCTOR"),
|
||||
std::make_pair("TPE4", "REMIXER"), // could also be ARRANGER
|
||||
std::make_pair("TPOS", "DISCNUMBER"),
|
||||
std::make_pair("TPRO", "PRODUCEDNOTICE"),
|
||||
std::make_pair("TPUB", "LABEL"),
|
||||
std::make_pair("TRCK", "TRACKNUMBER"),
|
||||
std::make_pair("TRSN", "RADIOSTATION"),
|
||||
std::make_pair("TRSO", "RADIOSTATIONOWNER"),
|
||||
std::make_pair("TSOA", "ALBUMSORT"),
|
||||
std::make_pair("TSOC", "COMPOSERSORT"),
|
||||
std::make_pair("TSOP", "ARTISTSORT"),
|
||||
std::make_pair("TSOT", "TITLESORT"),
|
||||
std::make_pair("TSO2", "ALBUMARTISTSORT"), // non-standard, used by iTunes
|
||||
std::make_pair("TSRC", "ISRC"),
|
||||
std::make_pair("TSSE", "ENCODING"),
|
||||
// URL frames
|
||||
{ "WCOP", "COPYRIGHTURL" },
|
||||
{ "WOAF", "FILEWEBPAGE" },
|
||||
{ "WOAR", "ARTISTWEBPAGE" },
|
||||
{ "WOAS", "AUDIOSOURCEWEBPAGE" },
|
||||
{ "WORS", "RADIOSTATIONWEBPAGE" },
|
||||
{ "WPAY", "PAYMENTWEBPAGE" },
|
||||
{ "WPUB", "PUBLISHERWEBPAGE" },
|
||||
//{ "WXXX", "URL"}, handled specially
|
||||
std::make_pair("WCOP", "COPYRIGHTURL"),
|
||||
std::make_pair("WOAF", "FILEWEBPAGE"),
|
||||
std::make_pair("WOAR", "ARTISTWEBPAGE"),
|
||||
std::make_pair("WOAS", "AUDIOSOURCEWEBPAGE"),
|
||||
std::make_pair("WORS", "RADIOSTATIONWEBPAGE"),
|
||||
std::make_pair("WPAY", "PAYMENTWEBPAGE"),
|
||||
std::make_pair("WPUB", "PUBLISHERWEBPAGE"),
|
||||
//std::make_pair("WXXX", "URL"), handled specially
|
||||
// Other frames
|
||||
{ "COMM", "COMMENT" },
|
||||
//{ "USLT", "LYRICS" }, handled specially
|
||||
std::make_pair("COMM", "COMMENT"),
|
||||
//std::make_pair("USLT", "LYRICS"), handled specially
|
||||
// Apple iTunes proprietary frames
|
||||
{ "PCST", "PODCAST" },
|
||||
{ "TCAT", "PODCASTCATEGORY" },
|
||||
{ "TDES", "PODCASTDESC" },
|
||||
{ "TGID", "PODCASTID" },
|
||||
{ "WFED", "PODCASTURL" },
|
||||
{ "MVNM", "MOVEMENTNAME" },
|
||||
{ "MVIN", "MOVEMENTNUMBER" },
|
||||
{ "GRP1", "GROUPING" },
|
||||
std::make_pair("PCST", "PODCAST"),
|
||||
std::make_pair("TCAT", "PODCASTCATEGORY"),
|
||||
std::make_pair("TDES", "PODCASTDESC"),
|
||||
std::make_pair("TGID", "PODCASTID"),
|
||||
std::make_pair("WFED", "PODCASTURL"),
|
||||
std::make_pair("MVNM", "MOVEMENTNAME"),
|
||||
std::make_pair("MVIN", "MOVEMENTNUMBER"),
|
||||
std::make_pair("GRP1", "GROUPING"),
|
||||
std::make_pair("TCMP", "COMPILATION"),
|
||||
};
|
||||
const size_t frameTranslationSize = sizeof(frameTranslation) / sizeof(frameTranslation[0]);
|
||||
|
||||
const char *txxxFrameTranslation[][2] = {
|
||||
{ "MUSICBRAINZ ALBUM ID", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MUSICBRAINZ ARTIST ID", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "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" },
|
||||
{ "ACOUSTID ID", "ACOUSTID_ID" },
|
||||
{ "ACOUSTID FINGERPRINT", "ACOUSTID_FINGERPRINT" },
|
||||
{ "MUSICIP PUID", "MUSICIP_PUID" },
|
||||
const std::pair<const char *, const char *> txxxFrameTranslation[] = {
|
||||
std::make_pair("MUSICBRAINZ ALBUM ID", "MUSICBRAINZ_ALBUMID"),
|
||||
std::make_pair("MUSICBRAINZ ARTIST ID", "MUSICBRAINZ_ARTISTID"),
|
||||
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("ACOUSTID ID", "ACOUSTID_ID"),
|
||||
std::make_pair("ACOUSTID FINGERPRINT", "ACOUSTID_FINGERPRINT"),
|
||||
std::make_pair("MUSICIP PUID", "MUSICIP_PUID"),
|
||||
};
|
||||
const size_t txxxFrameTranslationSize = sizeof(txxxFrameTranslation) / sizeof(txxxFrameTranslation[0]);
|
||||
|
||||
// list of deprecated frames and their successors
|
||||
const char *deprecatedFrames[][2] = {
|
||||
{"TRDA", "TDRC"}, // 2.3 -> 2.4 (http://en.wikipedia.org/wiki/ID3)
|
||||
{"TDAT", "TDRC"}, // 2.3 -> 2.4
|
||||
{"TYER", "TDRC"}, // 2.3 -> 2.4
|
||||
{"TIME", "TDRC"}, // 2.3 -> 2.4
|
||||
const std::pair<const char *, const char *> deprecatedFrames[] = {
|
||||
std::make_pair("TRDA", "TDRC"), // 2.3 -> 2.4 (http://en.wikipedia.org/wiki/ID3)
|
||||
std::make_pair("TDAT", "TDRC"), // 2.3 -> 2.4
|
||||
std::make_pair("TYER", "TDRC"), // 2.3 -> 2.4
|
||||
std::make_pair("TIME", "TDRC"), // 2.3 -> 2.4
|
||||
};
|
||||
const size_t deprecatedFramesSize = sizeof(deprecatedFrames) / sizeof(deprecatedFrames[0]);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
String Frame::frameIDToKey(const ByteVector &id)
|
||||
{
|
||||
ByteVector id24 = id;
|
||||
for(size_t i = 0; i < deprecatedFramesSize; ++i) {
|
||||
if(id24 == deprecatedFrames[i][0]) {
|
||||
id24 = deprecatedFrames[i][1];
|
||||
if(id24 == deprecatedFrames[i].first) {
|
||||
id24 = deprecatedFrames[i].second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(size_t i = 0; i < frameTranslationSize; ++i) {
|
||||
if(id24 == frameTranslation[i][0])
|
||||
return frameTranslation[i][1];
|
||||
if(id24 == frameTranslation[i].first)
|
||||
return frameTranslation[i].second;
|
||||
}
|
||||
return String();
|
||||
}
|
||||
@@ -448,8 +444,8 @@ ByteVector Frame::keyToFrameID(const String &s)
|
||||
{
|
||||
const String key = s.upper();
|
||||
for(size_t i = 0; i < frameTranslationSize; ++i) {
|
||||
if(key == frameTranslation[i][1])
|
||||
return frameTranslation[i][0];
|
||||
if(key == frameTranslation[i].second)
|
||||
return frameTranslation[i].first;
|
||||
}
|
||||
return ByteVector();
|
||||
}
|
||||
@@ -458,8 +454,8 @@ String Frame::txxxToKey(const String &description)
|
||||
{
|
||||
const String d = description.upper();
|
||||
for(size_t i = 0; i < txxxFrameTranslationSize; ++i) {
|
||||
if(d == txxxFrameTranslation[i][0])
|
||||
return txxxFrameTranslation[i][1];
|
||||
if(d == txxxFrameTranslation[i].first)
|
||||
return txxxFrameTranslation[i].second;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
@@ -468,8 +464,8 @@ String Frame::keyToTXXX(const String &s)
|
||||
{
|
||||
const String key = s.upper();
|
||||
for(size_t i = 0; i < txxxFrameTranslationSize; ++i) {
|
||||
if(key == txxxFrameTranslation[i][1])
|
||||
return txxxFrameTranslation[i][0];
|
||||
if(key == txxxFrameTranslation[i].second)
|
||||
return txxxFrameTranslation[i].first;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@@ -486,19 +482,19 @@ PropertyMap Frame::asProperties() const
|
||||
if(id == "TXXX")
|
||||
return dynamic_cast< const UserTextIdentificationFrame* >(this)->asProperties();
|
||||
// Apple proprietary WFED (Podcast URL), MVNM (Movement Name), MVIN (Movement Number), GRP1 (Grouping) are in fact text frames.
|
||||
else if(id[0] == 'T' || id == "WFED" || id == "MVNM" || id == "MVIN" || id == "GRP1")
|
||||
if(id[0] == 'T' || id == "WFED" || id == "MVNM" || id == "MVIN" || id == "GRP1")
|
||||
return dynamic_cast< const TextIdentificationFrame* >(this)->asProperties();
|
||||
else if(id == "WXXX")
|
||||
if(id == "WXXX")
|
||||
return dynamic_cast< const UserUrlLinkFrame* >(this)->asProperties();
|
||||
else if(id[0] == 'W')
|
||||
if(id[0] == 'W')
|
||||
return dynamic_cast< const UrlLinkFrame* >(this)->asProperties();
|
||||
else if(id == "COMM")
|
||||
if(id == "COMM")
|
||||
return dynamic_cast< const CommentsFrame* >(this)->asProperties();
|
||||
else if(id == "USLT")
|
||||
if(id == "USLT")
|
||||
return dynamic_cast< const UnsynchronizedLyricsFrame* >(this)->asProperties();
|
||||
else if(id == "UFID")
|
||||
if(id == "UFID")
|
||||
return dynamic_cast< const UniqueFileIdentifierFrame* >(this)->asProperties();
|
||||
else if(id == "PCST")
|
||||
if(id == "PCST")
|
||||
return dynamic_cast< const PodcastFrame* >(this)->asProperties();
|
||||
PropertyMap m;
|
||||
m.unsupportedData().append(id);
|
||||
|
||||
@@ -55,6 +55,8 @@ namespace TagLib {
|
||||
{
|
||||
friend class Tag;
|
||||
friend class FrameFactory;
|
||||
friend class TableOfContentsFrame;
|
||||
friend class ChapterFrame;
|
||||
|
||||
public:
|
||||
|
||||
@@ -503,7 +505,7 @@ namespace TagLib {
|
||||
ByteVector render() const;
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use fileAlterPreservation().
|
||||
*/
|
||||
TAGLIB_DEPRECATED bool frameAlterPreservation() const;
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace
|
||||
|
||||
frame->setText(newfields);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class FrameFactory::FrameFactoryPrivate
|
||||
{
|
||||
@@ -268,11 +268,9 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, const Header *tagHe
|
||||
if(frameID != "WXXX") {
|
||||
return new UrlLinkFrame(data, header);
|
||||
}
|
||||
else {
|
||||
UserUrlLinkFrame *f = new UserUrlLinkFrame(data, header);
|
||||
d->setTextEncoding(f);
|
||||
return f;
|
||||
}
|
||||
UserUrlLinkFrame *f = new UserUrlLinkFrame(data, header);
|
||||
d->setTextEncoding(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
// Unsynchronized lyric/text transcription (frames 4.8)
|
||||
@@ -342,19 +340,20 @@ void FrameFactory::rebuildAggregateFrames(ID3v2::Tag *tag) const
|
||||
{
|
||||
TextIdentificationFrame *tdrc =
|
||||
dynamic_cast<TextIdentificationFrame *>(tag->frameList("TDRC").front());
|
||||
UnknownFrame *tdat = static_cast<UnknownFrame *>(tag->frameList("TDAT").front());
|
||||
UnknownFrame *tdat = dynamic_cast<UnknownFrame *>(tag->frameList("TDAT").front());
|
||||
|
||||
if(tdrc &&
|
||||
tdrc->fieldList().size() == 1 &&
|
||||
tdrc->fieldList().front().size() == 4 &&
|
||||
tdat &&
|
||||
tdat->data().size() >= 5)
|
||||
{
|
||||
String date(tdat->data().mid(1), String::Type(tdat->data()[0]));
|
||||
if(date.length() == 4) {
|
||||
tdrc->setText(tdrc->toString() + '-' + date.substr(2, 2) + '-' + date.substr(0, 2));
|
||||
if(tag->frameList("TIME").size() == 1) {
|
||||
UnknownFrame *timeframe = static_cast<UnknownFrame *>(tag->frameList("TIME").front());
|
||||
if(timeframe->data().size() >= 5) {
|
||||
UnknownFrame *timeframe = dynamic_cast<UnknownFrame *>(tag->frameList("TIME").front());
|
||||
if(timeframe && timeframe->data().size() >= 5) {
|
||||
String time(timeframe->data().mid(1), String::Type(timeframe->data()[0]));
|
||||
if(time.length() == 4) {
|
||||
tdrc->setText(tdrc->toString() + 'T' + time.substr(0, 2) + ':' + time.substr(2, 2));
|
||||
@@ -394,90 +393,90 @@ FrameFactory::~FrameFactory()
|
||||
namespace
|
||||
{
|
||||
// Frame conversion table ID3v2.2 -> 2.4
|
||||
const char *frameConversion2[][2] = {
|
||||
{ "BUF", "RBUF" },
|
||||
{ "CNT", "PCNT" },
|
||||
{ "COM", "COMM" },
|
||||
{ "CRA", "AENC" },
|
||||
{ "ETC", "ETCO" },
|
||||
{ "GEO", "GEOB" },
|
||||
{ "IPL", "TIPL" },
|
||||
{ "MCI", "MCDI" },
|
||||
{ "MLL", "MLLT" },
|
||||
{ "POP", "POPM" },
|
||||
{ "REV", "RVRB" },
|
||||
{ "SLT", "SYLT" },
|
||||
{ "STC", "SYTC" },
|
||||
{ "TAL", "TALB" },
|
||||
{ "TBP", "TBPM" },
|
||||
{ "TCM", "TCOM" },
|
||||
{ "TCO", "TCON" },
|
||||
{ "TCP", "TCMP" },
|
||||
{ "TCR", "TCOP" },
|
||||
{ "TDY", "TDLY" },
|
||||
{ "TEN", "TENC" },
|
||||
{ "TFT", "TFLT" },
|
||||
{ "TKE", "TKEY" },
|
||||
{ "TLA", "TLAN" },
|
||||
{ "TLE", "TLEN" },
|
||||
{ "TMT", "TMED" },
|
||||
{ "TOA", "TOAL" },
|
||||
{ "TOF", "TOFN" },
|
||||
{ "TOL", "TOLY" },
|
||||
{ "TOR", "TDOR" },
|
||||
{ "TOT", "TOAL" },
|
||||
{ "TP1", "TPE1" },
|
||||
{ "TP2", "TPE2" },
|
||||
{ "TP3", "TPE3" },
|
||||
{ "TP4", "TPE4" },
|
||||
{ "TPA", "TPOS" },
|
||||
{ "TPB", "TPUB" },
|
||||
{ "TRC", "TSRC" },
|
||||
{ "TRD", "TDRC" },
|
||||
{ "TRK", "TRCK" },
|
||||
{ "TS2", "TSO2" },
|
||||
{ "TSA", "TSOA" },
|
||||
{ "TSC", "TSOC" },
|
||||
{ "TSP", "TSOP" },
|
||||
{ "TSS", "TSSE" },
|
||||
{ "TST", "TSOT" },
|
||||
{ "TT1", "TIT1" },
|
||||
{ "TT2", "TIT2" },
|
||||
{ "TT3", "TIT3" },
|
||||
{ "TXT", "TOLY" },
|
||||
{ "TXX", "TXXX" },
|
||||
{ "TYE", "TDRC" },
|
||||
{ "UFI", "UFID" },
|
||||
{ "ULT", "USLT" },
|
||||
{ "WAF", "WOAF" },
|
||||
{ "WAR", "WOAR" },
|
||||
{ "WAS", "WOAS" },
|
||||
{ "WCM", "WCOM" },
|
||||
{ "WCP", "WCOP" },
|
||||
{ "WPB", "WPUB" },
|
||||
{ "WXX", "WXXX" },
|
||||
const std::pair<const char *, const char *> frameConversion2[] = {
|
||||
std::make_pair("BUF", "RBUF"),
|
||||
std::make_pair("CNT", "PCNT"),
|
||||
std::make_pair("COM", "COMM"),
|
||||
std::make_pair("CRA", "AENC"),
|
||||
std::make_pair("ETC", "ETCO"),
|
||||
std::make_pair("GEO", "GEOB"),
|
||||
std::make_pair("IPL", "TIPL"),
|
||||
std::make_pair("MCI", "MCDI"),
|
||||
std::make_pair("MLL", "MLLT"),
|
||||
std::make_pair("POP", "POPM"),
|
||||
std::make_pair("REV", "RVRB"),
|
||||
std::make_pair("SLT", "SYLT"),
|
||||
std::make_pair("STC", "SYTC"),
|
||||
std::make_pair("TAL", "TALB"),
|
||||
std::make_pair("TBP", "TBPM"),
|
||||
std::make_pair("TCM", "TCOM"),
|
||||
std::make_pair("TCO", "TCON"),
|
||||
std::make_pair("TCP", "TCMP"),
|
||||
std::make_pair("TCR", "TCOP"),
|
||||
std::make_pair("TDY", "TDLY"),
|
||||
std::make_pair("TEN", "TENC"),
|
||||
std::make_pair("TFT", "TFLT"),
|
||||
std::make_pair("TKE", "TKEY"),
|
||||
std::make_pair("TLA", "TLAN"),
|
||||
std::make_pair("TLE", "TLEN"),
|
||||
std::make_pair("TMT", "TMED"),
|
||||
std::make_pair("TOA", "TOAL"),
|
||||
std::make_pair("TOF", "TOFN"),
|
||||
std::make_pair("TOL", "TOLY"),
|
||||
std::make_pair("TOR", "TDOR"),
|
||||
std::make_pair("TOT", "TOAL"),
|
||||
std::make_pair("TP1", "TPE1"),
|
||||
std::make_pair("TP2", "TPE2"),
|
||||
std::make_pair("TP3", "TPE3"),
|
||||
std::make_pair("TP4", "TPE4"),
|
||||
std::make_pair("TPA", "TPOS"),
|
||||
std::make_pair("TPB", "TPUB"),
|
||||
std::make_pair("TRC", "TSRC"),
|
||||
std::make_pair("TRD", "TDRC"),
|
||||
std::make_pair("TRK", "TRCK"),
|
||||
std::make_pair("TS2", "TSO2"),
|
||||
std::make_pair("TSA", "TSOA"),
|
||||
std::make_pair("TSC", "TSOC"),
|
||||
std::make_pair("TSP", "TSOP"),
|
||||
std::make_pair("TSS", "TSSE"),
|
||||
std::make_pair("TST", "TSOT"),
|
||||
std::make_pair("TT1", "TIT1"),
|
||||
std::make_pair("TT2", "TIT2"),
|
||||
std::make_pair("TT3", "TIT3"),
|
||||
std::make_pair("TXT", "TOLY"),
|
||||
std::make_pair("TXX", "TXXX"),
|
||||
std::make_pair("TYE", "TDRC"),
|
||||
std::make_pair("UFI", "UFID"),
|
||||
std::make_pair("ULT", "USLT"),
|
||||
std::make_pair("WAF", "WOAF"),
|
||||
std::make_pair("WAR", "WOAR"),
|
||||
std::make_pair("WAS", "WOAS"),
|
||||
std::make_pair("WCM", "WCOM"),
|
||||
std::make_pair("WCP", "WCOP"),
|
||||
std::make_pair("WPB", "WPUB"),
|
||||
std::make_pair("WXX", "WXXX"),
|
||||
|
||||
// Apple iTunes nonstandard frames
|
||||
{ "PCS", "PCST" },
|
||||
{ "TCT", "TCAT" },
|
||||
{ "TDR", "TDRL" },
|
||||
{ "TDS", "TDES" },
|
||||
{ "TID", "TGID" },
|
||||
{ "WFD", "WFED" },
|
||||
{ "MVN", "MVNM" },
|
||||
{ "MVI", "MVIN" },
|
||||
{ "GP1", "GRP1" },
|
||||
std::make_pair("PCS", "PCST"),
|
||||
std::make_pair("TCT", "TCAT"),
|
||||
std::make_pair("TDR", "TDRL"),
|
||||
std::make_pair("TDS", "TDES"),
|
||||
std::make_pair("TID", "TGID"),
|
||||
std::make_pair("WFD", "WFED"),
|
||||
std::make_pair("MVN", "MVNM"),
|
||||
std::make_pair("MVI", "MVIN"),
|
||||
std::make_pair("GP1", "GRP1"),
|
||||
};
|
||||
const size_t frameConversion2Size = sizeof(frameConversion2) / sizeof(frameConversion2[0]);
|
||||
|
||||
// Frame conversion table ID3v2.3 -> 2.4
|
||||
const char *frameConversion3[][2] = {
|
||||
{ "TORY", "TDOR" },
|
||||
{ "TYER", "TDRC" },
|
||||
{ "IPLS", "TIPL" },
|
||||
const std::pair<const char *, const char *> frameConversion3[] = {
|
||||
std::make_pair("TORY", "TDOR"),
|
||||
std::make_pair("TYER", "TDRC"),
|
||||
std::make_pair("IPLS", "TIPL"),
|
||||
};
|
||||
const size_t frameConversion3Size = sizeof(frameConversion3) / sizeof(frameConversion3[0]);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool FrameFactory::updateFrame(Frame::Header *header) const
|
||||
{
|
||||
@@ -504,8 +503,8 @@ bool FrameFactory::updateFrame(Frame::Header *header) const
|
||||
// the frames to their 4 byte ID3v2.4 equivalent.
|
||||
|
||||
for(size_t i = 0; i < frameConversion2Size; ++i) {
|
||||
if(frameID == frameConversion2[i][0]) {
|
||||
header->setFrameID(frameConversion2[i][1]);
|
||||
if(frameID == frameConversion2[i].first) {
|
||||
header->setFrameID(frameConversion2[i].second);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -528,8 +527,8 @@ bool FrameFactory::updateFrame(Frame::Header *header) const
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < frameConversion3Size; ++i) {
|
||||
if(frameID == frameConversion3[i][0]) {
|
||||
header->setFrameID(frameConversion3[i][1]);
|
||||
if(frameID == frameConversion3[i].first) {
|
||||
header->setFrameID(frameConversion3[i].second);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace TagLib {
|
||||
TAGLIB_DEPRECATED Frame *createFrame(const ByteVector &data, unsigned int version = 4) const;
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use createFrame(const ByteVector &, const Header *) const.
|
||||
*/
|
||||
// BIC: remove
|
||||
Frame *createFrame(const ByteVector &data, Header *tagHeader) const;
|
||||
|
||||
@@ -137,8 +137,7 @@ unsigned int Header::completeTagSize() const
|
||||
{
|
||||
if(d->footerPresent)
|
||||
return d->tagSize + size() + Footer::size();
|
||||
else
|
||||
return d->tagSize + size();
|
||||
return d->tagSize + size();
|
||||
}
|
||||
|
||||
void Header::setTagSize(unsigned int s)
|
||||
|
||||
@@ -74,6 +74,10 @@ ByteVector SynchData::fromUInt(unsigned int value)
|
||||
|
||||
ByteVector SynchData::decode(const ByteVector &data)
|
||||
{
|
||||
if (data.size() == 0) {
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
// We have this optimized method instead of using ByteVector::replace(),
|
||||
// since it makes a great difference when decoding huge unsynchronized frames.
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class ID3v2::Tag::TagPrivate
|
||||
{
|
||||
@@ -120,14 +120,12 @@ String Latin1StringHandler::parse(const ByteVector &data) const
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ID3v2::Tag::Tag() :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
d->factory = FrameFactory::instance();
|
||||
}
|
||||
|
||||
ID3v2::Tag::Tag(File *file, long tagOffset, const FrameFactory *factory) :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
d->factory = factory;
|
||||
@@ -187,8 +185,10 @@ String ID3v2::Tag::genre() const
|
||||
// should be separated by " / " instead of " ". For the moment to keep
|
||||
// the behavior the same as released versions it is being left with " ".
|
||||
|
||||
if(d->frameListMap["TCON"].isEmpty() ||
|
||||
!dynamic_cast<TextIdentificationFrame *>(d->frameListMap["TCON"].front()))
|
||||
const FrameList &tconFrames = d->frameListMap["TCON"];
|
||||
TextIdentificationFrame *f;
|
||||
if(tconFrames.isEmpty() ||
|
||||
!(f = dynamic_cast<TextIdentificationFrame *>(tconFrames.front())))
|
||||
{
|
||||
return String();
|
||||
}
|
||||
@@ -199,9 +199,6 @@ String ID3v2::Tag::genre() const
|
||||
// appended to the genre string. Multiple fields will be appended as the
|
||||
// string is built.
|
||||
|
||||
TextIdentificationFrame *f = static_cast<TextIdentificationFrame *>(
|
||||
d->frameListMap["TCON"].front());
|
||||
|
||||
StringList fields = f->fieldList();
|
||||
|
||||
StringList genres;
|
||||
|
||||
@@ -338,7 +338,7 @@ namespace TagLib {
|
||||
ByteVector render() const;
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use render(Version) const.
|
||||
*/
|
||||
TAGLIB_DEPRECATED ByteVector render(int version) const;
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace
|
||||
AudioProperties *audioProperties() const { return 0; }
|
||||
bool save() { return false; }
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool MPEG::File::isSupported(IOStream *stream)
|
||||
{
|
||||
|
||||
@@ -193,19 +193,19 @@ namespace TagLib {
|
||||
bool save(int tags);
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use save(int, StripTags, ID3v2::Version, DuplicateTags).
|
||||
*/
|
||||
// BIC: combine with the above method
|
||||
TAGLIB_DEPRECATED bool save(int tags, bool stripOthers);
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use save(int, StripTags, ID3v2::Version, DuplicateTags).
|
||||
*/
|
||||
// BIC: combine with the above method
|
||||
TAGLIB_DEPRECATED bool save(int tags, bool stripOthers, int id3v2Version);
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use save(int, StripTags, ID3v2::Version, DuplicateTags).
|
||||
*/
|
||||
// BIC: combine with the above method
|
||||
TAGLIB_DEPRECATED bool save(int tags, bool stripOthers, int id3v2Version, bool duplicateTags);
|
||||
@@ -315,7 +315,7 @@ namespace TagLib {
|
||||
* Set the ID3v2::FrameFactory to something other than the default.
|
||||
*
|
||||
* \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);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace TagLib {
|
||||
/*!
|
||||
* Parses an MPEG header based on \a data.
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use Header(File *, long, bool).
|
||||
*/
|
||||
TAGLIB_DEPRECATED Header(const ByteVector &data);
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
|
||||
@@ -41,10 +41,9 @@ namespace
|
||||
{
|
||||
if(page->header()->lastPacketCompleted())
|
||||
return page->firstPacketIndex() + page->packetCount();
|
||||
else
|
||||
return page->firstPacketIndex() + page->packetCount() - 1;
|
||||
return page->firstPacketIndex() + page->packetCount() - 1;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class Ogg::File::FilePrivate
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
|
||||
@@ -61,13 +61,11 @@ public:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Ogg::XiphComment::XiphComment() :
|
||||
TagLib::Tag(),
|
||||
d(new XiphCommentPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
Ogg::XiphComment::XiphComment(const ByteVector &data) :
|
||||
TagLib::Tag(),
|
||||
d(new XiphCommentPrivate())
|
||||
{
|
||||
parse(data);
|
||||
@@ -80,35 +78,34 @@ Ogg::XiphComment::~XiphComment()
|
||||
|
||||
String Ogg::XiphComment::title() const
|
||||
{
|
||||
if(d->fieldListMap["TITLE"].isEmpty())
|
||||
return String();
|
||||
return d->fieldListMap["TITLE"].toString();
|
||||
StringList value = d->fieldListMap.value("TITLE");
|
||||
return value.isEmpty() ? String() : value.toString();
|
||||
}
|
||||
|
||||
String Ogg::XiphComment::artist() const
|
||||
{
|
||||
if(d->fieldListMap["ARTIST"].isEmpty())
|
||||
return String();
|
||||
return d->fieldListMap["ARTIST"].toString();
|
||||
StringList value = d->fieldListMap.value("ARTIST");
|
||||
return value.isEmpty() ? String() : value.toString();
|
||||
}
|
||||
|
||||
String Ogg::XiphComment::album() const
|
||||
{
|
||||
if(d->fieldListMap["ALBUM"].isEmpty())
|
||||
return String();
|
||||
return d->fieldListMap["ALBUM"].toString();
|
||||
StringList value = d->fieldListMap.value("ALBUM");
|
||||
return value.isEmpty() ? String() : value.toString();
|
||||
}
|
||||
|
||||
String Ogg::XiphComment::comment() const
|
||||
{
|
||||
if(!d->fieldListMap["DESCRIPTION"].isEmpty()) {
|
||||
StringList value = d->fieldListMap.value("DESCRIPTION");
|
||||
if(!value.isEmpty()) {
|
||||
d->commentField = "DESCRIPTION";
|
||||
return d->fieldListMap["DESCRIPTION"].toString();
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
if(!d->fieldListMap["COMMENT"].isEmpty()) {
|
||||
value = d->fieldListMap.value("COMMENT");
|
||||
if(!value.isEmpty()) {
|
||||
d->commentField = "COMMENT";
|
||||
return d->fieldListMap["COMMENT"].toString();
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
return String();
|
||||
@@ -116,26 +113,29 @@ String Ogg::XiphComment::comment() const
|
||||
|
||||
String Ogg::XiphComment::genre() const
|
||||
{
|
||||
if(d->fieldListMap["GENRE"].isEmpty())
|
||||
return String();
|
||||
return d->fieldListMap["GENRE"].toString();
|
||||
StringList value = d->fieldListMap.value("GENRE");
|
||||
return value.isEmpty() ? String() : value.toString();
|
||||
}
|
||||
|
||||
unsigned int Ogg::XiphComment::year() const
|
||||
{
|
||||
if(!d->fieldListMap["DATE"].isEmpty())
|
||||
return d->fieldListMap["DATE"].front().toInt();
|
||||
if(!d->fieldListMap["YEAR"].isEmpty())
|
||||
return d->fieldListMap["YEAR"].front().toInt();
|
||||
StringList value = d->fieldListMap.value("DATE");
|
||||
if(!value.isEmpty())
|
||||
return value.front().toInt();
|
||||
value = d->fieldListMap.value("YEAR");
|
||||
if(!value.isEmpty())
|
||||
return value.front().toInt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int Ogg::XiphComment::track() const
|
||||
{
|
||||
if(!d->fieldListMap["TRACKNUMBER"].isEmpty())
|
||||
return d->fieldListMap["TRACKNUMBER"].front().toInt();
|
||||
if(!d->fieldListMap["TRACKNUM"].isEmpty())
|
||||
return d->fieldListMap["TRACKNUM"].front().toInt();
|
||||
StringList value = d->fieldListMap.value("TRACKNUMBER");
|
||||
if(!value.isEmpty())
|
||||
return value.front().toInt();
|
||||
value = d->fieldListMap.value("TRACKNUM");
|
||||
if(!value.isEmpty())
|
||||
return value.front().toInt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ void Ogg::XiphComment::setAlbum(const String &s)
|
||||
void Ogg::XiphComment::setComment(const String &s)
|
||||
{
|
||||
if(d->commentField.isEmpty()) {
|
||||
if(!d->fieldListMap["DESCRIPTION"].isEmpty())
|
||||
if(!d->fieldListMap.value("DESCRIPTION").isEmpty())
|
||||
d->commentField = "DESCRIPTION";
|
||||
else
|
||||
d->commentField = "COMMENT";
|
||||
@@ -324,7 +324,7 @@ void Ogg::XiphComment::removeAllFields()
|
||||
|
||||
bool Ogg::XiphComment::contains(const String &key) const
|
||||
{
|
||||
return !d->fieldListMap[key.upper()].isEmpty();
|
||||
return !d->fieldListMap.value(key.upper()).isEmpty();
|
||||
}
|
||||
|
||||
void Ogg::XiphComment::removePicture(FLAC::Picture *picture, bool del)
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
#include "flacpicture.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Explained at end of tpropertymap.cpp
|
||||
extern template class TAGLIB_EXPORT TagLib::Map<TagLib::String, TagLib::StringList>;
|
||||
#endif
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace Ogg {
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace TagLib {
|
||||
* Create an instance of AIFF::Properties with the data read from the
|
||||
* ByteVector \a data.
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use Properties(File *, ReadStyle).
|
||||
*/
|
||||
TAGLIB_DEPRECATED Properties(const ByteVector &data, ReadStyle style);
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of bitsPerSample().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use bitsPerSample().
|
||||
*/
|
||||
TAGLIB_DEPRECATED int sampleWidth() const;
|
||||
|
||||
|
||||
@@ -71,14 +71,12 @@ ByteVector RIFF::Info::StringHandler::render(const String &s) const
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RIFF::Info::Tag::Tag(const ByteVector &data) :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
parse(data);
|
||||
}
|
||||
|
||||
RIFF::Info::Tag::Tag() :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
}
|
||||
@@ -178,8 +176,7 @@ String RIFF::Info::Tag::fieldText(const ByteVector &id) const
|
||||
{
|
||||
if(d->fieldListMap.contains(id))
|
||||
return String(d->fieldListMap[id]);
|
||||
else
|
||||
return String();
|
||||
return String();
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setFieldText(const ByteVector &id, const String &s)
|
||||
@@ -221,8 +218,7 @@ ByteVector RIFF::Info::Tag::render() const
|
||||
|
||||
if(data.size() == 4)
|
||||
return ByteVector();
|
||||
else
|
||||
return data;
|
||||
return data;
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setStringHandler(const StringHandler *handler)
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace TagLib {
|
||||
virtual bool save();
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \deprecated Use save(TagTypes, StripTags, ID3v2::Version).
|
||||
*/
|
||||
TAGLIB_DEPRECATED bool save(TagTypes tags, bool stripOthers, int id3v2Version = 4);
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace TagLib {
|
||||
* Create an instance of WAV::Properties with the data read from the
|
||||
* ByteVector \a data.
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use Properties(File *, ReadStyle).
|
||||
*/
|
||||
TAGLIB_DEPRECATED Properties(const ByteVector &data, ReadStyle style);
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace TagLib {
|
||||
* Create an instance of WAV::Properties with the data read from the
|
||||
* ByteVector \a data and the length calculated using \a streamLength.
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use Properties(File *, ReadStyle).
|
||||
*/
|
||||
TAGLIB_DEPRECATED Properties(const ByteVector &data, unsigned int streamLength, ReadStyle style);
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of lengthInSeconds().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use lengthInSeconds().
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace TagLib {
|
||||
*
|
||||
* \note This method is just an alias of bitsPerSample().
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use bitsPerSample().
|
||||
*/
|
||||
TAGLIB_DEPRECATED int sampleWidth() const;
|
||||
|
||||
|
||||
@@ -129,12 +129,12 @@ bool S3M::File::save()
|
||||
StringList lines = d->tag.comment().split("\n");
|
||||
// write comment as sample names:
|
||||
for(unsigned short i = 0; i < sampleCount; ++ i) {
|
||||
seek(96L + length + ((long)i << 1));
|
||||
seek(96L + length + (static_cast<long>(i) << 1));
|
||||
|
||||
unsigned short instrumentOffset = 0;
|
||||
if(!readU16L(instrumentOffset))
|
||||
return false;
|
||||
seek(((long)instrumentOffset << 4) + 48);
|
||||
seek((static_cast<long>(instrumentOffset) << 4) + 48);
|
||||
|
||||
if(i < lines.size())
|
||||
writeString(lines[i], 27);
|
||||
@@ -214,10 +214,10 @@ void S3M::File::read(bool)
|
||||
// instead samples (SCRS).
|
||||
StringList comment;
|
||||
for(unsigned short i = 0; i < sampleCount; ++ i) {
|
||||
seek(96L + length + ((long)i << 1));
|
||||
seek(96L + length + (static_cast<long>(i) << 1));
|
||||
|
||||
READ_U16L_AS(sampleHeaderOffset);
|
||||
seek((long)sampleHeaderOffset << 4);
|
||||
seek(static_cast<long>(sampleHeaderOffset) << 4);
|
||||
|
||||
READ_BYTE_AS(sampleType);
|
||||
READ_STRING_AS(dosFileName, 13);
|
||||
|
||||
@@ -120,16 +120,16 @@ PropertyMap TagUnion::properties() const
|
||||
if(dynamic_cast<const ID3v1::Tag *>(d->tags[i]))
|
||||
return dynamic_cast<const ID3v1::Tag *>(d->tags[i])->properties();
|
||||
|
||||
else if(dynamic_cast<const ID3v2::Tag *>(d->tags[i]))
|
||||
if(dynamic_cast<const ID3v2::Tag *>(d->tags[i]))
|
||||
return dynamic_cast<const ID3v2::Tag *>(d->tags[i])->properties();
|
||||
|
||||
else if(dynamic_cast<const APE::Tag *>(d->tags[i]))
|
||||
if(dynamic_cast<const APE::Tag *>(d->tags[i]))
|
||||
return dynamic_cast<const APE::Tag *>(d->tags[i])->properties();
|
||||
|
||||
else if(dynamic_cast<const Ogg::XiphComment *>(d->tags[i]))
|
||||
if(dynamic_cast<const Ogg::XiphComment *>(d->tags[i]))
|
||||
return dynamic_cast<const Ogg::XiphComment *>(d->tags[i])->properties();
|
||||
|
||||
else if(dynamic_cast<const RIFF::Info::Tag *>(d->tags[i]))
|
||||
if(dynamic_cast<const RIFF::Info::Tag *>(d->tags[i]))
|
||||
return dynamic_cast<const RIFF::Info::Tag *>(d->tags[i])->properties();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,11 +38,22 @@ long Utils::findID3v1(File *file)
|
||||
if(!file->isValid())
|
||||
return -1;
|
||||
|
||||
file->seek(-128, File::End);
|
||||
const long p = file->tell();
|
||||
// Differentiate between a match of APEv2 magic and a match of ID3v1 magic.
|
||||
|
||||
if(file->readBlock(3) == ID3v1::Tag::fileIdentifier())
|
||||
return p;
|
||||
if (file->length() >= 131) {
|
||||
file->seek(-131, File::End);
|
||||
const long p = file->tell() + 3;
|
||||
const TagLib::ByteVector data = file->readBlock(8);
|
||||
|
||||
if(data.containsAt(ID3v1::Tag::fileIdentifier(), 3) && (data != APE::Tag::fileIdentifier()))
|
||||
return p;
|
||||
} else {
|
||||
file->seek(-128, File::End);
|
||||
const long p = file->tell();
|
||||
|
||||
if(file->readBlock(3) == ID3v1::Tag::fileIdentifier())
|
||||
return p;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "taglib_config.h"
|
||||
|
||||
#define TAGLIB_MAJOR_VERSION 1
|
||||
#define TAGLIB_MINOR_VERSION 12
|
||||
#define TAGLIB_MINOR_VERSION 13
|
||||
#define TAGLIB_PATCH_VERSION 0
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1)) || defined(__clang__)
|
||||
|
||||
@@ -145,8 +145,7 @@ T toNumber(const ByteVector &v, size_t offset, bool mostSignificantByteFirst)
|
||||
|
||||
if(swap)
|
||||
return Utils::byteSwap(tmp);
|
||||
else
|
||||
return tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -242,14 +241,12 @@ long double toFloat80(const ByteVector &v, size_t offset)
|
||||
debug("toFloat80() - can't handle the infinity or NaN. Returning 0.");
|
||||
return 0.0;
|
||||
}
|
||||
else
|
||||
val = ::ldexp(static_cast<long double>(fraction), exponent - 16383 - 63);
|
||||
val = ::ldexp(static_cast<long double>(fraction), exponent - 16383 - 63);
|
||||
}
|
||||
|
||||
if(negative)
|
||||
return -val;
|
||||
else
|
||||
return val;
|
||||
return val;
|
||||
}
|
||||
|
||||
class ByteVector::ByteVectorPrivate
|
||||
@@ -300,8 +297,7 @@ ByteVector ByteVector::fromCString(const char *s, unsigned int length)
|
||||
{
|
||||
if(length == 0xffffffff)
|
||||
return ByteVector(s, static_cast<unsigned int>(::strlen(s)));
|
||||
else
|
||||
return ByteVector(s, length);
|
||||
return ByteVector(s, length);
|
||||
}
|
||||
|
||||
ByteVector ByteVector::fromUInt(unsigned int value, bool mostSignificantByteFirst)
|
||||
@@ -443,8 +439,7 @@ int ByteVector::rfind(const ByteVector &pattern, unsigned int offset, int byteAl
|
||||
|
||||
if(pos == -1)
|
||||
return -1;
|
||||
else
|
||||
return size() - pos - pattern.size();
|
||||
return size() - pos - pattern.size();
|
||||
}
|
||||
|
||||
bool ByteVector::containsAt(const ByteVector &pattern, unsigned int offset, unsigned int patternOffset, unsigned int patternLength) const
|
||||
@@ -843,8 +838,7 @@ bool ByteVector::operator<(const ByteVector &v) const
|
||||
const int result = ::memcmp(data(), v.data(), std::min(size(), v.size()));
|
||||
if(result != 0)
|
||||
return result < 0;
|
||||
else
|
||||
return size() < v.size();
|
||||
return size() < v.size();
|
||||
}
|
||||
|
||||
bool ByteVector::operator>(const ByteVector &v) const
|
||||
@@ -925,8 +919,8 @@ ByteVector ByteVector::fromBase64(const ByteVector & input)
|
||||
|
||||
ByteVector output(len);
|
||||
|
||||
const unsigned char * src = (const unsigned char*) input.data();
|
||||
unsigned char * dst = (unsigned char*) output.data();
|
||||
const unsigned char * src = reinterpret_cast<const unsigned char*>(input.data());
|
||||
unsigned char * dst = reinterpret_cast<unsigned char*>(output.data());
|
||||
|
||||
while(4 <= len) {
|
||||
|
||||
@@ -976,7 +970,7 @@ ByteVector ByteVector::fromBase64(const ByteVector & input)
|
||||
|
||||
// Only return output if we processed all bytes
|
||||
if(len == 0) {
|
||||
output.resize(static_cast<unsigned int>(dst - (unsigned char*) output.data()));
|
||||
output.resize(static_cast<unsigned int>(dst - reinterpret_cast<unsigned char*>(output.data())));
|
||||
return output;
|
||||
}
|
||||
return ByteVector();
|
||||
@@ -1030,7 +1024,7 @@ void ByteVector::detach()
|
||||
ByteVector().swap(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace TagLib
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// related functions
|
||||
|
||||
@@ -278,7 +278,7 @@ namespace TagLib {
|
||||
*
|
||||
* \see isEmpty()
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use isEmpty(), do not differentiate between null and empty.
|
||||
*/
|
||||
// BIC: remove
|
||||
TAGLIB_DEPRECATED bool isNull() const;
|
||||
@@ -592,7 +592,7 @@ namespace TagLib {
|
||||
* \warning Do not modify this variable. It will mess up the internal state
|
||||
* of TagLib.
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use ByteVector().
|
||||
*/
|
||||
// BIC: remove
|
||||
TAGLIB_DEPRECATED static ByteVector null;
|
||||
|
||||
@@ -70,7 +70,7 @@ ByteVectorList ByteVectorList::split(const ByteVector &v, const ByteVector &patt
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ByteVectorList::ByteVectorList() : List<ByteVector>()
|
||||
ByteVectorList::ByteVectorList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -59,6 +59,6 @@ namespace TagLib
|
||||
debugListener->printMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace
|
||||
};
|
||||
|
||||
DefaultListener defaultListener;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
@@ -82,4 +82,4 @@ namespace TagLib
|
||||
else
|
||||
debugListener = &defaultListener;
|
||||
}
|
||||
}
|
||||
} // namespace TagLib
|
||||
|
||||
@@ -185,42 +185,41 @@ PropertyMap File::setProperties(const PropertyMap &properties)
|
||||
{
|
||||
if(dynamic_cast<APE::File* >(this))
|
||||
return dynamic_cast<APE::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<FLAC::File* >(this))
|
||||
if(dynamic_cast<FLAC::File* >(this))
|
||||
return dynamic_cast<FLAC::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<IT::File* >(this))
|
||||
if(dynamic_cast<IT::File* >(this))
|
||||
return dynamic_cast<IT::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<Mod::File* >(this))
|
||||
if(dynamic_cast<Mod::File* >(this))
|
||||
return dynamic_cast<Mod::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<MPC::File* >(this))
|
||||
if(dynamic_cast<MPC::File* >(this))
|
||||
return dynamic_cast<MPC::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<MPEG::File* >(this))
|
||||
if(dynamic_cast<MPEG::File* >(this))
|
||||
return dynamic_cast<MPEG::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<Ogg::FLAC::File* >(this))
|
||||
if(dynamic_cast<Ogg::FLAC::File* >(this))
|
||||
return dynamic_cast<Ogg::FLAC::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<Ogg::Speex::File* >(this))
|
||||
if(dynamic_cast<Ogg::Speex::File* >(this))
|
||||
return dynamic_cast<Ogg::Speex::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<Ogg::Opus::File* >(this))
|
||||
if(dynamic_cast<Ogg::Opus::File* >(this))
|
||||
return dynamic_cast<Ogg::Opus::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<Ogg::Vorbis::File* >(this))
|
||||
if(dynamic_cast<Ogg::Vorbis::File* >(this))
|
||||
return dynamic_cast<Ogg::Vorbis::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<RIFF::AIFF::File* >(this))
|
||||
if(dynamic_cast<RIFF::AIFF::File* >(this))
|
||||
return dynamic_cast<RIFF::AIFF::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<RIFF::WAV::File* >(this))
|
||||
if(dynamic_cast<RIFF::WAV::File* >(this))
|
||||
return dynamic_cast<RIFF::WAV::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<S3M::File* >(this))
|
||||
if(dynamic_cast<S3M::File* >(this))
|
||||
return dynamic_cast<S3M::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<TrueAudio::File* >(this))
|
||||
if(dynamic_cast<TrueAudio::File* >(this))
|
||||
return dynamic_cast<TrueAudio::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<WavPack::File* >(this))
|
||||
if(dynamic_cast<WavPack::File* >(this))
|
||||
return dynamic_cast<WavPack::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<XM::File* >(this))
|
||||
if(dynamic_cast<XM::File* >(this))
|
||||
return dynamic_cast<XM::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<MP4::File* >(this))
|
||||
if(dynamic_cast<MP4::File* >(this))
|
||||
return dynamic_cast<MP4::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<ASF::File* >(this))
|
||||
if(dynamic_cast<ASF::File* >(this))
|
||||
return dynamic_cast<ASF::File* >(this)->setProperties(properties);
|
||||
else
|
||||
return tag()->setProperties(properties);
|
||||
return tag()->setProperties(properties);
|
||||
}
|
||||
|
||||
ByteVector File::readBlock(unsigned long length)
|
||||
|
||||
@@ -261,14 +261,14 @@ namespace TagLib {
|
||||
* Returns true if \a file can be opened for reading. If the file does not
|
||||
* exist, this will return false.
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use system functions, e.g. access() (_access_s() on Windows).
|
||||
*/
|
||||
TAGLIB_DEPRECATED static bool isReadable(const char *file);
|
||||
|
||||
/*!
|
||||
* Returns true if \a file can be opened for writing.
|
||||
*
|
||||
* \deprecated
|
||||
* \deprecated Use system functions, e.g. access() (_access_s() on Windows).
|
||||
*/
|
||||
TAGLIB_DEPRECATED static bool isWritable(const char *name);
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class FileStream::FileStreamPrivate
|
||||
{
|
||||
@@ -206,9 +206,12 @@ ByteVector FileStream::readBlock(unsigned long length)
|
||||
if(length == 0)
|
||||
return ByteVector();
|
||||
|
||||
const unsigned long streamLength = static_cast<unsigned long>(FileStream::length());
|
||||
if(length > bufferSize() && length > streamLength)
|
||||
length = streamLength;
|
||||
if(length > bufferSize()) {
|
||||
const unsigned long streamLength = static_cast<unsigned long>(FileStream::length());
|
||||
if(length > streamLength) {
|
||||
length = streamLength;
|
||||
}
|
||||
}
|
||||
|
||||
ByteVector buffer(static_cast<unsigned int>(length));
|
||||
|
||||
@@ -250,7 +253,7 @@ void FileStream::insert(const ByteVector &data, unsigned long start, unsigned lo
|
||||
writeBlock(data);
|
||||
return;
|
||||
}
|
||||
else if(data.size() < replace) {
|
||||
if(data.size() < replace) {
|
||||
seek(start);
|
||||
writeBlock(data);
|
||||
removeBlock(start + data.size(), replace - data.size());
|
||||
|
||||
@@ -153,6 +153,14 @@ namespace TagLib {
|
||||
*/
|
||||
Map<Key, T> &erase(const Key &key);
|
||||
|
||||
/*!
|
||||
* Returns the value associated with \a key.
|
||||
*
|
||||
* If the map does not contain \a key, it returns defaultValue.
|
||||
* If no defaultValue is specified, it returns a default-constructed value.
|
||||
*/
|
||||
const T value(const Key &key, const T &defaultValue = T()) const;
|
||||
|
||||
/*!
|
||||
* Returns a reference to the value associated with \a key.
|
||||
*
|
||||
|
||||
@@ -155,6 +155,13 @@ unsigned int Map<Key, T>::size() const
|
||||
return static_cast<unsigned int>(d->map.size());
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
const T Map<Key, T>::value(const Key &key, const T &defaultValue) const
|
||||
{
|
||||
ConstIterator it = d->map.find(key);
|
||||
return it != d->map.end() ? it->second : defaultValue;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
const T &Map<Key, T>::operator[](const Key &key) const
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user