diff -Nru taglib-1.7.2/.gitignore taglib-1.8/.gitignore --- taglib-1.7.2/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/.gitignore 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,44 @@ +cmake_install.cmake +cmake_uninstall.cmake +Makefile +CTestTestfile.cmake +CMakeFiles/ +*.so +*.so.* +*.dylib +*.vcproj +*.ncb +*.sln +*.suo +*.user +.* +*~ +/CMakeCache.txt +/Doxyfile +/config.h +/taglib.pc +/tests/test_runner +/tests/Testing +/taglib_config.h +/taglib-config +/bindings/c/taglib_c.pc +/bindings/c/Debug +/bindings/c/MinSizeRel +/bindings/c/Release +/bindings/c/tag_c.dir/Debug +/bindings/c/tag_c.dir/MinSizeRel +/bindings/c/tag_c.dir/Release +/examples/framelist +/examples/strip-id3v1 +/examples/tagreader +/examples/tagreader_c +/examples/tagwriter +/doc/html +/taglib/Debug +/taglib/MinSizeRel +/taglib/Release +/taglib/tag.dir/Debug +/taglib/tag.dir/MinSizeRel +/taglib/tag.dir/Release +/ALL_BUILD.dir +/ZERO_CHECK.dir diff -Nru taglib-1.7.2/AUTHORS taglib-1.8/AUTHORS --- taglib-1.7.2/AUTHORS 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/AUTHORS 2012-09-06 18:03:15.000000000 +0000 @@ -1,11 +1,15 @@ Scott Wheeler Author, maintainer +Lukas Lalinsky + Implementation of multiple new file formats, many bug fixes, maintainer Ismael Orenstein Xing header implementation Allan Sandfeld Jensen FLAC metadata implementation Teemu Tervo Numerous bug reports and fixes +Mathias Panzenböck + Mod, S3M, IT and XM metadata implementations Please send all patches and questions to taglib-devel@kde.org rather than to individual developers! diff -Nru taglib-1.7.2/CMakeLists.txt taglib-1.8/CMakeLists.txt --- taglib-1.7.2/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/CMakeLists.txt 2012-09-06 18:03:15.000000000 +0000 @@ -2,81 +2,107 @@ cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR) -OPTION(ENABLE_STATIC "Make static version of libtag" OFF) +option(ENABLE_STATIC "Make static version of libtag" OFF) +if(ENABLE_STATIC) + add_definitions(-DTAGLIB_STATIC) + set(BUILD_SHARED_LIBS OFF) +else() + set(BUILD_SHARED_LIBS ON) +endif() +OPTION(ENABLE_STATIC_RUNTIME "Visual Studio, link with runtime statically" OFF) + +option(VISIBILITY_HIDDEN "Build with -fvisibility=hidden" OFF) +if(VISIBILITY_HIDDEN) + add_definitions (-fvisibility=hidden) +endif() -OPTION(BUILD_TESTS "Build the test suite" OFF) -OPTION(BUILD_EXAMPLES "Build the examples" OFF) +option(BUILD_TESTS "Build the test suite" OFF) +option(BUILD_EXAMPLES "Build the examples" OFF) -OPTION(NO_ITUNES_HACKS "Disable workarounds for iTunes bugs" OFF) -OPTION(WITH_ASF "Enable ASF tag reading/writing code" OFF) -OPTION(WITH_MP4 "Enable MP4 tag reading/writing code" OFF) +option(NO_ITUNES_HACKS "Disable workarounds for iTunes bugs" OFF) add_definitions(-DHAVE_CONFIG_H) +set(TESTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests/") -#add some KDE specific stuff -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" FORCE) -# ## the following are directories where stuff will be installed to -set(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "The subdirectory to the binaries prefix (default prefix/bin)" FORCE) -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})" FORCE) -set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The subdirectory to the header prefix" FORCE) - -if (CMAKE_COMPILER_IS_GNUCXX) - if (CMAKE_SYSTEM_NAME MATCHES Linux) - set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-long-long -ansi -Wundef -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -Wmissing-format-attribute -fno-common") - set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fno-check-new -fno-common") - endif (CMAKE_SYSTEM_NAME MATCHES Linux) -endif (CMAKE_COMPILER_IS_GNUCXX) -if(MSVC) - if (MSVC_VERSION GREATER 1399) - # If using Visual C++ 2005 (MSVC80) and greater (MSVC_VERSION=1400) - add_definitions(/D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /Zc:wchar_t-) - endif (MSVC_VERSION GREATER 1399) -endif(MSVC) -if (WIN32) - set(CMAKE_DEBUG_POSTFIX "d") -endif (WIN32) - -SET(TAGLIB_LIB_MAJOR_VERSION "1") -SET(TAGLIB_LIB_MINOR_VERSION "7") -SET(TAGLIB_LIB_PATCH_VERSION "2") - -SET(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}") - +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" FORCE) +set(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "The subdirectory to the binaries prefix (default prefix/bin)" FORCE) +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})" FORCE) +set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The subdirectory to the header prefix" FORCE) + +if(APPLE) + option(BUILD_FRAMEWORK "Build an OS X framework" OFF) + set(FRAMEWORK_INSTALL_DIR "/Library/Frameworks" CACHE STRING "Directory to install frameworks to.") +endif() + +if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") + 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) +endif() + +set(TAGLIB_LIB_MAJOR_VERSION "1") +set(TAGLIB_LIB_MINOR_VERSION "8") +set(TAGLIB_LIB_PATCH_VERSION "0") + +set(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}") + +# 1. If the library source code has changed at all since the last update, then increment revision. +# 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 13) +set(TAGLIB_SOVERSION_REVISION 0) +set(TAGLIB_SOVERSION_AGE 12) + +math(EXPR TAGLIB_SOVERSION_MAJOR "${TAGLIB_SOVERSION_CURRENT} - ${TAGLIB_SOVERSION_AGE}") +math(EXPR TAGLIB_SOVERSION_MINOR "${TAGLIB_SOVERSION_AGE}") +math(EXPR TAGLIB_SOVERSION_PATCH "${TAGLIB_SOVERSION_REVISION}") include(ConfigureChecks.cmake) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib-config ) +install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/taglib-config DESTINATION ${BIN_INSTALL_DIR}) -if(NOT WIN32) +if(NOT WIN32 AND NOT BUILD_FRAMEWORK) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib.pc ) -endif(NOT WIN32) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) +endif() + include_directories(${CMAKE_CURRENT_BINARY_DIR}) -configure_file(config-taglib.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h ) +configure_file(config-taglib.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) if(WITH_ASF) set(TAGLIB_WITH_ASF TRUE) -endif(WITH_ASF) +endif() if(WITH_MP4) set(TAGLIB_WITH_MP4 TRUE) -endif(WITH_MP4) -configure_file(taglib/taglib_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib_config.h ) -install( FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib_config.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) +endif() -ADD_SUBDIRECTORY( taglib ) +configure_file(taglib/taglib_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib_config.h) -ADD_SUBDIRECTORY(tests) -ADD_SUBDIRECTORY(examples) +add_subdirectory(taglib) +add_subdirectory(bindings) +if(BUILD_TESTS) + enable_testing() + add_subdirectory(tests) +endif(BUILD_TESTS) +add_subdirectory(examples) -ADD_SUBDIRECTORY(bindings) -if(NOT WIN32) - install( FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig ) -endif(NOT WIN32) - -INSTALL( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/taglib-config DESTINATION ${BIN_INSTALL_DIR}) - -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.cmake ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) +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) +add_custom_target(docs doxygen) + +# uninstall target +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) +add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") diff -Nru taglib-1.7.2/ConfigureChecks.cmake taglib-1.8/ConfigureChecks.cmake --- taglib-1.7.2/ConfigureChecks.cmake 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/ConfigureChecks.cmake 2012-09-06 18:03:15.000000000 +0000 @@ -1,8 +1,3 @@ -# NOTE: only add something here if it is really needed by all of kdelibs. -# Otherwise please prefer adding to the relevant config-foo.h.cmake file, -# and the CMakeLists.txt that generates it (or a separate ConfigureChecks.make file if you prefer) -# to minimize recompilations and increase modularity. - include(CheckIncludeFile) include(CheckIncludeFiles) include(CheckSymbolExists) @@ -11,18 +6,18 @@ include(CheckTypeSize) include(CheckCXXSourceCompiles) -#check for libz using the cmake supplied FindZLIB.cmake -FIND_PACKAGE(ZLIB) +# check for libz using the cmake supplied FindZLIB.cmake +find_package(ZLIB) +if(ZLIB_FOUND) + set(HAVE_ZLIB 1) +else() + set(HAVE_ZLIB 0) +endif() -IF(ZLIB_FOUND) - SET(HAVE_ZLIB 1) -ELSE(ZLIB_FOUND) - SET(HAVE_ZLIB 0) -ENDIF(ZLIB_FOUND) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) +find_package(CppUnit) +if(NOT CppUnit_FOUND AND BUILD_TESTS) + message(STATUS "CppUnit not found, disabling tests.") + set(BUILD_TESTS OFF) +endif() -SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) -FIND_PACKAGE(CppUnit) -IF (NOT CppUnit_FOUND AND BUILD_TESTS) - MESSAGE(STATUS "CppUnit not found, disabling tests.") - SET(BUILD_TESTS OFF) -ENDIF(NOT CppUnit_FOUND AND BUILD_TESTS) diff -Nru taglib-1.7.2/INSTALL taglib-1.8/INSTALL --- taglib-1.7.2/INSTALL 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/INSTALL 2012-09-06 18:03:15.000000000 +0000 @@ -9,17 +9,62 @@ make sudo make install -Some file formats in TagLib are not enabled by default, you can compile -support for MP4 and WMA using the following options: +In order to build the included examples, use the BUILD_EXAMPLES option: - cmake -DWITH_MP4=ON -DWITH_ASF=ON [...] + cmake -DBUILD_EXAMPLES=ON [...] + +See http://www.cmake.org/cmake/help/runningcmake.html for generic help on +running CMake. + +Mac OS X +-------- + +On Mac OS X, you might want to build a framework that can be easily integrated +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: + + cmake -DCMAKE_BUILD_TYPE=Release \ + -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" + +For a 10.6 Snow Leopard static library with both 32-bit and 64-bit code, use: + + cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=10.6 \ + -DCMAKE_OSX_ARCHITECTURES="i386;x86_64" \ + -DENABLE_STATIC=ON \ + -DCMAKE_INSTALL_PREFIX="" + +After 'make', and 'make install', add libtag.a to your XCode project, and add +the include folder to the project's User Header Search Paths. + +Windows +------- + +For building a static library on Windows with Visual Studio 2010, cd to +the TagLib folder then: + + cmake -DENABLE_STATIC=ON -DENABLE_STATIC_RUNTIME=ON -G "Visual Studio 10" ... + +Including ENABLE_STATIC_RUNTIME=ON indicates you want TagLib built using the +static runtime library, rather than the DLL form of the runtime. +CMake will create a Visual Studio solution, taglib.sln that you can open and +build as normal. + +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. The test suite has a custom target -in the build system, so you can run the tests using make: +system, you need to have cppunit installed. To build the tests, include +the option -DBUILD_TESTS=on when running cmake. - make check +The test suite has a custom target in the build system, so you can run +the tests using make: -See http://www.cmake.org/cmake/help/runningcmake.html for generic help on -running CMake. + make check diff -Nru taglib-1.7.2/NEWS taglib-1.8/NEWS --- taglib-1.7.2/NEWS 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/NEWS 2012-09-06 18:03:15.000000000 +0000 @@ -1,3 +1,36 @@ +TagLib 1.8 (Sep 6, 2012) +============================== + +1.8: + + * Added support for OWNE ID3 frames. + * Changed key validation in the new PropertyMap API. + * ID3v1::Tag::setStringHandler will no londer delete the previous handler, + the caller is responsible for this. + * File objects will also no longer delete the passed IOStream objects. It + should be done in the caller code after the File object is no longer + used. + * Added ID3v2::Tag::setLatin1StringHandler for custom handling of + latin1-encoded text in ID3v2 frames. + * Fixed validation of ID3v2 frame IDs (IDs with '0' were ignored). + +1.8 BETA: + + * New API for accessing tags by name. + * New abstract I/O stream layer to allow custom I/O handlers. + * Support for writing ID3v2.3 tags. + * Support for various module file formats (MOD, S3M, IT, XM). + * Support for MP4 and ASF is now enabled by default. + * Started using atomic int operations for reference counting. + * Added methods for checking if WMA and MP4 files are DRM-protected. + * Added taglib_free to the C bindings. + * New method to allow removing pictures from FLAC files. + * Support for reading audio properties from ALAC and Musepack SV8 files. + * Added replay-gain information to Musepack audio properties. + * Support for APEv2 binary tags. + * Many AudioProperties subclasses now provide information about the total number of samples. + * Various small bug fixes. + TagLib 1.7.2 (Apr 20, 2012) =========================== diff -Nru taglib-1.7.2/bindings/CMakeLists.txt taglib-1.8/bindings/CMakeLists.txt --- taglib-1.7.2/bindings/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/bindings/CMakeLists.txt 2012-09-06 18:03:15.000000000 +0000 @@ -1 +1 @@ -ADD_SUBDIRECTORY( c ) +add_subdirectory(c) diff -Nru taglib-1.7.2/bindings/README taglib-1.8/bindings/README --- taglib-1.7.2/bindings/README 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/bindings/README 2012-09-06 18:03:15.000000000 +0000 @@ -2,5 +2,5 @@ been made aware of. I have not personally reviewed these bindings, but I'm listing them here so that those who find them useful are able to find them: -- Ruby - http://www.hakubi.us/ruby-taglib/ -- Python - http://namingmuse.berlios.de/ +http://developer.kde.org/~wheeler/taglib.html#bindings + diff -Nru taglib-1.7.2/bindings/c/CMakeLists.txt taglib-1.8/bindings/c/CMakeLists.txt --- taglib-1.7.2/bindings/c/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/bindings/c/CMakeLists.txt 2012-09-06 18:03:15.000000000 +0000 @@ -1,37 +1,37 @@ -INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/toolkit - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/asf - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/vorbis - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/flac - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/flac - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpc - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mp4 - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2 - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2/frames - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/wavpack - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/speex - ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/trueaudio +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/toolkit + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/asf + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/vorbis + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/flac + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/flac + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpc + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mp4 + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2 + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2/frames + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/wavpack + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/speex + ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/trueaudio ) +set(tag_c_HDRS tag_c.h) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib_c.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc ) -########### next target ############### +add_library(tag_c tag_c.cpp ${tag_c_HDRS}) -ADD_LIBRARY(tag_c SHARED tag_c.cpp) -if(ENABLE_STATIC) - set_target_properties(tag_c PROPERTIES COMPILE_DEFINITIONS TAGLIB_STATIC) -endif(ENABLE_STATIC) - -TARGET_LINK_LIBRARIES(tag_c tag ) +target_link_libraries(tag_c tag) +set_target_properties(tag_c PROPERTIES PUBLIC_HEADER "${tag_c_HDRS}") +if(BUILD_FRAMEWORK) + set_target_properties(tag_c PROPERTIES FRAMEWORK TRUE) +endif() # On Solaris we need to explicitly add the C++ standard and runtime # libraries to the libs used by the C bindings, because those C bindings # themselves won't pull in the C++ libs -- and if a C application is # using the C bindings then we get link errors. -CHECK_LIBRARY_EXISTS(Crun __RTTI___ "" HAVE_CRUN_LIB) -IF(HAVE_CRUN_LIB) +check_library_exists(Crun __RTTI___ "" HAVE_CRUN_LIB) +if(HAVE_CRUN_LIB) # Which libraries to link depends critically on which # STL version is going to be used by your application # and which runtime is in use. While Crun is pretty much @@ -40,27 +40,29 @@ # team supports stdcxx (Apache RogueWave stdcxx 4.1.3). # According to http://bugs.kde.org/show_bug.cgi?id=215225 the library can have the following two names: - FIND_LIBRARY(ROGUEWAVE_STDCXX_LIBRARY NAMES stdcxx4 stdcxx) - IF(NOT ROGUEWAVE_STDCXX_LIBRARY) - MESSAGE(FATAL_ERROR "Did not find supported STL library (tried stdcxx4 and stdcxx)") - ENDIF(NOT ROGUEWAVE_STDCXX_LIBRARY) - TARGET_LINK_LIBRARIES(tag_c ${ROGUEWAVE_STDCXX_LIBRARY} Crun) -ENDIF(HAVE_CRUN_LIB) + find_library(ROGUEWAVE_STDCXX_LIBRARY NAMES stdcxx4 stdcxx) + if(NOT ROGUEWAVE_STDCXX_LIBRARY) + message(FATAL_ERROR "Did not find supported STL library (tried stdcxx4 and stdcxx)") + endif() + target_link_libraries(tag_c ${ROGUEWAVE_STDCXX_LIBRARY} Crun) +endif() -SET_TARGET_PROPERTIES(tag_c PROPERTIES +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(TARGETS tag_c +) +install(TARGETS tag_c + FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR} LIBRARY DESTINATION ${LIB_INSTALL_DIR} RUNTIME DESTINATION ${BIN_INSTALL_DIR} - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} + ARCHIVE DESTINATION ${LIB_INSTALL_DIR} + PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/taglib ) +if(NOT WIN32 AND 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) +endif() -########### install files ############### - -INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) -INSTALL( FILES tag_c.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/bindings/c/tag_c.cpp taglib-1.8/bindings/c/tag_c.cpp --- taglib-1.7.2/bindings/c/tag_c.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/bindings/c/tag_c.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -23,8 +23,6 @@ #include "config.h" #endif -#include "tag_c.h" - #include #include #include @@ -42,6 +40,8 @@ #include #include +#include "tag_c.h" + using namespace TagLib; static List strings; @@ -58,6 +58,11 @@ stringManagementEnabled = bool(management); } +void taglib_free(void* pointer) +{ + free(pointer); +} + //////////////////////////////////////////////////////////////////////////////// // TagLib::File wrapper //////////////////////////////////////////////////////////////////////////////// @@ -86,14 +91,10 @@ return reinterpret_cast(new Ogg::Speex::File(filename)); case TagLib_File_TrueAudio: return reinterpret_cast(new TrueAudio::File(filename)); -#ifdef TAGLIB_WITH_MP4 case TagLib_File_MP4: return reinterpret_cast(new MP4::File(filename)); -#endif -#ifdef TAGLIB_WITH_ASF case TagLib_File_ASF: return reinterpret_cast(new ASF::File(filename)); -#endif default: return 0; } @@ -108,7 +109,7 @@ BOOL taglib_file_is_valid(const TagLib_File *file) { - return reinterpret_cast(file)->isValid(); + return reinterpret_cast(file)->isValid(); } TagLib_Tag *taglib_file_tag(const TagLib_File *file) diff -Nru taglib-1.7.2/bindings/c/tag_c.h taglib-1.8/bindings/c/tag_c.h --- taglib-1.7.2/bindings/c/tag_c.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/bindings/c/tag_c.h 2012-09-06 18:03:15.000000000 +0000 @@ -79,6 +79,11 @@ */ TAGLIB_C_EXPORT void taglib_set_string_management_enabled(BOOL management); +/*! + * Explicitly free a string returned from TagLib + */ +TAGLIB_C_EXPORT void taglib_free(void* pointer); + /******************************************************************************* * File API ******************************************************************************/ @@ -99,7 +104,7 @@ /*! * Creates a TagLib file based on \a filename. TagLib will try to guess the file * type. - * + * * \returns NULL if the file type cannot be determined or the file cannot * be opened. */ diff -Nru taglib-1.7.2/cmake_uninstall.cmake.in taglib-1.8/cmake_uninstall.cmake.in --- taglib-1.7.2/cmake_uninstall.cmake.in 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/cmake_uninstall.cmake.in 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,21 @@ +if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +endif() + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach (file ${files}) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + if (EXISTS "$ENV{DESTDIR}${file}") + execute_process( + COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}" + OUTPUT_VARIABLE rm_out + RESULT_VARIABLE rm_retval + ) + if(NOT ${rm_retval} EQUAL 0) + message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + endif () + else () + message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + endif () +endforeach() diff -Nru taglib-1.7.2/config-taglib.h.cmake taglib-1.8/config-taglib.h.cmake --- taglib-1.7.2/config-taglib.h.cmake 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/config-taglib.h.cmake 2012-09-06 18:03:15.000000000 +0000 @@ -1,11 +1,11 @@ /* config-taglib.h. Generated by cmake from config-taglib.h.cmake */ -/* NOTE: only add something here if it is really needed by all of kdelibs. - Otherwise please prefer adding to the relevant config-foo.h.cmake file, - to minimize recompilations and increase modularity. */ /* Define if you have libz */ #cmakedefine HAVE_ZLIB 1 #cmakedefine NO_ITUNES_HACKS 1 #cmakedefine WITH_ASF 1 #cmakedefine WITH_MP4 1 + +#cmakedefine TESTS_DIR "@TESTS_DIR@" + diff -Nru taglib-1.7.2/debian/changelog taglib-1.8/debian/changelog --- taglib-1.7.2/debian/changelog 2012-06-27 22:37:43.000000000 +0000 +++ taglib-1.8/debian/changelog 2012-09-23 09:49:42.000000000 +0000 @@ -1,456 +1,13 @@ -taglib (1.7.2-1) unstable; urgency=medium +taglib (1.8-0quantal17) quantal; urgency=high - * New upstream release: - - fixed division by zero while parsing corrupted MP4 files (CVE-2012-2396); - - fixed compilation on Haiku. - * Update symbol files. - * Urgency=medium, security fix. + [ wsnipex ] + * initial release - -- Modestas Vainius Thu, 28 Jun 2012 01:18:37 +0300 + [ wsnipex ] + * install to /opt/taglib-1.8, do not break loads of taglib 1.7 dependent packages + * very dirty hack - symlink stuff to /usr/local as xbmc won't build otherwise -taglib (1.7.1-3) unstable; urgency=low + [ wsnipex ] + * build static library, shared ones still make problems for some users - * libtag1-dev and libtagc0-dev (libtag1-dev reverse dependency) are not - Multi-Arch: same compatible, unmark them. (Closes: #670029) - - -- Modestas Vainius Sun, 29 Apr 2012 10:48:12 +0300 - -taglib (1.7.1-2) unstable; urgency=low - - * Replace build hook with dh_auto_configure override. This should be - compatible with building package via binary-arch target. Fixes FTBFSes. - * Hook doc/html/index.html to build-indep target. This is compat=9 - compatible. - * Do not attempt to build some binary packages uselessly. - * Fix patch to doc/html/index.html. It's in builddir-vanilla. - - -- Modestas Vainius Mon, 16 Apr 2012 22:22:26 +0300 - -taglib (1.7.1-1) unstable; urgency=high - - * New upstream release: - - fixes security vulnerabilities: CVE-2012-1107, CVE-2012-1108 - and CVE-2012-1584. (Closes: #662705) - * Bump Standards-Version to 3.9.3: no changes needed. - * Drop upstream_doxygen_out_of_source.diff, merged upstream. - * Drop backport_protection_against_broken_wma_files.diff, merged upstream. - * Update symbol file. - * Urgency=high due to security fixes. - - -- Modestas Vainius Sun, 15 Apr 2012 19:08:51 +0300 - -taglib (1.7-2) unstable; urgency=low - - * Backport some fixes from upstream repository: (Closes: #656226) - - fix segfault when parsing some ID3v2 tags (patch - backport_id3v2_null_pointer.diff); - - partial protection against broken WMA files (patch - backport_protection_against_broken_wma_files.diff). - * Add Multi-arch support. (Closes: #651019) Implementation is mostly based on - the patch from Steve Langasek. The only difference is bumping debhelper - build dependency to 9. - * Pass visibility options via DEB_{CFLAGS,CXXFLAGS}_MAINT_APPEND in order to - inherit default flags from dh/dpkg-buildflags. This needs dpkg-dev 1.16.1 - hence build depend on it. - * Enable parallel building. - * Update symbol file. - * Remove debian/libtag1-doc.lintian-overrides, no longer needed. - - -- Modestas Vainius Sun, 19 Feb 2012 21:47:28 +0200 - -taglib (1.7-1) unstable; urgency=low - - * New upstream release. - * Drop topgit support and remove README.source, no longer needed. - * Bump Standards-Version to 3.9.2: adjust Replaces/Breaks where needed. - * Simplify debian/rules a bit: use fewer make "functions". - * Do not care about shlibs anymore since there is a symbol file. - * Adapt rusxmms_taglib.diff to upstream changes (autotools removal). - * Clean trailing whitespace from the rusxmms_taglib.diff. - * Add header to the rusxmms_taglib.diff patch. - * Update the list of supported formats in the package descriptions. - (Closes: #613149) - * Update package synopsis'. - * Use new way to call doxygen: via `make docs`. - * Add upstream_doxygen_out_of_source.diff patch to support building - documentation out-of-the-source tree. - * Update symbol files. - * Remove no longer used lintian-overrides. - * Override jquery.js lintian warning, doxygen adds it. - * Update install files. - - -- Modestas Vainius Sat, 09 Apr 2011 19:32:40 +0300 - -taglib (1.6.3-1) unstable; urgency=low - - * New upstream release: - - fixes a problem with ID3v2 APIC frame parsing (Closes: #577990). - * Update symbol files for new release. - * Remove duplicate "Section" fields from debian/control. - * Bump libtag1c2a shlibs to 1.6.3. - - -- Modestas Vainius Mon, 17 May 2010 01:43:14 +0300 - -taglib (1.6.2-1) unstable; urgency=low - - * New upstream release. - * Remove DMUA field from debian/control. I'm a DD now. - * Git repository moved to my new DD account on alioth. Change Vcs fields in - debian/control accordingly. - * Update libtag1-vanilla symbol file, bump libtag1-{vanilla,rusxmms} shlibs. - * Override lintian "taglib source: outdated-autotools-helper-file". Package - does not use autotools anyway. - * Change maintainer email address to @debian.org one. - * Bump Standards-Version to 3.8.4: no changes needed. - - -- Modestas Vainius Fri, 09 Apr 2010 23:58:57 +0300 - -taglib (1.6.1-1) unstable; urgency=low - - * New upstream release. - * Remove all patches, merged upstream: - - general/add_missing_exports_fix.diff - - general/gcc_visibility_feature.diff - - general/link_interface_libraries_fix.diff - - general/taglib_c_pc_fix.diff - * Switch to dpkg-source v3 format: - - do not use quilt dh addon anymore. - * Update install files. - * Update libtag1-vanilla.symbols file: new symbols added. - * Use Conflicts rather than Breaks for libtag-extras0 (as lintian insists). - * Bump shlibs to 1.6.1 in debian/rules. - - -- Modestas Vainius Mon, 02 Nov 2009 01:48:01 +0200 - -taglib (1.6-3) unstable; urgency=low - - * Fix 'optional' tags in symbols file. - * Release to unstable. - - -- Modestas Vainius Mon, 21 Sep 2009 22:32:22 +0300 - -taglib (1.6-2) experimental; urgency=low - - * Build with ASF (-DWITH_ASF=ON) and MP4 (-DWITH_MP4=ON). Update symbols - file and libtag1c2a shlibs accordingly. - * This release breaks libtaglib-extras0. Add Breaks: to libtag1c2a and - libtag1-* packages. - - -- Modestas Vainius Thu, 17 Sep 2009 23:20:26 +0300 - -taglib (1.6-1) unstable; urgency=low - - * New upstream release. - * Bump Standards-Version to 3.8.3 (no changes needed). - * Drop general/recognize_oga_files_fix.diff patch, merged upstream. - * Refresh other patches. - * Refresh rusxmms patch. - * Update install files. - * Update symbols file. - * Bump shlibs of libtag1-* to 1.6. - - -- Modestas Vainius Tue, 15 Sep 2009 22:13:51 +0300 - -taglib (1.5-7) unstable; urgency=low - - * Fix Vcs-Browser URL. - * Convert symbol files to dpkg-dev 1.15.3 compat format: - - drop build dependency on pkg-kde-tools and remove its references from - debian/rules; - - add dpkg-dev (>= 1.15.3) to build depends; - - convert and rename debian/*.symbols.in to dpkg-dev 1.15.3 compatible - format. - * Use dh --with quilt rather than quilt make snippet: - - build depend on quilt (>= 0.46-7~); - - adjust debian/rules accordingly. - * Clean up topgit stuff. - * Get rid of the build branch: update debian/README.source. - * Make use of debhelper 7.3 cmake / build directory support: - - build depend on debhelper (>= 7.3); - - debian/rules rewritten to use dh_auto and otherwise simplified. - * Fix taglib_c.pc (patch general/taglib_c_pc_fix.diff) (Closes: #524696). - * Recognize .oga files as OGGs (patch general/recognize_oga_files_fix.diff) - (Closes: #525571). - * Bump Standards-Version to 3.8.2. No changes needed. - - -- Modestas Vainius Sat, 25 Jul 2009 04:09:33 +0300 - -taglib (1.5-6) unstable; urgency=low - - * Fix potential rusxmms patching breakage in case there were no regular - patches. - * Build depend on debhelper 7.2.7, drop a hack needed for previous dh and - make use of --remaining-packages option for dh_makeshlibs. - * Fix debian/watch file. - * Upload to unstable. - - -- Modestas Vainius Sat, 28 Mar 2009 16:01:43 +0200 - -taglib (1.5-5) experimental; urgency=low - - * Port buildsystem from cdbs to debhelper v7 (>= 7.0.50). cmake - support implemented via dh_overrides. - * Pass CMAKE_USE_RELATIVE_PATHS=ON to cmake. Hence build depend on - cmake 2.6.2. - * Strip debian/tmp from debian/*.install files. Not needed with dh v7. - * Add RusXMMS support (Closes: #384573): - - RusXMMS patch contributed by Ivan Borzenkov, thanks; - - add two libtag1 flavours: vanilla (libtag1-vanilla) and rusxmms - libtag1-rusxmms); - - new libtag1-* flavours replaces old libtag1c2a; - - libtag1c2a becomes a metapackage which depends on either of flavours - via alternate depends. Both libtag1-vanilla and libtag1-rusxmms export - themselves as libtag1c2a via shlibs/symbol files; - - rework buildsystem and build both flavours in their own build directories - (builddir-vanilla and builddir-rusxmms); - - employ some quilt on-the-fly patching hacks to patch and unpatch source - with rusxmms patch as needed; - - build depend on librcc-dev. RusXMMS needs it; - - add more lintian-overrides as the changes above triggered them. - * Get rid of old conflicts/replaces of the libtag1c2a package. - - -- Modestas Vainius Fri, 20 Mar 2009 01:36:31 +0200 - -taglib (1.5-4) unstable; urgency=low - - * Drop Adeodato Simó from Uploaders by his request. Thanks for your work! - * Build depend on pkg-kde-tools (>= 0.4) and switch libtag1c2a symbol file - handling to pkgkde-symbolshelper instead of custom implementation. This - should fix FTBFS on kfreebsd-amd64 (Closes: #494276). - * Migrate patch handling to topgit. As a result, patches were renamed: - - 01_gcc_visibility.diff -> general/gcc_visibility_feature.diff; - - 02_export_public_functions.diff -> general/add_missing_exports_fix.diff; - - 96_link_interface_libraries.diff -> - general/link_interface_libraries_fix.diff. - * Add README.source about topgit/quilt. - * Bump Standards-Version to 3.8.1: README.source added (see above). - * Add ${misc:Depends} for all packages. - * Capitalize API in the libtag1-doc package description. - * Add Vcs-* fields. - - -- Modestas Vainius Thu, 19 Mar 2009 18:05:40 +0200 - -taglib (1.5-3) unstable; urgency=high - - * Add 02_export_more_public_functions.diff patch to TAGLIB_EXPORT some - public functions of the id3v1 module (Closes: #485229). Urgency high - because this breaks other software in testing. - * Drop gcc4.2 symbols files, No longer needed as gcc 4.3 is now default on - all architectures. - - -- Modestas Vainius Mon, 09 Jun 2008 01:11:57 +0300 - -taglib (1.5-2) unstable; urgency=low - - * Write symbol files for g++ 4.2 and g++ 4.3 architectures. Also handle - symbol differences due to size_t mangling. Resolves numerous FTBFSes. - - -- Modestas Vainius Sun, 25 May 2008 22:47:35 +0300 - -taglib (1.5-1) unstable; urgency=low - - * New upstream release (Closes: #477507). - - * Set myself as maintainer (with maintainer's permission). - * Bump debhelper compat level to 5. - * Bump Standards-Version to 3.7.3. No changes needed. - * Remove VCS fields from debian/control for now. - * Add Homepage field. - * Build with cmake & cdbs: - - Adjust build depends. - - Clean up debian/rules. - - Remove libtool patch. - * Remove all other patches - this upstream release contains all fixes. - * Add myself to Uploaders and set DM-Upload-Allowed: yes. - * Convert libtag1-doc.install to libtag1-doc.docs. - * Add debian/rules target to install & rename bindings/README from the - source tree. Remove libtag1c2a.docs. - * taglib v1.5 dropped a few private tag classes which have never been - exposed via public headers. Ignore missing symbols from them: - - TagLib::CombinedTag - - TagLib::FLAC::Tag - - TagLib::MPEGTag - * Add 01_gcc_visibility.diff patch which adds GCC visibility - __attribute__ to TAGLIB_EXPORT and TAGLIB_C_EXPORT definitions. - * 01 patch allows to build with -fvisibility=hidden and - -fvisibility-inlines-hidden. Ignore symbols which where dropped due to - these flags. - * Add symbols files for libtag1c2a and libtagc0. Make two versions of - libtag1c2a.symbols file for 32bit and 64bit arches (based on i386 and - amd64 respectively). There are a few diffs in mangling. - level to -c0 because symbol tables differ insignificantly among arches. - * Add lintian overrides (libtagc0 package name mismatch with soname and - taglib-config man page). - - -- Modestas Vainius Sun, 25 May 2008 18:47:24 +0300 - -taglib (1.4-8.1) unstable; urgency=low - - * Non-maintainer upload. - * Update patches/fix_gcc4.3_ftbfs.diff to fix g++-4.3 FTBFS, thanks to - daniel schepler (Closes: 441604). - - -- Pierre Habouzit Sun, 16 Mar 2008 22:27:41 +0000 - -taglib (1.4-8) unstable; urgency=low - - * Backport patch from upstream svn to reopen files in read-only mode if - opening read-write fails even if access(2) said read-write was ok (this - happens on networked file systems). (Closes: #421893) - - -- Adeodato Simó Thu, 03 May 2007 14:23:30 +0200 - -taglib (1.4-7) unstable; urgency=low - - * Backport patch from upstream svn to fix some cases of miscalculation of - the length of a MP3 VBR file. (Closes: #398998) - - -- Adeodato Simó Fri, 20 Apr 2007 17:02:32 +0200 - -taglib (1.4-6) unstable; urgency=low - - * Add missing bit to the previous backported patch (r583305). - - * Revamp debian/copyright, updating FSF's address at the same time. - - * Move from ${Source-Version} to ${binary:Version}. - - -- Adeodato Simó Fri, 20 Apr 2007 14:30:28 +0200 - -taglib (1.4-5) unstable; urgency=low - - * Backport patch from upstream svn to fix #include that should be - #include "foo.h" instead. (Closes: #241815, #397752) - - * Add patch to fix FTBFS with gcc-4.3. (Closes: #417727) - - * Rename X-VCS-Bzr to VCS-Bzr in debian/control. - - * Use quilt.make. - - -- Adeodato Simó Thu, 19 Apr 2007 23:24:01 +0200 - -taglib (1.4-4) unstable; urgency=low - - * Rework debian/rules a bit, taking chance to change patch management to - quilt and use config.{sub,guess} from autotools-dev. - - * Add a X-VCS-Bzr header to the source package, pointing to the repository - where the packaging is kept. - - * Update Standards-Version to 3.7.2 (no changes needed). - - * Add debian/watch file. - - -- Adeodato Simó Fri, 9 Jun 2006 11:10:35 +0200 - -taglib (1.4-3) unstable; urgency=low - - * libstdc++ allocator transition: rename libtag1c2 to libtag1c2a. - (Closes: #339270) - - * Re-libtoolize, fixing FTBFS on GNU/k*BSD. (Closes: #337953) (Patch in - debian/patches/01_update-libtool.diff, plus a bit of touch magic in - debian/rules.) - - * Update FSF postal address in debian/copyright. - - * Again, update my e-mail address in debian/control, yada yada. - - -- Adeodato Simó Sat, 26 Nov 2005 04:57:44 +0100 - -taglib (1.4-2) unstable; urgency=low - - * Include /usr/lib/pkgconfig/taglib.pc in libtag1-dev. (Closes: #335255) - - * Update Standards-Version to 3.6.2 (no changes needed). - - * Update my e-mail address in debian/control. - - -- Adeodato Simó Mon, 07 Nov 2005 14:25:31 +0100 - -taglib (1.4-1) unstable; urgency=low - - * New upstream release packaged (closes: #323280, #325219), which fixes the - following bugs reported in the BTS: - - + does not leak in APE items. - (Closes: #317831) - + does not segfault when requesting the text of an empty APE item. - (Closes: #325721) - + does not segfault while parsing large ogg vorbis user comments. - (Closes: #312068) - - Changes in the Debian package: - - + bump shlibs. - + remove tdebug.h from libtag1-dev.install, since upstream does not - install it anymore. - - * Add myself as an uploader, with Christopher's permission. - - * Add zlib1g-dev to Build-Depends, to gain support for compressed frames. - - * Pass --disable-debug to ./configure in order to prevent debug messages on - stderr. (Closes: #309753) - - * Now that graphviz is in main, add it to Build-Depends-Indep together with - gsfonts-x11 in order to generate inheritance graphs in docs; the "Class - Hierarchy" page is also created now, which closes: #302889. Removed no - longer needed debian/patches/10_doxygen_have_dot_no.diff. - - * While we're at it, install taglib.png that the html docs reference. - - * Install bindings/README as README.bindings. - - * Acknowledge NMU. (Closes: #319512) - - -- Adeodato Simó Thu, 15 Sep 2005 02:42:18 +0200 - -taglib (1.3.1-1.1) unstable; urgency=medium - - * NMU for the C++ ABI transition (closes: #319512): - - + debian/control: - - rename libtag1 to libtag1c2, and make it conflict and replace libtag1. - - make libtag1-dev depend on libtag1c2 instead of libtag1. - - + debian/rules: - - adjust path for dh_shlibdeps -l option. - - + debian/libtag1.install: - - renamed to libtag1c2.install. - - * Left libtagc0 alone since it only exports C symbols. - - -- Adeodato Simó Sat, 23 Jul 2005 23:09:55 +0200 - -taglib (1.3.1-1) unstable; urgency=low - - * New upstream release. (Closes: #273029) - - -- Christopher L Cheney Mon, 8 Nov 2004 03:00:00 -0600 - -taglib (1.2-1) unstable; urgency=low - - * New upstream release. - - -- Christopher L Cheney Wed, 28 Jul 2004 15:00:00 -0500 - -taglib (1.1-1) unstable; urgency=low - - * New upstream release. - - -- Christopher L Cheney Tue, 13 Apr 2004 20:00:00 -0500 - -taglib (1.0-2) unstable; urgency=low - - * Make rules ignore doxygen failure due to dpkg idiocy. (Closes: #235478) - - -- Christopher L Cheney Wed, 10 Mar 2004 04:00:00 -0600 - -taglib (1.0-1) unstable; urgency=low - - * Initial release. - - -- Christopher L Cheney Thu, 19 Feb 2004 02:00:00 -0600 + -- wsnipex Sun, 23 Sep 2012 11:48:01 +0200 diff -Nru taglib-1.7.2/debian/control taglib-1.8/debian/control --- taglib-1.7.2/debian/control 2012-04-29 07:53:56.000000000 +0000 +++ taglib-1.8/debian/control 2012-09-23 07:47:42.000000000 +0000 @@ -1,20 +1,19 @@ Source: taglib Section: libs Priority: optional -Maintainer: Modestas Vainius -Build-Depends: cmake (>= 2.6.2), debhelper (>= 9), dpkg-dev (>= 1.16.1), quilt (>= 0.46-7~), zlib1g-dev, librcc-dev -Build-Depends-Indep: doxygen, graphviz, gsfonts-x11 -Standards-Version: 3.9.3 +Maintainer: wsnipex +Build-Depends: cmake (>= 2.6.2), debhelper (>= 8.1.0), dpkg-dev (>= 1.14.3), zlib1g-dev +Build-Depends-Indep: +Standards-Version: 3.9.2 Homepage: http://developer.kde.org/~wheeler/taglib.html Vcs-Git: git://git.debian.org/users/modax/taglib.git Vcs-Browser: http://git.debian.org/?p=users/modax/taglib.git;a=summary -Package: libtag1c2a +Package: libtag1x8 Architecture: any Multi-Arch: same -Pre-Depends: ${misc:Pre-Depends} -Depends: libtag1-vanilla (= ${binary:Version}) | libtag1-rusxmms (= ${binary:Version}), ${misc:Depends} -Conflicts: libtag-extras0 +Depends: +Conflicts: Description: audio meta-data library TagLib is a library for reading and editing the meta-data of several popular audio formats. Currently it supports both ID3v1 and ID3v2 for MP3 files, Ogg @@ -26,91 +25,3 @@ TagLib flavour. Vanilla (original) flavour is default. Alternatively you may install RusXMMS flavour which can be found in the libtag1-rusxmms package. -Package: libtag1-vanilla -Architecture: any -Multi-Arch: same -Pre-Depends: ${misc:Pre-Depends} -Depends: ${shlibs:Depends}, ${misc:Depends} -Conflicts: libtag1-rusxmms, libtag-extras0 -Replaces: libtag1c2a (<< 1.5-5) -Breaks: libtag1c2a (<< 1.5-5) -Description: audio meta-data library - vanilla flavour - TagLib is a library for reading and editing the meta-data of several popular - audio formats. Currently it supports both ID3v1 and ID3v2 for MP3 files, Ogg - Vorbis comments and ID3 tags and Vorbis comments in FLAC, MPC, Speex, WavPack - TrueAudio, WAV, AIFF, MP4 and ASF files. - . - This is the runtime package for programs that use the TagLib Audio Meta-Data - Library. This package contains original and unpatched flavour of the library. - -Package: libtag1-rusxmms -Architecture: any -Multi-Arch: same -Pre-Depends: ${misc:Pre-Depends} -Depends: ${shlibs:Depends}, ${misc:Depends} -Conflicts: libtag1-vanilla, libtag-extras0 -Replaces: libtag1c2a (<< 1.5-5) -Breaks: libtag1c2a (<< 1.5-5) -Description: audio meta-data library - RusXMMS flavour - TagLib is a library for reading and editing the meta-data of several popular - audio formats. Currently it supports both ID3v1 and ID3v2 for MP3 files, Ogg - Vorbis comments and ID3 tags and Vorbis comments in FLAC, MPC, Speex, WavPack - TrueAudio, WAV, AIFF, MP4 and ASF files. - . - This is the RusXMMS flavour of the TagLib Audio Meta-Data Library. It is - patched with RusXMMS patch and adds support for autodetection of cyrillic - encodings under Russian/Ukrainian/Belarusian locales. - -Package: libtag1-dev -Section: libdevel -Architecture: any -Depends: libtag1c2a (= ${binary:Version}), ${misc:Depends} -Description: audio meta-data library - development files - TagLib is a library for reading and editing the meta-data of several popular - audio formats. Currently it supports both ID3v1 and ID3v2 for MP3 files, Ogg - Vorbis comments and ID3 tags and Vorbis comments in FLAC, MPC, Speex, WavPack - TrueAudio, WAV, AIFF, MP4 and ASF files. - . - This is the development package which contains headers and static libraries - for the TagLib Audio Meta-Data Library. - -Package: libtag1-doc -Section: doc -Architecture: all -Depends: ${misc:Depends} -Suggests: libtag1-dev -Description: audio meta-data library - API documentation - TagLib is a library for reading and editing the meta-data of several popular - audio formats. Currently it supports both ID3v1 and ID3v2 for MP3 files, Ogg - Vorbis comments and ID3 tags and Vorbis comments in FLAC, MPC, Speex, WavPack - TrueAudio, WAV, AIFF, MP4 and ASF files. - . - This is the documentation package which contains API documentation for the - TagLib Audio Meta-Data Library. - -Package: libtagc0 -Architecture: any -Multi-Arch: same -Pre-Depends: ${misc:Pre-Depends} -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: audio meta-data library - C bindings - TagLib is a library for reading and editing the meta-data of several popular - audio formats. Currently it supports both ID3v1 and ID3v2 for MP3 files, Ogg - Vorbis comments and ID3 tags and Vorbis comments in FLAC, MPC, Speex, WavPack - TrueAudio, WAV, AIFF, MP4 and ASF files. - . - This is the runtime package for programs that use the TagLib Audio Meta-Data - Library (C bindings). - -Package: libtagc0-dev -Section: libdevel -Architecture: any -Depends: libtagc0 (= ${binary:Version}), libtag1-dev (= ${binary:Version}), ${misc:Depends} -Description: audio meta-data library - development files for C bindings - TagLib is a library for reading and editing the meta-data of several popular - audio formats. Currently it supports both ID3v1 and ID3v2 for MP3 files, Ogg - Vorbis comments and ID3 tags and Vorbis comments in FLAC, MPC, Speex, WavPack - TrueAudio, WAV, AIFF, MP4 and ASF files. - . - This is the development package which contains headers and static libraries - for the TagLib Audio Meta-Data Library (C bindings). diff -Nru taglib-1.7.2/debian/libtag1-dev.examples taglib-1.8/debian/libtag1-dev.examples --- taglib-1.7.2/debian/libtag1-dev.examples 2010-05-13 21:52:24.000000000 +0000 +++ taglib-1.8/debian/libtag1-dev.examples 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -examples/framelist.cpp -examples/strip-id3v1.cpp -examples/tagreader.cpp -examples/tagwriter.cpp diff -Nru taglib-1.7.2/debian/libtag1-dev.install taglib-1.8/debian/libtag1-dev.install --- taglib-1.7.2/debian/libtag1-dev.install 2012-02-19 19:02:04.000000000 +0000 +++ taglib-1.8/debian/libtag1-dev.install 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -usr/bin/taglib-config -usr/include/taglib/aifffile.h -usr/include/taglib/aiffproperties.h -usr/include/taglib/apefile.h -usr/include/taglib/apefooter.h -usr/include/taglib/apeitem.h -usr/include/taglib/apeproperties.h -usr/include/taglib/apetag.h -usr/include/taglib/asfattribute.h -usr/include/taglib/asffile.h -usr/include/taglib/asfpicture.h -usr/include/taglib/asfproperties.h -usr/include/taglib/asftag.h -usr/include/taglib/attachedpictureframe.h -usr/include/taglib/audioproperties.h -usr/include/taglib/commentsframe.h -usr/include/taglib/fileref.h -usr/include/taglib/flacfile.h -usr/include/taglib/flacmetadatablock.h -usr/include/taglib/flacpicture.h -usr/include/taglib/flacproperties.h -usr/include/taglib/generalencapsulatedobjectframe.h -usr/include/taglib/id3v1genres.h -usr/include/taglib/id3v1tag.h -usr/include/taglib/id3v2extendedheader.h -usr/include/taglib/id3v2footer.h -usr/include/taglib/id3v2frame.h -usr/include/taglib/id3v2framefactory.h -usr/include/taglib/id3v2header.h -usr/include/taglib/id3v2synchdata.h -usr/include/taglib/id3v2tag.h -usr/include/taglib/mp4atom.h -usr/include/taglib/mp4coverart.h -usr/include/taglib/mp4file.h -usr/include/taglib/mp4item.h -usr/include/taglib/mp4properties.h -usr/include/taglib/mp4tag.h -usr/include/taglib/mpcfile.h -usr/include/taglib/mpcproperties.h -usr/include/taglib/mpegfile.h -usr/include/taglib/mpegheader.h -usr/include/taglib/mpegproperties.h -usr/include/taglib/oggfile.h -usr/include/taglib/oggflacfile.h -usr/include/taglib/oggpage.h -usr/include/taglib/oggpageheader.h -usr/include/taglib/popularimeterframe.h -usr/include/taglib/privateframe.h -usr/include/taglib/relativevolumeframe.h -usr/include/taglib/rifffile.h -usr/include/taglib/speexfile.h -usr/include/taglib/speexproperties.h -usr/include/taglib/tag.h -usr/include/taglib/taglib.h -usr/include/taglib/taglib_config.h -usr/include/taglib/taglib_export.h -usr/include/taglib/tbytevector.h -usr/include/taglib/tbytevectorlist.h -usr/include/taglib/textidentificationframe.h -usr/include/taglib/tfile.h -usr/include/taglib/tlist.h -usr/include/taglib/tlist.tcc -usr/include/taglib/tmap.h -usr/include/taglib/tmap.tcc -usr/include/taglib/trueaudiofile.h -usr/include/taglib/trueaudioproperties.h -usr/include/taglib/tstring.h -usr/include/taglib/tstringlist.h -usr/include/taglib/uniquefileidentifierframe.h -usr/include/taglib/unknownframe.h -usr/include/taglib/unsynchronizedlyricsframe.h -usr/include/taglib/urllinkframe.h -usr/include/taglib/vorbisfile.h -usr/include/taglib/vorbisproperties.h -usr/include/taglib/wavfile.h -usr/include/taglib/wavpackfile.h -usr/include/taglib/wavpackproperties.h -usr/include/taglib/wavproperties.h -usr/include/taglib/xingheader.h -usr/include/taglib/xiphcomment.h -usr/lib/*/libtag.so -usr/lib/*/pkgconfig/taglib.pc diff -Nru taglib-1.7.2/debian/libtag1-dev.lintian-overrides taglib-1.8/debian/libtag1-dev.lintian-overrides --- taglib-1.7.2/debian/libtag1-dev.lintian-overrides 2010-05-13 21:52:24.000000000 +0000 +++ taglib-1.8/debian/libtag1-dev.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -libtag1-dev: binary-without-manpage usr/bin/taglib-config diff -Nru taglib-1.7.2/debian/libtag1-doc.docs taglib-1.8/debian/libtag1-doc.docs --- taglib-1.7.2/debian/libtag1-doc.docs 2011-04-09 16:13:32.000000000 +0000 +++ taglib-1.8/debian/libtag1-doc.docs 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -builddir-vanilla/doc/. diff -Nru taglib-1.7.2/debian/libtag1-rusxmms.install taglib-1.8/debian/libtag1-rusxmms.install --- taglib-1.7.2/debian/libtag1-rusxmms.install 2012-02-19 19:02:04.000000000 +0000 +++ taglib-1.8/debian/libtag1-rusxmms.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/lib/*/libtag.so.1* diff -Nru taglib-1.7.2/debian/libtag1-rusxmms.lintian-overrides taglib-1.8/debian/libtag1-rusxmms.lintian-overrides --- taglib-1.7.2/debian/libtag1-rusxmms.lintian-overrides 2011-04-09 16:25:31.000000000 +0000 +++ taglib-1.8/debian/libtag1-rusxmms.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -libtag1-rusxmms: symbols-declares-dependency-on-other-package -libtag1-rusxmms: package-name-doesnt-match-sonames libtag1 diff -Nru taglib-1.7.2/debian/libtag1-rusxmms.symbols taglib-1.8/debian/libtag1-rusxmms.symbols --- taglib-1.7.2/debian/libtag1-rusxmms.symbols 2012-04-15 16:11:36.000000000 +0000 +++ taglib-1.8/debian/libtag1-rusxmms.symbols 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -#include "libtag1-vanilla.symbols" -libtag.so.1 libtag1c2a #MINVER# -| libtag1c2a (>= 1.4) -| libtag1-rusxmms #MINVER# - _ZN6TagLib6String11ID3RealTypeENS0_4TypeE@Base 1.5-5~ 2 - _ZN6TagLib6String7ID3TypeEi@Base 1.5-5~ 2 - _ZN6TagLib6String8ID3WTypeENS0_4TypeE@Base 1.5-5~ 2 diff -Nru taglib-1.7.2/debian/libtag1-vanilla.install taglib-1.8/debian/libtag1-vanilla.install --- taglib-1.7.2/debian/libtag1-vanilla.install 2012-02-19 19:02:04.000000000 +0000 +++ taglib-1.8/debian/libtag1-vanilla.install 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -usr/lib/*/libtag.so.1 -usr/lib/*/libtag.so.1.* diff -Nru taglib-1.7.2/debian/libtag1-vanilla.lintian-overrides taglib-1.8/debian/libtag1-vanilla.lintian-overrides --- taglib-1.7.2/debian/libtag1-vanilla.lintian-overrides 2011-04-09 16:25:37.000000000 +0000 +++ taglib-1.8/debian/libtag1-vanilla.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -libtag1-vanilla: symbols-declares-dependency-on-other-package -libtag1-vanilla: package-name-doesnt-match-sonames libtag1 diff -Nru taglib-1.7.2/debian/libtag1-vanilla.symbols taglib-1.8/debian/libtag1-vanilla.symbols --- taglib-1.7.2/debian/libtag1-vanilla.symbols 2012-06-27 22:31:49.000000000 +0000 +++ taglib-1.8/debian/libtag1-vanilla.symbols 1970-01-01 00:00:00.000000000 +0000 @@ -1,1768 +0,0 @@ -# SymbolsHelper-Confirmed: 1.7.1 amd64 armel armhf hurd-i386 i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc -libtag.so.1 libtag1c2a #MINVER# -| libtag1c2a (>= 1.4) - _ZN6TagLib10ByteVector11fromCStringEPKcj@Base 1.4 1 - _ZN6TagLib10ByteVector12fromLongLongExb@Base 1.4 1 - _ZN6TagLib10ByteVector3endEv@Base 1.4 1 - _ZN6TagLib10ByteVector4dataEv@Base 1.4 1 - _ZN6TagLib10ByteVector4nullE@Base 1.4 1 - _ZN6TagLib10ByteVector5beginEv@Base 1.4 1 - _ZN6TagLib10ByteVector5clearEv@Base 1.4 1 - _ZN6TagLib10ByteVector6appendERKS0_@Base 1.4 1 - _ZN6TagLib10ByteVector6detachEv@Base 1.4 1 - _ZN6TagLib10ByteVector6resizeEjc@Base 1.4 1 - _ZN6TagLib10ByteVector7replaceERKS0_S2_@Base 1.5 - _ZN6TagLib10ByteVector7setDataEPKc@Base 1.4 1 - _ZN6TagLib10ByteVector7setDataEPKcj@Base 1.4 1 - _ZN6TagLib10ByteVector8fromUIntEjb@Base 1.4 1 - _ZN6TagLib10ByteVector9fromShortEsb@Base 1.4 1 - _ZN6TagLib10ByteVectorC1EPKc@Base 1.4 1 - _ZN6TagLib10ByteVectorC1EPKcj@Base 1.4 1 - _ZN6TagLib10ByteVectorC1ERKS0_@Base 1.4 1 - _ZN6TagLib10ByteVectorC1Ec@Base 1.4 1 - _ZN6TagLib10ByteVectorC1Ejc@Base 1.4 1 - _ZN6TagLib10ByteVectorC1Ev@Base 1.4 1 - _ZN6TagLib10ByteVectorC2EPKc@Base 1.4 1 - _ZN6TagLib10ByteVectorC2EPKcj@Base 1.4 1 - _ZN6TagLib10ByteVectorC2ERKS0_@Base 1.4 1 - _ZN6TagLib10ByteVectorC2Ec@Base 1.4 1 - _ZN6TagLib10ByteVectorC2Ejc@Base 1.4 1 - _ZN6TagLib10ByteVectorC2Ev@Base 1.4 1 - _ZN6TagLib10ByteVectorD0Ev@Base 1.4 1 - _ZN6TagLib10ByteVectorD1Ev@Base 1.4 1 - _ZN6TagLib10ByteVectorD2Ev@Base 1.4 1 - _ZN6TagLib10ByteVectoraSEPKc@Base 1.4 1 - _ZN6TagLib10ByteVectoraSERKS0_@Base 1.4 1 - _ZN6TagLib10ByteVectoraSEc@Base 1.4 1 - _ZN6TagLib10ByteVectorixEi@Base 1.4 1 - _ZN6TagLib10StringList5splitERKNS_6StringES3_@Base 1.4 1 - _ZN6TagLib10StringList6appendERKNS_6StringE@Base 1.4 1 - _ZN6TagLib10StringList6appendERKS0_@Base 1.4 1 - _ZN6TagLib10StringListC1ERKNS_14ByteVectorListENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib10StringListC1ERKNS_6StringE@Base 1.4 1 - _ZN6TagLib10StringListC1ERKS0_@Base 1.4 1 - _ZN6TagLib10StringListC1Ev@Base 1.4 1 - _ZN6TagLib10StringListC2ERKNS_14ByteVectorListENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib10StringListC2ERKNS_6StringE@Base 1.4 1 - _ZN6TagLib10StringListC2ERKS0_@Base 1.4 1 - _ZN6TagLib10StringListC2Ev@Base 1.4 1 - _ZN6TagLib10StringListD0Ev@Base 1.4 1 - _ZN6TagLib10StringListD1Ev@Base 1.4 1 - _ZN6TagLib10StringListD2Ev@Base 1.4 1 - _ZN6TagLib14ByteVectorList5splitERKNS_10ByteVectorES3_i@Base 1.4 1 - _ZN6TagLib14ByteVectorList5splitERKNS_10ByteVectorES3_ii@Base 1.4 1 - _ZN6TagLib14ByteVectorListC1ERKS0_@Base 1.4 1 - _ZN6TagLib14ByteVectorListC1Ev@Base 1.4 1 - _ZN6TagLib14ByteVectorListC2ERKS0_@Base 1.4 1 - _ZN6TagLib14ByteVectorListC2Ev@Base 1.4 1 - _ZN6TagLib14ByteVectorListD0Ev@Base 1.4 1 - _ZN6TagLib14ByteVectorListD1Ev@Base 1.4 1 - _ZN6TagLib14ByteVectorListD2Ev@Base 1.4 1 - _ZN6TagLib15AudioPropertiesC1ENS0_9ReadStyleE@Base 1.4 1 - _ZN6TagLib15AudioPropertiesC2ENS0_9ReadStyleE@Base 1.4 1 - _ZN6TagLib15AudioPropertiesD0Ev@Base 1.4 1 - _ZN6TagLib15AudioPropertiesD1Ev@Base 1.4 1 - _ZN6TagLib15AudioPropertiesD2Ev@Base 1.4 1 - _ZN6TagLib3APE10Properties10analyzeOldEv@Base 1.7 - _ZN6TagLib3APE10Properties14analyzeCurrentEv@Base 1.7 - _ZN6TagLib3APE10Properties14findDescriptorEv@Base 1.7 - _ZN6TagLib3APE10Properties4readEv@Base 1.7 - _ZN6TagLib3APE10Properties9findID3v2Ev@Base 1.7 - _ZN6TagLib3APE10PropertiesC1EPNS0_4FileENS_15AudioProperties9ReadStyleE@Base 1.7 - _ZN6TagLib3APE10PropertiesC2EPNS0_4FileENS_15AudioProperties9ReadStyleE@Base 1.7 - _ZN6TagLib3APE10PropertiesD0Ev@Base 1.7 - _ZN6TagLib3APE10PropertiesD1Ev@Base 1.7 - _ZN6TagLib3APE10PropertiesD2Ev@Base 1.7 - _ZN6TagLib3APE3Tag10removeItemERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3APE3Tag10setCommentERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3APE3Tag14fileIdentifierEv@Base 1.4 1 - _ZN6TagLib3APE3Tag4readEv@Base 1.4 1 - _ZN6TagLib3APE3Tag5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib3APE3Tag7setItemERKNS_6StringERKNS0_4ItemE@Base 1.4 1 - _ZN6TagLib3APE3Tag7setYearEj@Base 1.4 1 - _ZN6TagLib3APE3Tag8addValueERKNS_6StringES4_b@Base 1.4 1 - _ZN6TagLib3APE3Tag8setAlbumERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3APE3Tag8setGenreERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3APE3Tag8setTitleERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3APE3Tag8setTrackEj@Base 1.4 1 - _ZN6TagLib3APE3Tag9setArtistERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3APE3TagC1EPNS_4FileEl@Base 1.4 1 - _ZN6TagLib3APE3TagC1Ev@Base 1.4 1 - _ZN6TagLib3APE3TagC2EPNS_4FileEl@Base 1.4 1 - _ZN6TagLib3APE3TagC2Ev@Base 1.4 1 - _ZN6TagLib3APE3TagD0Ev@Base 1.4 1 - _ZN6TagLib3APE3TagD1Ev@Base 1.4 1 - _ZN6TagLib3APE3TagD2Ev@Base 1.4 1 - _ZN6TagLib3APE4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.7 - _ZN6TagLib3APE4File4saveEv@Base 1.7 - _ZN6TagLib3APE4File5stripEi@Base 1.7 - _ZN6TagLib3APE4File6APETagEb@Base 1.7 - _ZN6TagLib3APE4File7findAPEEv@Base 1.7 - _ZN6TagLib3APE4File8ID3v1TagEb@Base 1.7 - _ZN6TagLib3APE4File9findID3v1Ev@Base 1.7 - _ZN6TagLib3APE4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.7 - _ZN6TagLib3APE4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.7 - _ZN6TagLib3APE4FileD0Ev@Base 1.7 - _ZN6TagLib3APE4FileD1Ev@Base 1.7 - _ZN6TagLib3APE4FileD2Ev@Base 1.7 - _ZN6TagLib3APE4Item11appendValueERKNS_6StringE@Base 1.5 - _ZN6TagLib3APE4Item11setReadOnlyEb@Base 1.4 1 - _ZN6TagLib3APE4Item12appendValuesERKNS_10StringListE@Base 1.5 - _ZN6TagLib3APE4Item5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib3APE4Item6setKeyERKNS_6StringE@Base 1.5 - _ZN6TagLib3APE4Item7setTypeENS1_9ItemTypesE@Base 1.4 1 - _ZN6TagLib3APE4Item8setValueERKNS_6StringE@Base 1.5 - _ZN6TagLib3APE4Item9setValuesERKNS_10StringListE@Base 1.5 - _ZN6TagLib3APE4ItemC1ERKNS_6StringERKNS_10StringListE@Base 1.4 1 - _ZN6TagLib3APE4ItemC1ERKNS_6StringES4_@Base 1.4 1 - _ZN6TagLib3APE4ItemC1ERKS1_@Base 1.4 1 - _ZN6TagLib3APE4ItemC1Ev@Base 1.4 1 - _ZN6TagLib3APE4ItemC2ERKNS_6StringERKNS_10StringListE@Base 1.4 1 - _ZN6TagLib3APE4ItemC2ERKNS_6StringES4_@Base 1.4 1 - _ZN6TagLib3APE4ItemC2ERKS1_@Base 1.4 1 - _ZN6TagLib3APE4ItemC2Ev@Base 1.4 1 - _ZN6TagLib3APE4ItemD0Ev@Base 1.4 1 - _ZN6TagLib3APE4ItemD1Ev@Base 1.4 1 - _ZN6TagLib3APE4ItemD2Ev@Base 1.4 1 - _ZN6TagLib3APE4ItemaSERKS1_@Base 1.4 1 - _ZN6TagLib3APE6Footer10setTagSizeEj@Base 1.4 1 - _ZN6TagLib3APE6Footer12setItemCountEj@Base 1.4 1 - _ZN6TagLib3APE6Footer14fileIdentifierEv@Base 1.4 1 - _ZN6TagLib3APE6Footer4sizeEv@Base 1.4 1 - _ZN6TagLib3APE6Footer5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib3APE6Footer7setDataERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib3APE6FooterC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib3APE6FooterC1Ev@Base 1.4 1 - _ZN6TagLib3APE6FooterC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib3APE6FooterC2Ev@Base 1.4 1 - _ZN6TagLib3APE6FooterD0Ev@Base 1.4 1 - _ZN6TagLib3APE6FooterD1Ev@Base 1.4 1 - _ZN6TagLib3APE6FooterD2Ev@Base 1.4 1 - _ZN6TagLib3ASF10Properties10setBitrateEi@Base 1.6-2~ - _ZN6TagLib3ASF10Properties11setChannelsEi@Base 1.6-2~ - _ZN6TagLib3ASF10Properties13setSampleRateEi@Base 1.6-2~ - _ZN6TagLib3ASF10Properties9setLengthEi@Base 1.6-2~ - _ZN6TagLib3ASF10PropertiesC1Ev@Base 1.6-2~ - _ZN6TagLib3ASF10PropertiesC2Ev@Base 1.6-2~ - _ZN6TagLib3ASF10PropertiesD0Ev@Base 1.6-2~ - _ZN6TagLib3ASF10PropertiesD1Ev@Base 1.6-2~ - _ZN6TagLib3ASF10PropertiesD2Ev@Base 1.6-2~ - _ZN6TagLib3ASF3Tag10removeItemERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3ASF3Tag10setCommentERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3ASF3Tag12addAttributeERKNS_6StringERKNS0_9AttributeE@Base 1.6-2~ - _ZN6TagLib3ASF3Tag12setAttributeERKNS_6StringERKNS0_9AttributeE@Base 1.6-2~ - _ZN6TagLib3ASF3Tag12setCopyrightERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3ASF3Tag16attributeListMapEv@Base 1.6-2~ - _ZN6TagLib3ASF3Tag7setYearEj@Base 1.6-2~ - _ZN6TagLib3ASF3Tag8setAlbumERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3ASF3Tag8setGenreERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3ASF3Tag8setTitleERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3ASF3Tag8setTrackEj@Base 1.6-2~ - _ZN6TagLib3ASF3Tag9setArtistERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3ASF3Tag9setRatingERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3ASF3TagC1Ev@Base 1.6-2~ - _ZN6TagLib3ASF3TagC2Ev@Base 1.6-2~ - _ZN6TagLib3ASF3TagD0Ev@Base 1.6-2~ - _ZN6TagLib3ASF3TagD1Ev@Base 1.6-2~ - _ZN6TagLib3ASF3TagD2Ev@Base 1.6-2~ - _ZN6TagLib3ASF4File10BaseObject5parseEPS1_j@Base 1.6-2~ - _ZN6TagLib3ASF4File10BaseObject6renderEPS1_@Base 1.6-2~ - _ZN6TagLib3ASF4File10readStringEi@Base 1.6-2~ - _ZN6TagLib3ASF4File12renderStringERKNS_6StringEb@Base 1.6-2~ - _ZN6TagLib3ASF4File13UnknownObject4guidEv@Base 1.6-2~ - _ZN6TagLib3ASF4File13UnknownObjectC1ERKNS_10ByteVectorE@Base 1.6-2~ - _ZN6TagLib3ASF4File13UnknownObjectC2ERKNS_10ByteVectorE@Base 1.6-2~ - _ZN6TagLib3ASF4File13UnknownObjectD0Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File13UnknownObjectD1Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File13UnknownObjectD2Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File14MetadataObject4guidEv@Base 1.6-2~ - _ZN6TagLib3ASF4File14MetadataObject5parseEPS1_j@Base 1.6-2~ - _ZN6TagLib3ASF4File14MetadataObject6renderEPS1_@Base 1.6-2~ - _ZN6TagLib3ASF4File14MetadataObjectD0Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File14MetadataObjectD1Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File14MetadataObjectD2Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File20FilePropertiesObject4guidEv@Base 1.6-2~ - _ZN6TagLib3ASF4File20FilePropertiesObject5parseEPS1_j@Base 1.6-2~ - _ZN6TagLib3ASF4File20FilePropertiesObjectD0Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File20FilePropertiesObjectD1Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File20FilePropertiesObjectD2Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File21HeaderExtensionObject4guidEv@Base 1.6-2~ - _ZN6TagLib3ASF4File21HeaderExtensionObject5parseEPS1_j@Base 1.6-2~ - _ZN6TagLib3ASF4File21HeaderExtensionObject6renderEPS1_@Base 1.6-2~ - _ZN6TagLib3ASF4File21HeaderExtensionObjectD0Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File21HeaderExtensionObjectD1Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File21HeaderExtensionObjectD2Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File21MetadataLibraryObject4guidEv@Base 1.6-2~ - _ZN6TagLib3ASF4File21MetadataLibraryObject5parseEPS1_j@Base 1.6-2~ - _ZN6TagLib3ASF4File21MetadataLibraryObject6renderEPS1_@Base 1.6-2~ - _ZN6TagLib3ASF4File21MetadataLibraryObjectD0Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File21MetadataLibraryObjectD1Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File21MetadataLibraryObjectD2Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File22StreamPropertiesObject4guidEv@Base 1.6-2~ - _ZN6TagLib3ASF4File22StreamPropertiesObject5parseEPS1_j@Base 1.6-2~ - _ZN6TagLib3ASF4File22StreamPropertiesObjectD0Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File22StreamPropertiesObjectD1Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File22StreamPropertiesObjectD2Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File24ContentDescriptionObject4guidEv@Base 1.6-2~ - _ZN6TagLib3ASF4File24ContentDescriptionObject5parseEPS1_j@Base 1.6-2~ - _ZN6TagLib3ASF4File24ContentDescriptionObject6renderEPS1_@Base 1.6-2~ - _ZN6TagLib3ASF4File24ContentDescriptionObjectD0Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File24ContentDescriptionObjectD1Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File24ContentDescriptionObjectD2Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File32ExtendedContentDescriptionObject4guidEv@Base 1.6-2~ - _ZN6TagLib3ASF4File32ExtendedContentDescriptionObject5parseEPS1_j@Base 1.6-2~ - _ZN6TagLib3ASF4File32ExtendedContentDescriptionObject6renderEPS1_@Base 1.6-2~ - _ZN6TagLib3ASF4File32ExtendedContentDescriptionObjectD0Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File32ExtendedContentDescriptionObjectD1Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File32ExtendedContentDescriptionObjectD2Ev@Base 1.7-2~ - _ZN6TagLib3ASF4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.6-2~ - _ZN6TagLib3ASF4File4saveEv@Base 1.6-2~ - _ZN6TagLib3ASF4File8readBYTEEPb@Base 1.7-2~ - _ZN6TagLib3ASF4File8readWORDEPb@Base 1.7-2~ - _ZN6TagLib3ASF4File9readDWORDEPb@Base 1.7-2~ - _ZN6TagLib3ASF4File9readQWORDEPb@Base 1.7-2~ - _ZN6TagLib3ASF4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.6-2~ - _ZN6TagLib3ASF4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.6-2~ - _ZN6TagLib3ASF4FileD0Ev@Base 1.6-2~ - _ZN6TagLib3ASF4FileD1Ev@Base 1.6-2~ - _ZN6TagLib3ASF4FileD2Ev@Base 1.6-2~ - _ZN6TagLib3ASF7Picture10setPictureERKNS_10ByteVectorE@Base 1.7 - _ZN6TagLib3ASF7Picture11fromInvalidEv@Base 1.7 - _ZN6TagLib3ASF7Picture11setMimeTypeERKNS_6StringE@Base 1.7 - _ZN6TagLib3ASF7Picture14setDescriptionERKNS_6StringE@Base 1.7 - _ZN6TagLib3ASF7Picture5parseERKNS_10ByteVectorE@Base 1.7 - _ZN6TagLib3ASF7Picture7setTypeERKNS1_4TypeE@Base 1.7 - _ZN6TagLib3ASF7PictureC1ERKS1_@Base 1.7 - _ZN6TagLib3ASF7PictureC1Ev@Base 1.7 - _ZN6TagLib3ASF7PictureC2ERKS1_@Base 1.7 - _ZN6TagLib3ASF7PictureC2Ev@Base 1.7 - _ZN6TagLib3ASF7PictureD0Ev@Base 1.7 - _ZN6TagLib3ASF7PictureD1Ev@Base 1.7 - _ZN6TagLib3ASF7PictureD2Ev@Base 1.7 - _ZN6TagLib3ASF7PictureaSERKS1_@Base 1.7 - _ZN6TagLib3ASF9Attribute11setLanguageEi@Base 1.6-2~ - _ZN6TagLib3ASF9Attribute5parseERNS0_4FileEi@Base 1.6-2~ - _ZN6TagLib3ASF9Attribute9setStreamEi@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC1ERKNS0_7PictureE@Base 1.7 - _ZN6TagLib3ASF9AttributeC1ERKNS_10ByteVectorE@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC1ERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC1ERKS1_@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC1Eb@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC1Ej@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC1Et@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC1Ev@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC1Ey@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC2ERKNS0_7PictureE@Base 1.7 - _ZN6TagLib3ASF9AttributeC2ERKNS_10ByteVectorE@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC2ERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC2ERKS1_@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC2Eb@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC2Ej@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC2Et@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC2Ev@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeC2Ey@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeD0Ev@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeD1Ev@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeD2Ev@Base 1.6-2~ - _ZN6TagLib3ASF9AttributeaSERKS1_@Base 1.6-2~ - _ZN6TagLib3MP410PropertiesC1EPNS0_4FileEPNS0_5AtomsENS_15AudioProperties9ReadStyleE@Base 1.6-2~ - _ZN6TagLib3MP410PropertiesC2EPNS0_4FileEPNS0_5AtomsENS_15AudioProperties9ReadStyleE@Base 1.6-2~ - _ZN6TagLib3MP410PropertiesD0Ev@Base 1.6-2~ - _ZN6TagLib3MP410PropertiesD1Ev@Base 1.6-2~ - _ZN6TagLib3MP410PropertiesD2Ev@Base 1.6-2~ - _ZN6TagLib3MP43Tag10renderAtomERKNS_10ByteVectorES4_@Base 1.6-2~ - _ZN6TagLib3MP43Tag10renderBoolERKNS_10ByteVectorERNS0_4ItemE@Base 1.6-2~ - _ZN6TagLib3MP43Tag10renderCovrERKNS_10ByteVectorERNS0_4ItemE@Base 1.6.1 - _ZN6TagLib3MP43Tag10renderDataERKNS_10ByteVectorEiRKNS_14ByteVectorListE@Base 1.6-2~ - _ZN6TagLib3MP43Tag10renderTextERKNS_10ByteVectorERNS0_4ItemEi@Base 1.6-2~ - _ZN6TagLib3MP43Tag10setCommentERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3MP43Tag11itemListMapEv@Base 1.6-2~ - _ZN6TagLib3MP43Tag12parseIntPairEPNS0_4AtomEPNS_4FileE@Base 1.6-2~ - _ZN6TagLib3MP43Tag12saveExistingERNS_10ByteVectorERNS_4ListIPNS0_4AtomEEE@Base 1.6-2~ - _ZN6TagLib3MP43Tag13parseFreeFormEPNS0_4AtomEPNS_4FileE@Base 1.6-2~ - _ZN6TagLib3MP43Tag13renderIntPairERKNS_10ByteVectorERNS0_4ItemE@Base 1.6-2~ - _ZN6TagLib3MP43Tag13updateOffsetsEll@Base 1.6-2~ - _ZN6TagLib3MP43Tag13updateParentsERNS_4ListIPNS0_4AtomEEEli@Base 1.6-2~ - _ZN6TagLib3MP43Tag14renderFreeFormERKNS_6StringERNS0_4ItemE@Base 1.6-2~ - _ZN6TagLib3MP43Tag23renderIntPairNoTrailingERKNS_10ByteVectorERNS0_4ItemE@Base 1.6-2~ - _ZN6TagLib3MP43Tag4saveEv@Base 1.6-2~ - _ZN6TagLib3MP43Tag7padIlstERKNS_10ByteVectorEi@Base 1.6-2~ - _ZN6TagLib3MP43Tag7saveNewERNS_10ByteVectorE@Base 1.6-2~ - _ZN6TagLib3MP43Tag7setYearEj@Base 1.6-2~ - _ZN6TagLib3MP43Tag8parseIntEPNS0_4AtomEPNS_4FileE@Base 1.6-2~ - _ZN6TagLib3MP43Tag8setAlbumERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3MP43Tag8setGenreERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3MP43Tag8setTitleERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3MP43Tag8setTrackEj@Base 1.6-2~ - _ZN6TagLib3MP43Tag9parseBoolEPNS0_4AtomEPNS_4FileE@Base 1.6-2~ - _ZN6TagLib3MP43Tag9parseCovrEPNS0_4AtomEPNS_4FileE@Base 1.6.1 - _ZN6TagLib3MP43Tag9parseDataEPNS0_4AtomEPNS_4FileEib@Base 1.6-2~ - _ZN6TagLib3MP43Tag9parseGnreEPNS0_4AtomEPNS_4FileE@Base 1.6-2~ - _ZN6TagLib3MP43Tag9parseTextEPNS0_4AtomEPNS_4FileEi@Base 1.6-2~ - _ZN6TagLib3MP43Tag9renderIntERKNS_10ByteVectorERNS0_4ItemE@Base 1.6-2~ - _ZN6TagLib3MP43Tag9setArtistERKNS_6StringE@Base 1.6-2~ - _ZN6TagLib3MP43TagC1EPNS_4FileEPNS0_5AtomsE@Base 1.6-2~ - _ZN6TagLib3MP43TagC2EPNS_4FileEPNS0_5AtomsE@Base 1.6-2~ - _ZN6TagLib3MP43TagD0Ev@Base 1.6-2~ - _ZN6TagLib3MP43TagD1Ev@Base 1.6-2~ - _ZN6TagLib3MP43TagD2Ev@Base 1.6-2~ - _ZN6TagLib3MP44File10checkValidERKNS_4ListIPNS0_4AtomEEE@Base 1.6.1 - _ZN6TagLib3MP44File4readEbNS_15AudioProperties9ReadStyleE@Base 1.6-2~ - _ZN6TagLib3MP44File4saveEv@Base 1.6-2~ - _ZN6TagLib3MP44FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.6-2~ - _ZN6TagLib3MP44FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.6-2~ - _ZN6TagLib3MP44FileD0Ev@Base 1.6-2~ - _ZN6TagLib3MP44FileD1Ev@Base 1.6-2~ - _ZN6TagLib3MP44FileD2Ev@Base 1.6-2~ - _ZN6TagLib3MP44ItemC1ERKNS_10StringListE@Base 1.6-2~ - _ZN6TagLib3MP44ItemC1ERKNS_4ListINS0_8CoverArtEEE@Base 1.6.1 - _ZN6TagLib3MP44ItemC1ERKS1_@Base 1.6-2~ - _ZN6TagLib3MP44ItemC1Eb@Base 1.6-2~ - _ZN6TagLib3MP44ItemC1Ei@Base 1.6-2~ - _ZN6TagLib3MP44ItemC1Eii@Base 1.6-2~ - _ZN6TagLib3MP44ItemC1Ev@Base 1.6-2~ - _ZN6TagLib3MP44ItemC2ERKNS_10StringListE@Base 1.6-2~ - _ZN6TagLib3MP44ItemC2ERKNS_4ListINS0_8CoverArtEEE@Base 1.6.1 - _ZN6TagLib3MP44ItemC2ERKS1_@Base 1.6-2~ - _ZN6TagLib3MP44ItemC2Eb@Base 1.6-2~ - _ZN6TagLib3MP44ItemC2Ei@Base 1.6-2~ - _ZN6TagLib3MP44ItemC2Eii@Base 1.6-2~ - _ZN6TagLib3MP44ItemC2Ev@Base 1.6-2~ - _ZN6TagLib3MP44ItemD1Ev@Base 1.6-2~ - _ZN6TagLib3MP44ItemD2Ev@Base 1.6-2~ - _ZN6TagLib3MP44ItemaSERKS1_@Base 1.6-2~ - _ZN6TagLib3MP48CoverArtC1ENS1_6FormatERKNS_10ByteVectorE@Base 1.6.1 - _ZN6TagLib3MP48CoverArtC1ERKS1_@Base 1.6.1 - _ZN6TagLib3MP48CoverArtC2ENS1_6FormatERKNS_10ByteVectorE@Base 1.6.1 - _ZN6TagLib3MP48CoverArtC2ERKS1_@Base 1.6.1 - _ZN6TagLib3MP48CoverArtD1Ev@Base 1.6.1 - _ZN6TagLib3MP48CoverArtD2Ev@Base 1.6.1 - _ZN6TagLib3MP48CoverArtaSERKS1_@Base 1.6.1 - _ZN6TagLib3MPC10Properties4readEv@Base 1.4 1 - _ZN6TagLib3MPC10PropertiesC1ERKNS_10ByteVectorElNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib3MPC10PropertiesC2ERKNS_10ByteVectorElNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib3MPC10PropertiesD0Ev@Base 1.4 1 - _ZN6TagLib3MPC10PropertiesD1Ev@Base 1.4 1 - _ZN6TagLib3MPC10PropertiesD2Ev@Base 1.4 1 - _ZN6TagLib3MPC4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib3MPC4File4saveEv@Base 1.4 1 - _ZN6TagLib3MPC4File5stripEi@Base 1.5 - _ZN6TagLib3MPC4File6APETagEb@Base 1.4 1 - _ZN6TagLib3MPC4File6removeEi@Base 1.4 1 - _ZN6TagLib3MPC4File7findAPEEv@Base 1.4 1 - _ZN6TagLib3MPC4File8ID3v1TagEb@Base 1.4 1 - _ZN6TagLib3MPC4File9findID3v1Ev@Base 1.4 1 - _ZN6TagLib3MPC4File9findID3v2Ev@Base 1.4 1 - _ZN6TagLib3MPC4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib3MPC4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib3MPC4FileD0Ev@Base 1.4 1 - _ZN6TagLib3MPC4FileD1Ev@Base 1.4 1 - _ZN6TagLib3MPC4FileD2Ev@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeader14setPacketSizesERKNS_4ListIiEE@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeader19setLastPageOfStreamEb@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeader20setFirstPageOfStreamEb@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeader21setPageSequenceNumberEi@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeader21setStreamSerialNumberEj@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeader22setLastPacketCompletedEb@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeader23setFirstPacketContinuedEb@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeader27setAbsoluteGranularPositionEx@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeader4readEv@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeaderC1EPNS0_4FileEl@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeaderC2EPNS0_4FileEl@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeaderD0Ev@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeaderD1Ev@Base 1.4 1 - _ZN6TagLib3Ogg10PageHeaderD2Ev@Base 1.4 1 - _ZN6TagLib3Ogg11XiphComment10setCommentERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3Ogg11XiphComment11removeFieldERKNS_6StringES4_@Base 1.4 1 - _ZN6TagLib3Ogg11XiphComment5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib3Ogg11XiphComment7setYearEj@Base 1.4 1 - _ZN6TagLib3Ogg11XiphComment8addFieldERKNS_6StringES4_b@Base 1.4 1 - _ZN6TagLib3Ogg11XiphComment8setAlbumERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3Ogg11XiphComment8setGenreERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3Ogg11XiphComment8setTitleERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3Ogg11XiphComment8setTrackEj@Base 1.4 1 - _ZN6TagLib3Ogg11XiphComment9setArtistERKNS_6StringE@Base 1.4 1 - _ZN6TagLib3Ogg11XiphCommentC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib3Ogg11XiphCommentC1Ev@Base 1.4 1 - _ZN6TagLib3Ogg11XiphCommentC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib3Ogg11XiphCommentC2Ev@Base 1.4 1 - _ZN6TagLib3Ogg11XiphCommentD0Ev@Base 1.4 1 - _ZN6TagLib3Ogg11XiphCommentD1Ev@Base 1.4 1 - _ZN6TagLib3Ogg11XiphCommentD2Ev@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4File12streamLengthEv@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4File14streamInfoDataEv@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4File15xiphCommentDataEv@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4File4saveEv@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4File4scanEv@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4FileD0Ev@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4FileD1Ev@Base 1.4 1 - _ZN6TagLib3Ogg4FLAC4FileD2Ev@Base 1.4 1 - _ZN6TagLib3Ogg4File14lastPageHeaderEv@Base 1.4 1 - _ZN6TagLib3Ogg4File14writePageGroupERKNS_4ListIiEE@Base 1.4 1 - _ZN6TagLib3Ogg4File15firstPageHeaderEv@Base 1.4 1 - _ZN6TagLib3Ogg4File4saveEv@Base 1.4 1 - _ZN6TagLib3Ogg4File6packetEj@Base 1.4 1 - _ZN6TagLib3Ogg4File8nextPageEv@Base 1.4 1 - _ZN6TagLib3Ogg4File9setPacketEjRKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib3Ogg4FileC1EPKc@Base 1.4 1 - _ZN6TagLib3Ogg4FileC2EPKc@Base 1.4 1 - _ZN6TagLib3Ogg4FileD0Ev@Base 1.4 1 - _ZN6TagLib3Ogg4FileD1Ev@Base 1.4 1 - _ZN6TagLib3Ogg4FileD2Ev@Base 1.4 1 - _ZN6TagLib3Ogg4Page19setFirstPacketIndexEi@Base 1.4 1 - _ZN6TagLib3Ogg4Page32getCopyWithNewPageSequenceNumberEi@Base 1.6 - _ZN6TagLib3Ogg4Page8paginateERKNS_14ByteVectorListENS1_18PaginationStrategyEjibbb@Base 1.4 1 - _ZN6TagLib3Ogg4PageC1EPNS0_4FileEl@Base 1.4 1 - _ZN6TagLib3Ogg4PageC1ERKNS_14ByteVectorListEjibbb@Base 1.4 1 - _ZN6TagLib3Ogg4PageC2EPNS0_4FileEl@Base 1.4 1 - _ZN6TagLib3Ogg4PageC2ERKNS_14ByteVectorListEjibbb@Base 1.4 1 - _ZN6TagLib3Ogg4PageD0Ev@Base 1.4 1 - _ZN6TagLib3Ogg4PageD1Ev@Base 1.4 1 - _ZN6TagLib3Ogg4PageD2Ev@Base 1.4 1 - _ZN6TagLib3Ogg5Speex10Properties4readEv@Base 1.5 - _ZN6TagLib3Ogg5Speex10PropertiesC1EPNS1_4FileENS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib3Ogg5Speex10PropertiesC2EPNS1_4FileENS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib3Ogg5Speex10PropertiesD0Ev@Base 1.5 - _ZN6TagLib3Ogg5Speex10PropertiesD1Ev@Base 1.5 - _ZN6TagLib3Ogg5Speex10PropertiesD2Ev@Base 1.5 - _ZN6TagLib3Ogg5Speex4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib3Ogg5Speex4File4saveEv@Base 1.5 - _ZN6TagLib3Ogg5Speex4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib3Ogg5Speex4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib3Ogg5Speex4FileD0Ev@Base 1.5 - _ZN6TagLib3Ogg5Speex4FileD1Ev@Base 1.5 - _ZN6TagLib3Ogg5Speex4FileD2Ev@Base 1.5 - _ZN6TagLib3Tag9duplicateEPKS0_PS0_b@Base 1.4 1 - _ZN6TagLib3TagC1Ev@Base 1.4 1 - _ZN6TagLib3TagC2Ev@Base 1.4 1 - _ZN6TagLib3TagD0Ev@Base 1.4 1 - _ZN6TagLib3TagD1Ev@Base 1.4 1 - _ZN6TagLib3TagD2Ev@Base 1.4 1 - _ZN6TagLib4FLAC10Properties4readEv@Base 1.4 1 - _ZN6TagLib4FLAC10PropertiesC1ENS_10ByteVectorElNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4FLAC10PropertiesC1EPNS0_4FileENS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4FLAC10PropertiesC2ENS_10ByteVectorElNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4FLAC10PropertiesC2EPNS0_4FileENS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4FLAC10PropertiesD0Ev@Base 1.4 1 - _ZN6TagLib4FLAC10PropertiesD1Ev@Base 1.4 1 - _ZN6TagLib4FLAC10PropertiesD2Ev@Base 1.4 1 - _ZN6TagLib4FLAC13MetadataBlockC1Ev@Base 1.7 - _ZN6TagLib4FLAC13MetadataBlockC2Ev@Base 1.7 - _ZN6TagLib4FLAC13MetadataBlockD0Ev@Base 1.7 - _ZN6TagLib4FLAC13MetadataBlockD1Ev@Base 1.7 - _ZN6TagLib4FLAC13MetadataBlockD2Ev@Base 1.7 - _ZN6TagLib4FLAC20UnknownMetadataBlock7setCodeEi@Base 1.7 - _ZN6TagLib4FLAC20UnknownMetadataBlock7setDataERKNS_10ByteVectorE@Base 1.7 - _ZN6TagLib4FLAC20UnknownMetadataBlockC1EiRKNS_10ByteVectorE@Base 1.7 - _ZN6TagLib4FLAC20UnknownMetadataBlockC2EiRKNS_10ByteVectorE@Base 1.7 - _ZN6TagLib4FLAC20UnknownMetadataBlockD0Ev@Base 1.7 - _ZN6TagLib4FLAC20UnknownMetadataBlockD1Ev@Base 1.7 - _ZN6TagLib4FLAC20UnknownMetadataBlockD2Ev@Base 1.7 - _ZN6TagLib4FLAC4File10addPictureEPNS0_7PictureE@Base 1.7 - _ZN6TagLib4FLAC4File11pictureListEv@Base 1.7 - _ZN6TagLib4FLAC4File11xiphCommentEb@Base 1.4 1 - _ZN6TagLib4FLAC4File12streamLengthEv@Base 1.4 1 - _ZN6TagLib4FLAC4File14removePicturesEv@Base 1.7 - _ZN6TagLib4FLAC4File14streamInfoDataEv@Base 1.4 1 - _ZN6TagLib4FLAC4File20setID3v2FrameFactoryEPKNS_5ID3v212FrameFactoryE@Base 1.4 1 - _ZN6TagLib4FLAC4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4FLAC4File4saveEv@Base 1.4 1 - _ZN6TagLib4FLAC4File4scanEv@Base 1.4 1 - _ZN6TagLib4FLAC4File8ID3v1TagEb@Base 1.4 1 - _ZN6TagLib4FLAC4File8ID3v2TagEb@Base 1.4 1 - _ZN6TagLib4FLAC4File9findID3v1Ev@Base 1.4 1 - _ZN6TagLib4FLAC4File9findID3v2Ev@Base 1.4 1 - _ZN6TagLib4FLAC4FileC1EPKcPNS_5ID3v212FrameFactoryEbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4FLAC4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4FLAC4FileC2EPKcPNS_5ID3v212FrameFactoryEbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4FLAC4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4FLAC4FileD0Ev@Base 1.4 1 - _ZN6TagLib4FLAC4FileD1Ev@Base 1.4 1 - _ZN6TagLib4FLAC4FileD2Ev@Base 1.4 1 - _ZN6TagLib4FLAC7Picture11setMimeTypeERKNS_6StringE@Base 1.7 - _ZN6TagLib4FLAC7Picture12setNumColorsEi@Base 1.7 - _ZN6TagLib4FLAC7Picture13setColorDepthEi@Base 1.7 - _ZN6TagLib4FLAC7Picture14setDescriptionERKNS_6StringE@Base 1.7 - _ZN6TagLib4FLAC7Picture5parseERKNS_10ByteVectorE@Base 1.7 - _ZN6TagLib4FLAC7Picture7setDataERKNS_10ByteVectorE@Base 1.7 - _ZN6TagLib4FLAC7Picture7setTypeENS1_4TypeE@Base 1.7 - _ZN6TagLib4FLAC7Picture8setWidthEi@Base 1.7 - _ZN6TagLib4FLAC7Picture9setHeightEi@Base 1.7 - _ZN6TagLib4FLAC7PictureC1ERKNS_10ByteVectorE@Base 1.7 - _ZN6TagLib4FLAC7PictureC1Ev@Base 1.7 - _ZN6TagLib4FLAC7PictureC2ERKNS_10ByteVectorE@Base 1.7 - _ZN6TagLib4FLAC7PictureC2Ev@Base 1.7 - _ZN6TagLib4FLAC7PictureD0Ev@Base 1.7 - _ZN6TagLib4FLAC7PictureD1Ev@Base 1.7 - _ZN6TagLib4FLAC7PictureD2Ev@Base 1.7 - _ZN6TagLib4File10bufferSizeEv@Base 1.4 1 - _ZN6TagLib4File10isReadableEPKc@Base 1.4 1 - _ZN6TagLib4File10isWritableEPKc@Base 1.4 1 - _ZN6TagLib4File10writeBlockERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib4File11FilePrivateC1EPKc@Base 1.5 - _ZN6TagLib4File11FilePrivateC2EPKc@Base 1.5 - _ZN6TagLib4File11removeBlockEmm@Base 1.4 1 - _ZN6TagLib4File4findERKNS_10ByteVectorElS3_@Base 1.4 1 - _ZN6TagLib4File4seekElNS0_8PositionE@Base 1.4 1 - _ZN6TagLib4File5clearEv@Base 1.4 1 - _ZN6TagLib4File5rfindERKNS_10ByteVectorElS3_@Base 1.4 1 - _ZN6TagLib4File6insertERKNS_10ByteVectorEmm@Base 1.4 1 - _ZN6TagLib4File6lengthEv@Base 1.4 1 - _ZN6TagLib4File8setValidEb@Base 1.4 1 - _ZN6TagLib4File8truncateEl@Base 1.4 1 - _ZN6TagLib4File9readBlockEm@Base 1.4 1 - _ZN6TagLib4FileC1EPKc@Base 1.4 1 - _ZN6TagLib4FileC2EPKc@Base 1.4 1 - _ZN6TagLib4FileD0Ev@Base 1.4 1 - _ZN6TagLib4FileD1Ev@Base 1.4 1 - _ZN6TagLib4FileD2Ev@Base 1.4 1 - _ZN6TagLib4MPEG10Properties4readEv@Base 1.4 1 - _ZN6TagLib4MPEG10PropertiesC1EPNS0_4FileENS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4MPEG10PropertiesC2EPNS0_4FileENS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4MPEG10PropertiesD0Ev@Base 1.4 1 - _ZN6TagLib4MPEG10PropertiesD1Ev@Base 1.4 1 - _ZN6TagLib4MPEG10PropertiesD2Ev@Base 1.4 1 - _ZN6TagLib4MPEG10XingHeader16xingHeaderOffsetENS0_6Header7VersionENS2_11ChannelModeE@Base 1.4 1 - _ZN6TagLib4MPEG10XingHeader5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib4MPEG10XingHeaderC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib4MPEG10XingHeaderC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib4MPEG10XingHeaderD0Ev@Base 1.4 1 - _ZN6TagLib4MPEG10XingHeaderD1Ev@Base 1.4 1 - _ZN6TagLib4MPEG10XingHeaderD2Ev@Base 1.4 1 - _ZN6TagLib4MPEG4File15lastFrameOffsetEv@Base 1.4 1 - _ZN6TagLib4MPEG4File15nextFrameOffsetEl@Base 1.4 1 - _ZN6TagLib4MPEG4File15secondSynchByteEc@Base 1.4 1 - _ZN6TagLib4MPEG4File16firstFrameOffsetEv@Base 1.4 1 - _ZN6TagLib4MPEG4File19previousFrameOffsetEl@Base 1.4 1 - _ZN6TagLib4MPEG4File20setID3v2FrameFactoryEPKNS_5ID3v212FrameFactoryE@Base 1.4 1 - _ZN6TagLib4MPEG4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4MPEG4File4saveEi@Base 1.4 1 - _ZN6TagLib4MPEG4File4saveEib@Base 1.4 1 - _ZN6TagLib4MPEG4File4saveEv@Base 1.4 1 - _ZN6TagLib4MPEG4File5stripEi@Base 1.4 1 - _ZN6TagLib4MPEG4File5stripEib@Base 1.4 1 - _ZN6TagLib4MPEG4File6APETagEb@Base 1.4 1 - _ZN6TagLib4MPEG4File7findAPEEv@Base 1.4 1 - _ZN6TagLib4MPEG4File8ID3v1TagEb@Base 1.4 1 - _ZN6TagLib4MPEG4File8ID3v2TagEb@Base 1.4 1 - _ZN6TagLib4MPEG4File9findID3v1Ev@Base 1.4 1 - _ZN6TagLib4MPEG4File9findID3v2Ev@Base 1.4 1 - _ZN6TagLib4MPEG4FileC1EPKcPNS_5ID3v212FrameFactoryEbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4MPEG4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4MPEG4FileC2EPKcPNS_5ID3v212FrameFactoryEbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4MPEG4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib4MPEG4FileD0Ev@Base 1.4 1 - _ZN6TagLib4MPEG4FileD1Ev@Base 1.4 1 - _ZN6TagLib4MPEG4FileD2Ev@Base 1.4 1 - _ZN6TagLib4MPEG6Header5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib4MPEG6HeaderC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib4MPEG6HeaderC1ERKS1_@Base 1.4 1 - _ZN6TagLib4MPEG6HeaderC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib4MPEG6HeaderC2ERKS1_@Base 1.4 1 - _ZN6TagLib4MPEG6HeaderD0Ev@Base 1.4 1 - _ZN6TagLib4MPEG6HeaderD1Ev@Base 1.4 1 - _ZN6TagLib4MPEG6HeaderD2Ev@Base 1.4 1 - _ZN6TagLib4MPEG6HeaderaSERKS1_@Base 1.4 1 - _ZN6TagLib4RIFF3WAV10Properties4readERKNS_10ByteVectorE@Base 1.6 - _ZN6TagLib4RIFF3WAV10PropertiesC1ERKNS_10ByteVectorENS_15AudioProperties9ReadStyleE@Base 1.6 - _ZN6TagLib4RIFF3WAV10PropertiesC1ERKNS_10ByteVectorEjNS_15AudioProperties9ReadStyleE@Base 1.7 - _ZN6TagLib4RIFF3WAV10PropertiesC2ERKNS_10ByteVectorENS_15AudioProperties9ReadStyleE@Base 1.6 - _ZN6TagLib4RIFF3WAV10PropertiesC2ERKNS_10ByteVectorEjNS_15AudioProperties9ReadStyleE@Base 1.7 - _ZN6TagLib4RIFF3WAV10PropertiesD0Ev@Base 1.6 - _ZN6TagLib4RIFF3WAV10PropertiesD1Ev@Base 1.6 - _ZN6TagLib4RIFF3WAV10PropertiesD2Ev@Base 1.6 - _ZN6TagLib4RIFF3WAV4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.6 - _ZN6TagLib4RIFF3WAV4File4saveEv@Base 1.6 - _ZN6TagLib4RIFF3WAV4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.6 - _ZN6TagLib4RIFF3WAV4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.6 - _ZN6TagLib4RIFF3WAV4FileD0Ev@Base 1.6 - _ZN6TagLib4RIFF3WAV4FileD1Ev@Base 1.6 - _ZN6TagLib4RIFF3WAV4FileD2Ev@Base 1.6 - _ZN6TagLib4RIFF4AIFF10Properties4readERKNS_10ByteVectorE@Base 1.6 - _ZN6TagLib4RIFF4AIFF10PropertiesC1ERKNS_10ByteVectorENS_15AudioProperties9ReadStyleE@Base 1.6 - _ZN6TagLib4RIFF4AIFF10PropertiesC2ERKNS_10ByteVectorENS_15AudioProperties9ReadStyleE@Base 1.6 - _ZN6TagLib4RIFF4AIFF10PropertiesD0Ev@Base 1.6 - _ZN6TagLib4RIFF4AIFF10PropertiesD1Ev@Base 1.6 - _ZN6TagLib4RIFF4AIFF10PropertiesD2Ev@Base 1.6 - _ZN6TagLib4RIFF4AIFF4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.6 - _ZN6TagLib4RIFF4AIFF4File4saveEv@Base 1.6 - _ZN6TagLib4RIFF4AIFF4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.6 - _ZN6TagLib4RIFF4AIFF4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.6 - _ZN6TagLib4RIFF4AIFF4FileD0Ev@Base 1.6 - _ZN6TagLib4RIFF4AIFF4FileD1Ev@Base 1.6 - _ZN6TagLib4RIFF4AIFF4FileD2Ev@Base 1.6 - _ZN6TagLib4RIFF4File10writeChunkERKNS_10ByteVectorES4_mmj@Base 1.7 - _ZN6TagLib4RIFF4File12setChunkDataERKNS_10ByteVectorES4_@Base 1.6 - _ZN6TagLib4RIFF4File4readEv@Base 1.6 - _ZN6TagLib4RIFF4File9chunkDataEj@Base 1.6 - _ZN6TagLib4RIFF4FileC1EPKcNS1_10EndiannessE@Base 1.6 - _ZN6TagLib4RIFF4FileC2EPKcNS1_10EndiannessE@Base 1.6 - _ZN6TagLib4RIFF4FileD0Ev@Base 1.6 - _ZN6TagLib4RIFF4FileD1Ev@Base 1.6 - _ZN6TagLib4RIFF4FileD2Ev@Base 1.6 - _ZN6TagLib5ID3v110genreIndexERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v13Tag10TagPrivate13stringHandlerE@Base 1.4 1 - _ZN6TagLib5ID3v13Tag10setCommentERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v13Tag14fileIdentifierEv@Base 1.4 1 - _ZN6TagLib5ID3v13Tag16setStringHandlerEPKNS0_13StringHandlerE@Base 1.4 1 - _ZN6TagLib5ID3v13Tag4readEv@Base 1.4 1 - _ZN6TagLib5ID3v13Tag5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v13Tag7setYearEj@Base 1.4 1 - _ZN6TagLib5ID3v13Tag8setAlbumERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v13Tag8setGenreERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v13Tag8setTitleERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v13Tag8setTrackEj@Base 1.4 1 - _ZN6TagLib5ID3v13Tag9setArtistERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v13TagC1EPNS_4FileEl@Base 1.4 1 - _ZN6TagLib5ID3v13TagC1Ev@Base 1.4 1 - _ZN6TagLib5ID3v13TagC2EPNS_4FileEl@Base 1.4 1 - _ZN6TagLib5ID3v13TagC2Ev@Base 1.4 1 - _ZN6TagLib5ID3v13TagD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v13TagD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v13TagD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v15genreEi@Base 1.4 1 - _ZN6TagLib5ID3v18genreMapEv@Base 1.4 1 - _ZN6TagLib5ID3v19genreListEv@Base 1.4 1 - _ZN6TagLib5ID3v212FrameFactory22setDefaultTextEncodingENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v212FrameFactory7factoryE@Base 1.4 1 - _ZN6TagLib5ID3v212FrameFactory8instanceEv@Base 1.4 1 - _ZN6TagLib5ID3v212FrameFactoryC1Ev@Base 1.4 1 - _ZN6TagLib5ID3v212FrameFactoryC2Ev@Base 1.4 1 - _ZN6TagLib5ID3v212FrameFactoryD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v212FrameFactoryD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v212FrameFactoryD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v212PrivateFrame11parseFieldsERKNS_10ByteVectorE@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrame7setDataERKNS_10ByteVectorE@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrame8setOwnerERKNS_6StringE@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrameC1ERKNS_10ByteVectorE@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrameC1Ev@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrameC2ERKNS_10ByteVectorE@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrameC2Ev@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrameD0Ev@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrameD1Ev@Base 1.6 - _ZN6TagLib5ID3v212PrivateFrameD2Ev@Base 1.6 - _ZN6TagLib5ID3v212UnknownFrame11parseFieldsERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v212UnknownFrameC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v212UnknownFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v212UnknownFrameC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v212UnknownFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v212UnknownFrameD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v212UnknownFrameD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v212UnknownFrameD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v212UrlLinkFrame11parseFieldsERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v212UrlLinkFrame6setUrlERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v212UrlLinkFrame7setTextERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v212UrlLinkFrameC1ERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v212UrlLinkFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.5 - _ZN6TagLib5ID3v212UrlLinkFrameC2ERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v212UrlLinkFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.5 - _ZN6TagLib5ID3v212UrlLinkFrameD0Ev@Base 1.5 - _ZN6TagLib5ID3v212UrlLinkFrameD1Ev@Base 1.5 - _ZN6TagLib5ID3v212UrlLinkFrameD2Ev@Base 1.5 - _ZN6TagLib5ID3v213CommentsFrame11parseFieldsERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrame11setLanguageERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrame14setDescriptionERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrame15setTextEncodingENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrame17findByDescriptionEPKNS0_3TagERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v213CommentsFrame7setTextERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrameC1ENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrameC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrameC2ENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrameC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrameD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrameD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v213CommentsFrameD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v214ExtendedHeader5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v214ExtendedHeader7setDataERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v214ExtendedHeaderC1Ev@Base 1.4 1 - _ZN6TagLib5ID3v214ExtendedHeaderC2Ev@Base 1.4 1 - _ZN6TagLib5ID3v214ExtendedHeaderD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v214ExtendedHeaderD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v214ExtendedHeaderD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v216UserUrlLinkFrame11parseFieldsERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrame14setDescriptionERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrame15setTextEncodingENS_6String4TypeE@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrameC1ENS_6String4TypeE@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrameC1ERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrameC2ENS_6String4TypeE@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrameC2ERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrameD0Ev@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrameD1Ev@Base 1.5 - _ZN6TagLib5ID3v216UserUrlLinkFrameD2Ev@Base 1.5 - _ZN6TagLib5ID3v218PopularimeterFrame10setCounterEj@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrame11parseFieldsERKNS_10ByteVectorE@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrame8setEmailERKNS_6StringE@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrame9setRatingEi@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrameC1ERKNS_10ByteVectorE@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrameC1Ev@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrameC2ERKNS_10ByteVectorE@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrameC2Ev@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrameD0Ev@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrameD1Ev@Base 1.6 - _ZN6TagLib5ID3v218PopularimeterFrameD2Ev@Base 1.6 - _ZN6TagLib5ID3v219RelativeVolumeFrame11parseFieldsERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrame13setPeakVolumeERKNS1_10PeakVolumeE@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrame13setPeakVolumeERKNS1_10PeakVolumeENS1_11ChannelTypeE@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrame14setChannelTypeENS1_11ChannelTypeE@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrame17setIdentificationERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v219RelativeVolumeFrame19setVolumeAdjustmentEf@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrame19setVolumeAdjustmentEfNS1_11ChannelTypeE@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrame24setVolumeAdjustmentIndexEs@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrame24setVolumeAdjustmentIndexEsNS1_11ChannelTypeE@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrameC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrameC1Ev@Base 1.5 - _ZN6TagLib5ID3v219RelativeVolumeFrameC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrameC2Ev@Base 1.5 - _ZN6TagLib5ID3v219RelativeVolumeFrameD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrameD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v219RelativeVolumeFrameD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrame10setPictureERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrame11parseFieldsERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrame11setMimeTypeERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrame14setDescriptionERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrame15setTextEncodingENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrame7setTypeENS1_4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrameC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrameC1Ev@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrameC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrameC2Ev@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrameD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrameD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v220AttachedPictureFrameD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v223AttachedPictureFrameV2211parseFieldsERKNS_10ByteVectorE@Base 1.6 - _ZN6TagLib5ID3v223AttachedPictureFrameV22C1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.6 - _ZN6TagLib5ID3v223AttachedPictureFrameV22C2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.6 - _ZN6TagLib5ID3v223AttachedPictureFrameV22D0Ev@Base 1.7-2~ - _ZN6TagLib5ID3v223AttachedPictureFrameV22D1Ev@Base 1.7-2~ - _ZN6TagLib5ID3v223AttachedPictureFrameV22D2Ev@Base 1.7-2~ - _ZN6TagLib5ID3v223TextIdentificationFrame11parseFieldsERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrame15setTextEncodingENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrame7setTextERKNS_10StringListE@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrame7setTextERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrameC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrameC1ERKNS_10ByteVectorENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrameC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrameC2ERKNS_10ByteVectorENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrameD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrameD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v223TextIdentificationFrameD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrame11parseFieldsERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrame13setIdentifierERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrame8setOwnerERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrameC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrameC1ERKNS_6StringERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrameC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrameC2ERKNS_6StringERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrameD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrameD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v225UniqueFileIdentifierFrameD2Ev@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrame11parseFieldsERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrame11setLanguageERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrame14setDescriptionERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrame15setTextEncodingENS_6String4TypeE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrame7setTextERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrameC1ENS_6String4TypeE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrameC1ERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrameC2ENS_6String4TypeE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrameC2ERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrameD0Ev@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrameD1Ev@Base 1.5 - _ZN6TagLib5ID3v225UnsynchronizedLyricsFrameD2Ev@Base 1.5 - _ZN6TagLib5ID3v227UserTextIdentificationFrame11checkFieldsEv@Base 1.5 - _ZN6TagLib5ID3v227UserTextIdentificationFrame14setDescriptionERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v227UserTextIdentificationFrame4findEPNS0_3TagERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v227UserTextIdentificationFrame7setTextERKNS_10StringListE@Base 1.4 1 - _ZN6TagLib5ID3v227UserTextIdentificationFrame7setTextERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v227UserTextIdentificationFrameC1ENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v227UserTextIdentificationFrameC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v227UserTextIdentificationFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v227UserTextIdentificationFrameC2ENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v227UserTextIdentificationFrameC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v227UserTextIdentificationFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v227UserTextIdentificationFrameD0Ev@Base 1.7-2~ - _ZN6TagLib5ID3v227UserTextIdentificationFrameD1Ev@Base 1.7-2~ - _ZN6TagLib5ID3v227UserTextIdentificationFrameD2Ev@Base 1.7-2~ - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrame11parseFieldsERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrame11setFileNameERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrame11setMimeTypeERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrame14setDescriptionERKNS_6StringE@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrame15setTextEncodingENS_6String4TypeE@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrame9setObjectERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrameC1ERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrameC1ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrameC1Ev@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrameC2ERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrameC2ERKNS_10ByteVectorEPNS0_5Frame6HeaderE@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrameC2Ev@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrameD0Ev@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrameD1Ev@Base 1.5 - _ZN6TagLib5ID3v230GeneralEncapsulatedObjectFrameD2Ev@Base 1.5 - _ZN6TagLib5ID3v23Tag10setCommentERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v23Tag11removeFrameEPNS0_5FrameEb@Base 1.4 1 - _ZN6TagLib5ID3v23Tag12removeFramesERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v23Tag12setTextFrameERKNS_10ByteVectorERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v23Tag4readEv@Base 1.4 1 - _ZN6TagLib5ID3v23Tag5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v23Tag7setYearEj@Base 1.4 1 - _ZN6TagLib5ID3v23Tag8addFrameEPNS0_5FrameE@Base 1.4 1 - _ZN6TagLib5ID3v23Tag8setAlbumERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v23Tag8setGenreERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v23Tag8setTitleERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v23Tag8setTrackEj@Base 1.4 1 - _ZN6TagLib5ID3v23Tag9setArtistERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v23TagC1EPNS_4FileElPKNS0_12FrameFactoryE@Base 1.4 1 - _ZN6TagLib5ID3v23TagC1Ev@Base 1.4 1 - _ZN6TagLib5ID3v23TagC2EPNS_4FileElPKNS0_12FrameFactoryE@Base 1.4 1 - _ZN6TagLib5ID3v23TagC2Ev@Base 1.4 1 - _ZN6TagLib5ID3v23TagD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v23TagD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v23TagD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v25Frame10headerSizeEj@Base 1.4 1 - _ZN6TagLib5ID3v25Frame10headerSizeEv@Base 1.4 1 - _ZN6TagLib5ID3v25Frame13checkEncodingERKNS_10StringListENS_6String4TypeE@Base 1.5 - _ZN6TagLib5ID3v25Frame13textDelimiterENS_6String4TypeE@Base 1.4 1 - _ZN6TagLib5ID3v25Frame15readStringFieldERKNS_10ByteVectorENS_6String4TypeEPi@Base 1.5 - _ZN6TagLib5ID3v25Frame5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6Header10setFrameIDERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6Header12setFrameSizeEj@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6Header23setTagAlterPreservationEb@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6Header4sizeEj@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6Header4sizeEv@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6Header7setDataERKNS_10ByteVectorEb@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6Header7setDataERKNS_10ByteVectorEj@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6HeaderC1ERKNS_10ByteVectorEb@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6HeaderC1ERKNS_10ByteVectorEj@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6HeaderC2ERKNS_10ByteVectorEb@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6HeaderC2ERKNS_10ByteVectorEj@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6HeaderD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6HeaderD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v25Frame6HeaderD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v25Frame7setDataERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v25Frame7setTextERKNS_6StringE@Base 1.4 1 - _ZN6TagLib5ID3v25Frame9setHeaderEPNS1_6HeaderEb@Base 1.4 1 - _ZN6TagLib5ID3v25FrameC1EPNS1_6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v25FrameC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v25FrameC2EPNS1_6HeaderE@Base 1.4 1 - _ZN6TagLib5ID3v25FrameC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v25FrameD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v25FrameD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v25FrameD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v26Footer4sizeEv@Base 1.4 1 - _ZN6TagLib5ID3v26FooterC1Ev@Base 1.4 1 - _ZN6TagLib5ID3v26FooterC2Ev@Base 1.4 1 - _ZN6TagLib5ID3v26FooterD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v26FooterD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v26FooterD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v26Header10setTagSizeEj@Base 1.4 1 - _ZN6TagLib5ID3v26Header14fileIdentifierEv@Base 1.4 1 - _ZN6TagLib5ID3v26Header15setMajorVersionEj@Base 1.5 - _ZN6TagLib5ID3v26Header4sizeEv@Base 1.4 1 - _ZN6TagLib5ID3v26Header5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v26Header7setDataERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v26HeaderC1ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v26HeaderC1Ev@Base 1.4 1 - _ZN6TagLib5ID3v26HeaderC2ERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v26HeaderC2Ev@Base 1.4 1 - _ZN6TagLib5ID3v26HeaderD0Ev@Base 1.4 1 - _ZN6TagLib5ID3v26HeaderD1Ev@Base 1.4 1 - _ZN6TagLib5ID3v26HeaderD2Ev@Base 1.4 1 - _ZN6TagLib5ID3v29SynchData6decodeERKNS_10ByteVectorE@Base 1.5 - _ZN6TagLib5ID3v29SynchData6toUIntERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib5ID3v29SynchData8fromUIntEj@Base 1.4 1 - _ZN6TagLib6String3endEv@Base 1.4 1 - _ZN6TagLib6String4nullE@Base 1.4 1 - _ZN6TagLib6String5beginEv@Base 1.4 1 - _ZN6TagLib6String6appendERKS0_@Base 1.4 1 - _ZN6TagLib6String6detachEv@Base 1.4 1 - _ZN6TagLib6String6numberEi@Base 1.4 1 - _ZN6TagLib6String7prepareENS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC1EPKcNS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC1EPKwNS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC1ERKNS_10ByteVectorENS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC1ERKS0_@Base 1.4 1 - _ZN6TagLib6StringC1ERKSbIwSt11char_traitsIwESaIwEENS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC1ERKSsNS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC1EcNS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC1Ev@Base 1.4 1 - _ZN6TagLib6StringC1EwNS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC2EPKcNS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC2EPKwNS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC2ERKNS_10ByteVectorENS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC2ERKS0_@Base 1.4 1 - _ZN6TagLib6StringC2ERKSbIwSt11char_traitsIwESaIwEENS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC2ERKSsNS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC2EcNS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringC2Ev@Base 1.4 1 - _ZN6TagLib6StringC2EwNS0_4TypeE@Base 1.4 1 - _ZN6TagLib6StringD0Ev@Base 1.4 1 - _ZN6TagLib6StringD1Ev@Base 1.4 1 - _ZN6TagLib6StringD2Ev@Base 1.4 1 - _ZN6TagLib6StringaSEPKc@Base 1.4 1 - _ZN6TagLib6StringaSEPKw@Base 1.4 1 - _ZN6TagLib6StringaSERKNS_10ByteVectorE@Base 1.4 1 - _ZN6TagLib6StringaSERKS0_@Base 1.4 1 - _ZN6TagLib6StringaSERKSbIwSt11char_traitsIwESaIwEE@Base 1.4 1 - _ZN6TagLib6StringaSERKSs@Base 1.4 1 - _ZN6TagLib6StringaSEc@Base 1.4 1 - _ZN6TagLib6StringaSEw@Base 1.4 1 - _ZN6TagLib6StringixEi@Base 1.4 1 - _ZN6TagLib6StringpLEPKc@Base 1.4 1 - _ZN6TagLib6StringpLEPKw@Base 1.4 1 - _ZN6TagLib6StringpLERKS0_@Base 1.4 1 - _ZN6TagLib6StringpLEc@Base 1.4 1 - _ZN6TagLib6StringpLEw@Base 1.4 1 - _ZN6TagLib6Vorbis10Properties4readEv@Base 1.4 1 - _ZN6TagLib6Vorbis10PropertiesC1EPNS0_4FileENS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib6Vorbis10PropertiesC2EPNS0_4FileENS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib6Vorbis10PropertiesD0Ev@Base 1.4 1 - _ZN6TagLib6Vorbis10PropertiesD1Ev@Base 1.4 1 - _ZN6TagLib6Vorbis10PropertiesD2Ev@Base 1.4 1 - _ZN6TagLib6Vorbis4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib6Vorbis4File4saveEv@Base 1.4 1 - _ZN6TagLib6Vorbis4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib6Vorbis4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib6Vorbis4FileD0Ev@Base 1.4 1 - _ZN6TagLib6Vorbis4FileD1Ev@Base 1.4 1 - _ZN6TagLib6Vorbis4FileD2Ev@Base 1.4 1 - _ZN6TagLib7FileRef14FileRefPrivate17fileTypeResolversE@Base 1.4 1 - _ZN6TagLib7FileRef19addFileTypeResolverEPKNS0_16FileTypeResolverE@Base 1.4 1 - _ZN6TagLib7FileRef21defaultFileExtensionsEv@Base 1.4 1 - _ZN6TagLib7FileRef4saveEv@Base 1.4 1 - _ZN6TagLib7FileRef6createEPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib7FileRefC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib7FileRefC1EPNS_4FileE@Base 1.4 1 - _ZN6TagLib7FileRefC1ERKS0_@Base 1.4 1 - _ZN6TagLib7FileRefC1Ev@Base 1.4 1 - _ZN6TagLib7FileRefC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.4 1 - _ZN6TagLib7FileRefC2EPNS_4FileE@Base 1.4 1 - _ZN6TagLib7FileRefC2ERKS0_@Base 1.4 1 - _ZN6TagLib7FileRefC2Ev@Base 1.4 1 - _ZN6TagLib7FileRefD0Ev@Base 1.4 1 - _ZN6TagLib7FileRefD1Ev@Base 1.4 1 - _ZN6TagLib7FileRefD2Ev@Base 1.4 1 - _ZN6TagLib7FileRefaSERKS0_@Base 1.4 1 - _ZN6TagLib7WavPack10Properties14seekFinalIndexEv@Base 1.7 - _ZN6TagLib7WavPack10Properties4readEv@Base 1.5 - _ZN6TagLib7WavPack10PropertiesC1EPNS0_4FileElNS_15AudioProperties9ReadStyleE@Base 1.7 - _ZN6TagLib7WavPack10PropertiesC1ERKNS_10ByteVectorElNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib7WavPack10PropertiesC2EPNS0_4FileElNS_15AudioProperties9ReadStyleE@Base 1.7 - _ZN6TagLib7WavPack10PropertiesC2ERKNS_10ByteVectorElNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib7WavPack10PropertiesD0Ev@Base 1.5 - _ZN6TagLib7WavPack10PropertiesD1Ev@Base 1.5 - _ZN6TagLib7WavPack10PropertiesD2Ev@Base 1.5 - _ZN6TagLib7WavPack4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib7WavPack4File4saveEv@Base 1.5 - _ZN6TagLib7WavPack4File5stripEi@Base 1.5 - _ZN6TagLib7WavPack4File6APETagEb@Base 1.5 - _ZN6TagLib7WavPack4File7findAPEEv@Base 1.5 - _ZN6TagLib7WavPack4File8ID3v1TagEb@Base 1.5 - _ZN6TagLib7WavPack4File9findID3v1Ev@Base 1.5 - _ZN6TagLib7WavPack4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib7WavPack4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib7WavPack4FileD0Ev@Base 1.5 - _ZN6TagLib7WavPack4FileD1Ev@Base 1.5 - _ZN6TagLib7WavPack4FileD2Ev@Base 1.5 - _ZN6TagLib9TrueAudio10Properties4readEv@Base 1.5 - _ZN6TagLib9TrueAudio10PropertiesC1ERKNS_10ByteVectorElNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib9TrueAudio10PropertiesC2ERKNS_10ByteVectorElNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib9TrueAudio10PropertiesD0Ev@Base 1.5 - _ZN6TagLib9TrueAudio10PropertiesD1Ev@Base 1.5 - _ZN6TagLib9TrueAudio10PropertiesD2Ev@Base 1.5 - _ZN6TagLib9TrueAudio4File20setID3v2FrameFactoryEPKNS_5ID3v212FrameFactoryE@Base 1.5 - _ZN6TagLib9TrueAudio4File4readEbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib9TrueAudio4File4saveEv@Base 1.5 - _ZN6TagLib9TrueAudio4File5stripEi@Base 1.5 - _ZN6TagLib9TrueAudio4File8ID3v1TagEb@Base 1.5 - _ZN6TagLib9TrueAudio4File8ID3v2TagEb@Base 1.5 - _ZN6TagLib9TrueAudio4File9findID3v1Ev@Base 1.5 - _ZN6TagLib9TrueAudio4File9findID3v2Ev@Base 1.5 - _ZN6TagLib9TrueAudio4FileC1EPKcPNS_5ID3v212FrameFactoryEbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib9TrueAudio4FileC1EPKcbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib9TrueAudio4FileC2EPKcPNS_5ID3v212FrameFactoryEbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib9TrueAudio4FileC2EPKcbNS_15AudioProperties9ReadStyleE@Base 1.5 - _ZN6TagLib9TrueAudio4FileD0Ev@Base 1.5 - _ZN6TagLib9TrueAudio4FileD1Ev@Base 1.5 - _ZN6TagLib9TrueAudio4FileD2Ev@Base 1.5 - _ZNK6TagLib10ByteVector10containsAtERKS0_jjj@Base 1.4 1 - _ZNK6TagLib10ByteVector10startsWithERKS0_@Base 1.4 1 - _ZNK6TagLib10ByteVector10toLongLongEb@Base 1.4 1 - _ZNK6TagLib10ByteVector20endsWithPartialMatchERKS0_@Base 1.4 1 - _ZNK6TagLib10ByteVector2atEj@Base 1.4 1 - _ZNK6TagLib10ByteVector3endEv@Base 1.4 1 - _ZNK6TagLib10ByteVector3midEjj@Base 1.4 1 - _ZNK6TagLib10ByteVector4dataEv@Base 1.4 1 - _ZNK6TagLib10ByteVector4findERKS0_ji@Base 1.4 1 - _ZNK6TagLib10ByteVector4sizeEv@Base 1.4 1 - _ZNK6TagLib10ByteVector5beginEv@Base 1.4 1 - _ZNK6TagLib10ByteVector5rfindERKS0_ji@Base 1.4 1 - _ZNK6TagLib10ByteVector5toHexEv@Base 1.7 - _ZNK6TagLib10ByteVector6isNullEv@Base 1.4 1 - _ZNK6TagLib10ByteVector6toUIntEb@Base 1.4 1 - _ZNK6TagLib10ByteVector7isEmptyEv@Base 1.4 1 - _ZNK6TagLib10ByteVector7toShortEb@Base 1.4 1 - _ZNK6TagLib10ByteVector8checksumEv@Base 1.4 1 - _ZNK6TagLib10ByteVector8endsWithERKS0_@Base 1.4 1 - _ZNK6TagLib10ByteVector8toUShortEb@Base 1.7 - _ZNK6TagLib10ByteVectoreqEPKc@Base 1.4 1 - _ZNK6TagLib10ByteVectoreqERKS0_@Base 1.4 1 - _ZNK6TagLib10ByteVectorgtERKS0_@Base 1.4 1 - _ZNK6TagLib10ByteVectorixEi@Base 1.4 1 - _ZNK6TagLib10ByteVectorltERKS0_@Base 1.4 1 - _ZNK6TagLib10ByteVectorneEPKc@Base 1.4 1 - _ZNK6TagLib10ByteVectorneERKS0_@Base 1.4 1 - _ZNK6TagLib10ByteVectorplERKS0_@Base 1.4 1 - _ZNK6TagLib10StringList8toStringERKNS_6StringE@Base 1.4 1 - _ZNK6TagLib14ByteVectorList12toByteVectorERKNS_10ByteVectorE@Base 1.4 1 - _ZNK6TagLib3APE10Properties10sampleRateEv@Base 1.7 - _ZNK6TagLib3APE10Properties13bitsPerSampleEv@Base 1.7 - _ZNK6TagLib3APE10Properties6lengthEv@Base 1.7 - _ZNK6TagLib3APE10Properties7bitrateEv@Base 1.7 - _ZNK6TagLib3APE10Properties7versionEv@Base 1.7 - _ZNK6TagLib3APE10Properties8channelsEv@Base 1.7 - _ZNK6TagLib3APE3Tag11itemListMapEv@Base 1.4 1 - _ZNK6TagLib3APE3Tag4yearEv@Base 1.4 1 - _ZNK6TagLib3APE3Tag5albumEv@Base 1.4 1 - _ZNK6TagLib3APE3Tag5genreEv@Base 1.4 1 - _ZNK6TagLib3APE3Tag5titleEv@Base 1.4 1 - _ZNK6TagLib3APE3Tag5trackEv@Base 1.4 1 - _ZNK6TagLib3APE3Tag6artistEv@Base 1.4 1 - _ZNK6TagLib3APE3Tag6footerEv@Base 1.4 1 - _ZNK6TagLib3APE3Tag6renderEv@Base 1.4 1 - _ZNK6TagLib3APE3Tag7commentEv@Base 1.4 1 - _ZNK6TagLib3APE3Tag7isEmptyEv@Base 1.7 - _ZNK6TagLib3APE4File15audioPropertiesEv@Base 1.7 - _ZNK6TagLib3APE4File3tagEv@Base 1.7 - _ZNK6TagLib3APE4Item10isReadOnlyEv@Base 1.4 1 - _ZNK6TagLib3APE4Item12toStringListEv@Base 1.4 1 - _ZNK6TagLib3APE4Item3keyEv@Base 1.4 1 - _ZNK6TagLib3APE4Item4sizeEv@Base 1.4 1 - _ZNK6TagLib3APE4Item4typeEv@Base 1.4 1 - _ZNK6TagLib3APE4Item5valueEv@Base 1.4 1 - _ZNK6TagLib3APE4Item6renderEv@Base 1.4 1 - _ZNK6TagLib3APE4Item6valuesEv@Base 1.5 - _ZNK6TagLib3APE4Item7isEmptyEv@Base 1.4 1 - _ZNK6TagLib3APE4Item8toStringEv@Base 1.4 1 - _ZNK6TagLib3APE6Footer12renderFooterEv@Base 1.4 1 - _ZNK6TagLib3APE6Footer12renderHeaderEv@Base 1.4 1 - _ZNK6TagLib3APE6Footer13footerPresentEv@Base 1.4 1 - _ZNK6TagLib3APE6Footer13headerPresentEv@Base 1.4 1 - _ZNK6TagLib3APE6Footer15completeTagSizeEv@Base 1.4 1 - _ZNK6TagLib3APE6Footer16setHeaderPresentEb@Base 1.4 1 - _ZNK6TagLib3APE6Footer6renderEb@Base 1.4 1 - _ZNK6TagLib3APE6Footer7tagSizeEv@Base 1.4 1 - _ZNK6TagLib3APE6Footer7versionEv@Base 1.4 1 - _ZNK6TagLib3APE6Footer8isHeaderEv@Base 1.4 1 - _ZNK6TagLib3APE6Footer9itemCountEv@Base 1.4 1 - _ZNK6TagLib3ASF10Properties10sampleRateEv@Base 1.6-2~ - _ZNK6TagLib3ASF10Properties6lengthEv@Base 1.6-2~ - _ZNK6TagLib3ASF10Properties7bitrateEv@Base 1.6-2~ - _ZNK6TagLib3ASF10Properties8channelsEv@Base 1.6-2~ - _ZNK6TagLib3ASF3Tag4yearEv@Base 1.6-2~ - _ZNK6TagLib3ASF3Tag5albumEv@Base 1.6-2~ - _ZNK6TagLib3ASF3Tag5genreEv@Base 1.6-2~ - _ZNK6TagLib3ASF3Tag5titleEv@Base 1.6-2~ - _ZNK6TagLib3ASF3Tag5trackEv@Base 1.6-2~ - _ZNK6TagLib3ASF3Tag6artistEv@Base 1.6-2~ - _ZNK6TagLib3ASF3Tag6ratingEv@Base 1.6-2~ - _ZNK6TagLib3ASF3Tag7commentEv@Base 1.6-2~ - _ZNK6TagLib3ASF3Tag7isEmptyEv@Base 1.6-2~ - _ZNK6TagLib3ASF3Tag9copyrightEv@Base 1.6-2~ - _ZNK6TagLib3ASF4File15audioPropertiesEv@Base 1.6-2~ - _ZNK6TagLib3ASF4File3tagEv@Base 1.6-2~ - _ZNK6TagLib3ASF7Picture11descriptionEv@Base 1.7 - _ZNK6TagLib3ASF7Picture4typeEv@Base 1.7 - _ZNK6TagLib3ASF7Picture6renderEv@Base 1.7 - _ZNK6TagLib3ASF7Picture7isValidEv@Base 1.7 - _ZNK6TagLib3ASF7Picture7pictureEv@Base 1.7 - _ZNK6TagLib3ASF7Picture8dataSizeEv@Base 1.7 - _ZNK6TagLib3ASF7Picture8mimeTypeEv@Base 1.7 - _ZNK6TagLib3ASF9Attribute11toULongLongEv@Base 1.6-2~ - _ZNK6TagLib3ASF9Attribute12toByteVectorEv@Base 1.6-2~ - _ZNK6TagLib3ASF9Attribute4typeEv@Base 1.6-2~ - _ZNK6TagLib3ASF9Attribute6renderERKNS_6StringEi@Base 1.6-2~ - _ZNK6TagLib3ASF9Attribute6streamEv@Base 1.6-2~ - _ZNK6TagLib3ASF9Attribute6toBoolEv@Base 1.6-2~ - _ZNK6TagLib3ASF9Attribute6toUIntEv@Base 1.6-2~ - _ZNK6TagLib3ASF9Attribute8dataSizeEv@Base 1.6.2 - _ZNK6TagLib3ASF9Attribute8languageEv@Base 1.6-2~ - _ZNK6TagLib3ASF9Attribute8toStringEv@Base 1.6-2~ - _ZNK6TagLib3ASF9Attribute8toUShortEv@Base 1.6-2~ - _ZNK6TagLib3ASF9Attribute9toPictureEv@Base 1.7 - _ZNK6TagLib3MP410Properties10sampleRateEv@Base 1.6-2~ - _ZNK6TagLib3MP410Properties13bitsPerSampleEv@Base 1.6-2~ - _ZNK6TagLib3MP410Properties6lengthEv@Base 1.6-2~ - _ZNK6TagLib3MP410Properties7bitrateEv@Base 1.6-2~ - _ZNK6TagLib3MP410Properties8channelsEv@Base 1.6-2~ - _ZNK6TagLib3MP43Tag4yearEv@Base 1.6-2~ - _ZNK6TagLib3MP43Tag5albumEv@Base 1.6-2~ - _ZNK6TagLib3MP43Tag5genreEv@Base 1.6-2~ - _ZNK6TagLib3MP43Tag5titleEv@Base 1.6-2~ - _ZNK6TagLib3MP43Tag5trackEv@Base 1.6-2~ - _ZNK6TagLib3MP43Tag6artistEv@Base 1.6-2~ - _ZNK6TagLib3MP43Tag7commentEv@Base 1.6-2~ - _ZNK6TagLib3MP44File15audioPropertiesEv@Base 1.6-2~ - _ZNK6TagLib3MP44File3tagEv@Base 1.6-2~ - _ZNK6TagLib3MP44Item12toStringListEv@Base 1.6-2~ - _ZNK6TagLib3MP44Item14toCoverArtListEv@Base 1.6.1 - _ZNK6TagLib3MP44Item5toIntEv@Base 1.6-2~ - _ZNK6TagLib3MP44Item6toBoolEv@Base 1.6-2~ - _ZNK6TagLib3MP44Item7isValidEv@Base 1.6-2~ - _ZNK6TagLib3MP44Item9toIntPairEv@Base 1.6-2~ - _ZNK6TagLib3MP48CoverArt4dataEv@Base 1.6.1 - _ZNK6TagLib3MP48CoverArt6formatEv@Base 1.6.1 - _ZNK6TagLib3MPC10Properties10mpcVersionEv@Base 1.4 1 - _ZNK6TagLib3MPC10Properties10sampleRateEv@Base 1.4 1 - _ZNK6TagLib3MPC10Properties6lengthEv@Base 1.4 1 - _ZNK6TagLib3MPC10Properties7bitrateEv@Base 1.4 1 - _ZNK6TagLib3MPC10Properties8channelsEv@Base 1.4 1 - _ZNK6TagLib3MPC4File15audioPropertiesEv@Base 1.4 1 - _ZNK6TagLib3MPC4File3tagEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader11packetSizesEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader12lacingValuesEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader16lastPageOfStreamEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader17firstPageOfStreamEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader18pageSequenceNumberEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader18streamSerialNumberEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader19lastPacketCompletedEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader20firstPacketContinuedEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader24absoluteGranularPositionEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader4sizeEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader6renderEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader7isValidEv@Base 1.4 1 - _ZNK6TagLib3Ogg10PageHeader8dataSizeEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment10fieldCountEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment12fieldListMapEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment4yearEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment5albumEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment5genreEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment5titleEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment5trackEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment6artistEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment6renderEb@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment6renderEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment7commentEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment7isEmptyEv@Base 1.4 1 - _ZNK6TagLib3Ogg11XiphComment8containsERKNS_6StringE@Base 1.5 - _ZNK6TagLib3Ogg11XiphComment8vendorIDEv@Base 1.4 1 - _ZNK6TagLib3Ogg4FLAC4File15audioPropertiesEv@Base 1.4 1 - _ZNK6TagLib3Ogg4FLAC4File3tagEv@Base 1.4 1 - _ZNK6TagLib3Ogg4Page10fileOffsetEv@Base 1.4 1 - _ZNK6TagLib3Ogg4Page11packetCountEv@Base 1.4 1 - _ZNK6TagLib3Ogg4Page14containsPacketEi@Base 1.4 1 - _ZNK6TagLib3Ogg4Page16firstPacketIndexEv@Base 1.4 1 - _ZNK6TagLib3Ogg4Page4sizeEv@Base 1.4 1 - _ZNK6TagLib3Ogg4Page6headerEv@Base 1.4 1 - _ZNK6TagLib3Ogg4Page6renderEv@Base 1.4 1 - _ZNK6TagLib3Ogg4Page7packetsEv@Base 1.4 1 - _ZNK6TagLib3Ogg5Speex10Properties10sampleRateEv@Base 1.5 - _ZNK6TagLib3Ogg5Speex10Properties12speexVersionEv@Base 1.5 - _ZNK6TagLib3Ogg5Speex10Properties6lengthEv@Base 1.5 - _ZNK6TagLib3Ogg5Speex10Properties7bitrateEv@Base 1.5 - _ZNK6TagLib3Ogg5Speex10Properties8channelsEv@Base 1.5 - _ZNK6TagLib3Ogg5Speex4File15audioPropertiesEv@Base 1.5 - _ZNK6TagLib3Ogg5Speex4File3tagEv@Base 1.5 - _ZNK6TagLib3Tag7isEmptyEv@Base 1.4 1 - _ZNK6TagLib4FLAC10Properties10sampleRateEv@Base 1.4 1 - _ZNK6TagLib4FLAC10Properties11sampleWidthEv@Base 1.4 1 - _ZNK6TagLib4FLAC10Properties6lengthEv@Base 1.4 1 - _ZNK6TagLib4FLAC10Properties7bitrateEv@Base 1.4 1 - _ZNK6TagLib4FLAC10Properties8channelsEv@Base 1.4 1 - _ZNK6TagLib4FLAC10Properties9signatureEv@Base 1.7 - _ZNK6TagLib4FLAC20UnknownMetadataBlock4codeEv@Base 1.7 - _ZNK6TagLib4FLAC20UnknownMetadataBlock4dataEv@Base 1.7 - _ZNK6TagLib4FLAC20UnknownMetadataBlock6renderEv@Base 1.7 - _ZNK6TagLib4FLAC4File15audioPropertiesEv@Base 1.4 1 - _ZNK6TagLib4FLAC4File15xiphCommentDataEv@Base 1.5 - _ZNK6TagLib4FLAC4File3tagEv@Base 1.4 1 - _ZNK6TagLib4FLAC7Picture10colorDepthEv@Base 1.7 - _ZNK6TagLib4FLAC7Picture11descriptionEv@Base 1.7 - _ZNK6TagLib4FLAC7Picture4codeEv@Base 1.7 - _ZNK6TagLib4FLAC7Picture4dataEv@Base 1.7 - _ZNK6TagLib4FLAC7Picture4typeEv@Base 1.7 - _ZNK6TagLib4FLAC7Picture5widthEv@Base 1.7 - _ZNK6TagLib4FLAC7Picture6heightEv@Base 1.7 - _ZNK6TagLib4FLAC7Picture6renderEv@Base 1.7 - _ZNK6TagLib4FLAC7Picture8mimeTypeEv@Base 1.7 - _ZNK6TagLib4FLAC7Picture9numColorsEv@Base 1.7 - _ZNK6TagLib4File4nameEv@Base 1.4 1 - _ZNK6TagLib4File4tellEv@Base 1.4 1 - _ZNK6TagLib4File6isOpenEv@Base 1.4 1 - _ZNK6TagLib4File7isValidEv@Base 1.4 1 - _ZNK6TagLib4File8readOnlyEv@Base 1.4 1 - _ZNK6TagLib4MPEG10Properties10isOriginalEv@Base 1.4 1 - _ZNK6TagLib4MPEG10Properties10sampleRateEv@Base 1.4 1 - _ZNK6TagLib4MPEG10Properties10xingHeaderEv@Base 1.5 - _ZNK6TagLib4MPEG10Properties11channelModeEv@Base 1.4 1 - _ZNK6TagLib4MPEG10Properties13isCopyrightedEv@Base 1.4 1 - _ZNK6TagLib4MPEG10Properties17protectionEnabledEv@Base 1.5 - _ZNK6TagLib4MPEG10Properties5layerEv@Base 1.4 1 - _ZNK6TagLib4MPEG10Properties6lengthEv@Base 1.4 1 - _ZNK6TagLib4MPEG10Properties7bitrateEv@Base 1.4 1 - _ZNK6TagLib4MPEG10Properties7versionEv@Base 1.4 1 - _ZNK6TagLib4MPEG10Properties8channelsEv@Base 1.4 1 - _ZNK6TagLib4MPEG10XingHeader11totalFramesEv@Base 1.4 1 - _ZNK6TagLib4MPEG10XingHeader7isValidEv@Base 1.4 1 - _ZNK6TagLib4MPEG10XingHeader9totalSizeEv@Base 1.4 1 - _ZNK6TagLib4MPEG4File15audioPropertiesEv@Base 1.4 1 - _ZNK6TagLib4MPEG4File3tagEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header10isOriginalEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header10sampleRateEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header11channelModeEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header11frameLengthEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header13isCopyrightedEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header15samplesPerFrameEv@Base 1.5 - _ZNK6TagLib4MPEG6Header17protectionEnabledEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header5layerEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header7bitrateEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header7isValidEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header7versionEv@Base 1.4 1 - _ZNK6TagLib4MPEG6Header8isPaddedEv@Base 1.4 1 - _ZNK6TagLib4RIFF3WAV10Properties10sampleRateEv@Base 1.6 - _ZNK6TagLib4RIFF3WAV10Properties11sampleWidthEv@Base 1.7 - _ZNK6TagLib4RIFF3WAV10Properties6lengthEv@Base 1.6 - _ZNK6TagLib4RIFF3WAV10Properties7bitrateEv@Base 1.6 - _ZNK6TagLib4RIFF3WAV10Properties8channelsEv@Base 1.6 - _ZNK6TagLib4RIFF3WAV4File15audioPropertiesEv@Base 1.6 - _ZNK6TagLib4RIFF3WAV4File3tagEv@Base 1.6 - _ZNK6TagLib4RIFF4AIFF10Properties10sampleRateEv@Base 1.6 - _ZNK6TagLib4RIFF4AIFF10Properties11sampleWidthEv@Base 1.7 - _ZNK6TagLib4RIFF4AIFF10Properties6lengthEv@Base 1.6 - _ZNK6TagLib4RIFF4AIFF10Properties7bitrateEv@Base 1.6 - _ZNK6TagLib4RIFF4AIFF10Properties8channelsEv@Base 1.6 - _ZNK6TagLib4RIFF4AIFF4File15audioPropertiesEv@Base 1.6 - _ZNK6TagLib4RIFF4AIFF4File3tagEv@Base 1.6 - _ZNK6TagLib4RIFF4File10chunkCountEv@Base 1.6 - _ZNK6TagLib4RIFF4File11chunkOffsetEj@Base 1.6 - _ZNK6TagLib4RIFF4File12chunkPaddingEj@Base 1.7 - _ZNK6TagLib4RIFF4File13chunkDataSizeEj@Base 1.7 - _ZNK6TagLib4RIFF4File8riffSizeEv@Base 1.7 - _ZNK6TagLib4RIFF4File9chunkNameEj@Base 1.6 - _ZNK6TagLib5ID3v113StringHandler5parseERKNS_10ByteVectorE@Base 1.4 1 - _ZNK6TagLib5ID3v113StringHandler6renderERKNS_6StringE@Base 1.4 1 - _ZNK6TagLib5ID3v13Tag4yearEv@Base 1.4 1 - _ZNK6TagLib5ID3v13Tag5albumEv@Base 1.4 1 - _ZNK6TagLib5ID3v13Tag5genreEv@Base 1.4 1 - _ZNK6TagLib5ID3v13Tag5titleEv@Base 1.4 1 - _ZNK6TagLib5ID3v13Tag5trackEv@Base 1.4 1 - _ZNK6TagLib5ID3v13Tag6artistEv@Base 1.4 1 - _ZNK6TagLib5ID3v13Tag6renderEv@Base 1.4 1 - _ZNK6TagLib5ID3v13Tag7commentEv@Base 1.4 1 - _ZNK6TagLib5ID3v212FrameFactory11createFrameERKNS_10ByteVectorEPNS0_6HeaderE@Base 1.5 - _ZNK6TagLib5ID3v212FrameFactory11createFrameERKNS_10ByteVectorEb@Base 1.4 1 - _ZNK6TagLib5ID3v212FrameFactory11createFrameERKNS_10ByteVectorEj@Base 1.4 1 - _ZNK6TagLib5ID3v212FrameFactory11updateFrameEPNS0_5Frame6HeaderE@Base 1.4 1 - _ZNK6TagLib5ID3v212FrameFactory11updateGenreEPNS0_23TextIdentificationFrameE@Base 1.5 - _ZNK6TagLib5ID3v212FrameFactory12convertFrameEPKcS3_PNS0_5Frame6HeaderE@Base 1.4 1 - _ZNK6TagLib5ID3v212FrameFactory19defaultTextEncodingEv@Base 1.4 1 - _ZNK6TagLib5ID3v212PrivateFrame12renderFieldsEv@Base 1.6 - _ZNK6TagLib5ID3v212PrivateFrame4dataEv@Base 1.6 - _ZNK6TagLib5ID3v212PrivateFrame5ownerEv@Base 1.6 - _ZNK6TagLib5ID3v212PrivateFrame8toStringEv@Base 1.6 - _ZNK6TagLib5ID3v212UnknownFrame12renderFieldsEv@Base 1.4 1 - _ZNK6TagLib5ID3v212UnknownFrame4dataEv@Base 1.4 1 - _ZNK6TagLib5ID3v212UnknownFrame8toStringEv@Base 1.4 1 - _ZNK6TagLib5ID3v212UrlLinkFrame12renderFieldsEv@Base 1.5 - _ZNK6TagLib5ID3v212UrlLinkFrame3urlEv@Base 1.5 - _ZNK6TagLib5ID3v212UrlLinkFrame8toStringEv@Base 1.5 - _ZNK6TagLib5ID3v213CommentsFrame11descriptionEv@Base 1.4 1 - _ZNK6TagLib5ID3v213CommentsFrame12renderFieldsEv@Base 1.4 1 - _ZNK6TagLib5ID3v213CommentsFrame12textEncodingEv@Base 1.4 1 - _ZNK6TagLib5ID3v213CommentsFrame4textEv@Base 1.4 1 - _ZNK6TagLib5ID3v213CommentsFrame8languageEv@Base 1.4 1 - _ZNK6TagLib5ID3v213CommentsFrame8toStringEv@Base 1.4 1 - _ZNK6TagLib5ID3v214ExtendedHeader4sizeEv@Base 1.4 1 - _ZNK6TagLib5ID3v216UserUrlLinkFrame11descriptionEv@Base 1.5 - _ZNK6TagLib5ID3v216UserUrlLinkFrame12renderFieldsEv@Base 1.5 - _ZNK6TagLib5ID3v216UserUrlLinkFrame12textEncodingEv@Base 1.5 - _ZNK6TagLib5ID3v216UserUrlLinkFrame8toStringEv@Base 1.5 - _ZNK6TagLib5ID3v218PopularimeterFrame12renderFieldsEv@Base 1.6 - _ZNK6TagLib5ID3v218PopularimeterFrame5emailEv@Base 1.6 - _ZNK6TagLib5ID3v218PopularimeterFrame6ratingEv@Base 1.6 - _ZNK6TagLib5ID3v218PopularimeterFrame7counterEv@Base 1.6 - _ZNK6TagLib5ID3v218PopularimeterFrame8toStringEv@Base 1.6 - _ZNK6TagLib5ID3v219RelativeVolumeFrame10peakVolumeENS1_11ChannelTypeE@Base 1.4 1 - _ZNK6TagLib5ID3v219RelativeVolumeFrame10peakVolumeEv@Base 1.4 1 - _ZNK6TagLib5ID3v219RelativeVolumeFrame11channelTypeEv@Base 1.4 1 - _ZNK6TagLib5ID3v219RelativeVolumeFrame12renderFieldsEv@Base 1.4 1 - _ZNK6TagLib5ID3v219RelativeVolumeFrame14identificationEv@Base 1.5 - _ZNK6TagLib5ID3v219RelativeVolumeFrame16volumeAdjustmentENS1_11ChannelTypeE@Base 1.4 1 - _ZNK6TagLib5ID3v219RelativeVolumeFrame16volumeAdjustmentEv@Base 1.4 1 - _ZNK6TagLib5ID3v219RelativeVolumeFrame21volumeAdjustmentIndexENS1_11ChannelTypeE@Base 1.4 1 - _ZNK6TagLib5ID3v219RelativeVolumeFrame21volumeAdjustmentIndexEv@Base 1.4 1 - _ZNK6TagLib5ID3v219RelativeVolumeFrame8channelsEv@Base 1.4 1 - _ZNK6TagLib5ID3v219RelativeVolumeFrame8toStringEv@Base 1.4 1 - _ZNK6TagLib5ID3v220AttachedPictureFrame11descriptionEv@Base 1.4 1 - _ZNK6TagLib5ID3v220AttachedPictureFrame12renderFieldsEv@Base 1.4 1 - _ZNK6TagLib5ID3v220AttachedPictureFrame12textEncodingEv@Base 1.4 1 - _ZNK6TagLib5ID3v220AttachedPictureFrame4typeEv@Base 1.4 1 - _ZNK6TagLib5ID3v220AttachedPictureFrame7pictureEv@Base 1.4 1 - _ZNK6TagLib5ID3v220AttachedPictureFrame8mimeTypeEv@Base 1.4 1 - _ZNK6TagLib5ID3v220AttachedPictureFrame8toStringEv@Base 1.4 1 - _ZNK6TagLib5ID3v223TextIdentificationFrame12renderFieldsEv@Base 1.4 1 - _ZNK6TagLib5ID3v223TextIdentificationFrame12textEncodingEv@Base 1.4 1 - _ZNK6TagLib5ID3v223TextIdentificationFrame8toStringEv@Base 1.4 1 - _ZNK6TagLib5ID3v223TextIdentificationFrame9fieldListEv@Base 1.4 1 - _ZNK6TagLib5ID3v225UniqueFileIdentifierFrame10identifierEv@Base 1.4 1 - _ZNK6TagLib5ID3v225UniqueFileIdentifierFrame12renderFieldsEv@Base 1.4 1 - _ZNK6TagLib5ID3v225UniqueFileIdentifierFrame5ownerEv@Base 1.4 1 - _ZNK6TagLib5ID3v225UniqueFileIdentifierFrame8toStringEv@Base 1.4 1 - _ZNK6TagLib5ID3v225UnsynchronizedLyricsFrame11descriptionEv@Base 1.5 - _ZNK6TagLib5ID3v225UnsynchronizedLyricsFrame12renderFieldsEv@Base 1.5 - _ZNK6TagLib5ID3v225UnsynchronizedLyricsFrame12textEncodingEv@Base 1.5 - _ZNK6TagLib5ID3v225UnsynchronizedLyricsFrame4textEv@Base 1.5 - _ZNK6TagLib5ID3v225UnsynchronizedLyricsFrame8languageEv@Base 1.5 - _ZNK6TagLib5ID3v225UnsynchronizedLyricsFrame8toStringEv@Base 1.5 - _ZNK6TagLib5ID3v227UserTextIdentificationFrame11descriptionEv@Base 1.4 1 - _ZNK6TagLib5ID3v227UserTextIdentificationFrame8toStringEv@Base 1.4 1 - _ZNK6TagLib5ID3v227UserTextIdentificationFrame9fieldListEv@Base 1.4 1 - _ZNK6TagLib5ID3v230GeneralEncapsulatedObjectFrame11descriptionEv@Base 1.5 - _ZNK6TagLib5ID3v230GeneralEncapsulatedObjectFrame12renderFieldsEv@Base 1.5 - _ZNK6TagLib5ID3v230GeneralEncapsulatedObjectFrame12textEncodingEv@Base 1.5 - _ZNK6TagLib5ID3v230GeneralEncapsulatedObjectFrame6objectEv@Base 1.5 - _ZNK6TagLib5ID3v230GeneralEncapsulatedObjectFrame8fileNameEv@Base 1.5 - _ZNK6TagLib5ID3v230GeneralEncapsulatedObjectFrame8mimeTypeEv@Base 1.5 - _ZNK6TagLib5ID3v230GeneralEncapsulatedObjectFrame8toStringEv@Base 1.5 - _ZNK6TagLib5ID3v23Tag12frameListMapEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag14extendedHeaderEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag4yearEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag5albumEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag5genreEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag5titleEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag5trackEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag6artistEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag6footerEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag6headerEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag6renderEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag7commentEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag7isEmptyEv@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag9frameListERKNS_10ByteVectorE@Base 1.4 1 - _ZNK6TagLib5ID3v23Tag9frameListEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame4sizeEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header10encryptionEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header11compressionEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header15unsycronisationEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header16groupingIdentityEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header17unsynchronisationEv@Base 1.5 - _ZNK6TagLib5ID3v25Frame6Header19dataLengthIndicatorEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header20tagAlterPreservationEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header21fileAlterPreservationEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header22frameAlterPreservationEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header6renderEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header7frameIDEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header7versionEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header8readOnlyEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6Header9frameSizeEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6headerEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame6renderEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame7frameIDEv@Base 1.4 1 - _ZNK6TagLib5ID3v25Frame9fieldDataERKNS_10ByteVectorE@Base 1.4 1 - _ZNK6TagLib5ID3v26Footer6renderEPKNS0_6HeaderE@Base 1.4 1 - _ZNK6TagLib5ID3v26Header12majorVersionEv@Base 1.4 1 - _ZNK6TagLib5ID3v26Header13footerPresentEv@Base 1.4 1 - _ZNK6TagLib5ID3v26Header14extendedHeaderEv@Base 1.4 1 - _ZNK6TagLib5ID3v26Header14revisionNumberEv@Base 1.4 1 - _ZNK6TagLib5ID3v26Header15completeTagSizeEv@Base 1.4 1 - _ZNK6TagLib5ID3v26Header17unsynchronisationEv@Base 1.4 1 - _ZNK6TagLib5ID3v26Header21experimentalIndicatorEv@Base 1.4 1 - _ZNK6TagLib5ID3v26Header6renderEv@Base 1.4 1 - _ZNK6TagLib5ID3v26Header7tagSizeEv@Base 1.4 1 - _ZNK6TagLib6String10startsWithERKS0_@Base 1.5 - _ZNK6TagLib6String15stripWhiteSpaceEv@Base 1.4 1 - _ZNK6TagLib6String3endEv@Base 1.4 1 - _ZNK6TagLib6String4dataENS0_4TypeE@Base 1.4 1 - _ZNK6TagLib6String4findERKS0_i@Base 1.4 1 - _ZNK6TagLib6String4sizeEv@Base 1.4 1 - _ZNK6TagLib6String5beginEv@Base 1.4 1 - _ZNK6TagLib6String5rfindERKS0_i@Base 1.6 - _ZNK6TagLib6String5toIntEPb@Base 1.6.3 - _ZNK6TagLib6String5toIntEv@Base 1.4 1 - _ZNK6TagLib6String5upperEv@Base 1.4 1 - _ZNK6TagLib6String6isNullEv@Base 1.4 1 - _ZNK6TagLib6String6lengthEv@Base 1.5 - _ZNK6TagLib6String6substrEjj@Base 1.4 1 - _ZNK6TagLib6String6to8BitEb@Base 1.4 1 - _ZNK6TagLib6String7isAsciiEv@Base 1.5 - _ZNK6TagLib6String7isEmptyEv@Base 1.4 1 - _ZNK6TagLib6String8isLatin1Ev@Base 1.5 - _ZNK6TagLib6String9toCStringEb@Base 1.4 1 - _ZNK6TagLib6String9toWStringEv@Base 1.5 - _ZNK6TagLib6StringeqERKS0_@Base 1.4 1 - _ZNK6TagLib6StringixEi@Base 1.4 1 - _ZNK6TagLib6StringltERKS0_@Base 1.4 1 - _ZNK6TagLib6Vorbis10Properties10sampleRateEv@Base 1.4 1 - _ZNK6TagLib6Vorbis10Properties13vorbisVersionEv@Base 1.4 1 - _ZNK6TagLib6Vorbis10Properties14bitrateMaximumEv@Base 1.4 1 - _ZNK6TagLib6Vorbis10Properties14bitrateMinimumEv@Base 1.4 1 - _ZNK6TagLib6Vorbis10Properties14bitrateNominalEv@Base 1.4 1 - _ZNK6TagLib6Vorbis10Properties6lengthEv@Base 1.4 1 - _ZNK6TagLib6Vorbis10Properties7bitrateEv@Base 1.4 1 - _ZNK6TagLib6Vorbis10Properties8channelsEv@Base 1.4 1 - _ZNK6TagLib6Vorbis4File15audioPropertiesEv@Base 1.4 1 - _ZNK6TagLib6Vorbis4File3tagEv@Base 1.4 1 - _ZNK6TagLib7FileRef15audioPropertiesEv@Base 1.4 1 - _ZNK6TagLib7FileRef3tagEv@Base 1.4 1 - _ZNK6TagLib7FileRef4fileEv@Base 1.4 1 - _ZNK6TagLib7FileRef6isNullEv@Base 1.4 1 - _ZNK6TagLib7FileRefeqERKS0_@Base 1.4 1 - _ZNK6TagLib7FileRefneERKS0_@Base 1.4 1 - _ZNK6TagLib7WavPack10Properties10sampleRateEv@Base 1.5 - _ZNK6TagLib7WavPack10Properties13bitsPerSampleEv@Base 1.5 - _ZNK6TagLib7WavPack10Properties6lengthEv@Base 1.5 - _ZNK6TagLib7WavPack10Properties7bitrateEv@Base 1.5 - _ZNK6TagLib7WavPack10Properties7versionEv@Base 1.5 - _ZNK6TagLib7WavPack10Properties8channelsEv@Base 1.5 - _ZNK6TagLib7WavPack4File15audioPropertiesEv@Base 1.5 - _ZNK6TagLib7WavPack4File3tagEv@Base 1.5 - _ZNK6TagLib9TrueAudio10Properties10sampleRateEv@Base 1.5 - _ZNK6TagLib9TrueAudio10Properties10ttaVersionEv@Base 1.5 - _ZNK6TagLib9TrueAudio10Properties13bitsPerSampleEv@Base 1.5 - _ZNK6TagLib9TrueAudio10Properties6lengthEv@Base 1.5 - _ZNK6TagLib9TrueAudio10Properties7bitrateEv@Base 1.5 - _ZNK6TagLib9TrueAudio10Properties8channelsEv@Base 1.5 - _ZNK6TagLib9TrueAudio4File15audioPropertiesEv@Base 1.5 - _ZNK6TagLib9TrueAudio4File3tagEv@Base 1.5 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIN9__gnu_cxx17__normal_iteratorIPKwS2_EEEEPwT_SA_RKS1_St20forward_iterator_tag@Base 1.7.1 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIN6TagLib10ByteVectorESaIS1_EE8_M_clearEv@Base 1.7.1 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIN6TagLib3ASF9AttributeESaIS2_EE8_M_clearEv@Base 1.7.1 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIN6TagLib3MP48CoverArtESaIS2_EE8_M_clearEv@Base 1.7.1 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIN6TagLib5ID3v219RelativeVolumeFrame11ChannelTypeESaIS3_EE8_M_clearEv@Base 1.7.1 - (optional=templinst)_ZNSt10_List_baseIN6TagLib6StringESaIS1_EE8_M_clearEv@Base 1.4 1 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt10_List_baseIN6TagLib6StringESaIS1_EED1Ev@Base 1.7-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt10_List_baseIN6TagLib6StringESaIS1_EED2Ev@Base 1.7-2~ - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIPKN6TagLib7FileRef16FileTypeResolverESaIS4_EE8_M_clearEv@Base 1.7.1 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIPN6TagLib3ASF4File10BaseObjectESaIS4_EE8_M_clearEv@Base 1.7.1 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt10_List_baseIPN6TagLib3MP44AtomESaIS3_EED1Ev@Base 1.7-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt10_List_baseIPN6TagLib3MP44AtomESaIS3_EED2Ev@Base 1.7-2~ - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIPN6TagLib3Ogg4PageESaIS3_EE8_M_clearEv@Base 1.7.1 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIPN6TagLib4FLAC13MetadataBlockESaIS3_EE8_M_clearEv@Base 1.7.1 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIPN6TagLib4FLAC7PictureESaIS3_EE8_M_clearEv@Base 1.7.1 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIPN6TagLib5ID3v25FrameESaIS3_EE8_M_clearEv@Base 1.7.1 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIiSaIiEE8_M_clearEv@Base 1.7.1 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt4pairIKN6TagLib6StringENS0_3APE4ItemEED1Ev@Base 1.7-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt4pairIKN6TagLib6StringENS0_3APE4ItemEED2Ev@Base 1.7-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt4pairIKN6TagLib6StringENS0_3MP44ItemEED1Ev@Base 1.7-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt4pairIKN6TagLib6StringENS0_3MP44ItemEED2Ev@Base 1.7-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt4pairIKN6TagLib6StringENS0_4ListINS0_3ASF9AttributeEEEED1Ev@Base 1.7-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt4pairIKN6TagLib6StringENS0_4ListINS0_3ASF9AttributeEEEED2Ev@Base 1.7-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt6vectorI5ChunkSaIS0_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS0_S2_EERKS0_@Base 1.7 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt6vectorIN6TagLib4ListIiEESaIS2_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS2_S4_EERKS2_@Base 1.4 1 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt6vectorIN6TagLib4ListIiEESaIS2_EED1Ev@Base 1.5 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt6vectorIN6TagLib4ListIiEESaIS2_EED2Ev@Base 1.7 - (optional=templinst)_ZNSt6vectorIcSaIcEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPcS1_EERKc@Base 1.4 1 - (optional=templinst|arch=!alpha !amd64 !ia64 !kfreebsd-amd64 !s390 !s390x)_ZNSt6vectorIcSaIcEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPcS1_EEjRKc@Base 1.4 1 - (optional=templinst|arch=alpha amd64 ia64 kfreebsd-amd64 s390 s390x)_ZNSt6vectorIcSaIcEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPcS1_EEmRKc@Base 1.4 1 - (optional=templinst)_ZNSt6vectorIcSaIcEE15_M_range_insertIN9__gnu_cxx17__normal_iteratorIPKcS1_EEEEvNS4_IPcS1_EET_SA_St20forward_iterator_tag@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIKN6TagLib6StringESt4pairIS2_NS0_3APE4ItemEESt10_Select1stIS6_ESt4lessIS2_ESaIS6_EE10_M_insert_EPKSt18_Rb_tree_node_baseSF_RKS6_@Base 1.5 - (optional=templinst)_ZNSt8_Rb_treeIKN6TagLib6StringESt4pairIS2_NS0_3APE4ItemEESt10_Select1stIS6_ESt4lessIS2_ESaIS6_EE16_M_insert_uniqueERKS6_@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIKN6TagLib6StringESt4pairIS2_NS0_3APE4ItemEESt10_Select1stIS6_ESt4lessIS2_ESaIS6_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS6_ERKS6_@Base 1.5 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt8_Rb_treeIKN6TagLib6StringESt4pairIS2_NS0_3APE4ItemEESt10_Select1stIS6_ESt4lessIS2_ESaIS6_EE4findERS2_@Base 1.7.1 - (optional=templinst)_ZNSt8_Rb_treeIKN6TagLib6StringESt4pairIS2_NS0_3APE4ItemEESt10_Select1stIS6_ESt4lessIS2_ESaIS6_EE7_M_copyEPKSt13_Rb_tree_nodeIS6_EPSE_@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIKN6TagLib6StringESt4pairIS2_NS0_3APE4ItemEESt10_Select1stIS6_ESt4lessIS2_ESaIS6_EE8_M_eraseEPSt13_Rb_tree_nodeIS6_E@Base 1.4 1 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib10ByteVectorESt4pairIKS1_NS0_4ListIPNS0_5ID3v25FrameEEEESt10_Select1stIS9_ESt4lessIS1_ESaIS9_EE10_M_insert_EPKSt18_Rb_tree_node_baseSI_RKS9_@Base 1.5 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib10ByteVectorESt4pairIKS1_NS0_4ListIPNS0_5ID3v25FrameEEEESt10_Select1stIS9_ESt4lessIS1_ESaIS9_EE16_M_insert_uniqueERKS9_@Base 1.4 1 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib10ByteVectorESt4pairIKS1_NS0_4ListIPNS0_5ID3v25FrameEEEESt10_Select1stIS9_ESt4lessIS1_ESaIS9_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS9_ERKS9_@Base 1.5 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib10ByteVectorESt4pairIKS1_NS0_4ListIPNS0_5ID3v25FrameEEEESt10_Select1stIS9_ESt4lessIS1_ESaIS9_EE7_M_copyEPKSt13_Rb_tree_nodeIS9_EPSH_@Base 1.5 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib10ByteVectorESt4pairIKS1_NS0_4ListIPNS0_5ID3v25FrameEEEESt10_Select1stIS9_ESt4lessIS1_ESaIS9_EE8_M_eraseEPSt13_Rb_tree_nodeIS9_E@Base 1.4 1 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib5ID3v219RelativeVolumeFrame11ChannelTypeESt4pairIKS3_11ChannelDataESt10_Select1stIS7_ESt4lessIS3_ESaIS7_EE10_M_insert_EPKSt18_Rb_tree_node_baseSG_RKS7_@Base 1.5 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib5ID3v219RelativeVolumeFrame11ChannelTypeESt4pairIKS3_11ChannelDataESt10_Select1stIS7_ESt4lessIS3_ESaIS7_EE16_M_insert_uniqueERKS7_@Base 1.4 1 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib5ID3v219RelativeVolumeFrame11ChannelTypeESt4pairIKS3_11ChannelDataESt10_Select1stIS7_ESt4lessIS3_ESaIS7_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS7_ERKS7_@Base 1.5 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib5ID3v219RelativeVolumeFrame11ChannelTypeESt4pairIKS3_11ChannelDataESt10_Select1stIS7_ESt4lessIS3_ESaIS7_EE7_M_copyEPKSt13_Rb_tree_nodeIS7_EPSF_@Base 1.4 1 - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib5ID3v219RelativeVolumeFrame11ChannelTypeESt4pairIKS3_11ChannelDataESt10_Select1stIS7_ESt4lessIS3_ESaIS7_EE8_M_eraseEPSt13_Rb_tree_nodeIS7_E@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_10StringListEESt10_Select1stIS5_ESt4lessIS1_ESaIS5_EE10_M_insert_EPKSt18_Rb_tree_node_baseSE_RKS5_@Base 1.5 - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_10StringListEESt10_Select1stIS5_ESt4lessIS1_ESaIS5_EE16_M_insert_uniqueERKS5_@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_10StringListEESt10_Select1stIS5_ESt4lessIS1_ESaIS5_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS5_ERKS5_@Base 1.5 - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_10StringListEESt10_Select1stIS5_ESt4lessIS1_ESaIS5_EE4findERS3_@Base 1.7.1 - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_10StringListEESt10_Select1stIS5_ESt4lessIS1_ESaIS5_EE7_M_copyEPKSt13_Rb_tree_nodeIS5_EPSD_@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_10StringListEESt10_Select1stIS5_ESt4lessIS1_ESaIS5_EE8_M_eraseEPSt13_Rb_tree_nodeIS5_E@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_3MP44ItemEESt10_Select1stIS6_ESt4lessIS1_ESaIS6_EE10_M_insert_EPKSt18_Rb_tree_node_baseSF_RKS6_@Base 1.6-2~ - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_3MP44ItemEESt10_Select1stIS6_ESt4lessIS1_ESaIS6_EE16_M_insert_uniqueERKS6_@Base 1.6-2~ - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_3MP44ItemEESt10_Select1stIS6_ESt4lessIS1_ESaIS6_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS6_ERKS6_@Base 1.6-2~ - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_3MP44ItemEESt10_Select1stIS6_ESt4lessIS1_ESaIS6_EE7_M_copyEPKSt13_Rb_tree_nodeIS6_EPSE_@Base 1.6-2~ - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_3MP44ItemEESt10_Select1stIS6_ESt4lessIS1_ESaIS6_EE8_M_eraseEPSt13_Rb_tree_nodeIS6_E@Base 1.6-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_4ListINS0_3ASF9AttributeEEEESt10_Select1stIS8_ESt4lessIS1_ESaIS8_EE10_M_insert_EPKSt18_Rb_tree_node_baseSH_RKS8_@Base 1.6-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_4ListINS0_3ASF9AttributeEEEESt10_Select1stIS8_ESt4lessIS1_ESaIS8_EE16_M_insert_uniqueERKS8_@Base 1.6-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_4ListINS0_3ASF9AttributeEEEESt10_Select1stIS8_ESt4lessIS1_ESaIS8_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS8_ERKS8_@Base 1.6-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_4ListINS0_3ASF9AttributeEEEESt10_Select1stIS8_ESt4lessIS1_ESaIS8_EE7_M_copyEPKSt13_Rb_tree_nodeIS8_EPSG_@Base 1.6-2~ - (optional=templinst|arch=!amd64 !hurd-i386 !i386 !kfreebsd-i386 !kfreebsd-amd64)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_NS0_4ListINS0_3ASF9AttributeEEEESt10_Select1stIS8_ESt4lessIS1_ESaIS8_EE8_M_eraseEPSt13_Rb_tree_nodeIS8_E@Base 1.6-2~ - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_iESt10_Select1stIS4_ESt4lessIS1_ESaIS4_EE10_M_insert_EPKSt18_Rb_tree_node_baseSD_RKS4_@Base 1.5 - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_iESt10_Select1stIS4_ESt4lessIS1_ESaIS4_EE16_M_insert_uniqueERKS4_@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_iESt10_Select1stIS4_ESt4lessIS1_ESaIS4_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS4_ERKS4_@Base 1.5 - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_iESt10_Select1stIS4_ESt4lessIS1_ESaIS4_EE7_M_copyEPKSt13_Rb_tree_nodeIS4_EPSC_@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIN6TagLib6StringESt4pairIKS1_iESt10_Select1stIS4_ESt4lessIS1_ESaIS4_EE8_M_eraseEPSt13_Rb_tree_nodeIS4_E@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIiSt4pairIKiN6TagLib10ByteVectorEESt10_Select1stIS4_ESt4lessIiESaIS4_EE10_M_insert_EPKSt18_Rb_tree_node_baseSD_RKS4_@Base 1.5 - (optional=templinst)_ZNSt8_Rb_treeIiSt4pairIKiN6TagLib10ByteVectorEESt10_Select1stIS4_ESt4lessIiESaIS4_EE16_M_insert_uniqueERKS4_@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIiSt4pairIKiN6TagLib10ByteVectorEESt10_Select1stIS4_ESt4lessIiESaIS4_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS4_ERKS4_@Base 1.5 - (optional=templinst)_ZNSt8_Rb_treeIiSt4pairIKiN6TagLib10ByteVectorEESt10_Select1stIS4_ESt4lessIiESaIS4_EE7_M_copyEPKSt13_Rb_tree_nodeIS4_EPSC_@Base 1.4 1 - (optional=templinst)_ZNSt8_Rb_treeIiSt4pairIKiN6TagLib10ByteVectorEESt10_Select1stIS4_ESt4lessIiESaIS4_EE8_M_eraseEPSt13_Rb_tree_nodeIS4_E@Base 1.4 1 - _ZTIN6TagLib10ByteVectorE@Base 1.4 1 - _ZTIN6TagLib10StringListE@Base 1.4 1 - _ZTIN6TagLib14ByteVectorListE@Base 1.4 1 - _ZTIN6TagLib15AudioPropertiesE@Base 1.4 1 - _ZTIN6TagLib3APE10PropertiesE@Base 1.7 - _ZTIN6TagLib3APE3TagE@Base 1.4 1 - _ZTIN6TagLib3APE4FileE@Base 1.7 - _ZTIN6TagLib3APE4ItemE@Base 1.4 1 - _ZTIN6TagLib3APE6FooterE@Base 1.4 1 - _ZTIN6TagLib3ASF10PropertiesE@Base 1.6-2~ - _ZTIN6TagLib3ASF3TagE@Base 1.6-2~ - _ZTIN6TagLib3ASF4File10BaseObjectE@Base 1.6-2~ - _ZTIN6TagLib3ASF4File13UnknownObjectE@Base 1.6-2~ - _ZTIN6TagLib3ASF4File14MetadataObjectE@Base 1.6-2~ - _ZTIN6TagLib3ASF4File20FilePropertiesObjectE@Base 1.6-2~ - _ZTIN6TagLib3ASF4File21HeaderExtensionObjectE@Base 1.6-2~ - _ZTIN6TagLib3ASF4File21MetadataLibraryObjectE@Base 1.6-2~ - _ZTIN6TagLib3ASF4File22StreamPropertiesObjectE@Base 1.6-2~ - _ZTIN6TagLib3ASF4File24ContentDescriptionObjectE@Base 1.6-2~ - _ZTIN6TagLib3ASF4File32ExtendedContentDescriptionObjectE@Base 1.6-2~ - _ZTIN6TagLib3ASF4FileE@Base 1.6-2~ - _ZTIN6TagLib3ASF7PictureE@Base 1.7 - _ZTIN6TagLib3ASF9AttributeE@Base 1.6-2~ - _ZTIN6TagLib3MP410PropertiesE@Base 1.6-2~ - _ZTIN6TagLib3MP43TagE@Base 1.6-2~ - _ZTIN6TagLib3MP44FileE@Base 1.6-2~ - _ZTIN6TagLib3MPC10PropertiesE@Base 1.4 1 - _ZTIN6TagLib3MPC4FileE@Base 1.4 1 - _ZTIN6TagLib3Ogg10PageHeaderE@Base 1.4 1 - _ZTIN6TagLib3Ogg11XiphCommentE@Base 1.4 1 - _ZTIN6TagLib3Ogg4FLAC4FileE@Base 1.4 1 - _ZTIN6TagLib3Ogg4FileE@Base 1.4 1 - _ZTIN6TagLib3Ogg4PageE@Base 1.4 1 - _ZTIN6TagLib3Ogg5Speex10PropertiesE@Base 1.5 - _ZTIN6TagLib3Ogg5Speex4FileE@Base 1.5 - _ZTIN6TagLib3TagE@Base 1.4 1 - _ZTIN6TagLib4FLAC10PropertiesE@Base 1.4 1 - _ZTIN6TagLib4FLAC13MetadataBlockE@Base 1.7 - _ZTIN6TagLib4FLAC20UnknownMetadataBlockE@Base 1.7 - _ZTIN6TagLib4FLAC4FileE@Base 1.4 1 - _ZTIN6TagLib4FLAC7PictureE@Base 1.7 - _ZTIN6TagLib4FileE@Base 1.4 1 - _ZTIN6TagLib4MPEG10PropertiesE@Base 1.4 1 - _ZTIN6TagLib4MPEG10XingHeaderE@Base 1.4 1 - _ZTIN6TagLib4MPEG4FileE@Base 1.4 1 - _ZTIN6TagLib4MPEG6HeaderE@Base 1.4 1 - _ZTIN6TagLib4RIFF3WAV10PropertiesE@Base 1.6 - _ZTIN6TagLib4RIFF3WAV4FileE@Base 1.6 - _ZTIN6TagLib4RIFF4AIFF10PropertiesE@Base 1.6 - _ZTIN6TagLib4RIFF4AIFF4FileE@Base 1.6 - _ZTIN6TagLib4RIFF4FileE@Base 1.6 - _ZTIN6TagLib5ID3v113StringHandlerE@Base 1.4 1 - _ZTIN6TagLib5ID3v13TagE@Base 1.4 1 - _ZTIN6TagLib5ID3v212FrameFactoryE@Base 1.4 1 - _ZTIN6TagLib5ID3v212PrivateFrameE@Base 1.6 - _ZTIN6TagLib5ID3v212UnknownFrameE@Base 1.4 1 - _ZTIN6TagLib5ID3v212UrlLinkFrameE@Base 1.5 - _ZTIN6TagLib5ID3v213CommentsFrameE@Base 1.4 1 - _ZTIN6TagLib5ID3v214ExtendedHeaderE@Base 1.4 1 - _ZTIN6TagLib5ID3v216UserUrlLinkFrameE@Base 1.5 - _ZTIN6TagLib5ID3v218PopularimeterFrameE@Base 1.6 - _ZTIN6TagLib5ID3v219RelativeVolumeFrameE@Base 1.4 1 - _ZTIN6TagLib5ID3v220AttachedPictureFrameE@Base 1.4 1 - _ZTIN6TagLib5ID3v223AttachedPictureFrameV22E@Base 1.6 - _ZTIN6TagLib5ID3v223TextIdentificationFrameE@Base 1.4 1 - _ZTIN6TagLib5ID3v225UniqueFileIdentifierFrameE@Base 1.4 1 - _ZTIN6TagLib5ID3v225UnsynchronizedLyricsFrameE@Base 1.5 - _ZTIN6TagLib5ID3v227UserTextIdentificationFrameE@Base 1.4 1 - _ZTIN6TagLib5ID3v230GeneralEncapsulatedObjectFrameE@Base 1.5 - _ZTIN6TagLib5ID3v23TagE@Base 1.4 1 - _ZTIN6TagLib5ID3v25Frame6HeaderE@Base 1.4 1 - _ZTIN6TagLib5ID3v25FrameE@Base 1.4 1 - _ZTIN6TagLib5ID3v26FooterE@Base 1.4 1 - _ZTIN6TagLib5ID3v26HeaderE@Base 1.4 1 - _ZTIN6TagLib6StringE@Base 1.4 1 - _ZTIN6TagLib6Vorbis10PropertiesE@Base 1.4 1 - _ZTIN6TagLib6Vorbis4FileE@Base 1.4 1 - _ZTIN6TagLib7FileRefE@Base 1.4 1 - _ZTIN6TagLib7WavPack10PropertiesE@Base 1.5 - _ZTIN6TagLib7WavPack4FileE@Base 1.5 - _ZTIN6TagLib9TrueAudio10PropertiesE@Base 1.5 - _ZTIN6TagLib9TrueAudio4FileE@Base 1.5 - _ZTSN6TagLib10ByteVectorE@Base 1.4 1 - _ZTSN6TagLib10StringListE@Base 1.4 1 - _ZTSN6TagLib14ByteVectorListE@Base 1.4 1 - _ZTSN6TagLib15AudioPropertiesE@Base 1.4 1 - _ZTSN6TagLib3APE10PropertiesE@Base 1.7 - _ZTSN6TagLib3APE3TagE@Base 1.4 1 - _ZTSN6TagLib3APE4FileE@Base 1.7 - _ZTSN6TagLib3APE4ItemE@Base 1.4 1 - _ZTSN6TagLib3APE6FooterE@Base 1.4 1 - _ZTSN6TagLib3ASF10PropertiesE@Base 1.6-2~ - _ZTSN6TagLib3ASF3TagE@Base 1.6-2~ - _ZTSN6TagLib3ASF4File10BaseObjectE@Base 1.6-2~ - _ZTSN6TagLib3ASF4File13UnknownObjectE@Base 1.6-2~ - _ZTSN6TagLib3ASF4File14MetadataObjectE@Base 1.6-2~ - _ZTSN6TagLib3ASF4File20FilePropertiesObjectE@Base 1.6-2~ - _ZTSN6TagLib3ASF4File21HeaderExtensionObjectE@Base 1.6-2~ - _ZTSN6TagLib3ASF4File21MetadataLibraryObjectE@Base 1.6-2~ - _ZTSN6TagLib3ASF4File22StreamPropertiesObjectE@Base 1.6-2~ - _ZTSN6TagLib3ASF4File24ContentDescriptionObjectE@Base 1.6-2~ - _ZTSN6TagLib3ASF4File32ExtendedContentDescriptionObjectE@Base 1.6-2~ - _ZTSN6TagLib3ASF4FileE@Base 1.6-2~ - _ZTSN6TagLib3ASF7PictureE@Base 1.7 - _ZTSN6TagLib3ASF9AttributeE@Base 1.6-2~ - _ZTSN6TagLib3MP410PropertiesE@Base 1.6-2~ - _ZTSN6TagLib3MP43TagE@Base 1.6-2~ - _ZTSN6TagLib3MP44FileE@Base 1.6-2~ - _ZTSN6TagLib3MPC10PropertiesE@Base 1.4 1 - _ZTSN6TagLib3MPC4FileE@Base 1.4 1 - _ZTSN6TagLib3Ogg10PageHeaderE@Base 1.4 1 - _ZTSN6TagLib3Ogg11XiphCommentE@Base 1.4 1 - _ZTSN6TagLib3Ogg4FLAC4FileE@Base 1.4 1 - _ZTSN6TagLib3Ogg4FileE@Base 1.4 1 - _ZTSN6TagLib3Ogg4PageE@Base 1.4 1 - _ZTSN6TagLib3Ogg5Speex10PropertiesE@Base 1.5 - _ZTSN6TagLib3Ogg5Speex4FileE@Base 1.5 - _ZTSN6TagLib3TagE@Base 1.4 1 - _ZTSN6TagLib4FLAC10PropertiesE@Base 1.4 1 - _ZTSN6TagLib4FLAC13MetadataBlockE@Base 1.7 - _ZTSN6TagLib4FLAC20UnknownMetadataBlockE@Base 1.7 - _ZTSN6TagLib4FLAC4FileE@Base 1.4 1 - _ZTSN6TagLib4FLAC7PictureE@Base 1.7 - _ZTSN6TagLib4FileE@Base 1.4 1 - _ZTSN6TagLib4MPEG10PropertiesE@Base 1.4 1 - _ZTSN6TagLib4MPEG10XingHeaderE@Base 1.4 1 - _ZTSN6TagLib4MPEG4FileE@Base 1.4 1 - _ZTSN6TagLib4MPEG6HeaderE@Base 1.4 1 - _ZTSN6TagLib4RIFF3WAV10PropertiesE@Base 1.6 - _ZTSN6TagLib4RIFF3WAV4FileE@Base 1.6 - _ZTSN6TagLib4RIFF4AIFF10PropertiesE@Base 1.6 - _ZTSN6TagLib4RIFF4AIFF4FileE@Base 1.6 - _ZTSN6TagLib4RIFF4FileE@Base 1.6 - _ZTSN6TagLib5ID3v113StringHandlerE@Base 1.4 1 - _ZTSN6TagLib5ID3v13TagE@Base 1.4 1 - _ZTSN6TagLib5ID3v212FrameFactoryE@Base 1.4 1 - _ZTSN6TagLib5ID3v212PrivateFrameE@Base 1.6 - _ZTSN6TagLib5ID3v212UnknownFrameE@Base 1.4 1 - _ZTSN6TagLib5ID3v212UrlLinkFrameE@Base 1.5 - _ZTSN6TagLib5ID3v213CommentsFrameE@Base 1.4 1 - _ZTSN6TagLib5ID3v214ExtendedHeaderE@Base 1.4 1 - _ZTSN6TagLib5ID3v216UserUrlLinkFrameE@Base 1.5 - _ZTSN6TagLib5ID3v218PopularimeterFrameE@Base 1.6 - _ZTSN6TagLib5ID3v219RelativeVolumeFrameE@Base 1.4 1 - _ZTSN6TagLib5ID3v220AttachedPictureFrameE@Base 1.4 1 - _ZTSN6TagLib5ID3v223AttachedPictureFrameV22E@Base 1.6 - _ZTSN6TagLib5ID3v223TextIdentificationFrameE@Base 1.4 1 - _ZTSN6TagLib5ID3v225UniqueFileIdentifierFrameE@Base 1.4 1 - _ZTSN6TagLib5ID3v225UnsynchronizedLyricsFrameE@Base 1.5 - _ZTSN6TagLib5ID3v227UserTextIdentificationFrameE@Base 1.4 1 - _ZTSN6TagLib5ID3v230GeneralEncapsulatedObjectFrameE@Base 1.5 - _ZTSN6TagLib5ID3v23TagE@Base 1.4 1 - _ZTSN6TagLib5ID3v25Frame6HeaderE@Base 1.4 1 - _ZTSN6TagLib5ID3v25FrameE@Base 1.4 1 - _ZTSN6TagLib5ID3v26FooterE@Base 1.4 1 - _ZTSN6TagLib5ID3v26HeaderE@Base 1.4 1 - _ZTSN6TagLib6StringE@Base 1.4 1 - _ZTSN6TagLib6Vorbis10PropertiesE@Base 1.4 1 - _ZTSN6TagLib6Vorbis4FileE@Base 1.4 1 - _ZTSN6TagLib7FileRefE@Base 1.4 1 - _ZTSN6TagLib7WavPack10PropertiesE@Base 1.5 - _ZTSN6TagLib7WavPack4FileE@Base 1.5 - _ZTSN6TagLib9TrueAudio10PropertiesE@Base 1.5 - _ZTSN6TagLib9TrueAudio4FileE@Base 1.5 - _ZTVN6TagLib10ByteVectorE@Base 1.4 1 - _ZTVN6TagLib10StringListE@Base 1.4 1 - _ZTVN6TagLib14ByteVectorListE@Base 1.4 1 - _ZTVN6TagLib15AudioPropertiesE@Base 1.4 1 - _ZTVN6TagLib3APE10PropertiesE@Base 1.7 - _ZTVN6TagLib3APE3TagE@Base 1.4 1 - _ZTVN6TagLib3APE4FileE@Base 1.7 - _ZTVN6TagLib3APE4ItemE@Base 1.4 1 - _ZTVN6TagLib3APE6FooterE@Base 1.4 1 - _ZTVN6TagLib3ASF10PropertiesE@Base 1.6-2~ - _ZTVN6TagLib3ASF3TagE@Base 1.6-2~ - _ZTVN6TagLib3ASF4File10BaseObjectE@Base 1.6-2~ - _ZTVN6TagLib3ASF4File13UnknownObjectE@Base 1.6-2~ - _ZTVN6TagLib3ASF4File14MetadataObjectE@Base 1.6-2~ - _ZTVN6TagLib3ASF4File20FilePropertiesObjectE@Base 1.6-2~ - _ZTVN6TagLib3ASF4File21HeaderExtensionObjectE@Base 1.6-2~ - _ZTVN6TagLib3ASF4File21MetadataLibraryObjectE@Base 1.6-2~ - _ZTVN6TagLib3ASF4File22StreamPropertiesObjectE@Base 1.6-2~ - _ZTVN6TagLib3ASF4File24ContentDescriptionObjectE@Base 1.6-2~ - _ZTVN6TagLib3ASF4File32ExtendedContentDescriptionObjectE@Base 1.6-2~ - _ZTVN6TagLib3ASF4FileE@Base 1.6-2~ - _ZTVN6TagLib3ASF7PictureE@Base 1.7 - _ZTVN6TagLib3ASF9AttributeE@Base 1.6-2~ - _ZTVN6TagLib3MP410PropertiesE@Base 1.6-2~ - _ZTVN6TagLib3MP43TagE@Base 1.6-2~ - _ZTVN6TagLib3MP44FileE@Base 1.6-2~ - _ZTVN6TagLib3MPC10PropertiesE@Base 1.4 1 - _ZTVN6TagLib3MPC4FileE@Base 1.4 1 - _ZTVN6TagLib3Ogg10PageHeaderE@Base 1.4 1 - _ZTVN6TagLib3Ogg11XiphCommentE@Base 1.4 1 - _ZTVN6TagLib3Ogg4FLAC4FileE@Base 1.4 1 - _ZTVN6TagLib3Ogg4FileE@Base 1.4 1 - _ZTVN6TagLib3Ogg4PageE@Base 1.4 1 - _ZTVN6TagLib3Ogg5Speex10PropertiesE@Base 1.5 - _ZTVN6TagLib3Ogg5Speex4FileE@Base 1.5 - _ZTVN6TagLib3TagE@Base 1.4 1 - _ZTVN6TagLib4FLAC10PropertiesE@Base 1.4 1 - _ZTVN6TagLib4FLAC13MetadataBlockE@Base 1.7 - _ZTVN6TagLib4FLAC20UnknownMetadataBlockE@Base 1.7 - _ZTVN6TagLib4FLAC4FileE@Base 1.4 1 - _ZTVN6TagLib4FLAC7PictureE@Base 1.7 - _ZTVN6TagLib4FileE@Base 1.4 1 - _ZTVN6TagLib4MPEG10PropertiesE@Base 1.4 1 - _ZTVN6TagLib4MPEG10XingHeaderE@Base 1.4 1 - _ZTVN6TagLib4MPEG4FileE@Base 1.4 1 - _ZTVN6TagLib4MPEG6HeaderE@Base 1.4 1 - _ZTVN6TagLib4RIFF3WAV10PropertiesE@Base 1.6 - _ZTVN6TagLib4RIFF3WAV4FileE@Base 1.6 - _ZTVN6TagLib4RIFF4AIFF10PropertiesE@Base 1.6 - _ZTVN6TagLib4RIFF4AIFF4FileE@Base 1.6 - _ZTVN6TagLib4RIFF4FileE@Base 1.6 - _ZTVN6TagLib5ID3v113StringHandlerE@Base 1.4 1 - _ZTVN6TagLib5ID3v13TagE@Base 1.4 1 - _ZTVN6TagLib5ID3v212FrameFactoryE@Base 1.4 1 - _ZTVN6TagLib5ID3v212PrivateFrameE@Base 1.6 - _ZTVN6TagLib5ID3v212UnknownFrameE@Base 1.4 1 - _ZTVN6TagLib5ID3v212UrlLinkFrameE@Base 1.5 - _ZTVN6TagLib5ID3v213CommentsFrameE@Base 1.4 1 - _ZTVN6TagLib5ID3v214ExtendedHeaderE@Base 1.4 1 - _ZTVN6TagLib5ID3v216UserUrlLinkFrameE@Base 1.5 - _ZTVN6TagLib5ID3v218PopularimeterFrameE@Base 1.6 - _ZTVN6TagLib5ID3v219RelativeVolumeFrameE@Base 1.4 1 - _ZTVN6TagLib5ID3v220AttachedPictureFrameE@Base 1.4 1 - _ZTVN6TagLib5ID3v223AttachedPictureFrameV22E@Base 1.6 - _ZTVN6TagLib5ID3v223TextIdentificationFrameE@Base 1.4 1 - _ZTVN6TagLib5ID3v225UniqueFileIdentifierFrameE@Base 1.4 1 - _ZTVN6TagLib5ID3v225UnsynchronizedLyricsFrameE@Base 1.5 - _ZTVN6TagLib5ID3v227UserTextIdentificationFrameE@Base 1.4 1 - _ZTVN6TagLib5ID3v230GeneralEncapsulatedObjectFrameE@Base 1.5 - _ZTVN6TagLib5ID3v23TagE@Base 1.4 1 - _ZTVN6TagLib5ID3v25Frame6HeaderE@Base 1.4 1 - _ZTVN6TagLib5ID3v25FrameE@Base 1.4 1 - _ZTVN6TagLib5ID3v26FooterE@Base 1.4 1 - _ZTVN6TagLib5ID3v26HeaderE@Base 1.4 1 - _ZTVN6TagLib6StringE@Base 1.4 1 - _ZTVN6TagLib6Vorbis10PropertiesE@Base 1.4 1 - _ZTVN6TagLib6Vorbis4FileE@Base 1.4 1 - _ZTVN6TagLib7FileRefE@Base 1.4 1 - _ZTVN6TagLib7WavPack10PropertiesE@Base 1.5 - _ZTVN6TagLib7WavPack4FileE@Base 1.5 - _ZTVN6TagLib9TrueAudio10PropertiesE@Base 1.5 - _ZTVN6TagLib9TrueAudio4FileE@Base 1.5 - _ZlsRSoRKN6TagLib10ByteVectorE@Base 1.4 1 - _ZlsRSoRKN6TagLib6StringE@Base 1.4 1 - _ZplPKcRKN6TagLib6StringE@Base 1.4 1 - _ZplRKN6TagLib6StringEPKc@Base 1.4 1 - _ZplRKN6TagLib6StringES2_@Base 1.4 1 diff -Nru taglib-1.7.2/debian/libtagc0-dev.examples taglib-1.8/debian/libtagc0-dev.examples --- taglib-1.7.2/debian/libtagc0-dev.examples 2010-05-13 21:52:24.000000000 +0000 +++ taglib-1.8/debian/libtagc0-dev.examples 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -examples/tagreader_c.c diff -Nru taglib-1.7.2/debian/libtagc0-dev.install taglib-1.8/debian/libtagc0-dev.install --- taglib-1.7.2/debian/libtagc0-dev.install 2012-02-19 19:02:04.000000000 +0000 +++ taglib-1.8/debian/libtagc0-dev.install 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -usr/include/taglib/tag_c.h -usr/lib/*/libtag_c.so -usr/lib/*/pkgconfig/taglib_c.pc diff -Nru taglib-1.7.2/debian/libtagc0.install taglib-1.8/debian/libtagc0.install --- taglib-1.7.2/debian/libtagc0.install 2012-02-19 19:02:04.000000000 +0000 +++ taglib-1.8/debian/libtagc0.install 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -usr/lib/*/libtag_c.so.0 -usr/lib/*/libtag_c.so.0.0.0 diff -Nru taglib-1.7.2/debian/libtagc0.lintian-overrides taglib-1.8/debian/libtagc0.lintian-overrides --- taglib-1.7.2/debian/libtagc0.lintian-overrides 2010-05-13 21:52:24.000000000 +0000 +++ taglib-1.8/debian/libtagc0.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -libtagc0: package-name-doesnt-match-sonames libtag-c0 diff -Nru taglib-1.7.2/debian/libtagc0.symbols taglib-1.8/debian/libtagc0.symbols --- taglib-1.7.2/debian/libtagc0.symbols 2012-06-27 22:37:25.000000000 +0000 +++ taglib-1.8/debian/libtagc0.symbols 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -# SymbolsHelper-Confirmed: 1.7.1 amd64 -libtag_c.so.0 libtagc0 #MINVER# -| libtagc0 (>= 1.4) - (optional=templinst|arch=amd64 hurd-i386 i386 kfreebsd-i386 kfreebsd-amd64)_ZNSt10_List_baseIPcSaIS0_EE8_M_clearEv@Base 1.7.2 - taglib_audioproperties_bitrate@Base 1.4 1 - taglib_audioproperties_channels@Base 1.4 1 - taglib_audioproperties_length@Base 1.4 1 - taglib_audioproperties_samplerate@Base 1.4 1 - taglib_file_audioproperties@Base 1.4 1 - taglib_file_free@Base 1.4 1 - taglib_file_is_valid@Base 1.5 - taglib_file_new@Base 1.4 1 - taglib_file_new_type@Base 1.4 1 - taglib_file_save@Base 1.4 1 - taglib_file_tag@Base 1.4 1 - taglib_id3v2_set_default_text_encoding@Base 1.5 - taglib_set_string_management_enabled@Base 1.4 1 - taglib_set_strings_unicode@Base 1.4 1 - taglib_tag_album@Base 1.4 1 - taglib_tag_artist@Base 1.4 1 - taglib_tag_comment@Base 1.4 1 - taglib_tag_free_strings@Base 1.4 1 - taglib_tag_genre@Base 1.4 1 - taglib_tag_set_album@Base 1.4 1 - taglib_tag_set_artist@Base 1.4 1 - taglib_tag_set_comment@Base 1.4 1 - taglib_tag_set_genre@Base 1.4 1 - taglib_tag_set_title@Base 1.4 1 - taglib_tag_set_track@Base 1.4 1 - taglib_tag_set_year@Base 1.4 1 - taglib_tag_title@Base 1.4 1 - taglib_tag_track@Base 1.4 1 - taglib_tag_year@Base 1.4 1 diff -Nru taglib-1.7.2/debian/patches/backport_id3v2_null_pointer.diff taglib-1.8/debian/patches/backport_id3v2_null_pointer.diff --- taglib-1.7.2/debian/patches/backport_id3v2_null_pointer.diff 2012-02-19 18:38:50.000000000 +0000 +++ taglib-1.8/debian/patches/backport_id3v2_null_pointer.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -Author: Jonathan Liu -Subject: Use the default frame factory when it's necessary to parse ID3v2 tags in APE files -Date: Sat Aug 6 11:05:11 2011 +0200 -Bug: https://bugs.kde.org/show_bug.cgi?id=278773 -Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=656226 -Origin: backport, commit:7cc36db7606dfc85d2e344d35c4e26fe8f698bdc - -diff --git a/taglib/ape/apeproperties.cpp b/taglib/ape/apeproperties.cpp -index 3154d10..aab9d25 100644 ---- a/taglib/ape/apeproperties.cpp -+++ b/taglib/ape/apeproperties.cpp -@@ -137,7 +137,7 @@ long APE::Properties::findDescriptor() - long ID3v2OriginalSize = 0; - bool hasID3v2 = false; - if(ID3v2Location >= 0) { -- ID3v2::Tag tag(d->file, ID3v2Location, 0); -+ ID3v2::Tag tag(d->file, ID3v2Location); - ID3v2OriginalSize = tag.header()->completeTagSize(); - if(tag.header()->tagSize() > 0) - hasID3v2 = true; diff -Nru taglib-1.7.2/debian/patches/multiarch.diff taglib-1.8/debian/patches/multiarch.diff --- taglib-1.7.2/debian/patches/multiarch.diff 2012-02-19 18:50:09.000000000 +0000 +++ taglib-1.8/debian/patches/multiarch.diff 2012-09-23 07:47:42.000000000 +0000 @@ -3,9 +3,11 @@ installation, so don't use the "FORCE" option to set(). Author: Steve Langasek ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -19,7 +19,7 @@ set(EXEC_INSTALL_PREFIX ${CMAKE_INSTALL +Index: trunk/CMakeLists.txt +=================================================================== +--- trunk.orig/CMakeLists.txt ++++ trunk/CMakeLists.txt +@@ -19,7 +19,7 @@ # ## the following are directories where stuff will be installed to set(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "The subdirectory to the binaries prefix (default prefix/bin)" FORCE) diff -Nru taglib-1.7.2/debian/patches/multiarch.patch taglib-1.8/debian/patches/multiarch.patch --- taglib-1.7.2/debian/patches/multiarch.patch 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/debian/patches/multiarch.patch 2012-09-23 07:47:42.000000000 +0000 @@ -0,0 +1,14 @@ +Description: multiarch + multiarch patch + +--- taglib-1.8.orig/CMakeLists.txt ++++ taglib-1.8/CMakeLists.txt +@@ -28,7 +28,7 @@ set(TESTS_DIR "${CMAKE_CURRENT_SOURCE_DI + 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" FORCE) + set(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "The subdirectory to the binaries prefix (default prefix/bin)" FORCE) +-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})" FORCE) ++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" FORCE) + + if(APPLE) diff -Nru taglib-1.7.2/debian/patches/series taglib-1.8/debian/patches/series --- taglib-1.7.2/debian/patches/series 2012-04-15 16:03:35.000000000 +0000 +++ taglib-1.8/debian/patches/series 2012-09-23 07:47:42.000000000 +0000 @@ -1,2 +0,0 @@ -multiarch.diff -backport_id3v2_null_pointer.diff diff -Nru taglib-1.7.2/debian/patches/upstream_doxygen_out_of_source.diff taglib-1.8/debian/patches/upstream_doxygen_out_of_source.diff --- taglib-1.7.2/debian/patches/upstream_doxygen_out_of_source.diff 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/debian/patches/upstream_doxygen_out_of_source.diff 2012-09-23 07:47:42.000000000 +0000 @@ -0,0 +1,41 @@ +From: Modestas Vainius +Subject: Support building documentation out-of-source-dir +Forwarded: no +Origin: vendor +Last-Update: 2011-04-09 + +--- a/Doxyfile.cmake ++++ b/Doxyfile.cmake +@@ -61,7 +61,7 @@ WARN_LOGFILE = + #--------------------------------------------------------------------------- + # configuration options related to the input files + #--------------------------------------------------------------------------- +-INPUT = taglib ++INPUT = @CMAKE_SOURCE_DIR@/taglib + FILE_PATTERNS = *.h \ + *.hh \ + *.H +@@ -96,9 +96,9 @@ IGNORE_PREFIX = + GENERATE_HTML = YES + HTML_OUTPUT = html + HTML_FILE_EXTENSION = .html +-HTML_HEADER = doc/api-header.html +-HTML_FOOTER = doc/api-footer.html +-HTML_STYLESHEET = doc/taglib-api.css ++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 + GENERATE_HTMLHELP = NO + CHM_FILE = +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -76,6 +76,7 @@ endif(NOT WIN32) + + INSTALL( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/taglib-config DESTINATION ${BIN_INSTALL_DIR}) + +-CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.cmake ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile) ++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) + diff -Nru taglib-1.7.2/debian/postinst taglib-1.8/debian/postinst --- taglib-1.7.2/debian/postinst 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/debian/postinst 2012-09-23 07:47:42.000000000 +0000 @@ -0,0 +1,52 @@ +#!/bin/bash +# postinst script for libtag1x8 +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + [ -d /usr/local/lib/pkgconfig ] || mkdir -p /usr/local/lib/pkgconfig + [ -h /usr/local/lib/pkgconfig/taglib.pc ] || ln -s /opt/taglib-1.8/lib/pkgconfig/taglib.pc /usr/local/lib/pkgconfig/taglib.pc + [ -h /usr/local/lib/pkgconfig/taglib_c.pc ] || ln -s /opt/taglib-1.8/lib/pkgconfig/taglib_c.pc /usr/local/lib/pkgconfig/taglib_c.pc + [ -f /usr/local/lib/libtag.a ] || ln -s /opt/taglib-1.8/lib/libtag.a /usr/local/lib/libtag.a + [ -f /usr/local/lib/libtag_c.a ] || ln -s /opt/taglib-1.8/lib/libtag_c.a /usr/local/lib/libtag_c.a + [ -d /usr/local/include ] || mkdir /usr/local/include + [ -h /usr/local/include/taglib ] || ln -s /opt/taglib-1.8/include/taglib /usr/local/include/taglib + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + [ -d /usr/local/include/taglib ] && rm -rf /usr/local/include/taglib + [ -h /usr/local/lib/libtag.a ] && rm /usr/local/lib/libtag.a + [ -h /usr/local/lib/libtag_c.a ] && rm /usr/local/lib/libtag_c.a + [ -h /usr/local/lib/pkgconfig/taglib.pc ] && rm /usr/local/lib/pkgconfig/taglib.pc + [ -h /usr/local/lib/pkgconfig/taglib_c.pc ] && rm /usr/local/lib/pkgconfig/taglib_c.pc + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff -Nru taglib-1.7.2/debian/postinst.old taglib-1.8/debian/postinst.old --- taglib-1.7.2/debian/postinst.old 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/debian/postinst.old 2012-09-23 07:47:42.000000000 +0000 @@ -0,0 +1,58 @@ +#!/bin/bash +# postinst script for libtag1x8 +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + [ -d /usr/local/lib/pkgconfig ] || mkdir -p /usr/local/lib/pkgconfig + [ -h /usr/local/lib/pkgconfig/taglib.pc ] || ln -s /opt/taglib-1.8/lib/pkgconfig/taglib.pc /usr/local/lib/pkgconfig/taglib.pc + [ -h /usr/local/lib/pkgconfig/taglib_c.pc ] || ln -s /opt/taglib-1.8/lib/pkgconfig/taglib_c.pc /usr/local/lib/pkgconfig/taglib_c.pc + [ -h /usr/local/lib/libtag.so.1 ] || ln /opt/taglib-1.8/lib/libtag.so.1 /usr/local/lib/libtag.so.1 + [ -h /usr/local/lib/libtag.so.1.12.0 ] || ln -s /opt/taglib-1.8/lib/libtag.so.1.12.0 /usr/local/lib/libtag.so.1.12.0 + [ -h /usr/local/lib/libtag.so ] || ln -s /opt/taglib-1.8/lib/libtag.so /usr/local/lib/libtag.so + [ -h /usr/local/lib/libtag_c.so ] || ln -s /opt/taglib-1.8/lib/libtag_c.so /usr/local/lib/libtag_c.so + [ -h /usr/local/lib/libtag_c.so.0 ] || ln -s /opt/taglib-1.8/lib/libtag_c.so.0 /usr/local/lib/libtag_c.so.0 + [ -d /usr/local/include ] || mkdir /usr/local/include + [ -h /usr/local/include/taglib ] || ln -s /opt/taglib-1.8/include/taglib /usr/local/include/taglib + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + [ -d /usr/local/include/taglib ] && rm -rf /usr/local/include/taglib + [ -h /usr/local/lib/libtag_c.so.0 ] && rm /usr/local/lib/libtag_c.so.0 + [ -h /usr/local/lib/libtag_c.so ] && rm /usr/local/lib/libtag_c.so + [ -h /usr/local/lib/libtag.so ] && rm /usr/local/lib/libtag.so + [ -h /usr/local/lib/libtag.so.1.12.0 ] && rm /usr/local/lib/libtag.so.1.12.0 + [ -h /usr/local/lib/libtag.so.1 ] && rm /usr/local/lib/libtag.so.1 + [ -h /usr/local/lib/pkgconfig/taglib.pc ] && rm /usr/local/lib/pkgconfig/taglib.pc + [ -h /usr/local/lib/pkgconfig/taglib_c.pc ] && rm /usr/local/lib/pkgconfig/taglib_c.pc + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff -Nru taglib-1.7.2/debian/postrm taglib-1.8/debian/postrm --- taglib-1.7.2/debian/postrm 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/debian/postrm 2012-09-23 07:47:42.000000000 +0000 @@ -0,0 +1,41 @@ +#!/bin/sh +# postrm script for libtag1x8 +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + [ -d /usr/local/include/taglib ] && rm -rf /usr/local/include/taglib + [ -h /usr/local/lib/libtag.a ] && rm /usr/local/lib/libtag.a + [ -h /usr/local/lib/libtag_c.a ] && rm /usr/local/lib/libtag_c.a + [ -h /usr/local/lib/pkgconfig/taglib.pc ] && rm /usr/local/lib/pkgconfig/taglib.pc + [ -h /usr/local/lib/pkgconfig/taglib_c.pc ] && rm /usr/local/lib/pkgconfig/taglib_c.pc + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff -Nru taglib-1.7.2/debian/postrm.old taglib-1.8/debian/postrm.old --- taglib-1.7.2/debian/postrm.old 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/debian/postrm.old 2012-09-23 07:47:42.000000000 +0000 @@ -0,0 +1,44 @@ +#!/bin/sh +# postrm script for libtag1x8 +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + [ -d /usr/local/include/taglib ] && rm -rf /usr/local/include/taglib + [ -h /usr/local/lib/libtag_c.so.0 ] && rm /usr/local/lib/libtag_c.so.0 + [ -h /usr/local/lib/libtag_c.so ] && rm /usr/local/lib/libtag_c.so + [ -h /usr/local/lib/libtag.so ] && rm /usr/local/lib/libtag.so + [ -h /usr/local/lib/libtag.so.1.12.0 ] && rm /usr/local/lib/libtag.so.1.12.0 + [ -h /usr/local/lib/libtag.so.1 ] && rm /usr/local/lib/libtag.so.1 + [ -h /usr/local/lib/pkgconfig/taglib.pc ] && rm /usr/local/lib/pkgconfig/taglib.pc + [ -h /usr/local/lib/pkgconfig/taglib_c.pc ] && rm /usr/local/lib/pkgconfig/taglib_c.pc + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff -Nru taglib-1.7.2/debian/rules taglib-1.8/debian/rules --- taglib-1.7.2/debian/rules 2012-04-16 19:56:28.000000000 +0000 +++ taglib-1.8/debian/rules 2012-09-23 07:47:42.000000000 +0000 @@ -1,100 +1,21 @@ #! /usr/bin/make -f -export DEB_CFLAGS_MAINT_APPEND += -fvisibility=hidden -fvisibility-inlines-hidden -export DEB_CXXFLAGS_MAINT_APPEND += -fvisibility=hidden -fvisibility-inlines-hidden -DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) +#export CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden +#export CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -CMAKE_ARGS = -DCMAKE_USE_RELATIVE_PATHS=ON -DWITH_ASF=ON -DWITH_MP4=ON -DLIB_INSTALL_DIR:PATH=/usr/lib/$(DEB_HOST_MULTIARCH) +CMAKE_ARGS = -DCMAKE_INSTALL_PREFIX=/opt/taglib-1.8 -DENABLE_STATIC=1 -DCMAKE_RELEASE_TYPE=Release DH_AUTO_ARGS = --buildsystem=cmake -QUILT := quilt --quiltrc /dev/null -MAKE_ME = $(MAKE) -f $(lastword $(MAKEFILE_LIST)) - -FLAVOURS := vanilla rusxmms -flavour = $(filter-out %-,$(subst -,- ,$@)) -builddir = builddir-$(flavour) - -# Various "functions" (can be invoked via $(call ...)) -buildstamp = $(patsubst %,debian/stamp-build-%,$(1)) -libpkg = libtag1-$(1) -quilt_safe = $(QUILT) $(1) || test $$? = 2 - -### Handle patching of rusxmms flavour ### -RUSXMMS_PATCH_DIR := debian/rusxmms-patches -RUSXMMS_PATCH_SERIES := debian/rusxmms-patches/series - -$(RUSXMMS_PATCH_SERIES): - cat $(wildcard debian/patches/series) $(RUSXMMS_PATCH_DIR)/rusxmms_series > $@ - -debian/stamp-patch-rusxmms: $(RUSXMMS_PATCH_SERIES) - QUILT_PATCHES="$(RUSXMMS_PATCH_DIR)" $(call quilt_safe,push -a) - touch $@ - -unpatch-rusxmms: $(RUSXMMS_PATCH_SERIES) - lastpatch="$(shell QUILT_SERIES=debian/patches/series $(QUILT) series | tail -n1)"; \ - if [ -z "$$lastpatch" ]; then \ - QUILT_PATCHES="$(RUSXMMS_PATCH_DIR)" $(call quilt_safe,pop -a); \ - elif $(QUILT) applied | grep -qF $$lastpatch; then \ - QUILT_PATCHES="$(RUSXMMS_PATCH_DIR)" $(call quilt_safe,pop $$lastpatch); \ - fi - -### Build rusxmms first, then build vanilla ### -$(call buildstamp,$(FLAVOURS)): - @echo Building $(flavour) - dh_auto_configure --parallel --builddirectory=$(builddir) $(DH_AUTO_ARGS) -- $(CMAKE_ARGS) - dh_auto_build --parallel --builddirectory=$(builddir) $(DH_AUTO_ARGS) - touch $@ - -$(call buildstamp,rusxmms): debian/stamp-patch-rusxmms -$(call buildstamp,vanilla): | unpatch-rusxmms override_dh_auto_configure: -ifneq ($(shell dh_listpackages -p$(call libpkg,rusxmms)),) - $(MAKE_ME) $(call buildstamp,rusxmms) -endif -ifneq ($(shell dh_listpackages -p$(call libpkg,vanilla)),) - $(MAKE_ME) $(call buildstamp,vanilla) -endif + dh_auto_configure $(DH_AUTO_ARGS) -- $(CMAKE_ARGS) ### Install / binary building ### override_dh_auto_install: -ifneq ($(shell dh_listpackages -p$(call libpkg,vanilla)),) - dh_auto_install --builddirectory=builddir-vanilla $(DH_AUTO_ARGS) -endif -ifneq ($(shell dh_listpackages -p$(call libpkg,rusxmms)),) - install -d -m755 debian/tmp-rusxmms/usr/lib/$(DEB_HOST_MULTIARCH) - cp -a builddir-rusxmms/taglib/libtag.so.* debian/tmp-rusxmms/usr/lib/$(DEB_HOST_MULTIARCH)/ -endif - -override_dh_installdocs: - dh_installdocs - # Install bindings README - if [ -d debian/libtag1c2a ]; then \ - install -m644 -oroot -groot -T bindings/README debian/libtag1c2a/usr/share/doc/libtag1c2a/README.bindings; \ - fi; - -override_dh_install: - dh_install -plibtag1-rusxmms --sourcedir=$(CURDIR)/debian/tmp-rusxmms - dh_install -Nlibtag1-rusxmms - -# Generate docs when building indep -builddir-vanilla/doc/html/index.html: $(call buildstamp,vanilla) - # build-indep gets invoked in buildds as well... - if [ -x /usr/bin/doxygen ]; then \ - dh_auto_build --buildsystem=makefile --builddirectory=builddir-vanilla -- docs; \ - fi - -build-indep: builddir-vanilla/doc/html/index.html - -clean: unpatch-rusxmms - dh_auto_clean --builddirectory=builddir-vanilla $(DH_AUTO_ARGS) - dh_auto_clean --builddirectory=builddir-rusxmms $(DH_AUTO_ARGS) - rm -rf $(patsubst %,debian/tmp-%,$(FLAVOURS)) - rm -f debian/stamp-* - rm -f $(RUSXMMS_PATCH_SERIES) - # Clean documentation - rm -rf doc/html - dh clean + dh_auto_install $(DH_AUTO_ARGS) + +override_dh_usrlocal: -# All-in-one default dh rule +override_dh_shlibdeps: + dh_shlibdeps -Llibtag1x8 -l/opt/taglib-1.8/lib/ %: - dh $@ --parallel + dh $@ diff -Nru taglib-1.7.2/debian/rusxmms-patches/rusxmms_series taglib-1.8/debian/rusxmms-patches/rusxmms_series --- taglib-1.7.2/debian/rusxmms-patches/rusxmms_series 2010-05-13 21:52:24.000000000 +0000 +++ taglib-1.8/debian/rusxmms-patches/rusxmms_series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -rusxmms_taglib.diff diff -Nru taglib-1.7.2/debian/rusxmms-patches/rusxmms_taglib.diff taglib-1.8/debian/rusxmms-patches/rusxmms_taglib.diff --- taglib-1.7.2/debian/rusxmms-patches/rusxmms_taglib.diff 2011-04-09 14:44:34.000000000 +0000 +++ taglib-1.8/debian/rusxmms-patches/rusxmms_taglib.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,510 +0,0 @@ -From: Ivan Borzenkov -Subject: Add RusXMMS support to taglib (autodetection of cyrillic locales) -Acked-By: Modestas Vainius -Bug-Debian: http://bugs.debian.org/384573 -Forwarded: not-needed -Origin: other -Last-Update: 2011-04-09 - -libtag1-rusxmms flavour is built with this patch applied. - ---- a/config-taglib.h.cmake -+++ b/config-taglib.h.cmake -@@ -6,6 +6,8 @@ - /* Define if you have libz */ - #cmakedefine HAVE_ZLIB 1 - -+#cmakedefine HAVE_LIBRCC 1 -+ - #cmakedefine NO_ITUNES_HACKS 1 - #cmakedefine WITH_ASF 1 - #cmakedefine WITH_MP4 1 ---- a/ConfigureChecks.cmake -+++ b/ConfigureChecks.cmake -@@ -14,6 +14,8 @@ include(CheckCXXSourceCompiles) - #check for libz using the cmake supplied FindZLIB.cmake - FIND_PACKAGE(ZLIB) - -+SET(HAVE_LIBRCC 1) -+ - IF(ZLIB_FOUND) - SET(HAVE_ZLIB 1) - ELSE(ZLIB_FOUND) ---- a/taglib/CMakeLists.txt -+++ b/taglib/CMakeLists.txt -@@ -171,6 +171,7 @@ riff/wav/wavproperties.cpp - ) - - SET(toolkit_SRCS -+toolkit/rccpatch.cpp - toolkit/tstring.cpp - toolkit/tstringlist.cpp - toolkit/tbytevector.cpp -@@ -198,7 +199,7 @@ else(ENABLE_STATIC) - add_library(tag SHARED ${tag_LIB_SRCS}) - endif(ENABLE_STATIC) - --TARGET_LINK_LIBRARIES(tag ) -+TARGET_LINK_LIBRARIES(tag rcc) - if(ZLIB_FOUND) - TARGET_LINK_LIBRARIES(tag ${ZLIB_LIBRARIES}) - endif(ZLIB_FOUND) ---- a/taglib/mpeg/id3v1/id3v1tag.cpp -+++ b/taglib/mpeg/id3v1/id3v1tag.cpp -@@ -59,17 +59,18 @@ const ID3v1::StringHandler *ID3v1::Tag:: - - String ID3v1::StringHandler::parse(const ByteVector &data) const - { -- return String(data, String::Latin1).stripWhiteSpace(); -+ return String(data, String::Latin1ID3).stripWhiteSpace(); - } - - ByteVector ID3v1::StringHandler::render(const String &s) const - { - if(!s.isLatin1()) - { -+ if (String::ID3WType(String::Latin1) == String::Latin1) - return ByteVector(); - } - -- return s.data(String::Latin1); -+ return s.data(String::Latin1ID3); - } - - //////////////////////////////////////////////////////////////////////////////// -@@ -240,7 +241,7 @@ void ID3v1::Tag::parse(const ByteVector - d->track = uchar(data[offset + 29]); - } - else -- d->comment = data.mid(offset, 30); -+ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); - - offset += 30; - ---- a/taglib/mpeg/id3v2/frames/commentsframe.cpp -+++ b/taglib/mpeg/id3v2/frames/commentsframe.cpp -@@ -136,10 +136,10 @@ void CommentsFrame::parseFields(const By - return; - } - -- d->textEncoding = String::Type(data[0]); -+ d->textEncoding = String::ID3Type(data[0]); - d->language = data.mid(1, 3); - -- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; -+ int byteAlign = d->textEncoding == (String::Latin1 || String::Latin1ID3 || String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; - - ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); - -@@ -155,10 +155,12 @@ ByteVector CommentsFrame::renderFields() - - String::Type encoding = d->textEncoding; - -+ encoding = String::ID3WType(encoding); -+ - encoding = checkEncoding(d->description, encoding); - encoding = checkEncoding(d->text, encoding); - -- v.append(char(encoding)); -+ v.append(char(String::ID3RealType(encoding))); - v.append(d->language.size() == 3 ? d->language : "XXX"); - v.append(d->description.data(encoding)); - v.append(textDelimiter(encoding)); ---- a/taglib/mpeg/id3v2/frames/textidentificationframe.cpp -+++ b/taglib/mpeg/id3v2/frames/textidentificationframe.cpp -@@ -105,12 +105,12 @@ void TextIdentificationFrame::parseField - - // read the string data type (the first byte of the field data) - -- d->textEncoding = String::Type(data[0]); -+ d->textEncoding = String::ID3Type(data[0]); - - // split the byte array into chunks based on the string type (two byte delimiter - // for unicode encodings) - -- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; -+ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; - - // build a small counter to strip nulls off the end of the field - -@@ -139,11 +139,14 @@ void TextIdentificationFrame::parseField - - ByteVector TextIdentificationFrame::renderFields() const - { -- String::Type encoding = checkEncoding(d->fieldList, d->textEncoding); -+ String::Type encoding = d->textEncoding; -+ -+ encoding = String::ID3WType(encoding); -+ encoding = checkEncoding(d->fieldList, encoding); - - ByteVector v; - -- v.append(char(encoding)); -+ v.append(char(String::ID3RealType(encoding))); - - for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { - ---- a/taglib/toolkit/CMakeLists.txt -+++ b/taglib/toolkit/CMakeLists.txt -@@ -1 +1 @@ --INSTALL( FILES taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) -+INSTALL( FILES rccpatch.h taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) ---- /dev/null -+++ b/taglib/toolkit/rccpatch.cpp -@@ -0,0 +1,198 @@ -+#include -+ -+#include -+#include "tstring.h" -+#include "tbytevector.h" -+ -+#ifndef HAVE_LIBRCC -+#include -+#endif -+ -+#ifdef HAVE_LIBRCC -+#include -+#include -+#endif /* HAVE_LIBRCC */ -+ -+ -+#ifdef HAVE_LIBRCC -+# define ID3_CLASS 0 -+# define ID3V2_CLASS 1 -+# define UTF_CLASS 2 -+# define OUT_CLASS 3 -+static rcc_class classes[] = { -+ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, -+ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, -+ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, -+ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, -+ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } -+}; -+ -+static int rcc_initialized = 0; -+ -+static rcc_context ctx = NULL; -+#endif /* HAVE_LIBRCC */ -+ -+ -+void rccPatchFree() { -+#ifdef HAVE_LIBRCC -+ if (rcc_initialized) { -+ rccFree(); -+ rcc_initialized = 0; -+ } -+#endif /* HAVE_LIBRCC */ -+} -+ -+void rccPatchInit() { -+#ifdef HAVE_LIBRCC -+ if (rcc_initialized) return; -+ rccInit(); -+ rccInitDefaultContext(NULL, 0, 0, classes, 0); -+ rccLoad(NULL, "xmms"); -+ rccInitDb4(NULL, NULL, 0); -+ rcc_initialized = 1; -+#endif /* HAVE_LIBRCC */ -+} -+ -+void rccPatchSetContext(void *newctx) { -+#ifdef HAVE_LIBRCC -+ if (newctx) { -+ ctx = (rcc_context)newctx; -+ rcc_initialized = 1; -+ } -+#endif /* HAVE_LIBRCC */ -+} -+ -+static void rccPatchTryInit() { -+#ifdef HAVE_LIBRCC -+ if (!rcc_initialized) { -+ rccPatchInit(); -+ if (rcc_initialized) atexit(rccPatchFree); -+ } -+#endif /* HAVE_LIBRCC */ -+} -+ -+ -+TagLib::ByteVector rccPatchRecodeOutput(const std::string &s) { -+ TagLib::ByteVector v; -+#ifdef HAVE_LIBRCC -+ size_t rlen; -+ char *res; -+ -+ rccPatchTryInit(); -+ -+ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); -+ if (res) v.setData(res, rlen); -+ else v.setData(s.c_str(), s.length()); -+ -+ return v; -+#else -+ v.setData("", 0); -+ -+ return v; -+#endif /* HAVE_LIBRCC */ -+} -+ -+TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false) { -+ TagLib::ByteVector v; -+#ifdef HAVE_LIBRCC -+ size_t rlen; -+ char *res; -+ -+ rccPatchTryInit(); -+ -+ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); -+ if (res) v.setData(res, rlen); -+ else v.setData(s.c_str(), s.length()); -+ -+ return v; -+#else -+ v.setData("", 0); -+ -+ return v; -+#endif /* HAVE_LIBRCC */ -+} -+ -+TagLib::ByteVector rccPatchRecodeInput(const std::string &s) { -+ TagLib::ByteVector v; -+#ifdef HAVE_LIBRCC -+ size_t rlen; -+ char *res; -+ -+ rccPatchTryInit(); -+ -+ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); -+ if (res) v.setData(res, rlen); -+ else v.setData(s.c_str(), s.length()); -+ -+ return v; -+#else -+ v.setData("", 0); -+ -+ return v; -+#endif /* HAVE_LIBRCC */ -+} -+ -+TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false) { -+ TagLib::ByteVector v; -+#ifdef HAVE_LIBRCC -+ size_t rlen; -+ char *res; -+ -+ rccPatchTryInit(); -+ -+ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); -+ if (res) v.setData(res, rlen); -+ else v.setData(s.c_str(), s.length()); -+ -+ return v; -+#else -+ v.setData("", 0); -+ -+ return v; -+#endif /* HAVE_LIBRCC */ -+} -+ -+TagLib::String::Type rccPatchGetLocaleType() { -+#ifdef HAVE_LIBRCC -+ size_t len; -+ char charset[32]; -+ -+ rccPatchTryInit(); -+ -+ if (!rccLocaleGetCharset(charset, NULL, 31)) { -+ if (!strncmp(charset, "UTF", 3)) { -+ len = strlen(charset); -+ -+ if (charset[len-1]=='8') return TagLib::String::UTF8; -+ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; -+ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; -+ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; -+ } -+ return TagLib::String::Latin1; -+ } -+#endif /* HAVE_LIBRCC */ -+ return TagLib::String::UTF8; -+} -+ -+TagLib::String::Type rccPatchGetID3Type() { -+#ifdef HAVE_LIBRCC -+ size_t len; -+ const char *charset; -+ -+ rccPatchTryInit(); -+ -+ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); -+ if (charset) { -+ if (!strncmp(charset, "UTF", 3)) { -+ len = strlen(charset); -+ -+ if (charset[len-1]=='8') return TagLib::String::UTF8; -+ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; -+ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; -+ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; -+ } -+ return TagLib::String::Latin1ID3V2; -+ } -+#endif /* HAVE_LIBRCC */ -+ return TagLib::String::Latin1; -+} ---- /dev/null -+++ b/taglib/toolkit/rccpatch.h -@@ -0,0 +1,20 @@ -+#ifndef _RCC_PATCH_H -+#define _RCC_PATCH_H -+ -+#include -+#include "tstring.h" -+#include "tbytevector.h" -+ -+void rccPatchFree(); -+void rccPatchInit(); -+void rccPatchSetContext(void *newctx); -+ -+TagLib::ByteVector rccPatchRecodeOutput(const std::string &s); -+TagLib::ByteVector rccPatchRecodeInput(const std::string &s); -+TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false); -+TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false); -+ -+TagLib::String::Type rccPatchGetLocaleType(); -+TagLib::String::Type rccPatchGetID3Type(); -+ -+#endif /* _RCC_PATCH_H */ ---- a/taglib/toolkit/tstring.cpp -+++ b/taglib/toolkit/tstring.cpp -@@ -23,6 +23,7 @@ - * http://www.mozilla.org/MPL/ * - ***************************************************************************/ - -+#include "rccpatch.h" - #include "tstring.h" - #include "unicode.h" - #include "tdebug.h" -@@ -167,7 +168,7 @@ String::String(const ByteVector &v, Type - if(v.isEmpty()) - return; - -- if(t == Latin1 || t == UTF8) { -+ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2 || t == UTF8) { - - int length = 0; - d->data.resize(v.size()); -@@ -369,10 +370,21 @@ ByteVector String::data(Type t) const - { - ByteVector v; - -- switch(t) { -+ if (t == Locale) t = rccPatchGetLocaleType(); - -+ switch(t) { -+ case Locale: - case Latin1: -+ case Latin1ID3: -+ case Latin1ID3V2: - { -+ std::string s = to8Bit(true); -+ if (t == Latin1ID3) v = rccPatchRecodeOutputID3(s, false); -+ else if (t == Latin1ID3V2) v = rccPatchRecodeOutputID3(s, true); -+ else /* if (t == Latin1(Locale) */ v = rccPatchRecodeOutput(s); -+ -+ if (v.size()) return v; -+ - for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) - v.append(char(*it)); - break; -@@ -717,6 +729,31 @@ void String::detach() - - void String::prepare(Type t) - { -+ if (t == Locale) t = rccPatchGetLocaleType(); -+ -+ if ((t == Latin1)||(t == Latin1ID3)||(t == Latin1ID3V2)) { -+ std::string s = to8Bit(false); -+ ByteVector v; -+ -+ if (t == Latin1ID3) v = rccPatchRecodeInputID3(s, false); -+ else if (t == Latin1ID3V2) v = rccPatchRecodeInputID3(s, true); -+ else /* Latin1 converted from Locale */ v = rccPatchRecodeInput(s); -+ -+ if (v.size()) { -+ int length = 0; -+ d->data.resize(v.size()); -+ wstring::iterator targetIt = d->data.begin(); -+ for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { -+ *targetIt = uchar(*it); -+ ++targetIt; -+ ++length; -+ } -+ d->data.resize(length); -+ } -+ -+ t = UTF8; -+ } -+ - switch(t) { - case UTF16: - { -@@ -806,6 +843,27 @@ const TagLib::String operator+(const Tag - - std::ostream &operator<<(std::ostream &s, const String &str) - { -- s << str.to8Bit(); -+ ByteVector bv = str.data(String::Locale); -+ s << bv; - return s; - } -+ -+String::Type String::ID3Type(int i) { -+ if (i == Latin1) return Latin1ID3V2; -+ return Type(i); -+}; -+ -+String::Type String::ID3WType(Type type) { -+ Type rcc_type = rccPatchGetID3Type(); -+ if ((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)) { -+ if (type == Latin1) return rcc_type; -+ return type; -+ } -+ -+ return rcc_type; -+}; -+ -+String::Type String::ID3RealType(Type type) { -+ if ((type == Latin1ID3)||(type == Latin1ID3V2)) return Latin1; -+ return type; -+} ---- a/taglib/toolkit/tstring.h -+++ b/taglib/toolkit/tstring.h -@@ -88,6 +88,18 @@ namespace TagLib { - */ - enum Type { - /*! -+ * Determine using current locale settings -+ */ -+ Locale = -1, -+ /*! -+ * Latin1 for ID3 tags. -+ */ -+ Latin1ID3 = 65, -+ /*! -+ * Latin1 for ID3 tags. -+ */ -+ Latin1ID3V2 = 66, -+ /*! - * IS08859-1, or Latin1 encoding. 8 bit characters. - */ - Latin1 = 0, -@@ -110,6 +122,10 @@ namespace TagLib { - UTF16LE = 4 - }; - -+ static Type ID3Type(int i); -+ static Type ID3WType(Type type); -+ static Type ID3RealType(Type type); -+ - /*! - * Constructs an empty String. - */ diff -Nru taglib-1.7.2/include/README taglib-1.8/include/README --- taglib-1.7.2/include/README 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -These are only necessary at build-time when building the entire kdesupport module; they do not need to be installed on a running system. - -It can be regenerated by using something like the following from the taglib/taglib directory: - -for file in `find -type f -name "*\.h"`; -do - dir=`dirname $file` - strippeddir=`echo $dir | cut -c 3-` - base=`basename $file` - if test -z $strippeddir - then - echo "#include \"../taglib/$base\"" > ../include/$base - else - echo "#include \"../taglib/$strippeddir/$base\"" > ../include/$base - fi -done diff -Nru taglib-1.7.2/include/aifffile.h taglib-1.8/include/aifffile.h --- taglib-1.7.2/include/aifffile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/aifffile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/riff/aiff/aifffile.h" diff -Nru taglib-1.7.2/include/aiffproperties.h taglib-1.8/include/aiffproperties.h --- taglib-1.7.2/include/aiffproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/aiffproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/riff/aiff/aiffproperties.h" diff -Nru taglib-1.7.2/include/apefooter.h taglib-1.8/include/apefooter.h --- taglib-1.7.2/include/apefooter.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/apefooter.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ape/apefooter.h" diff -Nru taglib-1.7.2/include/apeitem.h taglib-1.8/include/apeitem.h --- taglib-1.7.2/include/apeitem.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/apeitem.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ape/apeitem.h" diff -Nru taglib-1.7.2/include/apetag.h taglib-1.8/include/apetag.h --- taglib-1.7.2/include/apetag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/apetag.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ape/apetag.h" diff -Nru taglib-1.7.2/include/asfattribute.h taglib-1.8/include/asfattribute.h --- taglib-1.7.2/include/asfattribute.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/asfattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/asf/asfattribute.h" diff -Nru taglib-1.7.2/include/asffile.h taglib-1.8/include/asffile.h --- taglib-1.7.2/include/asffile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/asffile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/asf/asffile.h" diff -Nru taglib-1.7.2/include/asfproperties.h taglib-1.8/include/asfproperties.h --- taglib-1.7.2/include/asfproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/asfproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/asf/asfproperties.h" diff -Nru taglib-1.7.2/include/asftag.h taglib-1.8/include/asftag.h --- taglib-1.7.2/include/asftag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/asftag.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/asf/asftag.h" diff -Nru taglib-1.7.2/include/attachedpictureframe.h taglib-1.8/include/attachedpictureframe.h --- taglib-1.7.2/include/attachedpictureframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/attachedpictureframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/attachedpictureframe.h" diff -Nru taglib-1.7.2/include/audioproperties.h taglib-1.8/include/audioproperties.h --- taglib-1.7.2/include/audioproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/audioproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/audioproperties.h" diff -Nru taglib-1.7.2/include/commentsframe.h taglib-1.8/include/commentsframe.h --- taglib-1.7.2/include/commentsframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/commentsframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/commentsframe.h" diff -Nru taglib-1.7.2/include/fileref.h taglib-1.8/include/fileref.h --- taglib-1.7.2/include/fileref.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/fileref.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/fileref.h" diff -Nru taglib-1.7.2/include/flacfile.h taglib-1.8/include/flacfile.h --- taglib-1.7.2/include/flacfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/flacfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/flac/flacfile.h" diff -Nru taglib-1.7.2/include/flacproperties.h taglib-1.8/include/flacproperties.h --- taglib-1.7.2/include/flacproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/flacproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/flac/flacproperties.h" diff -Nru taglib-1.7.2/include/generalencapsulatedobjectframe.h taglib-1.8/include/generalencapsulatedobjectframe.h --- taglib-1.7.2/include/generalencapsulatedobjectframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/generalencapsulatedobjectframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h" diff -Nru taglib-1.7.2/include/id3v1genres.h taglib-1.8/include/id3v1genres.h --- taglib-1.7.2/include/id3v1genres.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/id3v1genres.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v1/id3v1genres.h" diff -Nru taglib-1.7.2/include/id3v1tag.h taglib-1.8/include/id3v1tag.h --- taglib-1.7.2/include/id3v1tag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/id3v1tag.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v1/id3v1tag.h" diff -Nru taglib-1.7.2/include/id3v2extendedheader.h taglib-1.8/include/id3v2extendedheader.h --- taglib-1.7.2/include/id3v2extendedheader.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/id3v2extendedheader.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/id3v2extendedheader.h" diff -Nru taglib-1.7.2/include/id3v2footer.h taglib-1.8/include/id3v2footer.h --- taglib-1.7.2/include/id3v2footer.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/id3v2footer.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/id3v2footer.h" diff -Nru taglib-1.7.2/include/id3v2frame.h taglib-1.8/include/id3v2frame.h --- taglib-1.7.2/include/id3v2frame.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/id3v2frame.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/id3v2frame.h" diff -Nru taglib-1.7.2/include/id3v2framefactory.h taglib-1.8/include/id3v2framefactory.h --- taglib-1.7.2/include/id3v2framefactory.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/id3v2framefactory.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/id3v2framefactory.h" diff -Nru taglib-1.7.2/include/id3v2header.h taglib-1.8/include/id3v2header.h --- taglib-1.7.2/include/id3v2header.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/id3v2header.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/id3v2header.h" diff -Nru taglib-1.7.2/include/id3v2synchdata.h taglib-1.8/include/id3v2synchdata.h --- taglib-1.7.2/include/id3v2synchdata.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/id3v2synchdata.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/id3v2synchdata.h" diff -Nru taglib-1.7.2/include/id3v2tag.h taglib-1.8/include/id3v2tag.h --- taglib-1.7.2/include/id3v2tag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/id3v2tag.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/id3v2tag.h" diff -Nru taglib-1.7.2/include/mp4atom.h taglib-1.8/include/mp4atom.h --- taglib-1.7.2/include/mp4atom.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mp4atom.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mp4/mp4atom.h" diff -Nru taglib-1.7.2/include/mp4coverart.h taglib-1.8/include/mp4coverart.h --- taglib-1.7.2/include/mp4coverart.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mp4coverart.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mp4/mp4coverart.h" diff -Nru taglib-1.7.2/include/mp4file.h taglib-1.8/include/mp4file.h --- taglib-1.7.2/include/mp4file.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mp4file.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mp4/mp4file.h" diff -Nru taglib-1.7.2/include/mp4item.h taglib-1.8/include/mp4item.h --- taglib-1.7.2/include/mp4item.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mp4item.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mp4/mp4item.h" diff -Nru taglib-1.7.2/include/mp4properties.h taglib-1.8/include/mp4properties.h --- taglib-1.7.2/include/mp4properties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mp4properties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mp4/mp4properties.h" diff -Nru taglib-1.7.2/include/mp4tag.h taglib-1.8/include/mp4tag.h --- taglib-1.7.2/include/mp4tag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mp4tag.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mp4/mp4tag.h" diff -Nru taglib-1.7.2/include/mpcfile.h taglib-1.8/include/mpcfile.h --- taglib-1.7.2/include/mpcfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mpcfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpc/mpcfile.h" diff -Nru taglib-1.7.2/include/mpcproperties.h taglib-1.8/include/mpcproperties.h --- taglib-1.7.2/include/mpcproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mpcproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpc/mpcproperties.h" diff -Nru taglib-1.7.2/include/mpegfile.h taglib-1.8/include/mpegfile.h --- taglib-1.7.2/include/mpegfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mpegfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/mpegfile.h" diff -Nru taglib-1.7.2/include/mpegheader.h taglib-1.8/include/mpegheader.h --- taglib-1.7.2/include/mpegheader.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mpegheader.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/mpegheader.h" diff -Nru taglib-1.7.2/include/mpegproperties.h taglib-1.8/include/mpegproperties.h --- taglib-1.7.2/include/mpegproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/mpegproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/mpegproperties.h" diff -Nru taglib-1.7.2/include/oggfile.h taglib-1.8/include/oggfile.h --- taglib-1.7.2/include/oggfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/oggfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ogg/oggfile.h" diff -Nru taglib-1.7.2/include/oggflacfile.h taglib-1.8/include/oggflacfile.h --- taglib-1.7.2/include/oggflacfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/oggflacfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ogg/flac/oggflacfile.h" diff -Nru taglib-1.7.2/include/oggpage.h taglib-1.8/include/oggpage.h --- taglib-1.7.2/include/oggpage.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/oggpage.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ogg/oggpage.h" diff -Nru taglib-1.7.2/include/oggpageheader.h taglib-1.8/include/oggpageheader.h --- taglib-1.7.2/include/oggpageheader.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/oggpageheader.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ogg/oggpageheader.h" diff -Nru taglib-1.7.2/include/popularimeterframe.h taglib-1.8/include/popularimeterframe.h --- taglib-1.7.2/include/popularimeterframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/popularimeterframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/popularimeterframe.h" diff -Nru taglib-1.7.2/include/privateframe.h taglib-1.8/include/privateframe.h --- taglib-1.7.2/include/privateframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/privateframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/privateframe.h" diff -Nru taglib-1.7.2/include/relativevolumeframe.h taglib-1.8/include/relativevolumeframe.h --- taglib-1.7.2/include/relativevolumeframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/relativevolumeframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/relativevolumeframe.h" diff -Nru taglib-1.7.2/include/rifffile.h taglib-1.8/include/rifffile.h --- taglib-1.7.2/include/rifffile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/rifffile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/riff/rifffile.h" diff -Nru taglib-1.7.2/include/speexfile.h taglib-1.8/include/speexfile.h --- taglib-1.7.2/include/speexfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/speexfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ogg/speex/speexfile.h" diff -Nru taglib-1.7.2/include/speexproperties.h taglib-1.8/include/speexproperties.h --- taglib-1.7.2/include/speexproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/speexproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ogg/speex/speexproperties.h" diff -Nru taglib-1.7.2/include/tag.h taglib-1.8/include/tag.h --- taglib-1.7.2/include/tag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/tag.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/tag.h" diff -Nru taglib-1.7.2/include/taglib.h taglib-1.8/include/taglib.h --- taglib-1.7.2/include/taglib.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/taglib.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/toolkit/taglib.h" diff -Nru taglib-1.7.2/include/taglib_export.h taglib-1.8/include/taglib_export.h --- taglib-1.7.2/include/taglib_export.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/taglib_export.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/taglib_export.h" diff -Nru taglib-1.7.2/include/tagunion.h taglib-1.8/include/tagunion.h --- taglib-1.7.2/include/tagunion.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/tagunion.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/tagunion.h" diff -Nru taglib-1.7.2/include/tbytevector.h taglib-1.8/include/tbytevector.h --- taglib-1.7.2/include/tbytevector.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/tbytevector.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/toolkit/tbytevector.h" diff -Nru taglib-1.7.2/include/tbytevectorlist.h taglib-1.8/include/tbytevectorlist.h --- taglib-1.7.2/include/tbytevectorlist.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/tbytevectorlist.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/toolkit/tbytevectorlist.h" diff -Nru taglib-1.7.2/include/tdebug.h taglib-1.8/include/tdebug.h --- taglib-1.7.2/include/tdebug.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/tdebug.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/toolkit/tdebug.h" diff -Nru taglib-1.7.2/include/textidentificationframe.h taglib-1.8/include/textidentificationframe.h --- taglib-1.7.2/include/textidentificationframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/textidentificationframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/textidentificationframe.h" diff -Nru taglib-1.7.2/include/tfile.h taglib-1.8/include/tfile.h --- taglib-1.7.2/include/tfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/tfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/toolkit/tfile.h" diff -Nru taglib-1.7.2/include/tlist.h taglib-1.8/include/tlist.h --- taglib-1.7.2/include/tlist.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/tlist.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/toolkit/tlist.h" diff -Nru taglib-1.7.2/include/tmap.h taglib-1.8/include/tmap.h --- taglib-1.7.2/include/tmap.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/tmap.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/toolkit/tmap.h" diff -Nru taglib-1.7.2/include/trueaudiofile.h taglib-1.8/include/trueaudiofile.h --- taglib-1.7.2/include/trueaudiofile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/trueaudiofile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/trueaudio/trueaudiofile.h" diff -Nru taglib-1.7.2/include/trueaudioproperties.h taglib-1.8/include/trueaudioproperties.h --- taglib-1.7.2/include/trueaudioproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/trueaudioproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/trueaudio/trueaudioproperties.h" diff -Nru taglib-1.7.2/include/tstring.h taglib-1.8/include/tstring.h --- taglib-1.7.2/include/tstring.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/tstring.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/toolkit/tstring.h" diff -Nru taglib-1.7.2/include/tstringlist.h taglib-1.8/include/tstringlist.h --- taglib-1.7.2/include/tstringlist.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/tstringlist.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/toolkit/tstringlist.h" diff -Nru taglib-1.7.2/include/unicode.h taglib-1.8/include/unicode.h --- taglib-1.7.2/include/unicode.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/unicode.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/toolkit/unicode.h" diff -Nru taglib-1.7.2/include/uniquefileidentifierframe.h taglib-1.8/include/uniquefileidentifierframe.h --- taglib-1.7.2/include/uniquefileidentifierframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/uniquefileidentifierframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/uniquefileidentifierframe.h" diff -Nru taglib-1.7.2/include/unknownframe.h taglib-1.8/include/unknownframe.h --- taglib-1.7.2/include/unknownframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/unknownframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/unknownframe.h" diff -Nru taglib-1.7.2/include/unsynchronizedlyricsframe.h taglib-1.8/include/unsynchronizedlyricsframe.h --- taglib-1.7.2/include/unsynchronizedlyricsframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/unsynchronizedlyricsframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.h" diff -Nru taglib-1.7.2/include/urllinkframe.h taglib-1.8/include/urllinkframe.h --- taglib-1.7.2/include/urllinkframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/urllinkframe.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/id3v2/frames/urllinkframe.h" diff -Nru taglib-1.7.2/include/vorbisfile.h taglib-1.8/include/vorbisfile.h --- taglib-1.7.2/include/vorbisfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/vorbisfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ogg/vorbis/vorbisfile.h" diff -Nru taglib-1.7.2/include/vorbisproperties.h taglib-1.8/include/vorbisproperties.h --- taglib-1.7.2/include/vorbisproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/vorbisproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ogg/vorbis/vorbisproperties.h" diff -Nru taglib-1.7.2/include/wavfile.h taglib-1.8/include/wavfile.h --- taglib-1.7.2/include/wavfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/wavfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/riff/wav/wavfile.h" diff -Nru taglib-1.7.2/include/wavpackfile.h taglib-1.8/include/wavpackfile.h --- taglib-1.7.2/include/wavpackfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/wavpackfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/wavpack/wavpackfile.h" diff -Nru taglib-1.7.2/include/wavpackproperties.h taglib-1.8/include/wavpackproperties.h --- taglib-1.7.2/include/wavpackproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/wavpackproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/wavpack/wavpackproperties.h" diff -Nru taglib-1.7.2/include/wavproperties.h taglib-1.8/include/wavproperties.h --- taglib-1.7.2/include/wavproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/wavproperties.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/riff/wav/wavproperties.h" diff -Nru taglib-1.7.2/include/xingheader.h taglib-1.8/include/xingheader.h --- taglib-1.7.2/include/xingheader.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/xingheader.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/mpeg/xingheader.h" diff -Nru taglib-1.7.2/include/xiphcomment.h taglib-1.8/include/xiphcomment.h --- taglib-1.7.2/include/xiphcomment.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/include/xiphcomment.h 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "../taglib/ogg/xiphcomment.h" diff -Nru taglib-1.7.2/taglib/CMakeLists.txt taglib-1.8/taglib/CMakeLists.txt --- taglib-1.7.2/taglib/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/CMakeLists.txt 2012-09-06 18:03:15.000000000 +0000 @@ -1,219 +1,321 @@ - set(CMAKE_INCLUDE_CURRENT_DIR ON) -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR}/toolkit - ${CMAKE_CURRENT_SOURCE_DIR}/asf - ${CMAKE_CURRENT_SOURCE_DIR}/mpeg - ${CMAKE_CURRENT_SOURCE_DIR}/ogg - ${CMAKE_CURRENT_SOURCE_DIR}/ogg/flac - ${CMAKE_CURRENT_SOURCE_DIR}/flac - ${CMAKE_CURRENT_SOURCE_DIR}/mpc - ${CMAKE_CURRENT_SOURCE_DIR}/mp4 - ${CMAKE_CURRENT_SOURCE_DIR}/ogg/vorbis - ${CMAKE_CURRENT_SOURCE_DIR}/ogg/speex - ${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2 - ${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2/frames - ${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v1 - ${CMAKE_CURRENT_SOURCE_DIR}/ape - ${CMAKE_CURRENT_SOURCE_DIR}/wavpack - ${CMAKE_CURRENT_SOURCE_DIR}/trueaudio - ${CMAKE_CURRENT_SOURCE_DIR}/riff - ${CMAKE_CURRENT_SOURCE_DIR}/riff/aiff - ${CMAKE_CURRENT_SOURCE_DIR}/riff/wav - ${CMAKE_CURRENT_BINARY_DIR}/.. -) -if(ZLIB_FOUND) - INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) -endif(ZLIB_FOUND) - -ADD_SUBDIRECTORY( toolkit ) -ADD_SUBDIRECTORY( asf ) -ADD_SUBDIRECTORY( mpeg ) -ADD_SUBDIRECTORY( ogg ) -ADD_SUBDIRECTORY( flac ) -ADD_SUBDIRECTORY( ape ) -ADD_SUBDIRECTORY( mpc ) -ADD_SUBDIRECTORY( mp4 ) -ADD_SUBDIRECTORY( wavpack ) -ADD_SUBDIRECTORY( trueaudio ) -ADD_SUBDIRECTORY( riff ) - -########### next target ############### - -SET(mpeg_SRCS -mpeg/mpegfile.cpp -mpeg/mpegproperties.cpp -mpeg/mpegheader.cpp -mpeg/xingheader.cpp -) - -SET(id3v1_SRCS -mpeg/id3v1/id3v1tag.cpp -mpeg/id3v1/id3v1genres.cpp -) - - -SET(id3v2_SRCS -mpeg/id3v2/id3v2framefactory.cpp -mpeg/id3v2/id3v2synchdata.cpp -mpeg/id3v2/id3v2tag.cpp -mpeg/id3v2/id3v2header.cpp -mpeg/id3v2/id3v2frame.cpp -mpeg/id3v2/id3v2footer.cpp -mpeg/id3v2/id3v2extendedheader.cpp -) - - -SET(frames_SRCS -mpeg/id3v2/frames/attachedpictureframe.cpp -mpeg/id3v2/frames/commentsframe.cpp -mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp -mpeg/id3v2/frames/popularimeterframe.cpp -mpeg/id3v2/frames/privateframe.cpp -mpeg/id3v2/frames/relativevolumeframe.cpp -mpeg/id3v2/frames/textidentificationframe.cpp -mpeg/id3v2/frames/uniquefileidentifierframe.cpp -mpeg/id3v2/frames/unknownframe.cpp -mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp -mpeg/id3v2/frames/urllinkframe.cpp -) - -SET(ogg_SRCS -ogg/oggfile.cpp -ogg/oggpage.cpp -ogg/oggpageheader.cpp -ogg/xiphcomment.cpp -) - -SET(vorbis_SRCS -ogg/vorbis/vorbisfile.cpp -ogg/vorbis/vorbisproperties.cpp -) - - -SET(flacs_SRCS -flac/flacfile.cpp -flac/flacpicture.cpp -flac/flacproperties.cpp -flac/flacmetadatablock.cpp -flac/flacunknownmetadatablock.cpp -) - -SET(oggflacs_SRCS -ogg/flac/oggflacfile.cpp -) - -SET(mpc_SRCS -mpc/mpcfile.cpp -mpc/mpcproperties.cpp -) - -IF(WITH_MP4) -SET(mp4_SRCS -mp4/mp4file.cpp -mp4/mp4atom.cpp -mp4/mp4tag.cpp -mp4/mp4item.cpp -mp4/mp4properties.cpp -mp4/mp4coverart.cpp -) -ELSE(WITH_MP4) -SET(mp4_SRCS) -ENDIF(WITH_MP4) - -SET(ape_SRCS -ape/apetag.cpp -ape/apefooter.cpp -ape/apeitem.cpp -ape/apefile.cpp -ape/apeproperties.cpp -) - -SET(wavpack_SRCS -wavpack/wavpackfile.cpp -wavpack/wavpackproperties.cpp -) - -SET(speex_SRCS -ogg/speex/speexfile.cpp -ogg/speex/speexproperties.cpp -) - -SET(trueaudio_SRCS -trueaudio/trueaudiofile.cpp -trueaudio/trueaudioproperties.cpp -) - -IF(WITH_ASF) -SET(asf_SRCS -asf/asftag.cpp -asf/asffile.cpp -asf/asfproperties.cpp -asf/asfattribute.cpp -asf/asfpicture.cpp -) -ELSE(WITH_ASF) -SET(asf_SRCS) -ENDIF(WITH_ASF) - -SET(riff_SRCS -riff/rifffile.cpp -) - -SET(aiff_SRCS -riff/aiff/aifffile.cpp -riff/aiff/aiffproperties.cpp -) - -SET(wav_SRCS -riff/wav/wavfile.cpp -riff/wav/wavproperties.cpp +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/toolkit + ${CMAKE_CURRENT_SOURCE_DIR}/asf + ${CMAKE_CURRENT_SOURCE_DIR}/mpeg + ${CMAKE_CURRENT_SOURCE_DIR}/ogg + ${CMAKE_CURRENT_SOURCE_DIR}/ogg/flac + ${CMAKE_CURRENT_SOURCE_DIR}/flac + ${CMAKE_CURRENT_SOURCE_DIR}/mpc + ${CMAKE_CURRENT_SOURCE_DIR}/mp4 + ${CMAKE_CURRENT_SOURCE_DIR}/ogg/vorbis + ${CMAKE_CURRENT_SOURCE_DIR}/ogg/speex + ${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2 + ${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2/frames + ${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v1 + ${CMAKE_CURRENT_SOURCE_DIR}/ape + ${CMAKE_CURRENT_SOURCE_DIR}/wavpack + ${CMAKE_CURRENT_SOURCE_DIR}/trueaudio + ${CMAKE_CURRENT_SOURCE_DIR}/riff + ${CMAKE_CURRENT_SOURCE_DIR}/riff/aiff + ${CMAKE_CURRENT_SOURCE_DIR}/riff/wav + ${CMAKE_CURRENT_SOURCE_DIR}/mod + ${CMAKE_CURRENT_SOURCE_DIR}/s3m + ${CMAKE_CURRENT_SOURCE_DIR}/it + ${CMAKE_CURRENT_SOURCE_DIR}/xm ) -SET(toolkit_SRCS -toolkit/tstring.cpp -toolkit/tstringlist.cpp -toolkit/tbytevector.cpp -toolkit/tbytevectorlist.cpp -toolkit/tfile.cpp -toolkit/tdebug.cpp -toolkit/unicode.cpp -) +if(ZLIB_FOUND) + include_directories(${ZLIB_INCLUDE_DIR}) +endif() -SET(tag_LIB_SRCS ${mpeg_SRCS} ${id3v1_SRCS} ${id3v2_SRCS} ${frames_SRCS} ${ogg_SRCS} - ${vorbis_SRCS} ${oggflacs_SRCS} ${mpc_SRCS} ${ape_SRCS} ${toolkit_SRCS} ${flacs_SRCS} - ${wavpack_SRCS} ${speex_SRCS} ${trueaudio_SRCS} ${riff_SRCS} ${aiff_SRCS} ${wav_SRCS} - ${mp4_SRCS} ${asf_SRCS} - tag.cpp - tagunion.cpp - fileref.cpp - audioproperties.cpp +set(tag_HDRS + tag.h + fileref.h + audioproperties.h + taglib_export.h + ${CMAKE_BINARY_DIR}/taglib_config.h + toolkit/taglib.h + toolkit/tstring.h + toolkit/tlist.h + toolkit/tlist.tcc + toolkit/tstringlist.h + toolkit/tbytevector.h + toolkit/tbytevectorlist.h + toolkit/tbytevectorstream.h + toolkit/tiostream.h + toolkit/tfile.h + toolkit/tfilestream.h + toolkit/tmap.h + toolkit/tmap.tcc + toolkit/tpropertymap.h + mpeg/mpegfile.h + mpeg/mpegproperties.h + mpeg/mpegheader.h + mpeg/xingheader.h + mpeg/id3v1/id3v1tag.h + mpeg/id3v1/id3v1genres.h + mpeg/id3v2/id3v2extendedheader.h + mpeg/id3v2/id3v2frame.h + mpeg/id3v2/id3v2header.h + mpeg/id3v2/id3v2synchdata.h + mpeg/id3v2/id3v2footer.h + mpeg/id3v2/id3v2framefactory.h + mpeg/id3v2/id3v2tag.h + mpeg/id3v2/frames/attachedpictureframe.h + mpeg/id3v2/frames/commentsframe.h + mpeg/id3v2/frames/generalencapsulatedobjectframe.h + mpeg/id3v2/frames/ownershipframe.h + mpeg/id3v2/frames/popularimeterframe.h + mpeg/id3v2/frames/privateframe.h + mpeg/id3v2/frames/relativevolumeframe.h + mpeg/id3v2/frames/textidentificationframe.h + mpeg/id3v2/frames/uniquefileidentifierframe.h + mpeg/id3v2/frames/unknownframe.h + mpeg/id3v2/frames/unsynchronizedlyricsframe.h + mpeg/id3v2/frames/urllinkframe.h + ogg/oggfile.h + ogg/oggpage.h + ogg/oggpageheader.h + ogg/xiphcomment.h + ogg/vorbis/vorbisfile.h + ogg/vorbis/vorbisproperties.h + ogg/flac/oggflacfile.h + ogg/speex/speexfile.h + ogg/speex/speexproperties.h + flac/flacfile.h + flac/flacpicture.h + flac/flacproperties.h + flac/flacmetadatablock.h + ape/apefile.h + ape/apeproperties.h + ape/apetag.h + ape/apefooter.h + ape/apeitem.h + mpc/mpcfile.h + mpc/mpcproperties.h + wavpack/wavpackfile.h + wavpack/wavpackproperties.h + trueaudio/trueaudiofile.h + trueaudio/trueaudioproperties.h + riff/rifffile.h + riff/aiff/aifffile.h + riff/aiff/aiffproperties.h + riff/wav/wavfile.h + riff/wav/wavproperties.h + asf/asffile.h + asf/asfproperties.h + asf/asftag.h + asf/asfattribute.h + asf/asfpicture.h + mp4/mp4file.h + mp4/mp4atom.h + mp4/mp4tag.h + mp4/mp4item.h + mp4/mp4properties.h + mp4/mp4coverart.h + mod/modfilebase.h + mod/modfile.h + mod/modtag.h + mod/modproperties.h + it/itfile.h + it/itproperties.h + s3m/s3mfile.h + s3m/s3mproperties.h + xm/xmfile.h + xm/xmproperties.h +) + +set(mpeg_SRCS + mpeg/mpegfile.cpp + mpeg/mpegproperties.cpp + mpeg/mpegheader.cpp + mpeg/xingheader.cpp +) + +set(id3v1_SRCS + mpeg/id3v1/id3v1tag.cpp + mpeg/id3v1/id3v1genres.cpp +) + +set(id3v2_SRCS + mpeg/id3v2/id3v2framefactory.cpp + mpeg/id3v2/id3v2synchdata.cpp + mpeg/id3v2/id3v2tag.cpp + mpeg/id3v2/id3v2header.cpp + mpeg/id3v2/id3v2frame.cpp + mpeg/id3v2/id3v2footer.cpp + mpeg/id3v2/id3v2extendedheader.cpp + ) + +set(frames_SRCS + mpeg/id3v2/frames/attachedpictureframe.cpp + mpeg/id3v2/frames/commentsframe.cpp + mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp + mpeg/id3v2/frames/ownershipframe.cpp + mpeg/id3v2/frames/popularimeterframe.cpp + mpeg/id3v2/frames/privateframe.cpp + mpeg/id3v2/frames/relativevolumeframe.cpp + mpeg/id3v2/frames/textidentificationframe.cpp + mpeg/id3v2/frames/uniquefileidentifierframe.cpp + mpeg/id3v2/frames/unknownframe.cpp + mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp + mpeg/id3v2/frames/urllinkframe.cpp +) + +set(ogg_SRCS + ogg/oggfile.cpp + ogg/oggpage.cpp + ogg/oggpageheader.cpp + ogg/xiphcomment.cpp +) + +set(vorbis_SRCS + ogg/vorbis/vorbisfile.cpp + ogg/vorbis/vorbisproperties.cpp +) + +set(flacs_SRCS + flac/flacfile.cpp + flac/flacpicture.cpp + flac/flacproperties.cpp + flac/flacmetadatablock.cpp + flac/flacunknownmetadatablock.cpp +) + +set(oggflacs_SRCS + ogg/flac/oggflacfile.cpp +) + +set(mpc_SRCS + mpc/mpcfile.cpp + mpc/mpcproperties.cpp +) + +set(mp4_SRCS + mp4/mp4file.cpp + mp4/mp4atom.cpp + mp4/mp4tag.cpp + mp4/mp4item.cpp + mp4/mp4properties.cpp + mp4/mp4coverart.cpp +) + +set(ape_SRCS + ape/apetag.cpp + ape/apefooter.cpp + ape/apeitem.cpp + ape/apefile.cpp + ape/apeproperties.cpp +) + +set(wavpack_SRCS + wavpack/wavpackfile.cpp + wavpack/wavpackproperties.cpp +) + +set(speex_SRCS + ogg/speex/speexfile.cpp + ogg/speex/speexproperties.cpp +) + +set(trueaudio_SRCS + trueaudio/trueaudiofile.cpp + trueaudio/trueaudioproperties.cpp +) + +set(asf_SRCS + asf/asftag.cpp + asf/asffile.cpp + asf/asfproperties.cpp + asf/asfattribute.cpp + asf/asfpicture.cpp +) + +set(riff_SRCS + riff/rifffile.cpp +) + +set(aiff_SRCS + riff/aiff/aifffile.cpp + riff/aiff/aiffproperties.cpp +) + +set(wav_SRCS + riff/wav/wavfile.cpp + riff/wav/wavproperties.cpp +) + +set(mod_SRCS + mod/modfilebase.cpp + mod/modfile.cpp + mod/modtag.cpp + mod/modproperties.cpp +) + +set(s3m_SRCS + s3m/s3mfile.cpp + s3m/s3mproperties.cpp +) + +set(it_SRCS + it/itfile.cpp + it/itproperties.cpp +) + +set(xm_SRCS + xm/xmfile.cpp + xm/xmproperties.cpp +) + +set(toolkit_SRCS + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp + toolkit/tbytevectorlist.cpp + toolkit/tbytevectorstream.cpp + toolkit/tiostream.cpp + toolkit/tfile.cpp + toolkit/tfilestream.cpp + toolkit/tdebug.cpp + toolkit/tpropertymap.cpp + toolkit/unicode.cpp +) + +set(tag_LIB_SRCS + ${mpeg_SRCS} ${id3v1_SRCS} ${id3v2_SRCS} ${frames_SRCS} ${ogg_SRCS} + ${vorbis_SRCS} ${oggflacs_SRCS} ${mpc_SRCS} ${ape_SRCS} ${toolkit_SRCS} ${flacs_SRCS} + ${wavpack_SRCS} ${speex_SRCS} ${trueaudio_SRCS} ${riff_SRCS} ${aiff_SRCS} ${wav_SRCS} + ${asf_SRCS} ${mp4_SRCS} ${mod_SRCS} ${s3m_SRCS} ${it_SRCS} ${xm_SRCS} + tag.cpp + tagunion.cpp + fileref.cpp + audioproperties.cpp ) +add_library(tag ${tag_LIB_SRCS} ${tag_HDRS}) -if(ENABLE_STATIC) - add_library(tag STATIC ${tag_LIB_SRCS}) - set_target_properties(tag PROPERTIES COMPILE_DEFINITIONS TAGLIB_STATIC) -else(ENABLE_STATIC) - add_library(tag SHARED ${tag_LIB_SRCS}) -endif(ENABLE_STATIC) - -TARGET_LINK_LIBRARIES(tag ) if(ZLIB_FOUND) - TARGET_LINK_LIBRARIES(tag ${ZLIB_LIBRARIES}) -endif(ZLIB_FOUND) + target_link_libraries(tag ${ZLIB_LIBRARIES}) +endif() -SET_TARGET_PROPERTIES(tag PROPERTIES - VERSION ${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION} - SOVERSION ${TAGLIB_LIB_MAJOR_VERSION} - INSTALL_NAME_DIR ${LIB_INSTALL_DIR} - DEFINE_SYMBOL MAKE_TAGLIB_LIB - LINK_INTERFACE_LIBRARIES "" -) -INSTALL(TARGETS tag +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} + DEFINE_SYMBOL MAKE_TAGLIB_LIB + LINK_INTERFACE_LIBRARIES "" + PUBLIC_HEADER "${tag_HDRS}" +) +if(BUILD_FRAMEWORK) + set_target_properties(tag PROPERTIES FRAMEWORK TRUE) +endif() + +install(TARGETS tag + FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR} LIBRARY DESTINATION ${LIB_INSTALL_DIR} RUNTIME DESTINATION ${BIN_INSTALL_DIR} - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} + ARCHIVE DESTINATION ${LIB_INSTALL_DIR} + PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/taglib ) -INSTALL( FILES tag.h fileref.h audioproperties.h taglib_export.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/ape/CMakeLists.txt taglib-1.8/taglib/ape/CMakeLists.txt --- taglib-1.7.2/taglib/ape/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ape/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES apefile.h apeproperties.h apetag.h apefooter.h apeitem.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/ape/apefile.cpp taglib-1.8/taglib/ape/apefile.cpp --- taglib-1.7.2/taglib/ape/apefile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ape/apefile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -36,6 +36,7 @@ #include #include #include +#include #include "apefile.h" @@ -46,7 +47,7 @@ namespace { - enum { APEIndex, ID3v1Index }; + enum { ApeAPEIndex, ApeID3v1Index }; } class APE::File::FilePrivate @@ -92,6 +93,13 @@ read(readProperties, propertiesStyle); } +APE::File::File(IOStream *stream, bool readProperties, + Properties::ReadStyle propertiesStyle) : TagLib::File(stream) +{ + d = new FilePrivate; + read(readProperties, propertiesStyle); +} + APE::File::~File() { delete d; @@ -102,6 +110,33 @@ return &d->tag; } +PropertyMap APE::File::properties() const +{ + if(d->hasAPE) + return d->tag.access(ApeAPEIndex, false)->properties(); + if(d->hasID3v1) + return d->tag.access(ApeID3v1Index, false)->properties(); + return PropertyMap(); +} + +void APE::File::removeUnsupportedProperties(const StringList &properties) +{ + if(d->hasAPE) + d->tag.access(ApeAPEIndex, false)->removeUnsupportedProperties(properties); + if(d->hasID3v1) + d->tag.access(ApeID3v1Index, false)->removeUnsupportedProperties(properties); +} + +PropertyMap APE::File::setProperties(const PropertyMap &properties) +{ + if(d->hasAPE) + return d->tag.access(ApeAPEIndex, false)->setProperties(properties); + else if(d->hasID3v1) + return d->tag.access(ApeID3v1Index, false)->setProperties(properties); + else + return d->tag.access(ApeAPEIndex, true)->setProperties(properties); +} + APE::Properties *APE::File::audioProperties() const { return d->properties; @@ -178,23 +213,23 @@ ID3v1::Tag *APE::File::ID3v1Tag(bool create) { - return d->tag.access(ID3v1Index, create); + return d->tag.access(ApeID3v1Index, create); } APE::Tag *APE::File::APETag(bool create) { - return d->tag.access(APEIndex, create); + return d->tag.access(ApeAPEIndex, create); } void APE::File::strip(int tags) { if(tags & ID3v1) { - d->tag.set(ID3v1Index, 0); + d->tag.set(ApeID3v1Index, 0); APETag(true); } if(tags & APE) { - d->tag.set(APEIndex, 0); + d->tag.set(ApeAPEIndex, 0); if(!ID3v1Tag()) APETag(true); @@ -212,7 +247,7 @@ d->ID3v1Location = findID3v1(); if(d->ID3v1Location >= 0) { - d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); + d->tag.set(ApeID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); d->hasID3v1 = true; } @@ -221,7 +256,7 @@ d->APELocation = findAPE(); if(d->APELocation >= 0) { - d->tag.set(APEIndex, new APE::Tag(this, d->APELocation)); + d->tag.set(ApeAPEIndex, new APE::Tag(this, d->APELocation)); d->APESize = APETag()->footer()->completeTagSize(); d->APELocation = d->APELocation + APETag()->footer()->size() - d->APESize; d->hasAPE = true; diff -Nru taglib-1.7.2/taglib/ape/apefile.h taglib-1.8/taglib/ape/apefile.h --- taglib-1.7.2/taglib/ape/apefile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ape/apefile.h 2012-09-06 18:03:15.000000000 +0000 @@ -92,6 +92,17 @@ Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs an WavPack file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); @@ -103,6 +114,25 @@ virtual TagLib::Tag *tag() const; /*! + * Implements the unified property interface -- export function. + * If the file contains both an APE and an ID3v1 tag, only APE + * will be converted to the PropertyMap. + */ + PropertyMap properties() const; + + /*! + * Removes unsupported properties. Forwards to the actual Tag's + * removeUnsupportedProperties() function. + */ + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + * As for the export, only one tag is taken into account. If the file + * has no tag at all, APE will be created. + */ + PropertyMap setProperties(const PropertyMap &); + /*! * Returns the APE::Properties for this file. If no audio properties * were read then this will return a null pointer. */ diff -Nru taglib-1.7.2/taglib/ape/apefooter.cpp taglib-1.8/taglib/ape/apefooter.cpp --- taglib-1.7.2/taglib/ape/apefooter.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ape/apefooter.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -35,7 +35,7 @@ using namespace TagLib; using namespace APE; -class Footer::FooterPrivate +class APE::Footer::FooterPrivate { public: FooterPrivate() : version(0), @@ -64,12 +64,12 @@ // static members //////////////////////////////////////////////////////////////////////////////// -TagLib::uint Footer::size() +TagLib::uint APE::Footer::size() { return FooterPrivate::size; } -ByteVector Footer::fileIdentifier() +ByteVector APE::Footer::fileIdentifier() { return ByteVector::fromCString("APETAGEX"); } @@ -78,63 +78,63 @@ // public members //////////////////////////////////////////////////////////////////////////////// -Footer::Footer() +APE::Footer::Footer() { d = new FooterPrivate; } -Footer::Footer(const ByteVector &data) +APE::Footer::Footer(const ByteVector &data) { d = new FooterPrivate; parse(data); } -Footer::~Footer() +APE::Footer::~Footer() { delete d; } -TagLib::uint Footer::version() const +TagLib::uint APE::Footer::version() const { return d->version; } -bool Footer::headerPresent() const +bool APE::Footer::headerPresent() const { return d->headerPresent; } -bool Footer::footerPresent() const +bool APE::Footer::footerPresent() const { return d->footerPresent; } -bool Footer::isHeader() const +bool APE::Footer::isHeader() const { return d->isHeader; } -void Footer::setHeaderPresent(bool b) const +void APE::Footer::setHeaderPresent(bool b) const { d->headerPresent = b; } -TagLib::uint Footer::itemCount() const +TagLib::uint APE::Footer::itemCount() const { return d->itemCount; } -void Footer::setItemCount(uint s) +void APE::Footer::setItemCount(uint s) { d->itemCount = s; } -TagLib::uint Footer::tagSize() const +TagLib::uint APE::Footer::tagSize() const { return d->tagSize; } -TagLib::uint Footer::completeTagSize() const +TagLib::uint APE::Footer::completeTagSize() const { if(d->headerPresent) return d->tagSize + d->size; @@ -142,22 +142,22 @@ return d->tagSize; } -void Footer::setTagSize(uint s) +void APE::Footer::setTagSize(uint s) { d->tagSize = s; } -void Footer::setData(const ByteVector &data) +void APE::Footer::setData(const ByteVector &data) { parse(data); } -ByteVector Footer::renderFooter() const +ByteVector APE::Footer::renderFooter() const { return render(false); } -ByteVector Footer::renderHeader() const +ByteVector APE::Footer::renderHeader() const { if (!d->headerPresent) return ByteVector(); @@ -168,7 +168,7 @@ // protected members //////////////////////////////////////////////////////////////////////////////// -void Footer::parse(const ByteVector &data) +void APE::Footer::parse(const ByteVector &data) { if(data.size() < size()) return; @@ -197,7 +197,7 @@ } -ByteVector Footer::render(bool isHeader) const +ByteVector APE::Footer::render(bool isHeader) const { ByteVector v; diff -Nru taglib-1.7.2/taglib/ape/apeitem.cpp taglib-1.8/taglib/ape/apeitem.cpp --- taglib-1.7.2/taglib/ape/apeitem.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ape/apeitem.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -62,6 +62,18 @@ d->text = values; } +APE::Item::Item(const String &key, const ByteVector &value, bool binary) +{ + d = new ItemPrivate; + d->key = key; + if(binary) { + d->type = Binary; + d->value = value; + } + else + d->text.append(value); +} + APE::Item::Item(const Item &item) { d = new ItemPrivate(*item.d); @@ -104,6 +116,17 @@ return d->key; } +ByteVector APE::Item::binaryData() const +{ + return d->value; +} + +void APE::Item::setBinaryData(const ByteVector &value) +{ + d->type = Binary; + d->value = value; +} + ByteVector APE::Item::value() const { // This seems incorrect as it won't be actually rendering the value to keep it @@ -119,27 +142,50 @@ void APE::Item::setValue(const String &value) { + d->type = Text; d->text = value; } void APE::Item::setValues(const StringList &value) { + d->type = Text; d->text = value; } void APE::Item::appendValue(const String &value) { + d->type = Text; d->text.append(value); } void APE::Item::appendValues(const StringList &values) { + d->type = Text; d->text.append(values); } int APE::Item::size() const { - return 8 + d->key.size() + 1 + d->value.size(); + // SFB: Why is d->key.size() used when size() returns the length in UniChars and not UTF-8? + int result = 8 + d->key.size() /* d->key.data(String::UTF8).size() */ + 1; + switch (d->type) { + case Text: + if(d->text.size()) { + StringList::ConstIterator it = d->text.begin(); + + result += it->data(String::UTF8).size(); + it++; + for(; it != d->text.end(); ++it) + result += 1 + it->data(String::UTF8).size(); + } + break; + + case Binary: + case Locator: + result += d->value.size(); + break; + } + return result; } StringList APE::Item::toStringList() const @@ -161,12 +207,12 @@ { switch(d->type) { case Text: - case Binary: if(d->text.isEmpty()) return true; if(d->text.size() == 1 && d->text.front().isEmpty()) return true; return false; + case Binary: case Locator: return d->value.isEmpty(); default: @@ -193,7 +239,7 @@ setReadOnly(flags & 1); setType(ItemTypes((flags >> 1) & 3)); - if(int(d->type) < 2) + if(Text == d->type) d->text = StringList(ByteVectorList::split(d->value, '\0'), String::UTF8); } diff -Nru taglib-1.7.2/taglib/ape/apeitem.h taglib-1.8/taglib/ape/apeitem.h --- taglib-1.7.2/taglib/ape/apeitem.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ape/apeitem.h 2012-09-06 18:03:15.000000000 +0000 @@ -59,17 +59,23 @@ Item(); /*! - * Constructs an item with \a key and \a value. + * Constructs a text item with \a key and \a value. */ // BIC: Remove this, StringList has a constructor from a single string Item(const String &key, const String &value); /*! - * Constructs an item with \a key and \a values. + * Constructs a text item with \a key and \a values. */ Item(const String &key, const StringList &values); /*! + * Constructs an item with \a key and \a value. + * If \a binary is true a Binary item will be created, otherwise \a value will be interpreted as text + */ + Item(const String &key, const ByteVector &value, bool binary); + + /*! * Construct an item as a copy of \a item. */ Item(const Item &item); @@ -91,12 +97,20 @@ /*! * Returns the binary value. - * - * \deprecated This will be removed in the next binary incompatible version - * as it is not kept in sync with the things that are set using setValue() - * and friends. + * If the item type is not \a Binary, the returned contents are undefined */ + ByteVector binaryData() const; + + /*! + * Set the binary value to \a value + * The item's type will also be set to \a Binary + */ + void setBinaryData(const ByteVector &value); + +#ifndef DO_NOT_DOCUMENT + /* Remove in next binary incompatible release */ ByteVector value() const; +#endif /*! * Sets the key for the item to \a key. @@ -104,14 +118,14 @@ void setKey(const String &key); /*! - * Sets the value of the item to \a value and clears any previous contents. + * Sets the text value of the item to \a value and clears any previous contents. * * \see toString() */ void setValue(const String &value); /*! - * Sets the value of the item to the list of values in \a value and clears + * Sets the text value of the item to the list of values in \a value and clears * any previous contents. * * \see toStringList() @@ -119,14 +133,14 @@ void setValues(const StringList &values); /*! - * Appends \a value to create (or extend) the current list of values. + * Appends \a value to create (or extend) the current list of text values. * * \see toString() */ void appendValue(const String &value); /*! - * Appends \a values to extend the current list of values. + * Appends \a values to extend the current list of text values. * * \see toStringList() */ @@ -143,14 +157,13 @@ */ String toString() const; - /*! - * \deprecated - * \see values - */ +#ifndef DO_NOT_DOCUMENT + /* Remove in next binary incompatible release */ StringList toStringList() const; +#endif /*! - * Returns the list of values. + * Returns the list of text values. */ StringList values() const; diff -Nru taglib-1.7.2/taglib/ape/apeproperties.cpp taglib-1.8/taglib/ape/apeproperties.cpp --- taglib-1.7.2/taglib/ape/apeproperties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ape/apeproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -46,6 +46,7 @@ channels(0), version(0), bitsPerSample(0), + sampleFrames(0), file(file), streamLength(streamLength) {} @@ -55,6 +56,7 @@ int channels; int version; int bitsPerSample; + uint sampleFrames; File *file; long streamLength; }; @@ -104,6 +106,11 @@ return d->bitsPerSample; } +TagLib::uint APE::Properties::sampleFrames() const +{ + return d->sampleFrames; +} + //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// @@ -137,7 +144,7 @@ long ID3v2OriginalSize = 0; bool hasID3v2 = false; if(ID3v2Location >= 0) { - ID3v2::Tag tag(d->file, ID3v2Location, 0); + ID3v2::Tag tag(d->file, ID3v2Location); ID3v2OriginalSize = tag.header()->completeTagSize(); if(tag.header()->tagSize() > 0) hasID3v2 = true; @@ -192,8 +199,8 @@ uint totalFrames = header.mid(12, 4).toUInt(false); uint blocksPerFrame = header.mid(4, 4).toUInt(false); uint finalFrameBlocks = header.mid(8, 4).toUInt(false); - uint totalBlocks = totalFrames > 0 ? (totalFrames - 1) * blocksPerFrame + finalFrameBlocks : 0; - d->length = d->sampleRate > 0 ? totalBlocks / d->sampleRate : 0; + d->sampleFrames = totalFrames > 0 ? (totalFrames - 1) * blocksPerFrame + finalFrameBlocks : 0; + d->length = d->sampleRate > 0 ? d->sampleFrames / d->sampleRate : 0; d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0; } diff -Nru taglib-1.7.2/taglib/ape/apeproperties.h taglib-1.8/taglib/ape/apeproperties.h --- taglib-1.7.2/taglib/ape/apeproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ape/apeproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -71,6 +71,7 @@ * Returns number of bits per sample. */ int bitsPerSample() const; + uint sampleFrames() const; /*! * Returns APE version. diff -Nru taglib-1.7.2/taglib/ape/apetag.cpp taglib-1.8/taglib/ape/apetag.cpp --- taglib-1.7.2/taglib/ape/apetag.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ape/apetag.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include "apetag.h" #include "apefooter.h" @@ -47,7 +48,7 @@ public: TagPrivate() : file(0), footerLocation(-1), tagLength(0) {} - File *file; + TagLib::File *file; long footerLocation; long tagLength; @@ -65,7 +66,7 @@ d = new TagPrivate; } -APE::Tag::Tag(File *file, long footerLocation) : TagLib::Tag() +APE::Tag::Tag(TagLib::File *file, long footerLocation) : TagLib::Tag() { d = new TagPrivate; d->file = file; @@ -174,6 +175,103 @@ addValue("TRACK", String::number(i), true); } +// conversions of tag keys between what we use in PropertyMap and what's usual +// for APE tags +static const TagLib::uint keyConversionsSize = 5; //usual, APE +static const char *keyConversions[][2] = {{"TRACKNUMBER", "TRACK" }, + {"DATE", "YEAR" }, + {"ALBUMARTIST", "ALBUM ARTIST"}, + {"DISCNUMBER", "DISC" }, + {"REMIXER", "MIXARTIST" }}; + +PropertyMap APE::Tag::properties() const +{ + PropertyMap properties; + ItemListMap::ConstIterator it = itemListMap().begin(); + for(; it != itemListMap().end(); ++it) { + String tagName = it->first.upper(); + // if the item is Binary or Locator, or if the key is an invalid string, + // add to unsupportedData + if(it->second.type() != Item::Text || tagName.isNull()) + properties.unsupportedData().append(it->first); + else { + // Some tags need to be handled specially + for(uint i = 0; i < keyConversionsSize; ++i) + if(tagName == keyConversions[i][1]) + tagName = keyConversions[i][0]; + properties[tagName].append(it->second.toStringList()); + } + } + return properties; +} + +void APE::Tag::removeUnsupportedProperties(const StringList &properties) +{ + StringList::ConstIterator it = properties.begin(); + for(; it != properties.end(); ++it) + removeItem(*it); +} + +PropertyMap APE::Tag::setProperties(const PropertyMap &origProps) +{ + PropertyMap properties(origProps); // make a local copy that can be modified + + // see comment in properties() + for(uint 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]); + } + + // first check if tags need to be removed completely + StringList toRemove; + ItemListMap::ConstIterator remIt = itemListMap().begin(); + for(; remIt != itemListMap().end(); ++remIt) { + String key = remIt->first.upper(); + // only remove if a) key is valid, b) type is text, c) key not contained in new properties + if(!key.isNull() && remIt->second.type() == APE::Item::Text && !properties.contains(key)) + toRemove.append(remIt->first); + } + + for (StringList::Iterator removeIt = toRemove.begin(); removeIt != toRemove.end(); removeIt++) + removeItem(*removeIt); + + // now sync in the "forward direction" + PropertyMap::ConstIterator it = properties.begin(); + PropertyMap invalid; + for(; it != properties.end(); ++it) { + const String &tagName = it->first; + if(!checkKey(tagName)) + invalid.insert(it->first, it->second); + else if(!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == it->second)) { + if(it->second.size() == 0) + removeItem(tagName); + else { + StringList::ConstIterator valueIt = it->second.begin(); + addValue(tagName, *valueIt, true); + ++valueIt; + for(; valueIt != it->second.end(); ++valueIt) + addValue(tagName, *valueIt, false); + } + } + } + return invalid; +} + +bool APE::Tag::checkKey(const String &key) +{ + if(key.size() < 2 || key.size() > 16) + return false; + for(String::ConstIterator it = key.begin(); it != key.end(); it++) + // only allow printable ASCII including space (32..127) + if (*it < 32 || *it >= 128) + return false; + String upperKey = key.upper(); + if (upperKey=="ID3" || upperKey=="TAG" || upperKey=="OGGS" || upperKey=="MP+") + return false; + return true; +} + APE::Footer *APE::Tag::footer() const { return &d->footer; @@ -195,17 +293,31 @@ { if(replace) removeItem(key); - if(!value.isEmpty()) { - if(d->itemListMap.contains(key) || !replace) - d->itemListMap[key.upper()].appendValue(value); + if(!key.isEmpty() && !value.isEmpty()) { + if(!replace && d->itemListMap.contains(key)) { + // Text items may contain more than one value + if(APE::Item::Text == d->itemListMap.begin()->second.type()) + d->itemListMap[key.upper()].appendValue(value); + // Binary or locator items may have only one value + else + setItem(key, Item(key, value)); + } else setItem(key, Item(key, value)); } } +void APE::Tag::setData(const String &key, const ByteVector &value) +{ + removeItem(key); + if(!key.isEmpty() && !value.isEmpty()) + setItem(key, Item(key, value, true)); +} + void APE::Tag::setItem(const String &key, const Item &item) { - d->itemListMap.insert(key.upper(), item); + if(!key.isEmpty()) + d->itemListMap.insert(key.upper(), item); } bool APE::Tag::isEmpty() const diff -Nru taglib-1.7.2/taglib/ape/apetag.h taglib-1.8/taglib/ape/apetag.h --- taglib-1.7.2/taglib/ape/apetag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ape/apetag.h 2012-09-06 18:03:15.000000000 +0000 @@ -104,6 +104,37 @@ virtual void setTrack(uint i); /*! + * Implements the unified tag dictionary interface -- export function. + * APE tags are perfectly compatible with the dictionary interface because they + * support both arbitrary tag names and multiple values. Currently only + * APE items of type *Text* are handled by the dictionary interface; all *Binary* + * and *Locator* items will be put into the unsupportedData list and can be + * deleted on request using removeUnsupportedProperties(). The same happens + * to Text items if their key is invalid for PropertyMap (which should actually + * never happen). + * + * The only conversion done by this export function is to rename the APE tags + * TRACK to TRACKNUMBER, YEAR to DATE, and ALBUM ARTIST to ALBUMARTIST, respectively, + * in order to be compliant with the names used in other formats. + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified tag dictionary interface -- import function. The same + * comments as for the export function apply; additionally note that the APE tag + * specification requires keys to have between 2 and 16 printable ASCII characters + * with the exception of the fixed strings "ID3", "TAG", "OGGS", and "MP+". + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Check if the given String is a valid APE tag key. + */ + static bool checkKey(const String&); + + /*! * Returns a pointer to the tag's footer. */ Footer *footer() const; @@ -128,12 +159,19 @@ void removeItem(const String &key); /*! - * Adds to the item specified by \a key the data \a value. If \a replace + * Adds to the text item specified by \a key the data \a value. If \a replace * is true, then all of the other values on the same key will be removed - * first. + * first. If a binary item exists for \a key it will be removed first. */ void addValue(const String &key, const String &value, bool replace = true); + /*! + * Set the binary data for the key specified by \a item to \a value + * This will convert the item to type \a Binary if it isn't already and + * all of the other values on the same key will be removed. + */ + void setData(const String &key, const ByteVector &value); + /*! * Sets the \a key item to the value of \a item. If an item with the \a key is already * present, it will be replaced. diff -Nru taglib-1.7.2/taglib/asf/CMakeLists.txt taglib-1.8/taglib/asf/CMakeLists.txt --- taglib-1.7.2/taglib/asf/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES asffile.h asfproperties.h asftag.h asfattribute.h asfpicture.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/asf/asfattribute.cpp taglib-1.8/taglib/asf/asfattribute.cpp --- taglib-1.7.2/taglib/asf/asfattribute.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/asfattribute.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,8 +27,6 @@ #include #endif -#ifdef WITH_ASF - #include #include #include "asfattribute.h" @@ -353,4 +351,3 @@ d->stream = value; } -#endif diff -Nru taglib-1.7.2/taglib/asf/asfattribute.h taglib-1.8/taglib/asf/asfattribute.h --- taglib-1.7.2/taglib/asf/asfattribute.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/asfattribute.h 2012-09-06 18:03:15.000000000 +0000 @@ -70,7 +70,7 @@ /*! * Constructs an attribute with \a key and a BytesType \a value. */ - Attribute(const ByteVector &value); + Attribute(const ByteVector &value); /*! * Constructs an attribute with \a key and a Picture \a value. diff -Nru taglib-1.7.2/taglib/asf/asffile.cpp taglib-1.8/taglib/asf/asffile.cpp --- taglib-1.7.2/taglib/asf/asffile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/asffile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,8 +27,6 @@ #include #endif -#ifdef WITH_ASF - #include #include #include @@ -69,6 +67,9 @@ static ByteVector headerExtensionGuid("\xb5\x03\xbf_.\xa9\xcf\x11\x8e\xe3\x00\xc0\x0c Se", 16); static ByteVector metadataGuid("\xEA\xCB\xF8\xC5\xAF[wH\204g\xAA\214D\xFAL\xCA", 16); static ByteVector metadataLibraryGuid("\224\034#D\230\224\321I\241A\x1d\x13NEpT", 16); +static ByteVector contentEncryptionGuid("\xFB\xB3\x11\x22\x23\xBD\xD2\x11\xB4\xB7\x00\xA0\xC9\x55\xFC\x6E", 16); +static ByteVector extendedContentEncryptionGuid("\x14\xE6\x8A\x29\x22\x26 \x17\x4C\xB9\x35\xDA\xE0\x7E\xE9\x28\x9C", 16); +static ByteVector advancedContentEncryptionGuid("\xB6\x9B\x07\x7A\xA4\xDA\x12\x4E\xA5\xCA\x91\xD3\x8D\xC1\x1A\x8D", 16); class ASF::File::BaseObject { @@ -347,7 +348,7 @@ else { obj = new UnknownObject(guid); } - obj->parse(file, size); + obj->parse(file, (unsigned int)size); objects.append(obj); dataPos += size; } @@ -367,13 +368,20 @@ // public members //////////////////////////////////////////////////////////////////////////////// -ASF::File::File(FileName file, bool readProperties, Properties::ReadStyle propertiesStyle) +ASF::File::File(FileName file, bool readProperties, Properties::ReadStyle propertiesStyle) : TagLib::File(file) { d = new FilePrivate; read(readProperties, propertiesStyle); } +ASF::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle propertiesStyle) + : TagLib::File(stream) +{ + d = new FilePrivate; + read(readProperties, propertiesStyle); +} + ASF::File::~File() { for(unsigned int i = 0; i < d->objects.size(); i++) { @@ -454,6 +462,11 @@ obj = new HeaderExtensionObject(); } else { + if(guid == contentEncryptionGuid || + guid == extendedContentEncryptionGuid || + guid == advancedContentEncryptionGuid) { + d->properties->setEncrypted(true); + } obj = new UnknownObject(guid); } obj->parse(this, size); @@ -522,7 +535,7 @@ data.append(d->objects[i]->render(this)); } data = headerGuid + ByteVector::fromLongLong(data.size() + 30, false) + ByteVector::fromUInt(d->objects.size(), false) + ByteVector("\x01\x02", 2) + data; - insert(data, 0, d->size); + insert(data, 0, (TagLib::ulong)d->size); return true; } @@ -600,4 +613,3 @@ return data; } -#endif diff -Nru taglib-1.7.2/taglib/asf/asffile.h taglib-1.8/taglib/asf/asffile.h --- taglib-1.7.2/taglib/asf/asffile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/asffile.h 2012-09-06 18:03:15.000000000 +0000 @@ -54,10 +54,26 @@ * * \note In the current implementation, both \a readProperties and * \a propertiesStyle are ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. */ File(FileName file, bool readProperties = true, Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs an ASF file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note In the current implementation, both \a readProperties and + * \a propertiesStyle are ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); diff -Nru taglib-1.7.2/taglib/asf/asfpicture.cpp taglib-1.8/taglib/asf/asfpicture.cpp --- taglib-1.7.2/taglib/asf/asfpicture.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/asfpicture.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,8 +27,6 @@ #include #endif -#ifdef WITH_ASF - #include #include #include "asfattribute.h" @@ -37,7 +35,7 @@ using namespace TagLib; -class ASF::Picture::PicturePriavte : public RefCounter +class ASF::Picture::PicturePrivate : public RefCounter { public: bool valid; @@ -53,7 +51,7 @@ ASF::Picture::Picture() { - d = new PicturePriavte(); + d = new PicturePrivate(); d->valid = true; } @@ -182,4 +180,3 @@ return ret; } -#endif diff -Nru taglib-1.7.2/taglib/asf/asfpicture.h taglib-1.8/taglib/asf/asfpicture.h --- taglib-1.7.2/taglib/asf/asfpicture.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/asfpicture.h 2012-09-06 18:03:15.000000000 +0000 @@ -208,8 +208,8 @@ friend class Attribute; #endif private: - struct PicturePriavte; - PicturePriavte *d; + class PicturePrivate; + PicturePrivate *d; }; } } diff -Nru taglib-1.7.2/taglib/asf/asfproperties.cpp taglib-1.8/taglib/asf/asfproperties.cpp --- taglib-1.7.2/taglib/asf/asfproperties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/asfproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,8 +27,6 @@ #include #endif -#ifdef WITH_ASF - #include #include #include "asfproperties.h" @@ -38,11 +36,12 @@ class ASF::Properties::PropertiesPrivate { public: - PropertiesPrivate(): length(0), bitrate(0), sampleRate(0), channels(0) {} + PropertiesPrivate(): length(0), bitrate(0), sampleRate(0), channels(0), encrypted(false) {} int length; int bitrate; int sampleRate; int channels; + bool encrypted; }; //////////////////////////////////////////////////////////////////////////////// @@ -57,7 +56,7 @@ ASF::Properties::~Properties() { if(d) - delete d; + delete d; } int ASF::Properties::length() const @@ -78,7 +77,12 @@ int ASF::Properties::channels() const { return d->channels; -} +} + +bool ASF::Properties::isEncrypted() const +{ + return d->encrypted; +} //////////////////////////////////////////////////////////////////////////////// // private members @@ -104,4 +108,8 @@ d->channels = length; } -#endif +void ASF::Properties::setEncrypted(bool encrypted) +{ + d->encrypted = encrypted; +} + diff -Nru taglib-1.7.2/taglib/asf/asfproperties.h taglib-1.8/taglib/asf/asfproperties.h --- taglib-1.7.2/taglib/asf/asfproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/asfproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -54,12 +54,14 @@ virtual int bitrate() const; virtual int sampleRate() const; virtual int channels() const; + bool isEncrypted() const; #ifndef DO_NOT_DOCUMENT void setLength(int value); void setBitrate(int value); void setSampleRate(int value); void setChannels(int value); + void setEncrypted(bool value); #endif private: @@ -71,4 +73,4 @@ } -#endif +#endif diff -Nru taglib-1.7.2/taglib/asf/asftag.cpp taglib-1.8/taglib/asf/asftag.cpp --- taglib-1.7.2/taglib/asf/asftag.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/asftag.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,8 +27,6 @@ #include #endif -#ifdef WITH_ASF - #include "asftag.h" using namespace TagLib; @@ -198,4 +196,3 @@ d->attributeListMap.isEmpty(); } -#endif diff -Nru taglib-1.7.2/taglib/asf/asftag.h taglib-1.8/taglib/asf/asftag.h --- taglib-1.7.2/taglib/asf/asftag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/asf/asftag.h 2012-09-06 18:03:15.000000000 +0000 @@ -120,17 +120,17 @@ virtual void setComment(const String &s); /*! - * Sets the rating to \a s. + * Sets the rating to \a s. */ virtual void setRating(const String &s); /*! - * Sets the copyright to \a s. + * Sets the copyright to \a s. */ virtual void setCopyright(const String &s); /*! - * Sets the genre to \a s. + * Sets the genre to \a s. */ virtual void setGenre(const String &s); diff -Nru taglib-1.7.2/taglib/fileref.cpp taglib-1.8/taglib/fileref.cpp --- taglib-1.7.2/taglib/fileref.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/fileref.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -1,7 +1,7 @@ /*************************************************************************** copyright : (C) 2002 - 2008 by Scott Wheeler email : wheeler@kde.org - + copyright : (C) 2010 by Alex Novichkov email : novichko@atnet.ru (added APE file support) @@ -49,6 +49,10 @@ #include "aifffile.h" #include "wavfile.h" #include "apefile.h" +#include "modfile.h" +#include "s3mfile.h" +#include "itfile.h" +#include "xmfile.h" using namespace TagLib; @@ -147,21 +151,25 @@ l.append("wv"); l.append("spx"); l.append("tta"); -#ifdef TAGLIB_WITH_MP4 l.append("m4a"); + l.append("m4r"); l.append("m4b"); l.append("m4p"); l.append("3g2"); l.append("mp4"); -#endif -#ifdef TAGLIB_WITH_ASF l.append("wma"); l.append("asf"); -#endif l.append("aif"); l.append("aiff"); l.append("wav"); l.append("ape"); + l.append("mod"); + l.append("module"); // alias for "mod" + l.append("nst"); // alias for "mod" + l.append("wow"); // alias for "mod" + l.append("s3m"); + l.append("it"); + l.append("xm"); return l; } @@ -246,20 +254,25 @@ return new Ogg::Speex::File(fileName, readAudioProperties, audioPropertiesStyle); if(ext == "TTA") return new TrueAudio::File(fileName, readAudioProperties, audioPropertiesStyle); -#ifdef TAGLIB_WITH_MP4 - if(ext == "M4A" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2") + if(ext == "M4A" || ext == "M4R" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2") return new MP4::File(fileName, readAudioProperties, audioPropertiesStyle); -#endif -#ifdef TAGLIB_WITH_ASF if(ext == "WMA" || ext == "ASF") return new ASF::File(fileName, readAudioProperties, audioPropertiesStyle); -#endif if(ext == "AIF" || ext == "AIFF") return new RIFF::AIFF::File(fileName, readAudioProperties, audioPropertiesStyle); if(ext == "WAV") return new RIFF::WAV::File(fileName, readAudioProperties, audioPropertiesStyle); if(ext == "APE") return new APE::File(fileName, readAudioProperties, audioPropertiesStyle); + // module, nst and wow are possible but uncommon extensions + if(ext == "MOD" || ext == "MODULE" || ext == "NST" || ext == "WOW") + return new Mod::File(fileName, readAudioProperties, audioPropertiesStyle); + if(ext == "S3M") + return new S3M::File(fileName, readAudioProperties, audioPropertiesStyle); + if(ext == "IT") + return new IT::File(fileName, readAudioProperties, audioPropertiesStyle); + if(ext == "XM") + return new XM::File(fileName, readAudioProperties, audioPropertiesStyle); } return 0; diff -Nru taglib-1.7.2/taglib/flac/CMakeLists.txt taglib-1.8/taglib/flac/CMakeLists.txt --- taglib-1.7.2/taglib/flac/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/flac/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES flacfile.h flacpicture.h flacproperties.h flacmetadatablock.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib ) diff -Nru taglib-1.7.2/taglib/flac/flacfile.cpp taglib-1.8/taglib/flac/flacfile.cpp --- taglib-1.7.2/taglib/flac/flacfile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/flac/flacfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -43,7 +44,7 @@ namespace { - enum { XiphIndex = 0, ID3v2Index = 1, ID3v1Index = 2 }; + enum { FlacXiphIndex = 0, FlacID3v2Index = 1, FlacID3v1Index = 2 }; enum { MinPaddingLength = 4096 }; enum { LastBlockFlag = 0x80 }; } @@ -119,6 +120,15 @@ read(readProperties, propertiesStyle); } +FLAC::File::File(IOStream *stream, ID3v2::FrameFactory *frameFactory, + bool readProperties, Properties::ReadStyle propertiesStyle) : + TagLib::File(stream) +{ + d = new FilePrivate; + d->ID3v2FrameFactory = frameFactory; + read(readProperties, propertiesStyle); +} + FLAC::File::~File() { delete d; @@ -129,6 +139,41 @@ return &d->tag; } +PropertyMap FLAC::File::properties() const +{ + // once Tag::properties() is virtual, this case distinction could actually be done + // within TagUnion. + if(d->hasXiphComment) + return d->tag.access(FlacXiphIndex, false)->properties(); + if(d->hasID3v2) + return d->tag.access(FlacID3v2Index, false)->properties(); + if(d->hasID3v1) + return d->tag.access(FlacID3v1Index, false)->properties(); + return PropertyMap(); +} + +void FLAC::File::removeUnsupportedProperties(const StringList &unsupported) +{ + if(d->hasXiphComment) + d->tag.access(FlacXiphIndex, false)->removeUnsupportedProperties(unsupported); + if(d->hasID3v2) + d->tag.access(FlacID3v2Index, false)->removeUnsupportedProperties(unsupported); + if(d->hasID3v1) + d->tag.access(FlacID3v1Index, false)->removeUnsupportedProperties(unsupported); +} + +PropertyMap FLAC::File::setProperties(const PropertyMap &properties) +{ + if(d->hasXiphComment) + return d->tag.access(FlacXiphIndex, false)->setProperties(properties); + else if(d->hasID3v2) + return d->tag.access(FlacID3v2Index, false)->setProperties(properties); + else if(d->hasID3v1) + return d->tag.access(FlacID3v1Index, false)->setProperties(properties); + else + return d->tag.access(FlacXiphIndex, true)->setProperties(properties); +} + FLAC::Properties *FLAC::File::audioProperties() const { return d->properties; @@ -198,7 +243,7 @@ } ByteVector padding = ByteVector::fromUInt(paddingLength); padding.resize(paddingLength + 4); - padding[0] = FLAC::MetadataBlock::Padding | LastBlockFlag; + padding[0] = (char)(FLAC::MetadataBlock::Padding | LastBlockFlag); data.append(padding); // Write the data to the file @@ -230,21 +275,21 @@ ID3v2::Tag *FLAC::File::ID3v2Tag(bool create) { - if(!create || d->tag[ID3v2Index]) - return static_cast(d->tag[ID3v2Index]); + if(!create || d->tag[FlacID3v2Index]) + return static_cast(d->tag[FlacID3v2Index]); - d->tag.set(ID3v2Index, new ID3v2::Tag); - return static_cast(d->tag[ID3v2Index]); + d->tag.set(FlacID3v2Index, new ID3v2::Tag); + return static_cast(d->tag[FlacID3v2Index]); } ID3v1::Tag *FLAC::File::ID3v1Tag(bool create) { - return d->tag.access(ID3v1Index, create); + return d->tag.access(FlacID3v1Index, create); } Ogg::XiphComment *FLAC::File::xiphComment(bool create) { - return d->tag.access(XiphIndex, create); + return d->tag.access(FlacXiphIndex, create); } void FLAC::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory) @@ -265,12 +310,12 @@ if(d->ID3v2Location >= 0) { - d->tag.set(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory)); + d->tag.set(FlacID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory)); d->ID3v2OriginalSize = ID3v2Tag()->header()->completeTagSize(); if(ID3v2Tag()->header()->tagSize() <= 0) - d->tag.set(ID3v2Index, 0); + d->tag.set(FlacID3v2Index, 0); else d->hasID3v2 = true; } @@ -280,7 +325,7 @@ d->ID3v1Location = findID3v1(); if(d->ID3v1Location >= 0) { - d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); + d->tag.set(FlacID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); d->hasID3v1 = true; } @@ -292,9 +337,9 @@ return; if(d->hasXiphComment) - d->tag.set(XiphIndex, new Ogg::XiphComment(xiphCommentData())); + d->tag.set(FlacXiphIndex, new Ogg::XiphComment(xiphCommentData())); else - d->tag.set(XiphIndex, new Ogg::XiphComment); + d->tag.set(FlacXiphIndex, new Ogg::XiphComment); if(readProperties) d->properties = new Properties(streamInfoData(), streamLength(), propertiesStyle); @@ -484,6 +529,17 @@ d->blocks.append(picture); } +void FLAC::File::removePicture(Picture *picture, bool del) +{ + MetadataBlock *block = picture; + List::Iterator it = d->blocks.find(block); + if(it != d->blocks.end()) + d->blocks.erase(it); + + if(del) + delete picture; +} + void FLAC::File::removePictures() { List newBlocks; diff -Nru taglib-1.7.2/taglib/flac/flacfile.h taglib-1.8/taglib/flac/flacfile.h --- taglib-1.7.2/taglib/flac/flacfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/flac/flacfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -29,6 +29,7 @@ #include "taglib_export.h" #include "tfile.h" #include "tlist.h" +#include "tag.h" #include "flacpicture.h" #include "flacproperties.h" @@ -36,7 +37,6 @@ namespace TagLib { class Tag; - namespace ID3v2 { class FrameFactory; class Tag; } namespace ID3v1 { class Tag; } namespace Ogg { class XiphComment; } @@ -91,6 +91,22 @@ Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs a FLAC file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * If this file contains and ID3v2 tag the frames will be created using + * \a frameFactory. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + // BIC: merge with the above constructor + File(IOStream *stream, ID3v2::FrameFactory *frameFactory, + bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); @@ -106,6 +122,23 @@ virtual TagLib::Tag *tag() const; /*! + * Implements the unified property interface -- export function. + * If the file contains more than one tag (e.g. XiphComment and ID3v1), + * only the first one (in the order XiphComment, ID3v2, ID3v1) will be + * converted to the PropertyMap. + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &); + + /*! + * Implements the unified property interface -- import function. + * As with the export, only one tag is taken into account. If the file + * has no tag at all, a XiphComment will be created. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! * Returns the FLAC::Properties for this file. If no audio properties * were read then this will return a null pointer. */ @@ -190,6 +223,12 @@ List pictureList(); /*! + * Removes an attached picture. If \a del is true the picture's memory + * will be freed; if it is false, it must be deleted by the user. + */ + void removePicture(Picture *picture, bool del = true); + + /*! * Remove all attached images. */ void removePictures(); diff -Nru taglib-1.7.2/taglib/flac/flacmetadatablock.cpp taglib-1.8/taglib/flac/flacmetadatablock.cpp --- taglib-1.7.2/taglib/flac/flacmetadatablock.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/flac/flacmetadatablock.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -33,7 +33,7 @@ using namespace TagLib; -class FLAC::MetadataBlock::MetadataBlockPrivate +class FLAC::MetadataBlock::MetadataBlockPrivate { public: MetadataBlockPrivate() {} diff -Nru taglib-1.7.2/taglib/flac/flacpicture.cpp taglib-1.8/taglib/flac/flacpicture.cpp --- taglib-1.7.2/taglib/flac/flacpicture.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/flac/flacpicture.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -33,7 +33,7 @@ using namespace TagLib; -class FLAC::Picture::PicturePrivate +class FLAC::Picture::PicturePrivate { public: PicturePrivate() : @@ -117,7 +117,7 @@ } d->data = data.mid(pos, dataLength); - return true; + return true; } ByteVector FLAC::Picture::render() const diff -Nru taglib-1.7.2/taglib/flac/flacproperties.cpp taglib-1.8/taglib/flac/flacproperties.cpp --- taglib-1.7.2/taglib/flac/flacproperties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/flac/flacproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -42,7 +42,8 @@ bitrate(0), sampleRate(0), sampleWidth(0), - channels(0) {} + channels(0), + sampleFrames(0) {} ByteVector data; long streamLength; @@ -52,6 +53,7 @@ int sampleRate; int sampleWidth; int channels; + unsigned long long sampleFrames; ByteVector signature; }; @@ -101,6 +103,11 @@ return d->channels; } +unsigned long long FLAC::Properties::sampleFrames() const +{ + return d->sampleFrames; +} + ByteVector FLAC::Properties::signature() const { return d->signature; @@ -132,6 +139,8 @@ pos += 3; uint flags = d->data.mid(pos, 4).toUInt(true); + pos += 4; + d->sampleRate = flags >> 12; d->channels = ((flags >> 9) & 7) + 1; d->sampleWidth = ((flags >> 4) & 31) + 1; @@ -139,12 +148,14 @@ // The last 4 bits are the most significant 4 bits for the 36 bit // stream length in samples. (Audio files measured in days) - uint highLength =d->sampleRate > 0 ? (((flags & 0xf) << 28) / d->sampleRate) << 4 : 0; + unsigned long long hi = flags & 0xf; + unsigned long long lo = d->data.mid(pos, 4).toUInt(true); pos += 4; - d->length = d->sampleRate > 0 ? - (d->data.mid(pos, 4).toUInt(true)) / d->sampleRate + highLength : 0; - pos += 4; + d->sampleFrames = (hi << 32) | lo; + + if(d->sampleRate > 0) + d->length = int(d->sampleFrames / d->sampleRate); // Uncompressed bitrate: diff -Nru taglib-1.7.2/taglib/flac/flacproperties.h taglib-1.8/taglib/flac/flacproperties.h --- taglib-1.7.2/taglib/flac/flacproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/flac/flacproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -78,8 +78,13 @@ int sampleWidth() const; /*! + * Return the number of sample frames + */ + unsigned long long sampleFrames() const; + + /*! * Returns the MD5 signature of the uncompressed audio stream as read - * from the stream info header header. + * from the stream info header header. */ ByteVector signature() const; diff -Nru taglib-1.7.2/taglib/flac/flacunknownmetadatablock.cpp taglib-1.8/taglib/flac/flacunknownmetadatablock.cpp --- taglib-1.7.2/taglib/flac/flacunknownmetadatablock.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/flac/flacunknownmetadatablock.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -34,7 +34,7 @@ using namespace TagLib; -class FLAC::UnknownMetadataBlock::UnknownMetadataBlockPrivate +class FLAC::UnknownMetadataBlock::UnknownMetadataBlockPrivate { public: UnknownMetadataBlockPrivate() : code(0) {} diff -Nru taglib-1.7.2/taglib/it/itfile.cpp taglib-1.8/taglib/it/itfile.cpp --- taglib-1.7.2/taglib/it/itfile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/it/itfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,328 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "tstringlist.h" +#include "itfile.h" +#include "tdebug.h" +#include "modfileprivate.h" +#include "tpropertymap.h" + +using namespace TagLib; +using namespace IT; + +class IT::File::FilePrivate +{ +public: + FilePrivate(AudioProperties::ReadStyle propertiesStyle) + : tag(), properties(propertiesStyle) + { + } + + Mod::Tag tag; + IT::Properties properties; +}; + +IT::File::File(FileName file, bool readProperties, + AudioProperties::ReadStyle propertiesStyle) : + Mod::FileBase(file), + d(new FilePrivate(propertiesStyle)) +{ + read(readProperties); +} + +IT::File::File(IOStream *stream, bool readProperties, + AudioProperties::ReadStyle propertiesStyle) : + Mod::FileBase(stream), + d(new FilePrivate(propertiesStyle)) +{ + read(readProperties); +} + +IT::File::~File() +{ + delete d; +} + +Mod::Tag *IT::File::tag() const +{ + return &d->tag; +} + +PropertyMap IT::File::properties() const +{ + return d->tag.properties(); +} + +PropertyMap IT::File::setProperties(const PropertyMap &properties) +{ + return d->tag.setProperties(properties); +} + +IT::Properties *IT::File::audioProperties() const +{ + return &d->properties; +} + +bool IT::File::save() +{ + if(readOnly()) + { + debug("IT::File::save() - Cannot save to a read only file."); + return false; + } + seek(4); + writeString(d->tag.title(), 25); + writeByte(0); + + seek(2, Current); + + ushort length = 0; + ushort instrumentCount = 0; + ushort sampleCount = 0; + + if(!readU16L(length) || !readU16L(instrumentCount) || !readU16L(sampleCount)) + return false; + + seek(15, Current); + + // write comment as instrument and sample names: + StringList lines = d->tag.comment().split("\n"); + for(ushort i = 0; i < instrumentCount; ++ i) { + seek(192L + length + ((long)i << 2)); + ulong instrumentOffset = 0; + if(!readU32L(instrumentOffset)) + return false; + + seek(instrumentOffset + 32); + + if(i < lines.size()) + writeString(lines[i], 25); + else + writeString(String::null, 25); + writeByte(0); + } + + for(ushort i = 0; i < sampleCount; ++ i) { + seek(192L + length + ((long)instrumentCount << 2) + ((long)i << 2)); + ulong sampleOffset = 0; + if(!readU32L(sampleOffset)) + return false; + + seek(sampleOffset + 20); + + if((TagLib::uint)(i + instrumentCount) < lines.size()) + writeString(lines[i + instrumentCount], 25); + else + writeString(String::null, 25); + writeByte(0); + } + + // write rest as message: + StringList messageLines; + for(uint i = instrumentCount + sampleCount; i < lines.size(); ++ i) + messageLines.append(lines[i]); + ByteVector message = messageLines.toString("\r").data(String::Latin1); + + // it's actually not really stated if the message needs a + // terminating NUL but it does not hurt to add one: + if(message.size() > 7999) + message.resize(7999); + message.append((char)0); + + ushort special = 0; + ushort messageLength = 0; + ulong messageOffset = 0; + + seek(46); + if(!readU16L(special)) + return false; + + ulong fileSize = File::length(); + if(special & Properties::MessageAttached) { + seek(54); + if(!readU16L(messageLength) || !readU32L(messageOffset)) + return false; + + if(messageLength == 0) + messageOffset = fileSize; + } + else + { + messageOffset = fileSize; + seek(46); + writeU16L(special | 0x1); + } + + if(messageOffset + messageLength >= fileSize) { + // append new message + seek(54); + writeU16L(message.size()); + writeU32L(messageOffset); + seek(messageOffset); + writeBlock(message); + truncate(messageOffset + message.size()); + } + else { + // Only overwrite existing message. + // I'd need to parse (understand!) the whole file for more. + // Although I could just move the message to the end of file + // and let the existing one be, but that would waste space. + message.resize(messageLength, 0); + seek(messageOffset); + writeBlock(message); + } + return true; +} + +void IT::File::read(bool) +{ + if(!isOpen()) + return; + + seek(0); + READ_ASSERT(readBlock(4) == "IMPM"); + READ_STRING(d->tag.setTitle, 26); + + seek(2, Current); + + READ_U16L_AS(length); + READ_U16L_AS(instrumentCount); + READ_U16L_AS(sampleCount); + + d->properties.setInstrumentCount(instrumentCount); + d->properties.setSampleCount(sampleCount); + READ_U16L(d->properties.setPatternCount); + READ_U16L(d->properties.setVersion); + READ_U16L(d->properties.setCompatibleVersion); + READ_U16L(d->properties.setFlags); + READ_U16L_AS(special); + d->properties.setSpecial(special); + READ_BYTE(d->properties.setGlobalVolume); + READ_BYTE(d->properties.setMixVolume); + READ_BYTE(d->properties.setBpmSpeed); + READ_BYTE(d->properties.setTempo); + READ_BYTE(d->properties.setPanningSeparation); + READ_BYTE(d->properties.setPitchWheelDepth); + + // IT supports some kind of comment tag. Still, the + // sample/instrument names are abused as comments so + // I just add all together. + String message; + if(special & Properties::MessageAttached) { + READ_U16L_AS(messageLength); + READ_U32L_AS(messageOffset); + seek(messageOffset); + ByteVector messageBytes = readBlock(messageLength); + READ_ASSERT(messageBytes.size() == messageLength); + int index = messageBytes.find((char) 0); + if(index > -1) + messageBytes.resize(index, 0); + messageBytes.replace('\r', '\n'); + message = messageBytes; + } + + seek(64); + + ByteVector pannings = readBlock(64); + ByteVector volumes = readBlock(64); + READ_ASSERT(pannings.size() == 64 && volumes.size() == 64); + int channels = 0; + for(int i = 0; i < 64; ++ i) { + // Strictly speaking an IT file has always 64 channels, but + // I don't count disabled and muted channels. + // 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) + ++channels; + } + d->properties.setChannels(channels); + + // real length might be shorter because of skips and terminator + ushort realLength = 0; + for(ushort i = 0; i < length; ++ i) { + READ_BYTE_AS(order); + if(order == 255) break; + if(order != 254) ++ realLength; + } + d->properties.setLengthInPatterns(realLength); + + StringList comment; + // Note: I found files that have nil characters somewhere + // in the instrument/sample names and more characters + // afterwards. The spec does not mention such a case. + // Currently I just discard anything after a nil, but + // e.g. VLC seems to interprete a nil as a space. I + // don't know what is the proper behaviour. + for(ushort i = 0; i < instrumentCount; ++ i) { + seek(192L + length + ((long)i << 2)); + READ_U32L_AS(instrumentOffset); + seek(instrumentOffset); + + ByteVector instrumentMagic = readBlock(4); + READ_ASSERT(instrumentMagic == "IMPI"); + + READ_STRING_AS(dosFileName, 13); + + seek(15, Current); + + READ_STRING_AS(instrumentName, 26); + comment.append(instrumentName); + } + + for(ushort i = 0; i < sampleCount; ++ i) { + seek(192L + length + ((long)instrumentCount << 2) + ((long)i << 2)); + READ_U32L_AS(sampleOffset); + + seek(sampleOffset); + + ByteVector sampleMagic = readBlock(4); + READ_ASSERT(sampleMagic == "IMPS"); + + READ_STRING_AS(dosFileName, 13); + READ_BYTE_AS(globalVolume); + READ_BYTE_AS(sampleFlags); + READ_BYTE_AS(sampleVolume); + READ_STRING_AS(sampleName, 26); + /* + READ_BYTE_AS(sampleCvt); + READ_BYTE_AS(samplePanning); + READ_U32L_AS(sampleLength); + READ_U32L_AS(loopStart); + READ_U32L_AS(loopStop); + READ_U32L_AS(c5speed); + READ_U32L_AS(sustainLoopStart); + READ_U32L_AS(sustainLoopEnd); + READ_U32L_AS(sampleDataOffset); + READ_BYTE_AS(vibratoSpeed); + READ_BYTE_AS(vibratoDepth); + READ_BYTE_AS(vibratoRate); + READ_BYTE_AS(vibratoType); + */ + + comment.append(sampleName); + } + + if(message.size() > 0) + comment.append(message); + d->tag.setComment(comment.toString("\n")); + d->tag.setTrackerName("Impulse Tracker"); +} diff -Nru taglib-1.7.2/taglib/it/itfile.h taglib-1.8/taglib/it/itfile.h --- taglib-1.7.2/taglib/it/itfile.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/it/itfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,105 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_ITFILE_H +#define TAGLIB_ITFILE_H + +#include "tfile.h" +#include "audioproperties.h" +#include "taglib_export.h" +#include "modfilebase.h" +#include "modtag.h" +#include "itproperties.h" + +namespace TagLib { + + namespace IT { + + class TAGLIB_EXPORT File : public Mod::FileBase { + public: + /*! + * Contructs a Impulse Tracker file from \a file. If \a readProperties + * is true the file's audio properties will also be read using + * \a propertiesStyle. If false, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + AudioProperties::ReadStyle propertiesStyle = + AudioProperties::Average); + + /*! + * Contructs a Impulse Tracker file from \a stream. If \a readProperties + * is true the file's audio properties will also be read using + * \a propertiesStyle. If false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stram, bool readProperties = true, + AudioProperties::ReadStyle propertiesStyle = + AudioProperties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + Mod::Tag *tag() const; + + /*! + * Forwards to Mod::Tag::properties(). + * BIC: will be removed once File::toDict() is made virtual + */ + PropertyMap properties() const; + + /*! + * Forwards to Mod::Tag::setProperties(). + * BIC: will be removed once File::setProperties() is made virtual + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the IT::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + IT::Properties *audioProperties() const; + + /*! + * Save the file. + * This is the same as calling save(AllTags); + * + * \note Saving Impulse Tracker tags is not supported. + */ + bool save(); + + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff -Nru taglib-1.7.2/taglib/it/itproperties.cpp taglib-1.8/taglib/it/itproperties.cpp --- taglib-1.7.2/taglib/it/itproperties.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/it/itproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,245 @@ +/*************************************************************************** + copyright :(C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "itproperties.h" + +using namespace TagLib; +using namespace IT; + +class IT::Properties::PropertiesPrivate +{ +public: + PropertiesPrivate() : + channels(0), + lengthInPatterns(0), + instrumentCount(0), + sampleCount(0), + patternCount(0), + version(0), + compatibleVersion(0), + flags(0), + special(0), + globalVolume(0), + mixVolume(0), + tempo(0), + bpmSpeed(0), + panningSeparation(0), + pitchWheelDepth(0) + { + } + + int channels; + ushort lengthInPatterns; + ushort instrumentCount; + ushort sampleCount; + ushort patternCount; + ushort version; + ushort compatibleVersion; + ushort flags; + ushort special; + uchar globalVolume; + uchar mixVolume; + uchar tempo; + uchar bpmSpeed; + uchar panningSeparation; + uchar pitchWheelDepth; +}; + +IT::Properties::Properties(AudioProperties::ReadStyle propertiesStyle) : + AudioProperties(propertiesStyle), + d(new PropertiesPrivate) +{ +} + +IT::Properties::~Properties() +{ + delete d; +} + +int IT::Properties::length() const +{ + return 0; +} + +int IT::Properties::bitrate() const +{ + return 0; +} + +int IT::Properties::sampleRate() const +{ + return 0; +} + +int IT::Properties::channels() const +{ + return d->channels; +} + +TagLib::ushort IT::Properties::lengthInPatterns() const +{ + return d->lengthInPatterns; +} + +bool IT::Properties::stereo() const +{ + return d->flags & Stereo; +} + +TagLib::ushort IT::Properties::instrumentCount() const +{ + return d->instrumentCount; +} + +TagLib::ushort IT::Properties::sampleCount() const +{ + return d->sampleCount; +} + +TagLib::ushort IT::Properties::patternCount() const +{ + return d->patternCount; +} + +TagLib::ushort IT::Properties::version() const +{ + return d->version; +} + +TagLib::ushort IT::Properties::compatibleVersion() const +{ + return d->compatibleVersion; +} + +TagLib::ushort IT::Properties::flags() const +{ + return d->flags; +} + +TagLib::ushort IT::Properties::special() const +{ + return d->special; +} + +uchar IT::Properties::globalVolume() const +{ + return d->globalVolume; +} + +uchar IT::Properties::mixVolume() const +{ + return d->mixVolume; +} + +uchar IT::Properties::tempo() const +{ + return d->tempo; +} + +uchar IT::Properties::bpmSpeed() const +{ + return d->bpmSpeed; +} + +uchar IT::Properties::panningSeparation() const +{ + return d->panningSeparation; +} + +uchar IT::Properties::pitchWheelDepth() const +{ + return d->pitchWheelDepth; +} + +void IT::Properties::setChannels(int channels) +{ + d->channels = channels; +} + +void IT::Properties::setLengthInPatterns(ushort lengthInPatterns) +{ + d->lengthInPatterns = lengthInPatterns; +} + +void IT::Properties::setInstrumentCount(ushort instrumentCount) +{ + d->instrumentCount = instrumentCount; +} + +void IT::Properties::setSampleCount(ushort sampleCount) +{ + d->sampleCount = sampleCount; +} + +void IT::Properties::setPatternCount(ushort patternCount) +{ + d->patternCount = patternCount; +} + +void IT::Properties::setFlags(ushort flags) +{ + d->flags = flags; +} + +void IT::Properties::setSpecial(ushort special) +{ + d->special = special; +} + +void IT::Properties::setCompatibleVersion(ushort compatibleVersion) +{ + d->compatibleVersion = compatibleVersion; +} + +void IT::Properties::setVersion(ushort version) +{ + d->version = version; +} + +void IT::Properties::setGlobalVolume(uchar globalVolume) +{ + d->globalVolume = globalVolume; +} + +void IT::Properties::setMixVolume(uchar mixVolume) +{ + d->mixVolume = mixVolume; +} + +void IT::Properties::setTempo(uchar tempo) +{ + d->tempo = tempo; +} + +void IT::Properties::setBpmSpeed(uchar bpmSpeed) +{ + d->bpmSpeed = bpmSpeed; +} + +void IT::Properties::setPanningSeparation(uchar panningSeparation) +{ + d->panningSeparation = panningSeparation; +} + +void IT::Properties::setPitchWheelDepth(uchar pitchWheelDepth) +{ + d->pitchWheelDepth = pitchWheelDepth; +} diff -Nru taglib-1.7.2/taglib/it/itproperties.h taglib-1.8/taglib/it/itproperties.h --- taglib-1.7.2/taglib/it/itproperties.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/it/itproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,101 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_ITPROPERTIES_H +#define TAGLIB_ITPROPERTIES_H + +#include "taglib.h" +#include "audioproperties.h" + +namespace TagLib { + namespace IT { + class TAGLIB_EXPORT Properties : public AudioProperties { + friend class File; + public: + /*! Flag bits. */ + enum { + Stereo = 1, + Vol0MixOptimizations = 2, + UseInstruments = 4, + LinearSlides = 8, + OldEffects = 16, + LinkEffects = 32, + UseMidiPitchController = 64, + RequestEmbeddedMidiConf = 128 + }; + + /*! Special bits. */ + enum { + MessageAttached = 1, + MidiConfEmbedded = 8 + }; + + Properties(AudioProperties::ReadStyle propertiesStyle); + virtual ~Properties(); + + int length() const; + int bitrate() const; + int sampleRate() const; + int channels() const; + + ushort lengthInPatterns() const; + bool stereo() const; + ushort instrumentCount() const; + ushort sampleCount() const; + ushort patternCount() const; + ushort version() const; + ushort compatibleVersion() const; + ushort flags() const; + ushort special() const; + uchar globalVolume() const; + uchar mixVolume() const; + uchar tempo() const; + uchar bpmSpeed() const; + uchar panningSeparation() const; + uchar pitchWheelDepth() const; + + void setChannels(int channels); + void setLengthInPatterns(ushort lengthInPatterns); + void setInstrumentCount(ushort instrumentCount); + void setSampleCount (ushort sampleCount); + void setPatternCount(ushort patternCount); + void setVersion (ushort version); + void setCompatibleVersion(ushort compatibleVersion); + void setFlags (ushort flags); + void setSpecial (ushort special); + void setGlobalVolume(uchar globalVolume); + void setMixVolume (uchar mixVolume); + void setTempo (uchar tempo); + void setBpmSpeed (uchar bpmSpeed); + void setPanningSeparation(uchar panningSeparation); + void setPitchWheelDepth (uchar pitchWheelDepth); + + private: + Properties(const Properties&); + Properties &operator=(const Properties&); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff -Nru taglib-1.7.2/taglib/mod/modfile.cpp taglib-1.8/taglib/mod/modfile.cpp --- taglib-1.7.2/taglib/mod/modfile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mod/modfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,185 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "modfile.h" +#include "tstringlist.h" +#include "tdebug.h" +#include "modfileprivate.h" +#include "tpropertymap.h" + +using namespace TagLib; +using namespace Mod; + +class Mod::File::FilePrivate +{ +public: + FilePrivate(AudioProperties::ReadStyle propertiesStyle) + : properties(propertiesStyle) + { + } + + Mod::Tag tag; + Mod::Properties properties; +}; + +Mod::File::File(FileName file, bool readProperties, + AudioProperties::ReadStyle propertiesStyle) : + Mod::FileBase(file), + d(new FilePrivate(propertiesStyle)) +{ + read(readProperties); +} + +Mod::File::File(IOStream *stream, bool readProperties, + AudioProperties::ReadStyle propertiesStyle) : + Mod::FileBase(stream), + d(new FilePrivate(propertiesStyle)) +{ + read(readProperties); +} + +Mod::File::~File() +{ + delete d; +} + +Mod::Tag *Mod::File::tag() const +{ + return &d->tag; +} + +Mod::Properties *Mod::File::audioProperties() const +{ + return &d->properties; +} + +PropertyMap Mod::File::properties() const +{ + return d->tag.properties(); +} + +PropertyMap Mod::File::setProperties(const PropertyMap &properties) +{ + return d->tag.setProperties(properties); +} + +bool Mod::File::save() +{ + if(readOnly()) { + debug("Mod::File::save() - Cannot save to a read only file."); + return false; + } + seek(0); + writeString(d->tag.title(), 20); + StringList lines = d->tag.comment().split("\n"); + uint n = std::min(lines.size(), d->properties.instrumentCount()); + for(uint i = 0; i < n; ++ i) { + writeString(lines[i], 22); + seek(8, Current); + } + + for(uint i = n; i < d->properties.instrumentCount(); ++ i) { + writeString(String::null, 22); + seek(8, Current); + } + return true; +} + +void Mod::File::read(bool) +{ + if(!isOpen()) + return; + + seek(1080); + ByteVector modId = readBlock(4); + READ_ASSERT(modId.size() == 4); + + int channels = 4; + uint instruments = 31; + if(modId == "M.K." || modId == "M!K!" || modId == "M&K!" || modId == "N.T.") { + d->tag.setTrackerName("ProTracker"); + channels = 4; + } + else if(modId.startsWith("FLT") || modId.startsWith("TDZ")) { + d->tag.setTrackerName("StarTrekker"); + char digit = modId[3]; + READ_ASSERT(digit >= '0' && digit <= '9'); + channels = digit - '0'; + } + else if(modId.endsWith("CHN")) { + d->tag.setTrackerName("StarTrekker"); + char digit = modId[0]; + READ_ASSERT(digit >= '0' && digit <= '9'); + channels = digit - '0'; + } + else if(modId == "CD81" || modId == "OKTA") { + d->tag.setTrackerName("Atari Oktalyzer"); + channels = 8; + } + else if(modId.endsWith("CH") || modId.endsWith("CN")) { + d->tag.setTrackerName("TakeTracker"); + char digit = modId[0]; + READ_ASSERT(digit >= '0' && digit <= '9'); + channels = (digit - '0') * 10; + digit = modId[1]; + READ_ASSERT(digit >= '0' && digit <= '9'); + channels += digit - '0'; + } + else { + // Not sure if this is correct. I'd need a file + // created with NoiseTracker to check this. + d->tag.setTrackerName("NoiseTracker"); // probably + channels = 4; + instruments = 15; + } + d->properties.setChannels(channels); + d->properties.setInstrumentCount(instruments); + + seek(0); + READ_STRING(d->tag.setTitle, 20); + + StringList comment; + for(uint i = 0; i < instruments; ++ i) { + READ_STRING_AS(instrumentName, 22); + // value in words, * 2 (<< 1) for bytes: + READ_U16B_AS(sampleLength); + + READ_BYTE_AS(fineTuneByte); + int fineTune = fineTuneByte & 0xF; + // > 7 means negative value + if(fineTune > 7) fineTune -= 16; + + READ_BYTE_AS(volume); + if(volume > 64) volume = 64; + // volume in decibels: 20 * log10(volume / 64) + + // value in words, * 2 (<< 1) for bytes: + READ_U16B_AS(repeatStart); + // value in words, * 2 (<< 1) for bytes: + READ_U16B_AS(repatLength); + + comment.append(instrumentName); + } + + READ_BYTE(d->properties.setLengthInPatterns); + + d->tag.setComment(comment.toString("\n")); +} diff -Nru taglib-1.7.2/taglib/mod/modfile.h taglib-1.8/taglib/mod/modfile.h --- taglib-1.7.2/taglib/mod/modfile.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mod/modfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,106 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_MODFILE_H +#define TAGLIB_MODFILE_H + +#include "tfile.h" +#include "audioproperties.h" +#include "taglib_export.h" +#include "modfilebase.h" +#include "modtag.h" +#include "modproperties.h" + +namespace TagLib { + + namespace Mod { + + class TAGLIB_EXPORT File : public TagLib::Mod::FileBase + { + public: + /*! + * Contructs a Protracker file from \a file. If \a readProperties + * is true the file's audio properties will also be read using + * \a propertiesStyle. If false, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + AudioProperties::ReadStyle propertiesStyle = + AudioProperties::Average); + + /*! + * Contructs a Protracker file from \a stream. If \a readProperties + * is true the file's audio properties will also be read using + * \a propertiesStyle. If false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + AudioProperties::ReadStyle propertiesStyle = + AudioProperties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + Mod::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * Forwards to Mod::Tag::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * Forwards to Mod::Tag::setProperties(). + */ + PropertyMap setProperties(const PropertyMap &); + /*! + * Returns the Mod::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + Mod::Properties *audioProperties() const; + + /*! + * Save the file. + * This is the same as calling save(AllTags); + * + * \note Saving Protracker tags is not supported. + */ + bool save(); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + + } + +} + +#endif diff -Nru taglib-1.7.2/taglib/mod/modfilebase.cpp taglib-1.8/taglib/mod/modfilebase.cpp --- taglib-1.7.2/taglib/mod/modfilebase.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mod/modfilebase.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,120 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "tdebug.h" +#include "modfilebase.h" + +using namespace TagLib; +using namespace Mod; + +Mod::FileBase::FileBase(FileName file) : TagLib::File(file) +{ +} + +Mod::FileBase::FileBase(IOStream *stream) : TagLib::File(stream) +{ +} + +void Mod::FileBase::writeString(const String &s, ulong size, char padding) +{ + ByteVector data(s.data(String::Latin1)); + data.resize(size, padding); + writeBlock(data); +} + +bool Mod::FileBase::readString(String &s, ulong size) +{ + ByteVector data(readBlock(size)); + if(data.size() < size) return false; + int index = data.find((char) 0); + if(index > -1) + { + data.resize(index); + } + data.replace((char) 0xff, ' '); + + s = data; + return true; +} + +void Mod::FileBase::writeByte(uchar byte) +{ + ByteVector data(1, byte); + writeBlock(data); +} + +void Mod::FileBase::writeU16L(ushort number) +{ + writeBlock(ByteVector::fromShort(number, false)); +} + +void Mod::FileBase::writeU32L(ulong number) +{ + writeBlock(ByteVector::fromUInt(number, false)); +} + +void Mod::FileBase::writeU16B(ushort number) +{ + writeBlock(ByteVector::fromShort(number, true)); +} + +void Mod::FileBase::writeU32B(ulong number) +{ + writeBlock(ByteVector::fromUInt(number, true)); +} + +bool Mod::FileBase::readByte(uchar &byte) +{ + ByteVector data(readBlock(1)); + if(data.size() < 1) return false; + byte = data[0]; + return true; +} + +bool Mod::FileBase::readU16L(ushort &number) +{ + ByteVector data(readBlock(2)); + if(data.size() < 2) return false; + number = data.toUShort(false); + return true; +} + +bool Mod::FileBase::readU32L(ulong &number) { + ByteVector data(readBlock(4)); + if(data.size() < 4) return false; + number = data.toUInt(false); + return true; +} + +bool Mod::FileBase::readU16B(ushort &number) +{ + ByteVector data(readBlock(2)); + if(data.size() < 2) return false; + number = data.toUShort(true); + return true; +} + +bool Mod::FileBase::readU32B(ulong &number) { + ByteVector data(readBlock(4)); + if(data.size() < 4) return false; + number = data.toUInt(true); + return true; +} diff -Nru taglib-1.7.2/taglib/mod/modfilebase.h taglib-1.8/taglib/mod/modfilebase.h --- taglib-1.7.2/taglib/mod/modfilebase.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mod/modfilebase.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,62 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_MODFILEBASE_H +#define TAGLIB_MODFILEBASE_H + +#include "taglib.h" +#include "tfile.h" +#include "tstring.h" +#include "tlist.h" +#include "taglib_export.h" + +#include + +namespace TagLib { + + namespace Mod { + + class TAGLIB_EXPORT FileBase : public TagLib::File + { + protected: + FileBase(FileName file); + FileBase(IOStream *stream); + + void writeString(const String &s, ulong size, char padding = 0); + void writeByte(uchar byte); + void writeU16L(ushort number); + void writeU32L(ulong number); + void writeU16B(ushort number); + void writeU32B(ulong number); + + bool readString(String &s, ulong size); + bool readByte(uchar &byte); + bool readU16L(ushort &number); + bool readU32L(ulong &number); + bool readU16B(ushort &number); + bool readU32B(ulong &number); + }; + + } + +} + +#endif diff -Nru taglib-1.7.2/taglib/mod/modfileprivate.h taglib-1.8/taglib/mod/modfileprivate.h --- taglib-1.7.2/taglib/mod/modfileprivate.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mod/modfileprivate.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,67 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_MODFILEPRIVATE_H +#define TAGLIB_MODFILEPRIVATE_H + +// some helper-macros only used internally by (s3m|it|xm)file.cpp +#define READ_ASSERT(cond) \ + if(!(cond)) \ + { \ + setValid(false); \ + return; \ + } + +#define READ(setter,type,read) \ + { \ + type number; \ + READ_ASSERT(read(number)); \ + setter(number); \ + } + +#define READ_BYTE(setter) READ(setter,uchar,readByte) +#define READ_U16L(setter) READ(setter,ushort,readU16L) +#define READ_U32L(setter) READ(setter,ulong,readU32L) +#define READ_U16B(setter) READ(setter,ushort,readU16B) +#define READ_U32B(setter) READ(setter,ulong,readU32B) + +#define READ_STRING(setter,size) \ + { \ + String s; \ + READ_ASSERT(readString(s, size)); \ + setter(s); \ + } + +#define READ_AS(type,name,read) \ + type name = 0; \ + READ_ASSERT(read(name)); + +#define READ_BYTE_AS(name) READ_AS(uchar,name,readByte) +#define READ_U16L_AS(name) READ_AS(ushort,name,readU16L) +#define READ_U32L_AS(name) READ_AS(ulong,name,readU32L) +#define READ_U16B_AS(name) READ_AS(ushort,name,readU16B) +#define READ_U32B_AS(name) READ_AS(ulong,name,readU32B) + +#define READ_STRING_AS(name,size) \ + String name; \ + READ_ASSERT(readString(name, size)); + +#endif diff -Nru taglib-1.7.2/taglib/mod/modproperties.cpp taglib-1.8/taglib/mod/modproperties.cpp --- taglib-1.7.2/taglib/mod/modproperties.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mod/modproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,96 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "modproperties.h" + +using namespace TagLib; +using namespace Mod; + +class Mod::Properties::PropertiesPrivate +{ +public: + PropertiesPrivate() : + channels(0), + instrumentCount(0), + lengthInPatterns(0) + { + } + + int channels; + uint instrumentCount; + uchar lengthInPatterns; +}; + +Mod::Properties::Properties(AudioProperties::ReadStyle propertiesStyle) : + AudioProperties(propertiesStyle), + d(new PropertiesPrivate) +{ +} + +Mod::Properties::~Properties() +{ + delete d; +} + +int Mod::Properties::length() const +{ + return 0; +} + +int Mod::Properties::bitrate() const +{ + return 0; +} + +int Mod::Properties::sampleRate() const +{ + return 0; +} + +int Mod::Properties::channels() const +{ + return d->channels; +} + +TagLib::uint Mod::Properties::instrumentCount() const +{ + return d->instrumentCount; +} + +uchar Mod::Properties::lengthInPatterns() const +{ + return d->lengthInPatterns; +} + +void Mod::Properties::setChannels(int channels) +{ + d->channels = channels; +} + +void Mod::Properties::setInstrumentCount(uint instrumentCount) +{ + d->instrumentCount = instrumentCount; +} + +void Mod::Properties::setLengthInPatterns(uchar lengthInPatterns) +{ + d->lengthInPatterns = lengthInPatterns; +} diff -Nru taglib-1.7.2/taglib/mod/modproperties.h taglib-1.8/taglib/mod/modproperties.h --- taglib-1.7.2/taglib/mod/modproperties.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mod/modproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,65 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_MODPROPERTIES_H +#define TAGLIB_MODPROPERTIES_H + +#include "taglib.h" +#include "audioproperties.h" + +namespace TagLib { + + namespace Mod { + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + Properties(AudioProperties::ReadStyle propertiesStyle); + virtual ~Properties(); + + int length() const; + int bitrate() const; + int sampleRate() const; + int channels() const; + + uint instrumentCount() const; + uchar lengthInPatterns() const; + + void setChannels(int channels); + + void setInstrumentCount(uint sampleCount); + void setLengthInPatterns(uchar lengthInPatterns); + + private: + friend class File; + + Properties(const Properties&); + Properties &operator=(const Properties&); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + + } + +} + +#endif diff -Nru taglib-1.7.2/taglib/mod/modtag.cpp taglib-1.8/taglib/mod/modtag.cpp --- taglib-1.7.2/taglib/mod/modtag.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mod/modtag.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,168 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "modtag.h" +#include "tstringlist.h" +#include "tpropertymap.h" + +using namespace TagLib; +using namespace Mod; + +class Mod::Tag::TagPrivate +{ +public: + TagPrivate() + { + } + + String title; + String comment; + String trackerName; +}; + +Mod::Tag::Tag() : TagLib::Tag() +{ + d = new TagPrivate; +} + +Mod::Tag::~Tag() +{ + delete d; +} + +String Mod::Tag::title() const +{ + return d->title; +} + +String Mod::Tag::artist() const +{ + return String::null; +} + +String Mod::Tag::album() const +{ + return String::null; +} + +String Mod::Tag::comment() const +{ + return d->comment; +} + +String Mod::Tag::genre() const +{ + return String::null; +} + +TagLib::uint Mod::Tag::year() const +{ + return 0; +} + +TagLib::uint Mod::Tag::track() const +{ + return 0; +} + +String Mod::Tag::trackerName() const +{ + return d->trackerName; +} + +void Mod::Tag::setTitle(const String &title) +{ + d->title = title; +} + +void Mod::Tag::setArtist(const String &) +{ +} + +void Mod::Tag::setAlbum(const String &) +{ +} + +void Mod::Tag::setComment(const String &comment) +{ + d->comment = comment; +} + +void Mod::Tag::setGenre(const String &) +{ +} + +void Mod::Tag::setYear(uint) +{ +} + +void Mod::Tag::setTrack(uint) +{ +} + +void Mod::Tag::setTrackerName(const String &trackerName) +{ + d->trackerName = trackerName; +} + +PropertyMap Mod::Tag::properties() const +{ + PropertyMap properties; + properties["TITLE"] = d->title; + properties["COMMENT"] = d->comment; + if(!(d->trackerName.isNull())) + properties["TRACKERNAME"] = d->trackerName; + return properties; +} + +PropertyMap Mod::Tag::setProperties(const PropertyMap &origProps) +{ + PropertyMap properties(origProps); + properties.removeEmpty(); + StringList oneValueSet; + if(properties.contains("TITLE")) { + d->title = properties["TITLE"].front(); + oneValueSet.append("TITLE"); + } else + d->title = String::null; + + if(properties.contains("COMMENT")) { + d->comment = properties["COMMENT"].front(); + oneValueSet.append("COMMENT"); + } else + d->comment = String::null; + + if(properties.contains("TRACKERNAME")) { + d->trackerName = properties["TRACKERNAME"].front(); + oneValueSet.append("TRACKERNAME"); + } else + d->trackerName = String::null; + + // for each tag that has been set above, remove the first entry in the corresponding + // value list. The others will be returned as unsupported by this format. + for(StringList::Iterator it = oneValueSet.begin(); it != oneValueSet.end(); ++it) { + if(properties[*it].size() == 1) + properties.erase(*it); + else + properties[*it].erase( properties[*it].begin() ); + } + return properties; +} diff -Nru taglib-1.7.2/taglib/mod/modtag.h taglib-1.8/taglib/mod/modtag.h --- taglib-1.7.2/taglib/mod/modtag.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mod/modtag.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,190 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_MODTAG_H +#define TAGLIB_MODTAG_H + +#include "tag.h" + +namespace TagLib { + + namespace Mod { + + /*! + * Tags for module files (Mod, S3M, IT, XM). + * + * Note that only the \a title is supported as such by most + * module file formats. Except for XM files the \a trackerName + * is derived from the file format or the flavour of the file + * format. For XM files it is stored in the file. + * + * The \a comment tag is not strictly supported by module files, + * but it is common practice to abuse instrument/sample/pattern + * names as multiline comments. TagLib does so as well. + */ + class TAGLIB_EXPORT Tag : public TagLib::Tag + { + public: + Tag(); + virtual ~Tag(); + + /*! + * Returns the track name; if no track name is present in the tag + * String::null will be returned. + */ + String title() const; + + /*! + * Not supported by module files. Therefore always returns String::null. + */ + String artist() const; + + /*! + * Not supported by module files. Therefore always returns String::null. + */ + String album() const; + + /*! + * Returns the track comment derived from the instrument/sample/pattern + * names; if no comment is present in the tag String::null will be + * returned. + */ + String comment() const; + + /*! + * Not supported by module files. Therefore always returns String::null. + */ + String genre() const; + + /*! + * Not supported by module files. Therefore always returns 0. + */ + uint year() const; + + /*! + * Not supported by module files. Therefore always returns 0. + */ + uint track() const; + + /*! + * Returns the name of the tracker used to create/edit the module file. + * Only XM files store this tag to the file as such, for other formats + * (Mod, S3M, IT) this is derived from the file type or the flavour of + * the file type. Therefore only XM files might have an empty + * (String::null) tracker name. + */ + String trackerName() const; + + /*! + * Sets the title to \a title. If \a title is String::null then this + * value will be cleared. + * + * The length limits per file type are (1 characetr = 1 byte): + * Mod 20 characters, S3M 27 characters, IT 25 characters and XM 20 + * characters. + */ + void setTitle(const String &title); + + /*! + * Not supported by module files and therefore ignored. + */ + void setArtist(const String &artist); + + /*! + * Not supported by module files and therefore ignored. + */ + void setAlbum(const String &album); + + /*! + * Sets the comment to \a comment. If \a comment is String::null then + * this value will be cleared. + * + * Note that module file formats don't actually support a comment tag. + * Instead the names of instruments/patterns/samples are abused as + * a multiline comment. Because of this the number of lines in a + * module file is fixed to the number of instruments/patterns/samples. + * + * Also note that the instrument/pattern/sample name length is limited + * an thus the line length in comments are limited. Too big comments + * will be truncated. + * + * The line length limits per file type are (1 characetr = 1 byte): + * Mod 22 characters, S3M 27 characters, IT 25 characters and XM 22 + * characters. + */ + void setComment(const String &comment); + + /*! + * Not supported by module files and therefore ignored. + */ + void setGenre(const String &genre); + + /*! + * Not supported by module files and therefore ignored. + */ + void setYear(uint year); + + /*! + * Not supported by module files and therefore ignored. + */ + void setTrack(uint track); + + /*! + * Sets the tracker name to \a trackerName. If \a trackerName is + * String::null then this value will be cleared. + * + * Note that only XM files support this tag. Setting the + * tracker name for other module file formats will be ignored. + * + * The length of this tag is limited to 20 characters (1 character + * = 1 byte). + */ + void setTrackerName(const String &trackerName); + + /*! + * Implements the unified property interface -- export function. + * Since the module tag is very limited, the exported map is as well. + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * Because of the limitations of the module file tag, any tags besides + * COMMENT, TITLE and, if it is an XM file, TRACKERNAME, will be + * returened. Additionally, if the map contains tags with multiple values, + * all but the first will be contained in the returned map of unsupported + * properties. + */ + PropertyMap setProperties(const PropertyMap &); + + private: + Tag(const Tag &); + Tag &operator=(const Tag &); + + class TagPrivate; + TagPrivate *d; + }; + + } + +} + +#endif diff -Nru taglib-1.7.2/taglib/mp4/CMakeLists.txt taglib-1.8/taglib/mp4/CMakeLists.txt --- taglib-1.7.2/taglib/mp4/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES mp4file.h mp4atom.h mp4tag.h mp4item.h mp4properties.h mp4coverart.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/mp4/mp4atom.cpp taglib-1.8/taglib/mp4/mp4atom.cpp --- taglib-1.7.2/taglib/mp4/mp4atom.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4atom.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,17 +27,16 @@ #include #endif -#ifdef WITH_MP4 - #include #include #include "mp4atom.h" using namespace TagLib; -const char *MP4::Atom::containers[10] = { +const char *MP4::Atom::containers[11] = { "moov", "udta", "mdia", "meta", "ilst", "stbl", "minf", "moof", "traf", "trak", + "stsd" }; MP4::Atom::Atom(File *file) @@ -82,6 +81,9 @@ if(name == "meta") { file->seek(4, File::Current); } + else if(name == "stsd") { + file->seek(8, File::Current); + } while(file->tell() < offset + length) { MP4::Atom *child = new MP4::Atom(file); children.append(child); @@ -194,4 +196,3 @@ return path; } -#endif diff -Nru taglib-1.7.2/taglib/mp4/mp4atom.h taglib-1.8/taglib/mp4/mp4atom.h --- taglib-1.7.2/taglib/mp4/mp4atom.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4atom.h 2012-09-06 18:03:15.000000000 +0000 @@ -1,5 +1,5 @@ /************************************************************************** - copyright : (C) 2007 by Lukáš Lalinský + copyright : (C) 2007,2011 by Lukáš Lalinský email : lalinsky@gmail.com **************************************************************************/ @@ -40,6 +40,40 @@ class Atom; typedef TagLib::List AtomList; + enum AtomDataType + { + TypeImplicit = 0, // for use with tags for which no type needs to be indicated because only one type is allowed + TypeUTF8 = 1, // without any count or null terminator + TypeUTF16 = 2, // also known as UTF-16BE + TypeSJIS = 3, // deprecated unless it is needed for special Japanese characters + TypeHTML = 6, // the HTML file header specifies which HTML version + TypeXML = 7, // the XML header must identify the DTD or schemas + TypeUUID = 8, // also known as GUID; stored as 16 bytes in binary (valid as an ID) + TypeISRC = 9, // stored as UTF-8 text (valid as an ID) + TypeMI3P = 10, // stored as UTF-8 text (valid as an ID) + TypeGIF = 12, // (deprecated) a GIF image + TypeJPEG = 13, // a JPEG image + TypePNG = 14, // a PNG image + TypeURL = 15, // absolute, in UTF-8 characters + TypeDuration = 16, // in milliseconds, 32-bit integer + TypeDateTime = 17, // in UTC, counting seconds since midnight, January 1, 1904; 32 or 64-bits + TypeGenred = 18, // a list of enumerated values + TypeInteger = 21, // a signed big-endian integer with length one of { 1,2,3,4,8 } bytes + TypeRIAAPA = 24, // RIAA parental advisory; { -1=no, 1=yes, 0=unspecified }, 8-bit ingteger + TypeUPC = 25, // Universal Product Code, in text UTF-8 format (valid as an ID) + TypeBMP = 27, // Windows bitmap image + TypeUndefined = 255 // undefined + }; + + struct AtomData { + AtomData(AtomDataType type, ByteVector data) : type(type), locale(0), data(data) {} + AtomDataType type; + int locale; + ByteVector data; + }; + + typedef TagLib::List AtomDataList; + class Atom { public: @@ -53,8 +87,8 @@ TagLib::ByteVector name; AtomList children; private: - static const int numContainers = 10; - static const char *containers[10]; + static const int numContainers = 11; + static const char *containers[11]; }; //! Root-level atoms diff -Nru taglib-1.7.2/taglib/mp4/mp4coverart.cpp taglib-1.8/taglib/mp4/mp4coverart.cpp --- taglib-1.7.2/taglib/mp4/mp4coverart.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4coverart.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,8 +27,6 @@ #include #endif -#ifdef WITH_MP4 - #include #include #include "mp4coverart.h" @@ -86,4 +84,3 @@ return d->data; } -#endif diff -Nru taglib-1.7.2/taglib/mp4/mp4coverart.h taglib-1.8/taglib/mp4/mp4coverart.h --- taglib-1.7.2/taglib/mp4/mp4coverart.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4coverart.h 2012-09-06 18:03:15.000000000 +0000 @@ -29,6 +29,7 @@ #include "tlist.h" #include "tbytevector.h" #include "taglib_export.h" +#include "mp4atom.h" namespace TagLib { @@ -41,8 +42,10 @@ * This describes the image type. */ enum Format { - JPEG = 0x0D, - PNG = 0x0E + JPEG = TypeJPEG, + PNG = TypePNG, + BMP = TypeBMP, + GIF = TypeGIF }; CoverArt(Format format, const ByteVector &data); diff -Nru taglib-1.7.2/taglib/mp4/mp4file.cpp taglib-1.8/taglib/mp4/mp4file.cpp --- taglib-1.7.2/taglib/mp4/mp4file.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4file.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,8 +27,6 @@ #include #endif -#ifdef WITH_MP4 - #include #include #include "mp4atom.h" @@ -72,6 +70,13 @@ read(readProperties, audioPropertiesStyle); } +MP4::File::File(IOStream *stream, bool readProperties, AudioProperties::ReadStyle audioPropertiesStyle) + : TagLib::File(stream) +{ + d = new FilePrivate; + read(readProperties, audioPropertiesStyle); +} + MP4::File::~File() { delete d; @@ -142,4 +147,3 @@ return d->tag->save(); } -#endif diff -Nru taglib-1.7.2/taglib/mp4/mp4file.h taglib-1.8/taglib/mp4/mp4file.h --- taglib-1.7.2/taglib/mp4/mp4file.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4file.h 2012-09-06 18:03:15.000000000 +0000 @@ -59,6 +59,19 @@ File(FileName file, bool readProperties = true, Properties::ReadStyle audioPropertiesStyle = Properties::Average); /*! + * Contructs a MP4 file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note In the current implementation, both \a readProperties and + * \a propertiesStyle are ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, Properties::ReadStyle audioPropertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); diff -Nru taglib-1.7.2/taglib/mp4/mp4item.cpp taglib-1.8/taglib/mp4/mp4item.cpp --- taglib-1.7.2/taglib/mp4/mp4item.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4item.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,8 +27,6 @@ #include #endif -#ifdef WITH_MP4 - #include #include #include "mp4item.h" @@ -38,15 +36,20 @@ class MP4::Item::ItemPrivate : public RefCounter { public: - ItemPrivate() : RefCounter(), valid(true) {} + ItemPrivate() : RefCounter(), valid(true), atomDataType(TypeUndefined) {} bool valid; + AtomDataType atomDataType; union { bool m_bool; int m_int; IntPair m_intPair; + uchar m_byte; + uint m_uint; + long long m_longlong; }; StringList m_stringList; + ByteVectorList m_byteVectorList; MP4::CoverArtList m_coverArtList; }; @@ -91,6 +94,24 @@ d->m_int = value; } +MP4::Item::Item(uchar value) +{ + d = new ItemPrivate; + d->m_byte = value; +} + +MP4::Item::Item(uint value) +{ + d = new ItemPrivate; + d->m_uint = value; +} + +MP4::Item::Item(long long value) +{ + d = new ItemPrivate; + d->m_longlong = value; +} + MP4::Item::Item(int value1, int value2) { d = new ItemPrivate; @@ -98,6 +119,12 @@ d->m_intPair.second = value2; } +MP4::Item::Item(const ByteVectorList &value) +{ + d = new ItemPrivate; + d->m_byteVectorList = value; +} + MP4::Item::Item(const StringList &value) { d = new ItemPrivate; @@ -110,6 +137,16 @@ d->m_coverArtList = value; } +void MP4::Item::setAtomDataType(MP4::AtomDataType type) +{ + d->atomDataType = type; +} + +MP4::AtomDataType MP4::Item::atomDataType() const +{ + return d->atomDataType; +} + bool MP4::Item::toBool() const { @@ -122,6 +159,24 @@ return d->m_int; } +uchar +MP4::Item::toByte() const +{ + return d->m_byte; +} + +TagLib::uint +MP4::Item::toUInt() const +{ + return d->m_uint; +} + +long long +MP4::Item::toLongLong() const +{ + return d->m_longlong; +} + MP4::Item::IntPair MP4::Item::toIntPair() const { @@ -134,6 +189,12 @@ return d->m_stringList; } +ByteVectorList +MP4::Item::toByteVectorList() const +{ + return d->m_byteVectorList; +} + MP4::CoverArtList MP4::Item::toCoverArtList() const { @@ -146,4 +207,3 @@ return d->valid; } -#endif diff -Nru taglib-1.7.2/taglib/mp4/mp4item.h taglib-1.8/taglib/mp4/mp4item.h --- taglib-1.7.2/taglib/mp4/mp4item.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4item.h 2012-09-06 18:03:15.000000000 +0000 @@ -47,15 +47,26 @@ ~Item(); Item(int value); + Item(uchar value); + Item(uint value); + Item(long long value); Item(bool value); Item(int first, int second); Item(const StringList &value); + Item(const ByteVectorList &value); Item(const CoverArtList &value); + void setAtomDataType(AtomDataType type); + AtomDataType atomDataType() const; + int toInt() const; + uchar toByte() const; + uint toUInt() const; + long long toLongLong() const; bool toBool() const; IntPair toIntPair() const; StringList toStringList() const; + ByteVectorList toByteVectorList() const; CoverArtList toCoverArtList() const; bool isValid() const; diff -Nru taglib-1.7.2/taglib/mp4/mp4properties.cpp taglib-1.8/taglib/mp4/mp4properties.cpp --- taglib-1.7.2/taglib/mp4/mp4properties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4properties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,8 +27,6 @@ #include #endif -#ifdef WITH_MP4 - #include #include #include "mp4file.h" @@ -40,13 +38,14 @@ class MP4::Properties::PropertiesPrivate { public: - PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), bitsPerSample(0) {} + PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), bitsPerSample(0), encrypted(false) {} int length; int bitrate; int sampleRate; int channels; int bitsPerSample; + bool encrypted; }; MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style) @@ -138,6 +137,19 @@ } } } + else if (data.mid(20, 4) == "alac") { + if (atom->length == 88 && data.mid(56, 4) == "alac") { + d->bitsPerSample = data.at(69); + d->channels = data.at(73); + d->bitrate = data.mid(80, 4).toUInt() / 1000; + d->sampleRate = data.mid(84, 4).toUInt(); + } + } + + MP4::Atom *drms = atom->find("drms"); + if(drms) { + d->encrypted = true; + } } MP4::Properties::~Properties() @@ -175,4 +187,9 @@ return d->bitsPerSample; } -#endif +bool +MP4::Properties::isEncrypted() const +{ + return d->encrypted; +} + diff -Nru taglib-1.7.2/taglib/mp4/mp4properties.h taglib-1.8/taglib/mp4/mp4properties.h --- taglib-1.7.2/taglib/mp4/mp4properties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4properties.h 2012-09-06 18:03:15.000000000 +0000 @@ -48,6 +48,7 @@ virtual int sampleRate() const; virtual int channels() const; virtual int bitsPerSample() const; + bool isEncrypted() const; private: class PropertiesPrivate; diff -Nru taglib-1.7.2/taglib/mp4/mp4tag.cpp taglib-1.8/taglib/mp4/mp4tag.cpp --- taglib-1.7.2/taglib/mp4/mp4tag.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4tag.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -1,5 +1,5 @@ /************************************************************************** - copyright : (C) 2007 by Lukáš Lalinský + copyright : (C) 2007,2011 by Lukáš Lalinský email : lalinsky@gmail.com **************************************************************************/ @@ -27,8 +27,6 @@ #include #endif -#ifdef WITH_MP4 - #include #include #include "mp4atom.h" @@ -47,6 +45,11 @@ ItemListMap items; }; +MP4::Tag::Tag() +{ + d = new TagPrivate; +} + MP4::Tag::Tag(TagLib::File *file, MP4::Atoms *atoms) { d = new TagPrivate; @@ -68,12 +71,23 @@ else if(atom->name == "trkn" || atom->name == "disk") { parseIntPair(atom, file); } - else if(atom->name == "cpil" || atom->name == "pgap" || atom->name == "pcst") { + else if(atom->name == "cpil" || atom->name == "pgap" || atom->name == "pcst" || + atom->name == "hdvd") { parseBool(atom, file); } else if(atom->name == "tmpo") { parseInt(atom, file); } + else if(atom->name == "tvsn" || atom->name == "tves" || atom->name == "cnID" || + atom->name == "sfID" || atom->name == "atID" || atom->name == "geID") { + parseUInt(atom, file); + } + else if(atom->name == "plID") { + parseLongLong(atom, file); + } + else if(atom->name == "stik" || atom->name == "rtng" || atom->name == "akID") { + parseByte(atom, file); + } else if(atom->name == "gnre") { parseGnre(atom, file); } @@ -91,10 +105,10 @@ delete d; } -ByteVectorList -MP4::Tag::parseData(MP4::Atom *atom, TagLib::File *file, int expectedFlags, bool freeForm) +MP4::AtomDataList +MP4::Tag::parseData2(MP4::Atom *atom, TagLib::File *file, int expectedFlags, bool freeForm) { - ByteVectorList result; + AtomDataList result; ByteVector data = file->readBlock(atom->length - 8); int i = 0; unsigned int pos = 0; @@ -111,7 +125,7 @@ debug("MP4: Unexpected atom \"" + name + "\", expecting \"name\""); return result; } - result.append(data.mid(pos + 12, length - 12)); + result.append(AtomData(AtomDataType(flags), data.mid(pos + 12, length - 12))); } else { if(name != "data") { @@ -119,7 +133,7 @@ return result; } if(expectedFlags == -1 || flags == expectedFlags) { - result.append(data.mid(pos + 16, length - 16)); + result.append(AtomData(AtomDataType(flags), data.mid(pos + 16, length - 16))); } } pos += length; @@ -128,6 +142,17 @@ return result; } +ByteVectorList +MP4::Tag::parseData(MP4::Atom *atom, TagLib::File *file, int expectedFlags, bool freeForm) +{ + AtomDataList data = parseData2(atom, file, expectedFlags, freeForm); + ByteVectorList result; + for(uint i = 0; i < data.size(); i++) { + result.append(data[i].data); + } + return result; +} + void MP4::Tag::parseInt(MP4::Atom *atom, TagLib::File *file) { @@ -138,6 +163,33 @@ } void +MP4::Tag::parseUInt(MP4::Atom *atom, TagLib::File *file) +{ + ByteVectorList data = parseData(atom, file); + if(data.size()) { + d->items.insert(atom->name, data[0].toUInt()); + } +} + +void +MP4::Tag::parseLongLong(MP4::Atom *atom, TagLib::File *file) +{ + ByteVectorList data = parseData(atom, file); + if(data.size()) { + d->items.insert(atom->name, data[0].toLongLong()); + } +} + +void +MP4::Tag::parseByte(MP4::Atom *atom, TagLib::File *file) +{ + ByteVectorList data = parseData(atom, file); + if(data.size()) { + d->items.insert(atom->name, (uchar)data[0].at(0)); + } +} + +void MP4::Tag::parseGnre(MP4::Atom *atom, TagLib::File *file) { ByteVectorList data = parseData(atom, file); @@ -186,14 +238,34 @@ void MP4::Tag::parseFreeForm(MP4::Atom *atom, TagLib::File *file) { - ByteVectorList data = parseData(atom, file, 1, true); + AtomDataList data = parseData2(atom, file, -1, true); if(data.size() > 2) { - StringList value; - for(unsigned int i = 2; i < data.size(); i++) { - value.append(String(data[i], String::UTF8)); + String name = "----:" + String(data[0].data, String::UTF8) + ':' + String(data[1].data, String::UTF8); + AtomDataType type = data[2].type; + for(uint i = 2; i < data.size(); i++) { + if(data[i].type != type) { + debug("MP4: We currently don't support values with multiple types"); + break; + } + } + if(type == TypeUTF8) { + StringList value; + for(uint i = 2; i < data.size(); i++) { + value.append(String(data[i].data, String::UTF8)); + } + Item item(value); + item.setAtomDataType(type); + d->items.insert(name, item); + } + else { + ByteVectorList value; + for(uint i = 2; i < data.size(); i++) { + value.append(data[i].data); + } + Item item(value); + item.setAtomDataType(type); + d->items.insert(name, item); } - String name = "----:" + data[0] + ':' + data[1]; - d->items.insert(name, value); } } @@ -211,7 +283,7 @@ debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\""); break; } - if(flags == MP4::CoverArt::PNG || flags == MP4::CoverArt::JPEG) { + if(flags == TypeJPEG || flags == TypePNG || flags == TypeBMP || flags == TypeGIF) { value.append(MP4::CoverArt(MP4::CoverArt::Format(flags), data.mid(pos + 16, length - 16))); } @@ -251,7 +323,7 @@ { ByteVectorList data; data.append(ByteVector(1, item.toBool() ? '\1' : '\0')); - return renderData(name, 0x15, data); + return renderData(name, TypeInteger, data); } ByteVector @@ -259,7 +331,31 @@ { ByteVectorList data; data.append(ByteVector::fromShort(item.toInt())); - return renderData(name, 0x15, data); + return renderData(name, TypeInteger, data); +} + +ByteVector +MP4::Tag::renderUInt(const ByteVector &name, MP4::Item &item) +{ + ByteVectorList data; + data.append(ByteVector::fromUInt(item.toUInt())); + return renderData(name, TypeInteger, data); +} + +ByteVector +MP4::Tag::renderLongLong(const ByteVector &name, MP4::Item &item) +{ + ByteVectorList data; + data.append(ByteVector::fromLongLong(item.toLongLong())); + return renderData(name, TypeInteger, data); +} + +ByteVector +MP4::Tag::renderByte(const ByteVector &name, MP4::Item &item) +{ + ByteVectorList data; + data.append(ByteVector(1, item.toByte())); + return renderData(name, TypeInteger, data); } ByteVector @@ -270,7 +366,7 @@ ByteVector::fromShort(item.toIntPair().first) + ByteVector::fromShort(item.toIntPair().second) + ByteVector(2, '\0')); - return renderData(name, 0x00, data); + return renderData(name, TypeImplicit, data); } ByteVector @@ -280,7 +376,7 @@ data.append(ByteVector(2, '\0') + ByteVector::fromShort(item.toIntPair().first) + ByteVector::fromShort(item.toIntPair().second)); - return renderData(name, 0x00, data); + return renderData(name, TypeImplicit, data); } ByteVector @@ -317,9 +413,26 @@ ByteVector data; data.append(renderAtom("mean", ByteVector::fromUInt(0) + header[1].data(String::UTF8))); data.append(renderAtom("name", ByteVector::fromUInt(0) + header[2].data(String::UTF8))); - StringList value = item.toStringList(); - for(unsigned int i = 0; i < value.size(); i++) { - data.append(renderAtom("data", ByteVector::fromUInt(1) + ByteVector(4, '\0') + value[i].data(String::UTF8))); + AtomDataType type = item.atomDataType(); + if(type == TypeUndefined) { + if(!item.toStringList().isEmpty()) { + type = TypeUTF8; + } + else { + type = TypeImplicit; + } + } + if(type == TypeUTF8) { + StringList value = item.toStringList(); + for(unsigned int i = 0; i < value.size(); i++) { + data.append(renderAtom("data", ByteVector::fromUInt(type) + ByteVector(4, '\0') + value[i].data(String::UTF8))); + } + } + else { + ByteVectorList value = item.toByteVectorList(); + for(unsigned int i = 0; i < value.size(); i++) { + data.append(renderAtom("data", ByteVector::fromUInt(type) + ByteVector(4, '\0') + value[i])); + } } return renderAtom("----", data); } @@ -339,12 +452,22 @@ else if(name == "disk") { data.append(renderIntPairNoTrailing(name.data(String::Latin1), i->second)); } - else if(name == "cpil" || name == "pgap" || name == "pcst") { + else if(name == "cpil" || name == "pgap" || name == "pcst" || name == "hdvd") { data.append(renderBool(name.data(String::Latin1), i->second)); } else if(name == "tmpo") { data.append(renderInt(name.data(String::Latin1), i->second)); } + else if(name == "tvsn" || name == "tves" || name == "cnID" || + name == "sfID" || name == "atID" || name == "geID") { + data.append(renderUInt(name.data(String::Latin1), i->second)); + } + else if(name == "plID") { + data.append(renderLongLong(name.data(String::Latin1), i->second)); + } + else if(name == "stik" || name == "rtng" || name == "akID") { + data.append(renderByte(name.data(String::Latin1), i->second)); + } else if(name == "covr") { data.append(renderCovr(name.data(String::Latin1), i->second)); } @@ -633,4 +756,3 @@ return d->items; } -#endif diff -Nru taglib-1.7.2/taglib/mp4/mp4tag.h taglib-1.8/taglib/mp4/mp4tag.h --- taglib-1.7.2/taglib/mp4/mp4tag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mp4/mp4tag.h 2012-09-06 18:03:15.000000000 +0000 @@ -1,5 +1,5 @@ /************************************************************************** - copyright : (C) 2007 by Lukáš Lalinský + copyright : (C) 2007,2011 by Lukáš Lalinský email : lalinsky@gmail.com **************************************************************************/ @@ -44,6 +44,7 @@ class TAGLIB_EXPORT Tag: public TagLib::Tag { public: + Tag(); Tag(TagLib::File *file, Atoms *atoms); ~Tag(); bool save(); @@ -67,10 +68,14 @@ ItemListMap &itemListMap(); private: + AtomDataList parseData2(Atom *atom, TagLib::File *file, int expectedFlags = -1, bool freeForm = false); TagLib::ByteVectorList parseData(Atom *atom, TagLib::File *file, int expectedFlags = -1, bool freeForm = false); void parseText(Atom *atom, TagLib::File *file, int expectedFlags = 1); void parseFreeForm(Atom *atom, TagLib::File *file); void parseInt(Atom *atom, TagLib::File *file); + void parseByte(Atom *atom, TagLib::File *file); + void parseUInt(Atom *atom, TagLib::File *file); + void parseLongLong(Atom *atom, TagLib::File *file); void parseGnre(Atom *atom, TagLib::File *file); void parseIntPair(Atom *atom, TagLib::File *file); void parseBool(Atom *atom, TagLib::File *file); @@ -79,10 +84,13 @@ TagLib::ByteVector padIlst(const ByteVector &data, int length = -1); TagLib::ByteVector renderAtom(const ByteVector &name, const TagLib::ByteVector &data); TagLib::ByteVector renderData(const ByteVector &name, int flags, const TagLib::ByteVectorList &data); - TagLib::ByteVector renderText(const ByteVector &name, Item &item, int flags = 1); + TagLib::ByteVector renderText(const ByteVector &name, Item &item, int flags = TypeUTF8); TagLib::ByteVector renderFreeForm(const String &name, Item &item); TagLib::ByteVector renderBool(const ByteVector &name, Item &item); TagLib::ByteVector renderInt(const ByteVector &name, Item &item); + TagLib::ByteVector renderByte(const ByteVector &name, Item &item); + TagLib::ByteVector renderUInt(const ByteVector &name, Item &item); + TagLib::ByteVector renderLongLong(const ByteVector &name, Item &item); TagLib::ByteVector renderIntPair(const ByteVector &name, Item &item); TagLib::ByteVector renderIntPairNoTrailing(const ByteVector &name, Item &item); TagLib::ByteVector renderCovr(const ByteVector &name, Item &item); diff -Nru taglib-1.7.2/taglib/mpc/CMakeLists.txt taglib-1.8/taglib/mpc/CMakeLists.txt --- taglib-1.7.2/taglib/mpc/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpc/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES mpcfile.h mpcproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/mpc/mpcfile.cpp taglib-1.8/taglib/mpc/mpcfile.cpp --- taglib-1.7.2/taglib/mpc/mpcfile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpc/mpcfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include #include "mpcfile.h" #include "id3v1tag.h" @@ -38,7 +39,7 @@ namespace { - enum { APEIndex, ID3v1Index }; + enum { MPCAPEIndex, MPCID3v1Index }; } class MPC::File::FilePrivate @@ -96,6 +97,13 @@ read(readProperties, propertiesStyle); } +MPC::File::File(IOStream *stream, bool readProperties, + Properties::ReadStyle propertiesStyle) : TagLib::File(stream) +{ + d = new FilePrivate; + read(readProperties, propertiesStyle); +} + MPC::File::~File() { delete d; @@ -106,6 +114,34 @@ return &d->tag; } +PropertyMap MPC::File::properties() const +{ + if(d->hasAPE) + return d->tag.access(MPCAPEIndex, false)->properties(); + if(d->hasID3v1) + return d->tag.access(MPCID3v1Index, false)->properties(); + return PropertyMap(); +} + +void MPC::File::removeUnsupportedProperties(const StringList &properties) +{ + if(d->hasAPE) + d->tag.access(MPCAPEIndex, false)->removeUnsupportedProperties(properties); + if(d->hasID3v1) + d->tag.access(MPCID3v1Index, false)->removeUnsupportedProperties(properties); +} + +PropertyMap MPC::File::setProperties(const PropertyMap &properties) +{ + if(d->hasAPE) + return d->tag.access(MPCAPEIndex, false)->setProperties(properties); + else if(d->hasID3v1) + return d->tag.access(MPCID3v1Index, false)->setProperties(properties); + else + return d->tag.access(APE, true)->setProperties(properties); +} + + MPC::Properties *MPC::File::audioProperties() const { return d->properties; @@ -189,18 +225,18 @@ ID3v1::Tag *MPC::File::ID3v1Tag(bool create) { - return d->tag.access(ID3v1Index, create); + return d->tag.access(MPCID3v1Index, create); } APE::Tag *MPC::File::APETag(bool create) { - return d->tag.access(APEIndex, create); + return d->tag.access(MPCAPEIndex, create); } void MPC::File::strip(int tags) { if(tags & ID3v1) { - d->tag.set(ID3v1Index, 0); + d->tag.set(MPCID3v1Index, 0); APETag(true); } @@ -210,7 +246,7 @@ } if(tags & APE) { - d->tag.set(APEIndex, 0); + d->tag.set(MPCAPEIndex, 0); if(!ID3v1Tag()) APETag(true); @@ -234,7 +270,7 @@ d->ID3v1Location = findID3v1(); if(d->ID3v1Location >= 0) { - d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); + d->tag.set(MPCID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); d->hasID3v1 = true; } @@ -245,7 +281,7 @@ d->APELocation = findAPE(); if(d->APELocation >= 0) { - d->tag.set(APEIndex, new APE::Tag(this, d->APELocation)); + d->tag.set(MPCAPEIndex, new APE::Tag(this, d->APELocation)); d->APESize = APETag()->footer()->completeTagSize(); d->APELocation = d->APELocation + APETag()->footer()->size() - d->APESize; @@ -274,8 +310,7 @@ // Look for MPC metadata if(readProperties) { - d->properties = new Properties(readBlock(MPC::HeaderSize), - length() - d->ID3v2Size - d->APESize); + d->properties = new Properties(this, length() - d->ID3v2Size - d->APESize); } } diff -Nru taglib-1.7.2/taglib/mpc/mpcfile.h taglib-1.8/taglib/mpc/mpcfile.h --- taglib-1.7.2/taglib/mpc/mpcfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpc/mpcfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -28,9 +28,12 @@ #include "taglib_export.h" #include "tfile.h" +#include "tag.h" #include "mpcproperties.h" +#include "tlist.h" + namespace TagLib { class Tag; @@ -89,6 +92,17 @@ Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs an MPC file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); @@ -100,6 +114,22 @@ virtual TagLib::Tag *tag() const; /*! + * Implements the unified property interface -- export function. + * If the file contains both an APE and an ID3v1 tag, only the APE + * tag will be converted to the PropertyMap. + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + * As with the export, only one tag is taken into account. If the file + * has no tag at all, an APE tag will be created. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! * Returns the MPC::Properties for this file. If no audio properties * were read then this will return a null pointer. */ @@ -155,7 +185,6 @@ */ void remove(int tags = AllTags); - private: File(const File &); File &operator=(const File &); diff -Nru taglib-1.7.2/taglib/mpc/mpcproperties.cpp taglib-1.8/taglib/mpc/mpcproperties.cpp --- taglib-1.7.2/taglib/mpc/mpcproperties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpc/mpcproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -26,6 +26,7 @@ #include #include #include +#include #include "mpcproperties.h" #include "mpcfile.h" @@ -35,17 +36,21 @@ class MPC::Properties::PropertiesPrivate { public: - PropertiesPrivate(const ByteVector &d, long length, ReadStyle s) : - data(d), + PropertiesPrivate(long length, ReadStyle s) : streamLength(length), style(s), version(0), length(0), bitrate(0), sampleRate(0), - channels(0) {} + channels(0), + totalFrames(0), + sampleFrames(0), + trackGain(0), + trackPeak(0), + albumGain(0), + albumPeak(0) {} - ByteVector data; long streamLength; ReadStyle style; int version; @@ -53,6 +58,13 @@ int bitrate; int sampleRate; int channels; + uint totalFrames; + uint sampleFrames; + uint trackGain; + uint trackPeak; + uint albumGain; + uint albumPeak; + String flags; }; //////////////////////////////////////////////////////////////////////////////// @@ -61,8 +73,22 @@ MPC::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) : AudioProperties(style) { - d = new PropertiesPrivate(data, streamLength, style); - read(); + d = new PropertiesPrivate(streamLength, style); + readSV7(data); +} + +MPC::Properties::Properties(File *file, long streamLength, ReadStyle style) : AudioProperties(style) +{ + d = new PropertiesPrivate(streamLength, style); + ByteVector magic = file->readBlock(4); + if(magic == "MPCK") { + // Musepack version 8 + readSV8(file); + } + else { + // Musepack version 7 or older, fixed size header + readSV7(magic + file->readBlock(MPC::HeaderSize - 4)); + } } MPC::Properties::~Properties() @@ -95,30 +121,179 @@ return d->version; } +TagLib::uint MPC::Properties::totalFrames() const +{ + return d->totalFrames; +} + +TagLib::uint MPC::Properties::sampleFrames() const +{ + return d->sampleFrames; +} + +int MPC::Properties::trackGain() const +{ + return d->trackGain; +} + +int MPC::Properties::trackPeak() const +{ + return d->trackPeak; +} + +int MPC::Properties::albumGain() const +{ + return d->albumGain; +} + +int MPC::Properties::albumPeak() const +{ + return d->albumPeak; +} + //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// +unsigned long readSize(File *file, TagLib::uint &sizelength) +{ + unsigned char tmp; + unsigned long size = 0; + + do { + ByteVector b = file->readBlock(1); + tmp = b[0]; + size = (size << 7) | (tmp & 0x7F); + sizelength++; + } while((tmp & 0x80)); + return size; +} + +unsigned long readSize(const ByteVector &data, TagLib::uint &sizelength) +{ + unsigned char tmp; + unsigned long size = 0; + unsigned long pos = 0; + + do { + tmp = data[pos++]; + size = (size << 7) | (tmp & 0x7F); + sizelength++; + } while((tmp & 0x80) && (pos < data.size())); + return size; +} + static const unsigned short sftable [4] = { 44100, 48000, 37800, 32000 }; -void MPC::Properties::read() +void MPC::Properties::readSV8(File *file) { - if(!d->data.startsWith("MP+")) - return; + bool readSH = false, readRG = false; - d->version = d->data[3] & 15; + while(!readSH && !readRG) { + ByteVector packetType = file->readBlock(2); + uint packetSizeLength = 0; + unsigned long packetSize = readSize(file, packetSizeLength); + unsigned long dataSize = packetSize - 2 - packetSizeLength; + + if(packetType == "SH") { + // Stream Header + // http://trac.musepack.net/wiki/SV8Specification#StreamHeaderPacket + ByteVector data = file->readBlock(dataSize); + readSH = true; + + TagLib::uint pos = 4; + d->version = data[pos]; + pos += 1; + d->sampleFrames = readSize(data.mid(pos), pos); + ulong begSilence = readSize(data.mid(pos), pos); + + std::bitset<16> flags(TAGLIB_CONSTRUCT_BITSET(data.mid(pos, 2).toUShort(true))); + pos += 2; + + d->sampleRate = sftable[flags[15] * 4 + flags[14] * 2 + flags[13]]; + d->channels = flags[7] * 8 + flags[6] * 4 + flags[5] * 2 + flags[4] + 1; + + if((d->sampleFrames - begSilence) != 0) + d->bitrate = (int)(d->streamLength * 8.0 * d->sampleRate / (d->sampleFrames - begSilence)); + d->bitrate = d->bitrate / 1000; + + d->length = (d->sampleFrames - begSilence) / d->sampleRate; + } + + else if (packetType == "RG") { + // Replay Gain + // http://trac.musepack.net/wiki/SV8Specification#ReplaygainPacket + ByteVector data = file->readBlock(dataSize); + readRG = true; + + int replayGainVersion = data[0]; + if(replayGainVersion == 1) { + d->trackGain = data.mid(1, 2).toUInt(true); + d->trackPeak = data.mid(3, 2).toUInt(true); + d->albumGain = data.mid(5, 2).toUInt(true); + d->albumPeak = data.mid(7, 2).toUInt(true); + } + } + + else if(packetType == "SE") { + break; + } + + else { + file->seek(dataSize, File::Current); + } + } +} - unsigned int frames; +void MPC::Properties::readSV7(const ByteVector &data) +{ + if(data.startsWith("MP+")) { + d->version = data[3] & 15; + if(d->version < 7) + return; - if(d->version >= 7) { - frames = d->data.mid(4, 4).toUInt(false); + d->totalFrames = data.mid(4, 4).toUInt(false); - std::bitset<32> flags(TAGLIB_CONSTRUCT_BITSET(d->data.mid(8, 4).toUInt(false))); + std::bitset<32> flags(TAGLIB_CONSTRUCT_BITSET(data.mid(8, 4).toUInt(false))); d->sampleRate = sftable[flags[17] * 2 + flags[16]]; d->channels = 2; + + uint gapless = data.mid(5, 4).toUInt(false); + + d->trackGain = data.mid(14,2).toShort(false); + d->trackPeak = data.mid(12,2).toUInt(false); + d->albumGain = data.mid(18,2).toShort(false); + d->albumPeak = data.mid(16,2).toUInt(false); + + // convert gain info + if(d->trackGain != 0) { + int tmp = (int)((64.82 - (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); + 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); + + if (d->albumPeak != 0) + d->albumPeak = (int)(log10((double)d->albumPeak) * 20 * 256 + .5); + + bool trueGapless = (gapless >> 31) & 0x0001; + if(trueGapless) { + uint lastFrameSamples = (gapless >> 20) & 0x07FF; + d->sampleFrames = d->totalFrames * 1152 - lastFrameSamples; + } + else + d->sampleFrames = d->totalFrames * 1152 - 576; } else { - uint headerData = d->data.mid(0, 4).toUInt(false); + uint headerData = data.mid(0, 4).toUInt(false); d->bitrate = (headerData >> 23) & 0x01ff; d->version = (headerData >> 11) & 0x03ff; @@ -126,15 +301,16 @@ d->channels = 2; if(d->version >= 5) - frames = d->data.mid(4, 4).toUInt(false); + d->totalFrames = data.mid(4, 4).toUInt(false); else - frames = d->data.mid(6, 2).toUInt(false); - } + d->totalFrames = data.mid(6, 2).toUInt(false); - uint samples = frames * 1152 - 576; + d->sampleFrames = d->totalFrames * 1152 - 576; + } - d->length = d->sampleRate > 0 ? (samples + (d->sampleRate / 2)) / d->sampleRate : 0; + d->length = d->sampleRate > 0 ? (d->sampleFrames + (d->sampleRate / 2)) / d->sampleRate : 0; if(!d->bitrate) d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0; } + diff -Nru taglib-1.7.2/taglib/mpc/mpcproperties.h taglib-1.8/taglib/mpc/mpcproperties.h --- taglib-1.7.2/taglib/mpc/mpcproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpc/mpcproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -50,10 +50,18 @@ /*! * Create an instance of MPC::Properties with the data read from the * ByteVector \a data. + * + * This constructor is deprecated. It only works for MPC version up to 7. */ Properties(const ByteVector &data, long streamLength, ReadStyle style = Average); /*! + * Create an instance of MPC::Properties with the data read directly + * from a MPC::File. + */ + Properties(File *file, long streamLength, ReadStyle style = Average); + + /*! * Destroys this MPC::Properties instance. */ virtual ~Properties(); @@ -66,15 +74,44 @@ virtual int channels() const; /*! - * Returns the version of the bitstream (SV4-SV7) + * Returns the version of the bitstream (SV4-SV8) */ int mpcVersion() const; + uint totalFrames() const; + uint sampleFrames() const; + + /*! + * Returns the track gain as an integer value, + * to convert to dB: trackGain in dB = 64.82 - (trackGain / 256) + */ + int trackGain() const; + + /*! + * Returns the track peak as an integer value, + * to convert to dB: trackPeak in dB = trackPeak / 256 + * to convert to floating [-1..1]: trackPeak = 10^(trackPeak / 256 / 20)/32768 + */ + int trackPeak() const; + + /*! + * Returns the album gain as an integer value, + * to convert to dB: albumGain in dB = 64.82 - (albumGain / 256) + */ + int albumGain() const; + + /*! + * Returns the album peak as an integer value, + * to convert to dB: albumPeak in dB = albumPeak / 256 + * to convert to floating [-1..1]: albumPeak = 10^(albumPeak / 256 / 20)/32768 + */ + int albumPeak() const; private: Properties(const Properties &); Properties &operator=(const Properties &); - void read(); + void readSV7(const ByteVector &data); + void readSV8(File *file); class PropertiesPrivate; PropertiesPrivate *d; diff -Nru taglib-1.7.2/taglib/mpeg/CMakeLists.txt taglib-1.8/taglib/mpeg/CMakeLists.txt --- taglib-1.7.2/taglib/mpeg/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -ADD_SUBDIRECTORY( id3v1 ) -ADD_SUBDIRECTORY( id3v2 ) - -INSTALL(FILES mpegfile.h mpegproperties.h mpegheader.h xingheader.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib ) diff -Nru taglib-1.7.2/taglib/mpeg/id3v1/CMakeLists.txt taglib-1.8/taglib/mpeg/id3v1/CMakeLists.txt --- taglib-1.7.2/taglib/mpeg/id3v1/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v1/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES id3v1tag.h id3v1genres.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/mpeg/id3v1/id3v1genres.cpp taglib-1.8/taglib/mpeg/id3v1/id3v1genres.cpp --- taglib-1.7.2/taglib/mpeg/id3v1/id3v1genres.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v1/id3v1genres.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -207,7 +207,7 @@ String ID3v1::genre(int i) { if(i >= 0 && i < genresSize) - return genres[i]; + return genres[i] + String::null; // always make a copy return String::null; } diff -Nru taglib-1.7.2/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.8/taglib/mpeg/id3v1/id3v1tag.cpp --- taglib-1.7.2/taglib/mpeg/id3v1/id3v1tag.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v1/id3v1tag.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -51,12 +51,17 @@ static const StringHandler *stringHandler; }; -const ID3v1::StringHandler *ID3v1::Tag::TagPrivate::stringHandler = new StringHandler; +static const StringHandler defaultStringHandler; +const ID3v1::StringHandler *ID3v1::Tag::TagPrivate::stringHandler = &defaultStringHandler; //////////////////////////////////////////////////////////////////////////////// // StringHandler implementation //////////////////////////////////////////////////////////////////////////////// +StringHandler::StringHandler() +{ +} + String ID3v1::StringHandler::parse(const ByteVector &data) const { return String(data, String::Latin1).stripWhiteSpace(); @@ -189,8 +194,10 @@ void ID3v1::Tag::setStringHandler(const StringHandler *handler) { - delete TagPrivate::stringHandler; - TagPrivate::stringHandler = handler; + if (handler) + TagPrivate::stringHandler = handler; + else + TagPrivate::stringHandler = &defaultStringHandler; } //////////////////////////////////////////////////////////////////////////////// diff -Nru taglib-1.7.2/taglib/mpeg/id3v1/id3v1tag.h taglib-1.8/taglib/mpeg/id3v1/id3v1tag.h --- taglib-1.7.2/taglib/mpeg/id3v1/id3v1tag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v1/id3v1tag.h 2012-09-06 18:03:15.000000000 +0000 @@ -62,6 +62,7 @@ TAGLIB_IGNORE_MISSING_DESTRUCTOR public: // BIC: Add virtual destructor. + StringHandler(); /*! * Decode a string from \a data. The default implementation assumes that @@ -153,6 +154,11 @@ /*! * Sets the string handler that decides how the ID3v1 data will be * converted to and from binary data. + * If the parameter \a handler is null, the previous handler is + * released and default ISO-8859-1 handler is restored. + * + * \note The caller is responsible for deleting the previous handler + * as needed after it is released. * * \see StringHandler */ diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/CMakeLists.txt taglib-1.8/taglib/mpeg/id3v2/CMakeLists.txt --- taglib-1.7.2/taglib/mpeg/id3v2/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -ADD_SUBDIRECTORY( frames ) - -INSTALL(FILES id3v2extendedheader.h id3v2frame.h id3v2header.h id3v2synchdata.h id3v2footer.h id3v2framefactory.h id3v2tag.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) - diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/CMakeLists.txt taglib-1.8/taglib/mpeg/id3v2/frames/CMakeLists.txt --- taglib-1.7.2/taglib/mpeg/id3v2/frames/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -INSTALL(FILES - attachedpictureframe.h - commentsframe.h - generalencapsulatedobjectframe.h - popularimeterframe.h - privateframe.h - relativevolumeframe.h - textidentificationframe.h - uniquefileidentifierframe.h - unknownframe.h - unsynchronizedlyricsframe.h - urllinkframe.h - DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp taglib-1.8/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -136,7 +136,7 @@ int pos = 1; d->mimeType = readStringField(data, String::Latin1, &pos); - /* Now we need at least two more bytes available */ + /* Now we need at least two more bytes available */ if (uint(pos) + 1 >= data.size()) { debug("Truncated picture frame."); return; @@ -152,7 +152,7 @@ { ByteVector data; - String::Type encoding = checkEncoding(d->description, d->textEncoding); + String::Type encoding = checkTextEncoding(d->description, d->textEncoding); data.append(char(encoding)); data.append(d->mimeType.data(String::Latin1)); diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/frames/commentsframe.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -29,6 +29,7 @@ #include #include "commentsframe.h" +#include "tpropertymap.h" using namespace TagLib; using namespace ID3v2; @@ -109,6 +110,19 @@ d->textEncoding = encoding; } +PropertyMap CommentsFrame::asProperties() const +{ + String key = description().upper(); + PropertyMap map; + if(key.isEmpty() || key == "COMMENT") + map.insert("COMMENT", text()); + else if(key.isNull()) + map.unsupportedData().append(L"COMM/" + description()); + else + map.insert("COMMENT:" + key, text()); + return map; +} + CommentsFrame *CommentsFrame::findByDescription(const ID3v2::Tag *tag, const String &d) // static { ID3v2::FrameList comments = tag->frameList("COMM"); @@ -144,8 +158,13 @@ ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); if(l.size() == 2) { - d->description = String(l.front(), d->textEncoding); - d->text = String(l.back(), d->textEncoding); + if(d->textEncoding == String::Latin1) { + d->description = Tag::latin1StringHandler()->parse(l.front()); + d->text = Tag::latin1StringHandler()->parse(l.back()); + } else { + d->description = String(l.front(), d->textEncoding); + d->text = String(l.back(), d->textEncoding); + } } } @@ -155,8 +174,8 @@ String::Type encoding = d->textEncoding; - encoding = checkEncoding(d->description, encoding); - encoding = checkEncoding(d->text, encoding); + encoding = checkTextEncoding(d->description, encoding); + encoding = checkTextEncoding(d->text, encoding); v.append(char(encoding)); v.append(d->language.size() == 3 ? d->language : "XXX"); diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/commentsframe.h taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.h --- taglib-1.7.2/taglib/mpeg/id3v2/frames/commentsframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.h 2012-09-06 18:03:15.000000000 +0000 @@ -137,6 +137,17 @@ void setTextEncoding(String::Type encoding); /*! + * Parses this frame as PropertyMap with a single key. + * - if description() is empty or "COMMENT", the key will be "COMMENT" + * - if description() is not a valid PropertyMap key, the frame will be + * marked unsupported by an entry "COMM/" in the unsupportedData() + * attribute of the returned map. + * - otherwise, the key will be "COMMENT:" + * - The single value will be the frame's text(). + */ + PropertyMap asProperties() const; + + /*! * Comments each have a unique description. This searches for a comment * frame with the decription \a d and returns a pointer to it. If no * frame is found that matches the given description null is returned. diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/ownershipframe.cpp taglib-1.8/taglib/mpeg/id3v2/frames/ownershipframe.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/frames/ownershipframe.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/ownershipframe.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,162 @@ +/*************************************************************************** + copyright : (C) 2012 by Rupert Daniel + email : rupert@cancelmonday.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include + +#include "ownershipframe.h" +#include + +using namespace TagLib; +using namespace ID3v2; + +class OwnershipFrame::OwnershipFramePrivate +{ +public: + String pricePaid; + String datePurchased; + String seller; + String::Type textEncoding; +}; + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +OwnershipFrame::OwnershipFrame(String::Type encoding) : Frame("OWNE") +{ + d = new OwnershipFramePrivate; + d->textEncoding = encoding; +} + +OwnershipFrame::OwnershipFrame(const ByteVector &data) : Frame(data) +{ + d = new OwnershipFramePrivate; + setData(data); +} + +OwnershipFrame::~OwnershipFrame() +{ + delete d; +} + +String OwnershipFrame::toString() const +{ + return "pricePaid=" + d->pricePaid + " datePurchased=" + d->datePurchased + " seller=" + d->seller; +} + +String OwnershipFrame::pricePaid() const +{ + return d->pricePaid; +} + +void OwnershipFrame::setPricePaid(const String &s) +{ + d->pricePaid = s; +} + +String OwnershipFrame::datePurchased() const +{ + return d->datePurchased; +} + +void OwnershipFrame::setDatePurchased(const String &s) +{ + d->datePurchased = s; +} + +String OwnershipFrame::seller() const +{ + return d->seller; +} + +void OwnershipFrame::setSeller(const String &s) +{ + d->seller = s; +} + +String::Type OwnershipFrame::textEncoding() const +{ + return d->textEncoding; +} + +void OwnershipFrame::setTextEncoding(String::Type encoding) +{ + d->textEncoding = encoding; +} + +//////////////////////////////////////////////////////////////////////////////// +// protected members +//////////////////////////////////////////////////////////////////////////////// + +void OwnershipFrame::parseFields(const ByteVector &data) +{ + int pos = 0; + + // Get the text encoding + d->textEncoding = String::Type(data[0]); + pos += 1; + + // Read the price paid this is a null terminate string + d->pricePaid = readStringField(data, String::Latin1, &pos); + + // If we don't have at least 8 bytes left then don't parse the rest of the + // data + if(data.size() - pos < 8) { + return; + } + + // Read the date purchased YYYYMMDD + d->datePurchased = String(data.mid(pos, 8)); + pos += 8; + + // Read the seller + if(d->textEncoding == String::Latin1) + d->seller = Tag::latin1StringHandler()->parse(data.mid(pos)); + else + d->seller = String(data.mid(pos), d->textEncoding); +} + +ByteVector OwnershipFrame::renderFields() const +{ + ByteVector v; + + v.append(char(d->textEncoding)); + v.append(d->pricePaid.data(String::Latin1)); + v.append(textDelimiter(String::Latin1)); + v.append(d->datePurchased.data(String::Latin1)); + v.append(d->seller.data(d->textEncoding)); + + return v; +} + +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + +OwnershipFrame::OwnershipFrame(const ByteVector &data, Header *h) : Frame(h) +{ + d = new OwnershipFramePrivate; + parseFields(fieldData(data)); +} diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/ownershipframe.h taglib-1.8/taglib/mpeg/id3v2/frames/ownershipframe.h --- taglib-1.7.2/taglib/mpeg/id3v2/frames/ownershipframe.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/ownershipframe.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,151 @@ +/*************************************************************************** + copyright : (C) 2012 by Rupert Daniel + email : rupert@cancelmonday.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_OWNERSHIPFRAME_H +#define TAGLIB_OWNERSHIPFRAME_H + +#include "id3v2frame.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + //! An implementation of ID3v2 "ownership" + + /*! + * This implements the ID3v2 ownership (OWNE frame). It consists of + * a price paid, a date purchased (YYYYMMDD) and the name of the seller. + */ + + class TAGLIB_EXPORT OwnershipFrame : public Frame + { + friend class FrameFactory; + + public: + /*! + * Construct an empty ownership frame. + */ + explicit OwnershipFrame(String::Type encoding = String::Latin1); + + /*! + * Construct a ownership based on the data in \a data. + */ + explicit OwnershipFrame(const ByteVector &data); + + /*! + * Destroys this OwnershipFrame instance. + */ + virtual ~OwnershipFrame(); + + /*! + * Returns the text of this popularimeter. + * + * \see text() + */ + virtual String toString() const; + + /*! + * Returns the date purchased. + * + * \see setDatePurchased() + */ + String datePurchased() const; + + /*! + * Set the date purchased. + * + * \see datePurchased() + */ + void setDatePurchased(const String &datePurchased); + + /*! + * Returns the price paid. + * + * \see setPricePaid() + */ + String pricePaid() const; + + /*! + * Set the price paid. + * + * \see pricePaid() + */ + void setPricePaid(const String &pricePaid); + + /*! + * Returns the seller. + * + * \see setSeller() + */ + String seller() const; + + /*! + * Set the seller. + * + * \see seller() + */ + void setSeller(const String &seller); + + /*! + * Returns the text encoding that will be used in rendering this frame. + * This defaults to the type that was either specified in the constructor + * or read from the frame when parsed. + * + * \see setTextEncoding() + * \see render() + */ + String::Type textEncoding() const; + + /*! + * Sets the text encoding to be used when rendering this frame to + * \a encoding. + * + * \see textEncoding() + * \see render() + */ + void setTextEncoding(String::Type encoding); + + protected: + // Reimplementations. + + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + /*! + * The constructor used by the FrameFactory. + */ + OwnershipFrame(const ByteVector &data, Header *h); + OwnershipFrame(const OwnershipFrame &); + OwnershipFrame &operator=(const OwnershipFrame &); + + class OwnershipFramePrivate; + OwnershipFramePrivate *d; + }; + + } +} +#endif diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/privateframe.cpp taglib-1.8/taglib/mpeg/id3v2/frames/privateframe.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/frames/privateframe.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/privateframe.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -98,7 +98,7 @@ } // Owner identifier is assumed to be Latin1 - + const int byteAlign = 1; const int endOfOwner = data.find(textDelimiter(String::Latin1), 0, byteAlign); diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -25,8 +25,9 @@ #include #include - #include "textidentificationframe.h" +#include "tpropertymap.h" +#include "id3v1genres.h" using namespace TagLib; using namespace ID3v2; @@ -57,6 +58,32 @@ setData(data); } +TextIdentificationFrame *TextIdentificationFrame::createTIPLFrame(const PropertyMap &properties) // static +{ + TextIdentificationFrame *frame = new TextIdentificationFrame("TIPL"); + StringList l; + for(PropertyMap::ConstIterator it = properties.begin(); it != properties.end(); ++it){ + l.append(it->first); + l.append(it->second.toString(",")); // comma-separated list of names + } + frame->setText(l); + return frame; +} + +TextIdentificationFrame *TextIdentificationFrame::createTMCLFrame(const PropertyMap &properties) // static +{ + TextIdentificationFrame *frame = new TextIdentificationFrame("TMCL"); + StringList l; + for(PropertyMap::ConstIterator it = properties.begin(); it != properties.end(); ++it){ + if(!it->first.startsWith(instrumentPrefix)) // should not happen + continue; + l.append(it->first.substr(instrumentPrefix.size())); + l.append(it->second.toString(",")); + } + frame->setText(l); + return frame; +} + TextIdentificationFrame::~TextIdentificationFrame() { delete d; @@ -92,6 +119,61 @@ d->textEncoding = encoding; } +// array of allowed TIPL prefixes and their corresponding key value +static const TagLib::uint involvedPeopleSize = 5; +static const char* involvedPeople[][2] = { + {"ARRANGER", "ARRANGER"}, + {"ENGINEER", "ENGINEER"}, + {"PRODUCER", "PRODUCER"}, + {"DJ-MIX", "DJMIXER"}, + {"MIX", "MIXER"}, +}; + +const KeyConversionMap &TextIdentificationFrame::involvedPeopleMap() // static +{ + static KeyConversionMap m; + if(m.isEmpty()) + for(uint i = 0; i < involvedPeopleSize; ++i) + m.insert(involvedPeople[i][1], involvedPeople[i][0]); + return m; +} + +PropertyMap TextIdentificationFrame::asProperties() const +{ + if(frameID() == "TIPL") + return makeTIPLProperties(); + if(frameID() == "TMCL") + return makeTMCLProperties(); + PropertyMap map; + String tagName = frameIDToKey(frameID()); + if(tagName.isNull()) { + map.unsupportedData().append(frameID()); + return map; + } + StringList values = fieldList(); + if(tagName == "GENRE") { + // Special case: Support ID3v1-style genre numbers. They are not officially supported in + // ID3v2, however it seems that still a lot of programs use them. + for(StringList::Iterator it = values.begin(); it != values.end(); ++it) { + bool ok = false; + int test = it->toInt(&ok); // test if the genre value is an integer + if(ok) + *it = ID3v1::genre(test); + } + } else if(tagName == "DATE") { + for(StringList::Iterator it = values.begin(); it != values.end(); ++it) { + // ID3v2 specifies ISO8601 timestamps which contain a 'T' as separator between date and time. + // Since this is unusual in other formats, the T is removed. + int tpos = it->find("T"); + if(tpos != -1) + (*it)[tpos] = ' '; + } + } + PropertyMap ret; + ret.insert(tagName, values); + return ret; +} + //////////////////////////////////////////////////////////////////////////////// // TextIdentificationFrame protected members //////////////////////////////////////////////////////////////////////////////// @@ -131,15 +213,17 @@ for(ByteVectorList::Iterator it = l.begin(); it != l.end(); it++) { if(!(*it).isEmpty()) { - String s(*it, d->textEncoding); - d->fieldList.append(s); + if(d->textEncoding == String::Latin1) + d->fieldList.append(Tag::latin1StringHandler()->parse(*it)); + else + d->fieldList.append(String(*it, d->textEncoding)); } } } ByteVector TextIdentificationFrame::renderFields() const { - String::Type encoding = checkEncoding(d->fieldList, d->textEncoding); + String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding); ByteVector v; @@ -170,6 +254,55 @@ parseFields(fieldData(data)); } +PropertyMap TextIdentificationFrame::makeTIPLProperties() const +{ + PropertyMap map; + if(fieldList().size() % 2 != 0){ + // according to the ID3 spec, TIPL must contain an even number of entries + map.unsupportedData().append(frameID()); + return map; + } + StringList l = fieldList(); + for(StringList::ConstIterator it = l.begin(); it != l.end(); ++it) { + bool found = false; + for(uint i = 0; i < involvedPeopleSize; ++i) + if(*it == involvedPeople[i][0]) { + map.insert(involvedPeople[i][1], (++it)->split(",")); + found = true; + break; + } + if(!found){ + // invalid involved role -> mark whole frame as unsupported in order to be consisten with writing + map.clear(); + map.unsupportedData().append(frameID()); + return map; + } + } + return map; +} + +PropertyMap TextIdentificationFrame::makeTMCLProperties() const +{ + PropertyMap map; + if(fieldList().size() % 2 != 0){ + // according to the ID3 spec, TMCL must contain an even number of entries + map.unsupportedData().append(frameID()); + return map; + } + StringList l = fieldList(); + for(StringList::ConstIterator it = l.begin(); it != l.end(); ++it) { + String instrument = it->upper(); + if(instrument.isNull()) { + // instrument is not a valid key -> frame unsupported + map.clear(); + map.unsupportedData().append(frameID()); + return map; + } + map.insert(L"PERFORMER:" + instrument, (++it)->split(",")); + } + return map; +} + //////////////////////////////////////////////////////////////////////////////// // UserTextIdentificationFrame public members //////////////////////////////////////////////////////////////////////////////// @@ -191,6 +324,14 @@ checkFields(); } +UserTextIdentificationFrame::UserTextIdentificationFrame(const String &description, const StringList &values, String::Type encoding) : + TextIdentificationFrame("TXXX", encoding), + d(0) +{ + setDescription(description); + setText(values); +} + String UserTextIdentificationFrame::toString() const { return "[" + description() + "] " + fieldList().toString(); @@ -238,6 +379,23 @@ TextIdentificationFrame::setText(l); } +PropertyMap UserTextIdentificationFrame::asProperties() const +{ + String tagName = description(); + + PropertyMap map; + String key = tagName.upper(); + if(key.isNull()) // this frame's description is not a valid PropertyMap key -> add to unsupported list + map.unsupportedData().append(L"TXXX/" + description()); + else { + StringList v = fieldList(); + for(StringList::ConstIterator it = v.begin(); it != v.end(); ++it) + if(*it != description()) + map.insert(key, *it); + } + return map; +} + UserTextIdentificationFrame *UserTextIdentificationFrame::find( ID3v2::Tag *tag, const String &description) // static { diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/textidentificationframe.h taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.h --- taglib-1.7.2/taglib/mpeg/id3v2/frames/textidentificationframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.h 2012-09-06 18:03:15.000000000 +0000 @@ -27,6 +27,7 @@ #define TAGLIB_TEXTIDENTIFICATIONFRAME_H #include "tstringlist.h" +#include "tmap.h" #include "taglib_export.h" #include "id3v2frame.h" @@ -36,6 +37,7 @@ namespace ID3v2 { class Tag; + typedef Map KeyConversionMap; //! An ID3v2 text identification frame implementation @@ -124,6 +126,20 @@ explicit TextIdentificationFrame(const ByteVector &data); /*! + * This is a special factory method to create a TIPL (involved people list) + * frame from the given \a properties. Will parse key=[list of values] data + * into the TIPL format as specified in the ID3 standard. + */ + static TextIdentificationFrame *createTIPLFrame(const PropertyMap &properties); + + /*! + * This is a special factory method to create a TMCL (musician credits list) + * frame from the given \a properties. Will parse key=[list of values] data + * into the TMCL format as specified in the ID3 standard, where key should be + * of the form instrumentPrefix:instrument. + */ + static TextIdentificationFrame *createTMCLFrame(const PropertyMap &properties); + /*! * Destroys this TextIdentificationFrame instance. */ virtual ~TextIdentificationFrame(); @@ -173,6 +189,14 @@ */ StringList fieldList() const; + /*! + * Returns a KeyConversionMap mapping a role as it would be used in a PropertyMap + * to the corresponding key used in a TIPL ID3 frame to describe that role. + */ + static const KeyConversionMap &involvedPeopleMap(); + + PropertyMap asProperties() const; + protected: // Reimplementations. @@ -188,6 +212,16 @@ TextIdentificationFrame(const TextIdentificationFrame &); TextIdentificationFrame &operator=(const TextIdentificationFrame &); + /*! + * Parses the special structure of a TIPL frame + * Only the whitelisted roles "ARRANGER", "ENGINEER", "PRODUCER", + * "DJMIXER" (ID3: "DJ-MIX") and "MIXER" (ID3: "MIX") are allowed. + */ + PropertyMap makeTIPLProperties() const; + /*! + * Parses the special structure of a TMCL frame. + */ + PropertyMap makeTMCLProperties() const; class TextIdentificationFramePrivate; TextIdentificationFramePrivate *d; }; @@ -218,6 +252,12 @@ */ explicit UserTextIdentificationFrame(const ByteVector &data); + /*! + * Creates a user defined text identification frame with the given \a description + * and \a values. + */ + UserTextIdentificationFrame(const String &description, const StringList &values, String::Type encoding = String::UTF8); + virtual String toString() const; /*! @@ -237,6 +277,21 @@ void setText(const StringList &fields); /*! + * A UserTextIdentificationFrame is parsed into a PropertyMap as follows: + * - the key is the frame's description, uppercased + * - if the description contains '::', only the substring after that + * separator is considered as key (compatibility with exfalso) + * - if the above rules don't yield a valid key (e.g. containing non-ASCII + * characters), the returned map will contain an entry "TXXX/" + * in its unsupportedData() list. + * - The values will be copies of the fieldList(). + * - If the description() appears as value in fieldList(), it will be omitted + * in the value list, in order to be compatible with TagLib which copies + * the description() into the fieldList(). + */ + PropertyMap asProperties() const; + + /*! * Searches for the user defined text frame with the description \a description * in \a tag. This returns null if no matching frames were found. */ diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.h taglib-1.8/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.h --- taglib-1.7.2/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.h 2012-09-06 18:03:15.000000000 +0000 @@ -100,7 +100,7 @@ private: UniqueFileIdentifierFrame(const UniqueFileIdentifierFrame &); - UniqueFileIdentifierFrame &operator=(UniqueFileIdentifierFrame &); + UniqueFileIdentifierFrame &operator=(const UniqueFileIdentifierFrame &); UniqueFileIdentifierFrame(const ByteVector &data, Header *h); diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp taglib-1.8/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,7 +27,9 @@ #include "unsynchronizedlyricsframe.h" #include +#include #include +#include using namespace TagLib; using namespace ID3v2; @@ -111,6 +113,30 @@ d->textEncoding = encoding; } +PropertyMap UnsynchronizedLyricsFrame::asProperties() const +{ + PropertyMap map; + String key = description().upper(); + if(key.isEmpty() || key.upper() == "LYRICS") + map.insert("LYRICS", text()); + else if(key.isNull()) + map.unsupportedData().append(L"USLT/" + description()); + else + map.insert("LYRICS:" + key, text()); + return map; +} + +UnsynchronizedLyricsFrame *UnsynchronizedLyricsFrame::findByDescription(const ID3v2::Tag *tag, const String &d) // static +{ + ID3v2::FrameList lyrics = tag->frameList("USLT"); + + for(ID3v2::FrameList::ConstIterator it = lyrics.begin(); it != lyrics.end(); ++it){ + UnsynchronizedLyricsFrame *frame = dynamic_cast(*it); + if(frame && frame->description() == d) + return frame; + } + return 0; +} //////////////////////////////////////////////////////////////////////////////// // protected members //////////////////////////////////////////////////////////////////////////////// @@ -132,8 +158,13 @@ ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); if(l.size() == 2) { - d->description = String(l.front(), d->textEncoding); - d->text = String(l.back(), d->textEncoding); + if(d->textEncoding == String::Latin1) { + d->description = Tag::latin1StringHandler()->parse(l.front()); + d->text = Tag::latin1StringHandler()->parse(l.back()); + } else { + d->description = String(l.front(), d->textEncoding); + d->text = String(l.back(), d->textEncoding); + } } } diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.h taglib-1.8/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.h --- taglib-1.7.2/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.h 2012-09-06 18:03:15.000000000 +0000 @@ -134,6 +134,28 @@ */ void setTextEncoding(String::Type encoding); + + /*! Parses this frame as PropertyMap with a single key. + * - if description() is empty or "LYRICS", the key will be "LYRICS" + * - if description() is not a valid PropertyMap key, the frame will be + * marked unsupported by an entry "USLT/" in the unsupportedData() + * attribute of the returned map. + * - otherwise, the key will be "LYRICS:" + * - The single value will be the frame's text(). + * Note that currently the language() field is not supported by the PropertyMap + * interface. + */ + PropertyMap asProperties() const; + + /*! + * LyricsFrames each have a unique description. This searches for a lyrics + * frame with the decription \a d and returns a pointer to it. If no + * frame is found that matches the given description null is returned. + * + * \see description() + */ + static UnsynchronizedLyricsFrame *findByDescription(const Tag *tag, const String &d); + protected: // Reimplementations. diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/urllinkframe.cpp taglib-1.8/taglib/mpeg/id3v2/frames/urllinkframe.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/frames/urllinkframe.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/urllinkframe.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -26,8 +26,10 @@ ***************************************************************************/ #include "urllinkframe.h" +#include "id3v2tag.h" #include #include +#include using namespace TagLib; using namespace ID3v2; @@ -78,6 +80,18 @@ return url(); } +PropertyMap UrlLinkFrame::asProperties() const +{ + String key = frameIDToKey(frameID()); + PropertyMap map; + if(key.isNull()) + // unknown W*** frame - this normally shouldn't happen + map.unsupportedData().append(frameID()); + else + map.insert(key, url()); + return map; +} + void UrlLinkFrame::parseFields(const ByteVector &data) { d->url = String(data); @@ -139,6 +153,30 @@ d->description = s; } +PropertyMap UserUrlLinkFrame::asProperties() const +{ + PropertyMap map; + String key = description().upper(); + if(key.isEmpty() || key.upper() == "URL") + map.insert("URL", url()); + else if(key.isNull()) + map.unsupportedData().append(L"WXXX/" + description()); + else + map.insert("URL:" + key, url()); + return map; +} + +UserUrlLinkFrame *UserUrlLinkFrame::find(ID3v2::Tag *tag, const String &description) // static +{ + FrameList l = tag->frameList("WXXX"); + for(FrameList::Iterator it = l.begin(); it != l.end(); ++it) { + UserUrlLinkFrame *f = dynamic_cast(*it); + if(f && f->description() == description) + return f; + } + return 0; +} + void UserUrlLinkFrame::parseFields(const ByteVector &data) { if(data.size() < 2) { @@ -175,7 +213,7 @@ { ByteVector v; - String::Type encoding = checkEncoding(d->description, d->textEncoding); + String::Type encoding = checkTextEncoding(d->description, d->textEncoding); v.append(char(encoding)); v.append(d->description.data(encoding)); diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/frames/urllinkframe.h taglib-1.8/taglib/mpeg/id3v2/frames/urllinkframe.h --- taglib-1.7.2/taglib/mpeg/id3v2/frames/urllinkframe.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/frames/urllinkframe.h 2012-09-06 18:03:15.000000000 +0000 @@ -68,6 +68,7 @@ virtual void setText(const String &s); virtual String toString() const; + PropertyMap asProperties() const; protected: virtual void parseFields(const ByteVector &data); @@ -150,6 +151,22 @@ */ void setDescription(const String &s); + /*! + * Parses the UserUrlLinkFrame as PropertyMap. The description() is taken as key, + * and the URL as single value. + * - if description() is empty, the key will be "URL". + * - otherwise, if description() is not a valid key (e.g. containing non-ASCII + * characters), the returned map will contain an entry "WXXX/" + * in its unsupportedData() list. + */ + PropertyMap asProperties() const; + + /*! + * Searches for the user defined url frame with the description \a description + * in \a tag. This returns null if no matching frames were found. + */ + static UserUrlLinkFrame *find(Tag *tag, const String &description); + protected: virtual void parseFields(const ByteVector &data); virtual ByteVector renderFields() const; diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/id3v2frame.cpp taglib-1.8/taglib/mpeg/id3v2/id3v2frame.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/id3v2frame.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/id3v2frame.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -23,7 +23,7 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ -#ifndef HAVE_ZLIB +#ifdef HAVE_CONFIG_H #include #endif @@ -36,8 +36,15 @@ #include #include +#include "id3v2tag.h" #include "id3v2frame.h" #include "id3v2synchdata.h" +#include "tpropertymap.h" +#include "frames/textidentificationframe.h" +#include "frames/urllinkframe.h" +#include "frames/unsynchronizedlyricsframe.h" +#include "frames/commentsframe.h" +#include "frames/unknownframe.h" using namespace TagLib; using namespace ID3v2; @@ -65,7 +72,7 @@ return false; for(ByteVector::ConstIterator it = frameID.begin(); it != frameID.end(); it++) { - if( (*it < 'A' || *it > 'Z') && (*it < '1' || *it > '9') ) { + if( (*it < 'A' || *it > 'Z') && (*it < '0' || *it > '9') ) { return false; } } @@ -95,10 +102,56 @@ return d; } +const String Frame::instrumentPrefix("PERFORMER:"); +const String Frame::commentPrefix("COMMENT:"); +const String Frame::lyricsPrefix("LYRICS:"); +const String Frame::urlPrefix("URL:"); + //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// +Frame *Frame::createTextualFrame(const String &key, const StringList &values) //static +{ + // check if the key is contained in the key<=>frameID mapping + ByteVector frameID = keyToFrameID(key); + if(!frameID.isNull()) { + if(frameID[0] == 'T'){ // text frame + TextIdentificationFrame *frame = new TextIdentificationFrame(frameID, String::UTF8); + frame->setText(values); + return frame; + } else if(values.size() == 1){ // URL frame (not WXXX); support only one value + UrlLinkFrame* frame = new UrlLinkFrame(frameID); + frame->setUrl(values.front()); + return frame; + } + } + // now we check if it's one of the "special" cases: + // -LYRICS: depending on the number of values, use USLT or TXXX (with description=LYRICS) + if((key == "LYRICS" || key.startsWith(lyricsPrefix)) && values.size() == 1){ + UnsynchronizedLyricsFrame *frame = new UnsynchronizedLyricsFrame(); + frame->setDescription(key == "LYRICS" ? key : key.substr(lyricsPrefix.size())); + frame->setText(values.front()); + return frame; + } + // -URL: depending on the number of values, use WXXX or TXXX (with description=URL) + if((key == "URL" || key.startsWith(urlPrefix)) && values.size() == 1){ + UserUrlLinkFrame *frame = new UserUrlLinkFrame(String::UTF8); + frame->setDescription(key == "URL" ? key : key.substr(urlPrefix.size())); + frame->setUrl(values.front()); + return frame; + } + // -COMMENT: depending on the number of values, use COMM or TXXX (with description=COMMENT) + if((key == "COMMENT" || key.startsWith(commentPrefix)) && values.size() == 1){ + CommentsFrame *frame = new CommentsFrame(String::UTF8); + frame->setDescription(key == "COMMENT" ? key : key.substr(commentPrefix.size())); + frame->setText(values.front()); + return frame; + } + // if non of the above cases apply, we use a TXXX frame with the key as description + return new UserTextIdentificationFrame(key, values, String::UTF8); +} + Frame::~Frame() { delete d; @@ -221,7 +274,11 @@ if(end < *position) return String::null; - String str = String(data.mid(*position, end - *position), encoding); + String str; + if(encoding == String::Latin1) + str = Tag::latin1StringHandler()->parse(data.mid(*position, end - *position)); + else + str = String(data.mid(*position, end - *position), encoding); *position = end + delimiter.size(); @@ -230,19 +287,195 @@ String::Type Frame::checkEncoding(const StringList &fields, String::Type encoding) // static { + return checkEncoding(fields, encoding, 4); +} + +String::Type Frame::checkEncoding(const StringList &fields, String::Type encoding, uint version) // static +{ + if((encoding == String::UTF8 || encoding == String::UTF16BE) && version != 4) + return String::UTF16; + if(encoding != String::Latin1) return encoding; for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) { if(!(*it).isLatin1()) { - debug("Frame::checkEncoding() -- Rendering using UTF8."); - return String::UTF8; + if(version == 4) { + debug("Frame::checkEncoding() -- Rendering using UTF8."); + return String::UTF8; + } + else { + debug("Frame::checkEncoding() -- Rendering using UTF16."); + return String::UTF16; + } } } return String::Latin1; } +String::Type Frame::checkTextEncoding(const StringList &fields, String::Type encoding) const +{ + return checkEncoding(fields, encoding, header()->version()); +} + +static const TagLib::uint frameTranslationSize = 51; +static const char *frameTranslation[][2] = { + // 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" }, + { "TIT2", "TITLE"}, + { "TIT3", "SUBTITLE" }, + { "TKEY", "INITIALKEY" }, + { "TLAN", "LANGUAGE" }, + { "TLEN", "LENGTH" }, + //{ "TMCL", "MUSICIANCREDITS" }, handled separately + { "TMED", "MEDIATYPE" }, + { "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", "PUBLISHER" }, + { "TRCK", "TRACKNUMBER" }, + { "TRSN", "RADIOSTATION" }, + { "TRSO", "RADIOSTATIONOWNER" }, + { "TSOA", "ALBUMSORT" }, + { "TSOP", "ARTISTSORT" }, + { "TSOT", "TITLESORT" }, + { "TSO2", "ALBUMARTISTSORT" }, // non-standard, used by iTunes + { "TSRC", "ISRC" }, + { "TSSE", "ENCODING" }, + // URL frames + { "WCOP", "COPYRIGHTURL" }, + { "WOAF", "FILEWEBPAGE" }, + { "WOAR", "ARTISTWEBPAGE" }, + { "WOAS", "AUDIOSOURCEWEBPAGE" }, + { "WORS", "RADIOSTATIONWEBPAGE" }, + { "WPAY", "PAYMENTWEBPAGE" }, + { "WPUB", "PUBLISHERWEBPAGE" }, + //{ "WXXX", "URL"}, handled specially + // Other frames + { "COMM", "COMMENT" }, + //{ "USLT", "LYRICS" }, handled specially +}; + +Map &idMap() +{ + static Map m; + if(m.isEmpty()) + for(size_t i = 0; i < frameTranslationSize; ++i) + m[frameTranslation[i][0]] = frameTranslation[i][1]; + return m; +} + +// list of deprecated frames and their successors +static const TagLib::uint deprecatedFramesSize = 4; +static 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 +}; + +Map &deprecationMap() +{ + static Map depMap; + if(depMap.isEmpty()) + for(TagLib::uint i = 0; i < deprecatedFramesSize; ++i) + depMap[deprecatedFrames[i][0]] = deprecatedFrames[i][1]; + return depMap; +} + +String Frame::frameIDToKey(const ByteVector &id) +{ + Map &m = idMap(); + if(m.contains(id)) + return m[id]; + if(deprecationMap().contains(id)) + return m[deprecationMap()[id]]; + return String::null; +} + +ByteVector Frame::keyToFrameID(const String &s) +{ + static Map m; + if(m.isEmpty()) + for(size_t i = 0; i < frameTranslationSize; ++i) + m[frameTranslation[i][1]] = frameTranslation[i][0]; + if(m.contains(s.upper())) + return m[s]; + return ByteVector::null; +} + +PropertyMap Frame::asProperties() const +{ + if(dynamic_cast< const UnknownFrame *>(this)) { + PropertyMap m; + m.unsupportedData().append("UNKNOWN/" + frameID()); + return m; + } + const ByteVector &id = frameID(); + // workaround until this function is virtual + if(id == "TXXX") + return dynamic_cast< const UserTextIdentificationFrame* >(this)->asProperties(); + else if(id[0] == 'T') + return dynamic_cast< const TextIdentificationFrame* >(this)->asProperties(); + else if(id == "WXXX") + return dynamic_cast< const UserUrlLinkFrame* >(this)->asProperties(); + else if(id[0] == 'W') + return dynamic_cast< const UrlLinkFrame* >(this)->asProperties(); + else if(id == "COMM") + return dynamic_cast< const CommentsFrame* >(this)->asProperties(); + else if(id == "USLT") + return dynamic_cast< const UnsynchronizedLyricsFrame* >(this)->asProperties(); + PropertyMap m; + m.unsupportedData().append(id); + return m; +} + +void Frame::splitProperties(const PropertyMap &original, PropertyMap &singleFrameProperties, + PropertyMap &tiplProperties, PropertyMap &tmclProperties) +{ + + singleFrameProperties.clear(); + tiplProperties.clear(); + tmclProperties.clear(); + for(PropertyMap::ConstIterator it = original.begin(); it != original.end(); ++it) { + if(TextIdentificationFrame::involvedPeopleMap().contains(it->first)) + tiplProperties.insert(it->first, it->second); + else if(it->first.startsWith(TextIdentificationFrame::instrumentPrefix)) + tmclProperties.insert(it->first, it->second); + else + singleFrameProperties.insert(it->first, it->second); + } +} + //////////////////////////////////////////////////////////////////////////////// // Frame::Header class //////////////////////////////////////////////////////////////////////////////// @@ -484,6 +717,11 @@ return d->version; } +void Frame::Header::setVersion(TagLib::uint version) +{ + d->version = version; +} + bool Frame::Header::tagAlterPreservation() const { return d->tagAlterPreservation; @@ -538,7 +776,11 @@ { ByteVector flags(2, char(0)); // just blank for the moment - ByteVector v = d->frameID + SynchData::fromUInt(d->frameSize) + flags; + ByteVector v = d->frameID + + (d->version == 3 + ? ByteVector::fromUInt(d->frameSize) + : SynchData::fromUInt(d->frameSize)) + + flags; return v; } diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/id3v2frame.h taglib-1.8/taglib/mpeg/id3v2/id3v2frame.h --- taglib-1.7.2/taglib/mpeg/id3v2/id3v2frame.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/id3v2frame.h 2012-09-06 18:03:15.000000000 +0000 @@ -33,6 +33,7 @@ namespace TagLib { class StringList; + class PropertyMap; namespace ID3v2 { @@ -56,6 +57,14 @@ friend class FrameFactory; public: + + /*! + * Creates a textual frame which corresponds to a single key in the PropertyMap + * interface. These are all (User)TextIdentificationFrames except TIPL and TMCL, + * all (User)URLLinkFrames, CommentsFrames, and UnsynchronizedLyricsFrame. + */ + static Frame *createTextualFrame(const String &key, const StringList &values); + /*! * Destroys this Frame instance. */ @@ -126,6 +135,28 @@ */ static ByteVector textDelimiter(String::Type t); + /*! + * The string with which an instrument name is prefixed to build a key in a PropertyMap; + * used to translate PropertyMaps to TMCL frames. In the current implementation, this + * is "PERFORMER:". + */ + static const String instrumentPrefix; + /*! + * The PropertyMap key prefix which triggers the use of a COMM frame instead of a TXXX + * frame for a non-standard key. In the current implementation, this is "COMMENT:". + */ + static const String commentPrefix; + /*! + * The PropertyMap key prefix which triggers the use of a USLT frame instead of a TXXX + * frame for a non-standard key. In the current implementation, this is "LYRICS:". + */ + static const String lyricsPrefix; + /*! + * The PropertyMap key prefix which triggers the use of a WXXX frame instead of a TXX + * frame for a non-standard key. In the current implementation, this is "URL:". + */ + static const String urlPrefix; + protected: class Header; @@ -199,9 +230,67 @@ * Checks a the list of string values to see if they can be used with the * specified encoding and returns the recommended encoding. */ + // BIC: remove and make non-static static String::Type checkEncoding(const StringList &fields, String::Type encoding); + /*! + * Checks a the list of string values to see if they can be used with the + * specified encoding and returns the recommended encoding. This method + * also checks the ID3v2 version and makes sure the encoding can be used + * in the specified version. + */ + // BIC: remove and make non-static + static String::Type checkEncoding(const StringList &fields, + String::Type encoding, uint version); + + /*! + * Checks a the list of string values to see if they can be used with the + * specified encoding and returns the recommended encoding. This method + * also checks the ID3v2 version and makes sure the encoding can be used + * in the version specified by the frame's header. + */ + String::Type checkTextEncoding(const StringList &fields, + String::Type encoding) const; + + + /*! + * Parses the contents of this frame as PropertyMap. If that fails, the returend + * PropertyMap will be empty, and its unsupportedData() will contain this frame's + * ID. + * BIC: Will be a virtual function in future releases. + */ + PropertyMap asProperties() const; + + /*! + * Returns an appropriate ID3 frame ID for the given free-form tag key. This method + * will return ByteVector::null if no specialized translation is found. + */ + static ByteVector keyToFrameID(const String &); + + /*! + * Returns a free-form tag name for the given ID3 frame ID. Note that this does not work + * for general frame IDs such as TXXX or WXXX; in such a case String::null is returned. + */ + static String frameIDToKey(const ByteVector &); + + + /*! + * This helper function splits the PropertyMap \a original into three ProperytMaps + * \a singleFrameProperties, \a tiplProperties, and \a tmclProperties, such that: + * - \a singleFrameProperties contains only of keys which can be represented with + * exactly one ID3 frame per key. In the current implementation + * this is everything except for the fixed "involved people" keys and keys of the + * form "TextIdentificationFrame::instrumentPrefix" + "instrument", which are + * mapped to a TMCL frame. + * - \a tiplProperties will consist of those keys that are present in + * TextIdentificationFrame::involvedPeopleMap() + * - \a tmclProperties contains the "musician credits" keys which should be mapped + * to a TMCL frame + */ + static void splitProperties(const PropertyMap &original, PropertyMap &singleFrameProperties, + PropertyMap &tiplProperties, PropertyMap &tmclProperties); + private: Frame(const Frame &); Frame &operator=(const Frame &); @@ -294,12 +383,18 @@ void setFrameSize(uint size); /*! - * Returns the ID3v2 version of the header (as passed in from the - * construction of the header). + * Returns the ID3v2 version of the header, as passed in from the + * construction of the header or set via setVersion(). */ uint version() const; /*! + * Sets the ID3v2 version of the header, changing has impact on the + * correct parsing/rendering of frame data. + */ + void setVersion(uint version); + + /*! * Returns the size of the frame header in bytes. * * \deprecated Please use the version of this method that accepts a diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/id3v2framefactory.cpp taglib-1.8/taglib/mpeg/id3v2/id3v2framefactory.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/id3v2framefactory.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/id3v2framefactory.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -23,7 +23,7 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ -#ifndef HAVE_ZLIB +#ifdef HAVE_CONFIG_H #include #endif @@ -44,6 +44,7 @@ #include "frames/unsynchronizedlyricsframe.h" #include "frames/popularimeterframe.h" #include "frames/privateframe.h" +#include "frames/ownershipframe.h" using namespace TagLib; using namespace ID3v2; @@ -65,7 +66,7 @@ } }; -FrameFactory *FrameFactory::factory = 0; +FrameFactory FrameFactory::factory; //////////////////////////////////////////////////////////////////////////////// // public members @@ -73,9 +74,7 @@ FrameFactory *FrameFactory::instance() { - if(!factory) - factory = new FrameFactory; - return factory; + return &factory; } Frame *FrameFactory::createFrame(const ByteVector &data, bool synchSafeInts) const @@ -109,7 +108,7 @@ } for(ByteVector::ConstIterator it = frameID.begin(); it != frameID.end(); it++) { - if( (*it < 'A' || *it > 'Z') && (*it < '1' || *it > '9') ) { + if( (*it < 'A' || *it > 'Z') && (*it < '0' || *it > '9') ) { delete header; return 0; } @@ -185,13 +184,13 @@ // ID3v2.2 Attached Picture - if(frameID == "PIC") { + if(frameID == "PIC") { AttachedPictureFrame *f = new AttachedPictureFrameV22(data, header); d->setTextEncoding(f); return f; } - // Relative Volume Adjustment (frames 4.11) + // Relative Volume Adjustment (frames 4.11) if(frameID == "RVA2") return new RelativeVolumeFrame(data, header); @@ -240,6 +239,14 @@ if(frameID == "PRIV") return new PrivateFrame(data, header); + + // Ownership (frames 4.22) + + if(frameID == "OWNE") { + OwnershipFrame *f = new OwnershipFrame(data, header); + d->setTextEncoding(f); + return f; + } return new UnknownFrame(data, header); } @@ -310,6 +317,7 @@ convertFrame("TBP", "TBPM", header); convertFrame("TCM", "TCOM", header); convertFrame("TCO", "TCON", header); + convertFrame("TCP", "TCMP", header); convertFrame("TCR", "TCOP", header); convertFrame("TDY", "TDLY", header); convertFrame("TEN", "TENC", header); @@ -332,7 +340,12 @@ convertFrame("TRC", "TSRC", header); convertFrame("TRD", "TDRC", header); convertFrame("TRK", "TRCK", header); + convertFrame("TS2", "TSO2", header); + convertFrame("TSA", "TSOA", header); + convertFrame("TSC", "TSOC", header); + convertFrame("TSP", "TSOP", header); convertFrame("TSS", "TSSE", header); + convertFrame("TST", "TSOT", header); convertFrame("TT1", "TIT1", header); convertFrame("TT2", "TIT2", header); convertFrame("TT3", "TIT3", header); @@ -368,6 +381,7 @@ convertFrame("TORY", "TDOR", header); convertFrame("TYER", "TDRC", header); + convertFrame("IPLS", "TIPL", header); break; } diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/id3v2framefactory.h taglib-1.8/taglib/mpeg/id3v2/id3v2framefactory.h --- taglib-1.7.2/taglib/mpeg/id3v2/id3v2framefactory.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/id3v2framefactory.h 2012-09-06 18:03:15.000000000 +0000 @@ -123,8 +123,7 @@ FrameFactory(); /*! - * Destroys the frame factory. In most cases this will never be called (as - * is typical of singletons). + * Destroys the frame factory. */ virtual ~FrameFactory(); @@ -155,7 +154,7 @@ void updateGenre(TextIdentificationFrame *frame) const; - static FrameFactory *factory; + static FrameFactory factory; class FrameFactoryPrivate; FrameFactoryPrivate *d; diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/id3v2header.cpp taglib-1.8/taglib/mpeg/id3v2/id3v2header.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/id3v2header.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/id3v2header.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -164,7 +164,7 @@ // add the version number -- we always render a 2.4.0 tag regardless of what // the tag originally was. - v.append(char(4)); + v.append(char(majorVersion())); v.append(char(0)); // Currently we don't actually support writing extended headers, footers or diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/id3v2tag.cpp taglib-1.8/taglib/mpeg/id3v2/id3v2tag.cpp --- taglib-1.7.2/taglib/mpeg/id3v2/id3v2tag.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/id3v2tag.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -24,18 +24,23 @@ ***************************************************************************/ #include -#include #include "id3v2tag.h" #include "id3v2header.h" #include "id3v2extendedheader.h" #include "id3v2footer.h" #include "id3v2synchdata.h" - +#include "tbytevector.h" #include "id3v1genres.h" +#include "tpropertymap.h" +#include #include "frames/textidentificationframe.h" #include "frames/commentsframe.h" +#include "frames/urllinkframe.h" +#include "frames/uniquefileidentifierframe.h" +#include "frames/unsynchronizedlyricsframe.h" +#include "frames/unknownframe.h" using namespace TagLib; using namespace ID3v2; @@ -65,8 +70,30 @@ FrameListMap frameListMap; FrameList frameList; + + static const Latin1StringHandler *stringHandler; }; +static const Latin1StringHandler defaultStringHandler; +const ID3v2::Latin1StringHandler *ID3v2::Tag::TagPrivate::stringHandler = &defaultStringHandler; + +//////////////////////////////////////////////////////////////////////////////// +// StringHandler implementation +//////////////////////////////////////////////////////////////////////////////// + +Latin1StringHandler::Latin1StringHandler() +{ +} + +Latin1StringHandler::~Latin1StringHandler() +{ +} + +String Latin1StringHandler::parse(const ByteVector &data) const +{ + return String(data, String::Latin1); +} + //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// @@ -324,13 +351,203 @@ void ID3v2::Tag::removeFrames(const ByteVector &id) { - FrameList l = d->frameListMap[id]; - for(FrameList::Iterator it = l.begin(); it != l.end(); ++it) - removeFrame(*it, true); + FrameList l = d->frameListMap[id]; + for(FrameList::Iterator it = l.begin(); it != l.end(); ++it) + removeFrame(*it, true); +} + +PropertyMap ID3v2::Tag::properties() const +{ + PropertyMap properties; + for(FrameList::ConstIterator it = frameList().begin(); it != frameList().end(); ++it) { + PropertyMap props = (*it)->asProperties(); + properties.merge(props); + } + return properties; +} + +void ID3v2::Tag::removeUnsupportedProperties(const StringList &properties) +{ + for(StringList::ConstIterator it = properties.begin(); it != properties.end(); ++it){ + if(it->startsWith("UNKNOWN/")) { + String frameID = it->substr(String("UNKNOWN/").size()); + if(frameID.size() != 4) + continue; // invalid specification + ByteVector id = frameID.data(String::Latin1); + // delete all unknown frames of given type + FrameList l = frameList(id); + for(FrameList::ConstIterator fit = l.begin(); fit != l.end(); fit++) + if (dynamic_cast(*fit) != 0) + removeFrame(*fit); + } else if(it->size() == 4){ + ByteVector id = it->data(String::Latin1); + removeFrames(id); + } else { + ByteVector id = it->substr(0,4).data(String::Latin1); + if(it->size() <= 5) + continue; // invalid specification + String description = it->substr(5); + Frame *frame = 0; + if(id == "TXXX") + frame = UserTextIdentificationFrame::find(this, description); + else if(id == "WXXX") + frame = UserUrlLinkFrame::find(this, description); + else if(id == "COMM") + frame = CommentsFrame::findByDescription(this, description); + else if(id == "USLT") + frame = UnsynchronizedLyricsFrame::findByDescription(this, description); + if(frame) + removeFrame(frame); + } + } +} + +PropertyMap ID3v2::Tag::setProperties(const PropertyMap &origProps) +{ + FrameList framesToDelete; + // we split up the PropertyMap into the "normal" keys and the "complicated" ones, + // which are those according to TIPL or TMCL frames. + PropertyMap properties; + PropertyMap tiplProperties; + PropertyMap tmclProperties; + Frame::splitProperties(origProps, properties, tiplProperties, tmclProperties); + for(FrameListMap::ConstIterator it = frameListMap().begin(); it != frameListMap().end(); ++it){ + for(FrameList::ConstIterator lit = it->second.begin(); lit != it->second.end(); ++lit){ + PropertyMap frameProperties = (*lit)->asProperties(); + if(it->first == "TIPL") { + if (tiplProperties != frameProperties) + framesToDelete.append(*lit); + else + tiplProperties.erase(frameProperties); + } else if(it->first == "TMCL") { + if (tmclProperties != frameProperties) + framesToDelete.append(*lit); + else + tmclProperties.erase(frameProperties); + } else if(!properties.contains(frameProperties)) + framesToDelete.append(*lit); + else + properties.erase(frameProperties); + } + } + for(FrameList::ConstIterator it = framesToDelete.begin(); it != framesToDelete.end(); ++it) + removeFrame(*it); + + // now create remaining frames: + // start with the involved people list (TIPL) + if(!tiplProperties.isEmpty()) + addFrame(TextIdentificationFrame::createTIPLFrame(tiplProperties)); + // proceed with the musician credit list (TMCL) + if(!tmclProperties.isEmpty()) + addFrame(TextIdentificationFrame::createTMCLFrame(tmclProperties)); + // now create the "one key per frame" frames + for(PropertyMap::ConstIterator it = properties.begin(); it != properties.end(); ++it) + addFrame(Frame::createTextualFrame(it->first, it->second)); + return PropertyMap(); // ID3 implements the complete PropertyMap interface, so an empty map is returned } ByteVector ID3v2::Tag::render() const { + return render(4); +} + +void ID3v2::Tag::downgradeFrames(FrameList *frames, FrameList *newFrames) const +{ + const char *unsupportedFrames[] = { + "ASPI", "EQU2", "RVA2", "SEEK", "SIGN", "TDRL", "TDTG", + "TMOO", "TPRO", "TSOA", "TSOT", "TSST", "TSOP", 0 + }; + ID3v2::TextIdentificationFrame *frameTDOR = 0; + ID3v2::TextIdentificationFrame *frameTDRC = 0; + ID3v2::TextIdentificationFrame *frameTIPL = 0; + ID3v2::TextIdentificationFrame *frameTMCL = 0; + for(FrameList::Iterator it = d->frameList.begin(); it != d->frameList.end(); it++) { + ID3v2::Frame *frame = *it; + ByteVector frameID = frame->header()->frameID(); + for(int i = 0; unsupportedFrames[i]; i++) { + if(frameID == unsupportedFrames[i]) { + debug("A frame that is not supported in ID3v2.3 \'" + + String(frameID) + "\' has been discarded"); + frame = 0; + break; + } + } + if(frame && frameID == "TDOR") { + frameTDOR = dynamic_cast(frame); + frame = 0; + } + if(frame && frameID == "TDRC") { + frameTDRC = dynamic_cast(frame); + frame = 0; + } + if(frame && frameID == "TIPL") { + frameTIPL = dynamic_cast(frame); + frame = 0; + } + if(frame && frameID == "TMCL") { + frameTMCL = dynamic_cast(frame); + frame = 0; + } + if(frame) { + frames->append(frame); + } + } + if(frameTDOR) { + String content = frameTDOR->toString(); + if(content.size() >= 4) { + ID3v2::TextIdentificationFrame *frameTORY = new ID3v2::TextIdentificationFrame("TORY", String::Latin1); + frameTORY->setText(content.substr(0, 4)); + frames->append(frameTORY); + newFrames->append(frameTORY); + } + } + if(frameTDRC) { + String content = frameTDRC->toString(); + if(content.size() >= 4) { + ID3v2::TextIdentificationFrame *frameTYER = new ID3v2::TextIdentificationFrame("TYER", String::Latin1); + frameTYER->setText(content.substr(0, 4)); + frames->append(frameTYER); + newFrames->append(frameTYER); + if(content.size() >= 10 && content[4] == '-' && content[7] == '-') { + ID3v2::TextIdentificationFrame *frameTDAT = new ID3v2::TextIdentificationFrame("TDAT", String::Latin1); + frameTDAT->setText(content.substr(8, 2) + content.substr(5, 2)); + frames->append(frameTDAT); + newFrames->append(frameTDAT); + if(content.size() >= 16 && content[10] == 'T' && content[13] == ':') { + ID3v2::TextIdentificationFrame *frameTIME = new ID3v2::TextIdentificationFrame("TIME", String::Latin1); + frameTIME->setText(content.substr(11, 2) + content.substr(14, 2)); + frames->append(frameTIME); + newFrames->append(frameTIME); + } + } + } + } + if(frameTIPL || frameTMCL) { + ID3v2::TextIdentificationFrame *frameIPLS = new ID3v2::TextIdentificationFrame("IPLS", String::Latin1); + StringList people; + if(frameTMCL) { + StringList v24People = frameTMCL->fieldList(); + for(uint i = 0; i + 1 < v24People.size(); i += 2) { + people.append(v24People[i]); + people.append(v24People[i+1]); + } + } + if(frameTIPL) { + StringList v24People = frameTIPL->fieldList(); + for(uint i = 0; i + 1 < v24People.size(); i += 2) { + people.append(v24People[i]); + people.append(v24People[i+1]); + } + } + frameIPLS->setText(people); + frames->append(frameIPLS); + newFrames->append(frameIPLS); + } +} + + +ByteVector ID3v2::Tag::render(int version) const +{ // We need to render the "tag data" first so that we have to correct size to // render in the tag's header. The "tag data" -- everything that is included // in ID3v2::Header::tagSize() -- includes the extended header, frames and @@ -338,11 +555,28 @@ ByteVector tagData; + if(version != 3 && version != 4) { + debug("Unknown ID3v2 version, using ID3v2.4"); + version = 4; + } + // TODO: Render the extended header. // Loop through the frames rendering them and adding them to the tagData. - for(FrameList::Iterator it = d->frameList.begin(); it != d->frameList.end(); it++) { + FrameList newFrames; + newFrames.setAutoDelete(true); + + FrameList frameList; + if(version == 4) { + frameList = d->frameList; + } + else { + downgradeFrames(&frameList, &newFrames); + } + + for(FrameList::Iterator it = frameList.begin(); it != frameList.end(); it++) { + (*it)->header()->setVersion(version); if((*it)->header()->frameID().size() != 4) { debug("A frame of unsupported or unknown type \'" + String((*it)->header()->frameID()) + "\' has been discarded"); @@ -364,13 +598,27 @@ tagData.append(ByteVector(paddingSize, char(0))); - // Set the tag size. + // Set the version and data size. + d->header.setMajorVersion(version); d->header.setTagSize(tagData.size()); // TODO: This should eventually include d->footer->render(). return d->header.render() + tagData; } +Latin1StringHandler const *ID3v2::Tag::latin1StringHandler() +{ + return TagPrivate::stringHandler; +} + +void ID3v2::Tag::setLatin1StringHandler(const Latin1StringHandler *handler) +{ + if(handler) + TagPrivate::stringHandler = handler; + else + TagPrivate::stringHandler = &defaultStringHandler; +} + //////////////////////////////////////////////////////////////////////////////// // protected members //////////////////////////////////////////////////////////////////////////////// @@ -432,8 +680,9 @@ // portion of the frame data. if(data.at(frameDataPosition) == 0) { - if(d->header.footerPresent()) + if(d->header.footerPresent()) { debug("Padding *and* a footer found. This is not allowed by the spec."); + } d->paddingSize = frameDataLength - frameDataPosition; return; diff -Nru taglib-1.7.2/taglib/mpeg/id3v2/id3v2tag.h taglib-1.8/taglib/mpeg/id3v2/id3v2tag.h --- taglib-1.7.2/taglib/mpeg/id3v2/id3v2tag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/id3v2/id3v2tag.h 2012-09-06 18:03:15.000000000 +0000 @@ -57,6 +57,36 @@ typedef List FrameList; typedef Map FrameListMap; + //! An abstraction for the ISO-8859-1 string to data encoding in ID3v2 tags. + + /*! + * ID3v2 tag can store strings in ISO-8859-1 (Latin1), and TagLib only + * supports genuine ISO-8859-1 by default. However, in practice, non + * ISO-8859-1 encodings are often used instead of ISO-8859-1, such as + * Windows-1252 for western languages, Shift_JIS for Japanese and so on. + * + * Here is an option to read such tags by subclassing this class, + * reimplementing parse() and setting your reimplementation as the default + * with ID3v2::Tag::setStringHandler(). + * + * \note Writing non-ISO-8859-1 tags is not implemented intentionally. + * Use UTF-16 or UTF-8 instead. + * + * \see ID3v2::Tag::setStringHandler() + */ + class TAGLIB_EXPORT Latin1StringHandler + { + public: + Latin1StringHandler(); + virtual ~Latin1StringHandler(); + + /*! + * Decode a string from \a data. The default implementation assumes that + * \a data is an ISO-8859-1 (Latin1) character array. + */ + virtual String parse(const ByteVector &data) const; + }; + //! The main class in the ID3v2 implementation /*! @@ -261,10 +291,90 @@ void removeFrames(const ByteVector &id); /*! + * Implements the unified property interface -- export function. + * This function does some work to translate the hard-specified ID3v2 + * frame types into a free-form string-to-stringlist PropertyMap: + * - if ID3v2 frame ID is known by Frame::frameIDToKey(), the returned + * key is used + * - if the frame ID is "TXXX" (user text frame), the description() is + * used as key + * - if the frame ID is "WXXX" (user url frame), + * - if the description is empty or "URL", the key "URL" is used + * - otherwise, the key "URL:" is used; + * - if the frame ID is "COMM" (comments frame), + * - if the description is empty or "COMMENT", the key "COMMENT" + * is used + * - otherwise, the key "COMMENT:" is used; + * - if the frame ID is "USLT" (unsynchronized lyrics), + * - if the description is empty or "LYRICS", the key "LYRICS" is used + * - otherwise, the key "LYRICS:" is used; + * - if the frame ID is "TIPL" (involved peoples list), and if all the + * roles defined in the frame are known in TextIdentificationFrame::involvedPeopleMap(), + * then "=" will be contained in the returned obejct for each + * - if the frame ID is "TMCL" (musician credit list), then + * "PERFORMER:=" will be contained in the returned + * PropertyMap for each defined musician + * In any other case, the unsupportedData() of the returned object will contain + * the frame's ID and, in case of a frame ID which is allowed to appear more than + * once, the description, separated by a "/". + * + */ + PropertyMap properties() const; + + /*! + * Removes unsupported frames given by \a properties. The elements of + * \a properties must be taken from properties().unsupportedData(); they + * are of one of the following forms: + * - a four-character frame ID, if the ID3 specification allows only one + * frame with that ID (thus, the frame is uniquely determined) + * - frameID + "/" + description(), when the ID is one of "TXXX", "WXXX", + * "COMM", or "USLT", + * - "UNKNOWN/" + frameID, for frames that could not be parsed by TagLib. + * In that case, *all* unknown frames with the given ID will be removed. + */ + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + * See the comments in properties(). + */ + PropertyMap setProperties(const PropertyMap &); + + /*! * Render the tag back to binary data, suitable to be written to disk. */ ByteVector render() const; + /*! + * Render the tag back to binary data, suitable to be written to disk. + * + * The \a version parameter specifies the version of the rendered + * ID3v2 tag. It can be either 4 or 3. + */ + // BIC: combine with the above method + ByteVector render(int version) const; + + /*! + * Gets the current string handler that decides how the "Latin-1" data + * will be converted to and from binary data. + * + * \see Latin1StringHandler + */ + static Latin1StringHandler const *latin1StringHandler(); + + /*! + * Sets the string handler that decides how the "Latin-1" data will be + * converted to and from binary data. + * If the parameter \a handler is null, the previous handler is + * released and default ISO-8859-1 handler is restored. + * + * \note The caller is responsible for deleting the previous handler + * as needed after it is released. + * + * \see Latin1StringHandler + */ + static void setLatin1StringHandler(const Latin1StringHandler *handler); + protected: /*! * Reads data from the file specified in the constructor. It does basic @@ -286,6 +396,8 @@ */ void setTextFrame(const ByteVector &id, const String &value); + void downgradeFrames(FrameList *existingFrames, FrameList *newFrames) const; + private: Tag(const Tag &); Tag &operator=(const Tag &); diff -Nru taglib-1.7.2/taglib/mpeg/mpegfile.cpp taglib-1.8/taglib/mpeg/mpegfile.cpp --- taglib-1.7.2/taglib/mpeg/mpegfile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/mpegfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -35,6 +35,7 @@ #include "mpegfile.h" #include "mpegheader.h" +#include "tpropertymap.h" using namespace TagLib; @@ -113,6 +114,16 @@ read(readProperties, propertiesStyle); } +MPEG::File::File(IOStream *stream, ID3v2::FrameFactory *frameFactory, + bool readProperties, Properties::ReadStyle propertiesStyle) : + TagLib::File(stream) +{ + d = new FilePrivate(frameFactory); + + if(isOpen()) + read(readProperties, propertiesStyle); +} + MPEG::File::~File() { delete d; @@ -123,6 +134,40 @@ return &d->tag; } +PropertyMap MPEG::File::properties() const +{ + // once Tag::properties() is virtual, this case distinction could actually be done + // within TagUnion. + if(d->hasID3v2) + return d->tag.access(ID3v2Index, false)->properties(); + if(d->hasAPE) + return d->tag.access(APEIndex, false)->properties(); + if(d->hasID3v1) + return d->tag.access(ID3v1Index, false)->properties(); + return PropertyMap(); +} + +void MPEG::File::removeUnsupportedProperties(const StringList &properties) +{ + if(d->hasID3v2) + d->tag.access(ID3v2Index, false)->removeUnsupportedProperties(properties); + else if(d->hasAPE) + d->tag.access(APEIndex, false)->removeUnsupportedProperties(properties); + else if(d->hasID3v1) + d->tag.access(ID3v1Index, false)->removeUnsupportedProperties(properties); +} +PropertyMap MPEG::File::setProperties(const PropertyMap &properties) +{ + if(d->hasID3v2) + return d->tag.access(ID3v2Index, false)->setProperties(properties); + else if(d->hasAPE) + return d->tag.access(APEIndex, false)->setProperties(properties); + else if(d->hasID3v1) + return d->tag.access(ID3v1Index, false)->setProperties(properties); + else + return d->tag.access(ID3v2Index, true)->setProperties(properties); +} + MPEG::Properties *MPEG::File::audioProperties() const { return d->properties; @@ -140,6 +185,11 @@ bool MPEG::File::save(int tags, bool stripOthers) { + return save(tags, stripOthers, 4); +} + +bool MPEG::File::save(int tags, bool stripOthers, int id3v2Version) +{ if(tags == NoTags && stripOthers) return strip(AllTags); @@ -157,12 +207,12 @@ } // Create the tags if we've been asked to. Copy the values from the tag that - // does exist into the new tag. + // does exist into the new tag, except if the existing tag is to be stripped. - if((tags & ID3v2) && ID3v1Tag()) + if((tags & ID3v2) && ID3v1Tag() && !(stripOthers && !(tags & ID3v1))) Tag::duplicate(ID3v1Tag(), ID3v2Tag(true), false); - if((tags & ID3v1) && d->tag[ID3v2Index]) + if((tags & ID3v1) && d->tag[ID3v2Index] && !(stripOthers && !(tags & ID3v2))) Tag::duplicate(ID3v2Tag(), ID3v1Tag(true), false); bool success = true; @@ -174,7 +224,7 @@ if(!d->hasID3v2) d->ID3v2Location = 0; - insert(ID3v2Tag()->render(), d->ID3v2Location, d->ID3v2OriginalSize); + insert(ID3v2Tag()->render(id3v2Version), d->ID3v2Location, d->ID3v2OriginalSize); d->hasID3v2 = true; @@ -186,7 +236,7 @@ // APE tag location has changed, update if it exists if(APETag()) - findAPE(); + findAPE(); } else if(stripOthers) success = strip(ID3v2, false) && success; @@ -224,9 +274,10 @@ else { seek(0, End); d->APELocation = tell(); - d->APEFooterLocation = d->APELocation - + d->tag.access(APEIndex, false)->footer()->completeTagSize() - - APE::Footer::size(); + APE::Tag *apeTag = d->tag.access(APEIndex, false); + d->APEFooterLocation = d->APELocation + + apeTag->footer()->completeTagSize() + - APE::Footer::size(); writeBlock(APETag()->render()); d->APEOriginalSize = APETag()->footer()->completeTagSize(); d->hasAPE = true; @@ -572,7 +623,7 @@ seek(d->APEFooterLocation); APE::Footer footer(readBlock(APE::Footer::size())); d->APELocation = d->APEFooterLocation - footer.completeTagSize() - + APE::Footer::size(); + + APE::Footer::size(); return; } } diff -Nru taglib-1.7.2/taglib/mpeg/mpegfile.h taglib-1.8/taglib/mpeg/mpegfile.h --- taglib-1.7.2/taglib/mpeg/mpegfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/mpegfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -28,6 +28,7 @@ #include "taglib_export.h" #include "tfile.h" +#include "tag.h" #include "mpegproperties.h" @@ -85,13 +86,29 @@ * file's audio properties will also be read using \a propertiesStyle. If * false, \a propertiesStyle is ignored. The frames will be created using * \a frameFactory. + * + * \deprecated This constructor will be dropped in favor of the one below + * in a future version. */ - // BIC: merge with the above constructor File(FileName file, ID3v2::FrameFactory *frameFactory, bool readProperties = true, Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs an MPEG file from \a stream. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. The frames will be created using + * \a frameFactory. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + // BIC: merge with the above constructor + File(IOStream *stream, ID3v2::FrameFactory *frameFactory, + bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); @@ -116,6 +133,23 @@ virtual Tag *tag() const; /*! + * Implements the unified property interface -- export function. + * If the file contains more than one tag, only the + * first one (in the order ID3v2, APE, ID3v1) will be converted to the + * PropertyMap. + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified tag dictionary interface -- import function. + * As with the export, only one tag is taken into account. If the file + * has no tag at all, ID3v2 will be created. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! * Returns the MPEG::Properties for this file. If no audio properties * were read then this will return a null pointer. */ @@ -162,11 +196,26 @@ bool save(int tags, bool stripOthers); /*! + * Save the file. This will attempt to save all of the tag types that are + * specified by OR-ing together TagTypes values. The save() method above + * uses AllTags. This returns true if saving was successful. + * + * If \a stripOthers is true this strips all tags not included in the mask, + * but does not modify them in memory, so later calls to save() which make + * use of these tags will remain valid. This also strips empty tags. + * + * The \a id3v2Version parameter specifies the version of the saved + * ID3v2 tag. It can be either 4 or 3. + */ + // BIC: combine with the above method + bool save(int tags, bool stripOthers, int id3v2Version); + + /*! * Returns a pointer to the ID3v2 tag of the file. * - * If \a create is false (the default) this will return a null pointer - * if there is no valid ID3v2 tag. If \a create is true it will create - * an ID3v2 tag if one does not exist. + * A tag will always be returned, regardless of whether there is a + * tag in the file or not. Use ID3v2::Tag::isEmpty() to check if + * the tag contains no data. * * \note The Tag is still owned by the MPEG::File and should not be * deleted by the user. It will be deleted when the file (object) is @@ -177,9 +226,9 @@ /*! * Returns a pointer to the ID3v1 tag of the file. * - * If \a create is false (the default) this will return a null pointer - * if there is no valid ID3v1 tag. If \a create is true it will create - * an ID3v1 tag if one does not exist. + * A tag will always be returned, regardless of whether there is a + * tag in the file or not. Use Tag::isEmpty() to check if + * the tag contains no data. * * \note The Tag is still owned by the MPEG::File and should not be * deleted by the user. It will be deleted when the file (object) is diff -Nru taglib-1.7.2/taglib/mpeg/mpegproperties.cpp taglib-1.8/taglib/mpeg/mpegproperties.cpp --- taglib-1.7.2/taglib/mpeg/mpegproperties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/mpeg/mpegproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -221,7 +221,7 @@ double length = timePerFrame * d->xingHeader->totalFrames(); d->length = int(length); - d->bitrate = d->length > 0 ? d->xingHeader->totalSize() * 8 / length / 1000 : 0; + d->bitrate = d->length > 0 ? (int)(d->xingHeader->totalSize() * 8 / length / 1000) : 0; } else { // Since there was no valid Xing header found, we hope that we're in a constant diff -Nru taglib-1.7.2/taglib/ogg/CMakeLists.txt taglib-1.8/taglib/ogg/CMakeLists.txt --- taglib-1.7.2/taglib/ogg/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -ADD_SUBDIRECTORY( vorbis ) -ADD_SUBDIRECTORY( speex ) -ADD_SUBDIRECTORY( flac ) - -INSTALL( FILES oggfile.h oggpage.h oggpageheader.h xiphcomment.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib ) - diff -Nru taglib-1.7.2/taglib/ogg/flac/CMakeLists.txt taglib-1.8/taglib/ogg/flac/CMakeLists.txt --- taglib-1.7.2/taglib/ogg/flac/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/flac/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -INSTALL( FILES oggflacfile.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) - diff -Nru taglib-1.7.2/taglib/ogg/flac/oggflacfile.cpp taglib-1.8/taglib/ogg/flac/oggflacfile.cpp --- taglib-1.7.2/taglib/ogg/flac/oggflacfile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/flac/oggflacfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -75,6 +75,13 @@ read(readProperties, propertiesStyle); } +Ogg::FLAC::File::File(IOStream *stream, bool readProperties, + Properties::ReadStyle propertiesStyle) : Ogg::File(stream) +{ + d = new FilePrivate; + read(readProperties, propertiesStyle); +} + Ogg::FLAC::File::~File() { delete d; @@ -256,9 +263,9 @@ d->hasXiphComment = true; d->commentPacket = ipacket; } - else if(blockType > 5) + else if(blockType > 5) { debug("Ogg::FLAC::File::scan() -- Unknown metadata block"); - + } } // End of metadata, now comes the datastream diff -Nru taglib-1.7.2/taglib/ogg/flac/oggflacfile.h taglib-1.8/taglib/ogg/flac/oggflacfile.h --- taglib-1.7.2/taglib/ogg/flac/oggflacfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/flac/oggflacfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -72,6 +72,17 @@ Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs an Ogg/FLAC file from \a file. If \a readProperties is true + * the file's audio properties will also be read using \a propertiesStyle. + * If false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); diff -Nru taglib-1.7.2/taglib/ogg/oggfile.cpp taglib-1.8/taglib/ogg/oggfile.cpp --- taglib-1.7.2/taglib/ogg/oggfile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/oggfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -213,6 +213,11 @@ d = new FilePrivate; } +Ogg::File::File(IOStream *stream) : TagLib::File(stream) +{ + d = new FilePrivate; +} + //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// @@ -276,8 +281,8 @@ return; - // pages in the pageGroup and packets must be equivalent - // (originalSize and size of packets would not work together), + // pages in the pageGroup and packets must be equivalent + // (originalSize and size of packets would not work together), // therefore we sometimes have to add pages to the group List pageGroup(thePageGroup); while (!d->pages[pageGroup.back()]->header()->lastPacketCompleted()) { @@ -336,7 +341,7 @@ if (pages.back()->header()->pageSequenceNumber() != pageGroup.back()) { - // TODO: change the internal data structure so that we don't need to hold the + // TODO: change the internal data structure so that we don't need to hold the // complete file in memory (is unavoidable at the moment) // read the complete stream diff -Nru taglib-1.7.2/taglib/ogg/oggfile.h taglib-1.8/taglib/ogg/oggfile.h --- taglib-1.7.2/taglib/ogg/oggfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/oggfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -92,6 +92,20 @@ */ File(FileName file); + /*! + * Contructs an Ogg file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note This constructor is protected since Ogg::File shouldn't be + * instantiated directly but rather should be used through the codec + * specific subclasses. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream); + private: File(const File &); File &operator=(const File &); diff -Nru taglib-1.7.2/taglib/ogg/oggpage.cpp taglib-1.8/taglib/ogg/oggpage.cpp --- taglib-1.7.2/taglib/ogg/oggpage.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/oggpage.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -116,9 +116,9 @@ flags = ContainsPacketFlags(flags | CompletePacket); } - // Or if there is more than one page and the page is - // (a) the first page and it's complete or - // (b) the last page and it's complete or + // Or if there is more than one page and the page is + // (a) the first page and it's complete or + // (b) the last page and it's complete or // (c) a page in the middle. else if(packetCount() > 1 && ((flags & BeginsWithPacket && !d->header.firstPacketContinued()) || @@ -266,7 +266,7 @@ } Page *p = new Page(packetList, streamSerialNumber, firstPage+pageIndex, continued, - lastPacketInList ? lastPacketCompleted : true, + lastPacketInList ? lastPacketCompleted : true, isVeryLastPacket); pageIndex++; diff -Nru taglib-1.7.2/taglib/ogg/oggpage.h taglib-1.8/taglib/ogg/oggpage.h --- taglib-1.7.2/taglib/ogg/oggpage.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/oggpage.h 2012-09-06 18:03:15.000000000 +0000 @@ -70,9 +70,9 @@ */ const PageHeader *header() const; - /*! + /*! * Returns a copy of the page with \a sequenceNumber set as sequence number. - * + * * \see header() * \see PageHeader::setPageSequenceNumber() */ diff -Nru taglib-1.7.2/taglib/ogg/speex/CMakeLists.txt taglib-1.8/taglib/ogg/speex/CMakeLists.txt --- taglib-1.7.2/taglib/ogg/speex/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/speex/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES speexfile.h speexproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/ogg/speex/speexfile.cpp taglib-1.8/taglib/ogg/speex/speexfile.cpp --- taglib-1.7.2/taglib/ogg/speex/speexfile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/speex/speexfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -65,6 +65,13 @@ read(readProperties, propertiesStyle); } +Speex::File::File(IOStream *stream, bool readProperties, + Properties::ReadStyle propertiesStyle) : Ogg::File(stream) +{ + d = new FilePrivate; + read(readProperties, propertiesStyle); +} + Speex::File::~File() { delete d; diff -Nru taglib-1.7.2/taglib/ogg/speex/speexfile.h taglib-1.8/taglib/ogg/speex/speexfile.h --- taglib-1.7.2/taglib/ogg/speex/speexfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/speex/speexfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -64,6 +64,17 @@ Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs a Speex file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); diff -Nru taglib-1.7.2/taglib/ogg/vorbis/CMakeLists.txt taglib-1.8/taglib/ogg/vorbis/CMakeLists.txt --- taglib-1.7.2/taglib/ogg/vorbis/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/vorbis/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES vorbisfile.h vorbisproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/ogg/vorbis/vorbisfile.cpp taglib-1.8/taglib/ogg/vorbis/vorbisfile.cpp --- taglib-1.7.2/taglib/ogg/vorbis/vorbisfile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/vorbis/vorbisfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,9 +27,11 @@ #include #include +#include #include "vorbisfile.h" + using namespace TagLib; class Vorbis::File::FilePrivate @@ -68,6 +70,13 @@ read(readProperties, propertiesStyle); } +Vorbis::File::File(IOStream *stream, bool readProperties, + Properties::ReadStyle propertiesStyle) : Ogg::File(stream) +{ + d = new FilePrivate; + read(readProperties, propertiesStyle); +} + Vorbis::File::~File() { delete d; @@ -78,6 +87,16 @@ return d->comment; } +PropertyMap Vorbis::File::properties() const +{ + return d->comment->properties(); +} + +PropertyMap Vorbis::File::setProperties(const PropertyMap &properties) +{ + return d->comment->setProperties(properties); +} + Vorbis::Properties *Vorbis::File::audioProperties() const { return d->properties; diff -Nru taglib-1.7.2/taglib/ogg/vorbis/vorbisfile.h taglib-1.8/taglib/ogg/vorbis/vorbisfile.h --- taglib-1.7.2/taglib/ogg/vorbis/vorbisfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/vorbis/vorbisfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -71,6 +71,17 @@ Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs a Vorbis file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); @@ -82,6 +93,19 @@ */ virtual Ogg::XiphComment *tag() const; + + /*! + * Implements the unified property interface -- export function. + * This forwards directly to XiphComment::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * Like properties(), this is a forwarder to the file's XiphComment. + */ + PropertyMap setProperties(const PropertyMap &); + /*! * Returns the Vorbis::Properties for this file. If no audio properties * were read then this will return a null pointer. diff -Nru taglib-1.7.2/taglib/ogg/vorbis/vorbisproperties.cpp taglib-1.8/taglib/ogg/vorbis/vorbisproperties.cpp --- taglib-1.7.2/taglib/ogg/vorbis/vorbisproperties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/vorbis/vorbisproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -173,7 +173,7 @@ long long end = last->absoluteGranularPosition(); if(start >= 0 && end >= 0 && d->sampleRate > 0) - d->length = (end - start) / (long long) d->sampleRate; + d->length = (int)((end - start) / (long long) d->sampleRate); else debug("Vorbis::Properties::read() -- Either the PCM values for the start or " "end of this file was incorrect or the sample rate is zero."); diff -Nru taglib-1.7.2/taglib/ogg/xiphcomment.cpp taglib-1.8/taglib/ogg/xiphcomment.cpp --- taglib-1.7.2/taglib/ogg/xiphcomment.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/xiphcomment.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -27,6 +27,7 @@ #include #include +#include using namespace TagLib; @@ -188,6 +189,58 @@ return d->fieldListMap; } +PropertyMap Ogg::XiphComment::properties() const +{ + return d->fieldListMap; +} + +PropertyMap Ogg::XiphComment::setProperties(const PropertyMap &properties) +{ + // check which keys are to be deleted + StringList toRemove; + for(FieldListMap::ConstIterator it = d->fieldListMap.begin(); it != d->fieldListMap.end(); ++it) + if (!properties.contains(it->first)) + toRemove.append(it->first); + + for(StringList::ConstIterator it = toRemove.begin(); it != toRemove.end(); ++it) + removeField(*it); + + // now go through keys in \a properties and check that the values match those in the xiph comment + PropertyMap invalid; + PropertyMap::ConstIterator it = properties.begin(); + for(; it != properties.end(); ++it) + { + if(!checkKey(it->first)) + invalid.insert(it->first, it->second); + else if(!d->fieldListMap.contains(it->first) || !(it->second == d->fieldListMap[it->first])) { + const StringList &sl = it->second; + if(sl.size() == 0) + // zero size string list -> remove the tag with all values + removeField(it->first); + else { + // replace all strings in the list for the tag + StringList::ConstIterator valueIterator = sl.begin(); + addField(it->first, *valueIterator, true); + ++valueIterator; + for(; valueIterator != sl.end(); ++valueIterator) + addField(it->first, *valueIterator, false); + } + } + } + return invalid; +} + +bool Ogg::XiphComment::checkKey(const String &key) +{ + if(key.size() < 1) + return false; + for(String::ConstIterator it = key.begin(); it != key.end(); it++) + // forbid non-printable, non-ascii, '=' (#61) and '~' (#126) + if (*it < 32 || *it >= 128 || *it == 61 || *it == 126) + return false; + return true; +} + String Ogg::XiphComment::vendorID() const { return d->vendorID; @@ -285,7 +338,7 @@ // The first thing in the comment data is the vendor ID length, followed by a // UTF8 string with the vendor ID. - int pos = 0; + uint pos = 0; uint vendorLength = data.mid(0, 4).toUInt(false); pos += 4; diff -Nru taglib-1.7.2/taglib/ogg/xiphcomment.h taglib-1.8/taglib/ogg/xiphcomment.h --- taglib-1.7.2/taglib/ogg/xiphcomment.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/ogg/xiphcomment.h 2012-09-06 18:03:15.000000000 +0000 @@ -141,6 +141,29 @@ const FieldListMap &fieldListMap() const; /*! + * Implements the unified property interface -- export function. + * The result is a one-to-one match of the Xiph comment, since it is + * completely compatible with the property interface (in fact, a Xiph + * comment is nothing more than a map from tag names to list of values, + * as is the dict interface). + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * The tags from the given map will be stored one-to-one in the file, + * except for invalid keys (less than one character, non-ASCII, or + * containing '=' or '~') in which case the according values will + * be contained in the returned PropertyMap. + */ + PropertyMap setProperties(const PropertyMap&); + + /*! + * Check if the given String is a valid Xiph comment key. + */ + static bool checkKey(const String&); + + /*! * Returns the vendor ID of the Ogg Vorbis encoder. libvorbis 1.0 as the * most common case always returns "Xiph.Org libVorbis I 20020717". */ diff -Nru taglib-1.7.2/taglib/riff/CMakeLists.txt taglib-1.8/taglib/riff/CMakeLists.txt --- taglib-1.7.2/taglib/riff/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -ADD_SUBDIRECTORY( aiff ) -ADD_SUBDIRECTORY( wav ) - -INSTALL( FILES rifffile.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/riff/aiff/CMakeLists.txt taglib-1.8/taglib/riff/aiff/CMakeLists.txt --- taglib-1.7.2/taglib/riff/aiff/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/aiff/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES aifffile.h aiffproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/riff/aiff/aifffile.cpp taglib-1.8/taglib/riff/aiff/aifffile.cpp --- taglib-1.7.2/taglib/riff/aiff/aifffile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/aiff/aifffile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include "aifffile.h" @@ -65,6 +67,14 @@ read(readProperties, propertiesStyle); } +RIFF::AIFF::File::File(IOStream *stream, bool readProperties, + Properties::ReadStyle propertiesStyle) : RIFF::File(stream, BigEndian) +{ + d = new FilePrivate; + if(isOpen()) + read(readProperties, propertiesStyle); +} + RIFF::AIFF::File::~File() { delete d; @@ -75,6 +85,17 @@ return d->tag; } +PropertyMap RIFF::AIFF::File::properties() const +{ + return d->tag->properties(); +} + +PropertyMap RIFF::AIFF::File::setProperties(const PropertyMap &properties) +{ + return d->tag->setProperties(properties); +} + + RIFF::AIFF::Properties *RIFF::AIFF::File::audioProperties() const { return d->properties; diff -Nru taglib-1.7.2/taglib/riff/aiff/aifffile.h taglib-1.8/taglib/riff/aiff/aifffile.h --- taglib-1.7.2/taglib/riff/aiff/aifffile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/aiff/aifffile.h 2012-09-06 18:03:15.000000000 +0000 @@ -66,6 +66,17 @@ Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs an AIFF file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); @@ -76,6 +87,18 @@ virtual ID3v2::Tag *tag() const; /*! + * Implements the unified property interface -- export function. + * This method forwards to ID3v2::Tag::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * This method forwards to ID3v2::Tag::setProperties(). + */ + PropertyMap setProperties(const PropertyMap &); + + /*! * Returns the AIFF::Properties for this file. If no audio properties * were read then this will return a null pointer. */ diff -Nru taglib-1.7.2/taglib/riff/aiff/aiffproperties.cpp taglib-1.8/taglib/riff/aiff/aiffproperties.cpp --- taglib-1.7.2/taglib/riff/aiff/aiffproperties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/aiff/aiffproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -44,7 +44,7 @@ double f; int expon; unsigned long hiMant, loMant; - + expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF); hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24) | @@ -85,7 +85,8 @@ bitrate(0), sampleRate(0), channels(0), - sampleWidth(0) + sampleWidth(0), + sampleFrames(0) { } @@ -95,6 +96,7 @@ int sampleRate; int channels; int sampleWidth; + uint sampleFrames; }; //////////////////////////////////////////////////////////////////////////////// @@ -137,6 +139,11 @@ return d->sampleWidth; } +TagLib::uint RIFF::AIFF::Properties::sampleFrames() const +{ + return d->sampleFrames; +} + //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// @@ -144,10 +151,10 @@ void RIFF::AIFF::Properties::read(const ByteVector &data) { d->channels = data.mid(0, 2).toShort(); - uint sampleFrames = data.mid(2, 4).toUInt(); + d->sampleFrames = data.mid(2, 4).toUInt(); d->sampleWidth = data.mid(6, 2).toShort(); double sampleRate = ConvertFromIeeeExtended(reinterpret_cast(data.mid(8, 10).data())); - d->sampleRate = sampleRate; - d->bitrate = (sampleRate * d->sampleWidth * d->channels) / 1000.0; - d->length = d->sampleRate > 0 ? sampleFrames / d->sampleRate : 0; + d->sampleRate = (int)sampleRate; + d->bitrate = (int)((sampleRate * d->sampleWidth * d->channels) / 1000.0); + d->length = d->sampleRate > 0 ? d->sampleFrames / d->sampleRate : 0; } diff -Nru taglib-1.7.2/taglib/riff/aiff/aiffproperties.h taglib-1.8/taglib/riff/aiff/aiffproperties.h --- taglib-1.7.2/taglib/riff/aiff/aiffproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/aiff/aiffproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -46,34 +46,35 @@ class TAGLIB_EXPORT Properties : public AudioProperties { public: - /*! - * Create an instance of AIFF::Properties with the data read from the - * ByteVector \a data. - */ - Properties(const ByteVector &data, ReadStyle style); - - /*! - * Destroys this AIFF::Properties instance. - */ - virtual ~Properties(); - - // Reimplementations. - - virtual int length() const; - virtual int bitrate() const; - virtual int sampleRate() const; - virtual int channels() const; + /*! + * Create an instance of AIFF::Properties with the data read from the + * ByteVector \a data. + */ + Properties(const ByteVector &data, ReadStyle style); + + /*! + * Destroys this AIFF::Properties instance. + */ + virtual ~Properties(); + + // Reimplementations. + + virtual int length() const; + virtual int bitrate() const; + virtual int sampleRate() const; + virtual int channels() const; - int sampleWidth() const; + int sampleWidth() const; + uint sampleFrames() const; private: - Properties(const Properties &); - Properties &operator=(const Properties &); + Properties(const Properties &); + Properties &operator=(const Properties &); - void read(const ByteVector &data); + void read(const ByteVector &data); - class PropertiesPrivate; - PropertiesPrivate *d; + class PropertiesPrivate; + PropertiesPrivate *d; }; } } diff -Nru taglib-1.7.2/taglib/riff/rifffile.cpp taglib-1.8/taglib/riff/rifffile.cpp --- taglib-1.7.2/taglib/riff/rifffile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/rifffile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -79,6 +79,15 @@ read(); } +RIFF::File::File(IOStream *stream, Endianness endianness) : TagLib::File(stream) +{ + d = new FilePrivate; + d->endianness = endianness; + + if(isOpen()) + read(); +} + TagLib::uint RIFF::File::riffSize() const { return d->size; @@ -180,7 +189,7 @@ d->chunks[i].padding = 1; offset++; } - + Chunk chunk; chunk.name = name; chunk.size = data.size(); diff -Nru taglib-1.7.2/taglib/riff/rifffile.h taglib-1.8/taglib/riff/rifffile.h --- taglib-1.7.2/taglib/riff/rifffile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/rifffile.h 2012-09-06 18:03:15.000000000 +0000 @@ -56,6 +56,7 @@ enum Endianness { BigEndian, LittleEndian }; File(FileName file, Endianness endianness); + File(IOStream *stream, Endianness endianness); /*! * \return The size of the main RIFF chunk. diff -Nru taglib-1.7.2/taglib/riff/wav/CMakeLists.txt taglib-1.8/taglib/riff/wav/CMakeLists.txt --- taglib-1.7.2/taglib/riff/wav/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/wav/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES wavfile.h wavproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/riff/wav/wavfile.cpp taglib-1.8/taglib/riff/wav/wavfile.cpp --- taglib-1.7.2/taglib/riff/wav/wavfile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/wav/wavfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include "wavfile.h" @@ -65,6 +67,14 @@ read(readProperties, propertiesStyle); } +RIFF::WAV::File::File(IOStream *stream, bool readProperties, + Properties::ReadStyle propertiesStyle) : RIFF::File(stream, LittleEndian) +{ + d = new FilePrivate; + if(isOpen()) + read(readProperties, propertiesStyle); +} + RIFF::WAV::File::~File() { delete d; @@ -75,6 +85,17 @@ return d->tag; } +PropertyMap RIFF::WAV::File::properties() const +{ + return d->tag->properties(); +} + +PropertyMap RIFF::WAV::File::setProperties(const PropertyMap &properties) +{ + return d->tag->setProperties(properties); +} + + RIFF::WAV::Properties *RIFF::WAV::File::audioProperties() const { return d->properties; diff -Nru taglib-1.7.2/taglib/riff/wav/wavfile.h taglib-1.8/taglib/riff/wav/wavfile.h --- taglib-1.7.2/taglib/riff/wav/wavfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/wav/wavfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -66,6 +66,17 @@ Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs an WAV file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); @@ -76,6 +87,18 @@ virtual ID3v2::Tag *tag() const; /*! + * Implements the unified property interface -- export function. + * This method forwards to ID3v2::Tag::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * This method forwards to ID3v2::Tag::setProperties(). + */ + PropertyMap setProperties(const PropertyMap &); + + /*! * Returns the WAV::Properties for this file. If no audio properties * were read then this will return a null pointer. */ diff -Nru taglib-1.7.2/taglib/riff/wav/wavproperties.cpp taglib-1.8/taglib/riff/wav/wavproperties.cpp --- taglib-1.7.2/taglib/riff/wav/wavproperties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/wav/wavproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -42,6 +42,7 @@ sampleRate(0), channels(0), sampleWidth(0), + sampleFrames(0), streamLength(streamLength) { @@ -53,6 +54,7 @@ int sampleRate; int channels; int sampleWidth; + uint sampleFrames; uint streamLength; }; @@ -102,6 +104,11 @@ return d->sampleWidth; } +TagLib::uint RIFF::WAV::Properties::sampleFrames() const +{ + return d->sampleFrames; +} + //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// @@ -117,4 +124,6 @@ d->bitrate = byteRate * 8 / 1000; d->length = byteRate > 0 ? d->streamLength / byteRate : 0; + if(d->channels > 0 && d->sampleWidth > 0) + d->sampleFrames = d->streamLength / (d->channels * ((d->sampleWidth + 7) / 8)); } diff -Nru taglib-1.7.2/taglib/riff/wav/wavproperties.h taglib-1.8/taglib/riff/wav/wavproperties.h --- taglib-1.7.2/taglib/riff/wav/wavproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/riff/wav/wavproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -49,40 +49,41 @@ class TAGLIB_EXPORT Properties : public AudioProperties { public: - /*! - * Create an instance of WAV::Properties with the data read from the - * ByteVector \a data. - */ - Properties(const ByteVector &data, ReadStyle style); - - /*! - * Create an instance of WAV::Properties with the data read from the - * ByteVector \a data and the length calculated using \a streamLength. - */ - Properties(const ByteVector &data, uint streamLength, ReadStyle style); - - /*! - * Destroys this WAV::Properties instance. - */ - virtual ~Properties(); - - // Reimplementations. - - virtual int length() const; - virtual int bitrate() const; - virtual int sampleRate() const; - virtual int channels() const; + /*! + * Create an instance of WAV::Properties with the data read from the + * ByteVector \a data. + */ + Properties(const ByteVector &data, ReadStyle style); + + /*! + * Create an instance of WAV::Properties with the data read from the + * ByteVector \a data and the length calculated using \a streamLength. + */ + Properties(const ByteVector &data, uint streamLength, ReadStyle style); + + /*! + * Destroys this WAV::Properties instance. + */ + virtual ~Properties(); + + // Reimplementations. + + virtual int length() const; + virtual int bitrate() const; + virtual int sampleRate() const; + virtual int channels() const; - int sampleWidth() const; + int sampleWidth() const; + uint sampleFrames() const; private: - Properties(const Properties &); - Properties &operator=(const Properties &); + Properties(const Properties &); + Properties &operator=(const Properties &); - void read(const ByteVector &data); + void read(const ByteVector &data); - class PropertiesPrivate; - PropertiesPrivate *d; + class PropertiesPrivate; + PropertiesPrivate *d; }; } } diff -Nru taglib-1.7.2/taglib/s3m/s3mfile.cpp taglib-1.8/taglib/s3m/s3mfile.cpp --- taglib-1.7.2/taglib/s3m/s3mfile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/s3m/s3mfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,241 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "s3mfile.h" +#include "tstringlist.h" +#include "tdebug.h" +#include "modfileprivate.h" +#include "tpropertymap.h" + +#include + +using namespace TagLib; +using namespace S3M; + +class S3M::File::FilePrivate +{ +public: + FilePrivate(AudioProperties::ReadStyle propertiesStyle) + : properties(propertiesStyle) + { + } + + Mod::Tag tag; + S3M::Properties properties; +}; + +S3M::File::File(FileName file, bool readProperties, + AudioProperties::ReadStyle propertiesStyle) : + Mod::FileBase(file), + d(new FilePrivate(propertiesStyle)) +{ + read(readProperties); +} + +S3M::File::File(IOStream *stream, bool readProperties, + AudioProperties::ReadStyle propertiesStyle) : + Mod::FileBase(stream), + d(new FilePrivate(propertiesStyle)) +{ + read(readProperties); +} + +S3M::File::~File() +{ + delete d; +} + +Mod::Tag *S3M::File::tag() const +{ + return &d->tag; +} + +PropertyMap S3M::File::properties() const +{ + return d->tag.properties(); +} + +PropertyMap S3M::File::setProperties(const PropertyMap &properties) +{ + return d->tag.setProperties(properties); +} + +S3M::Properties *S3M::File::audioProperties() const +{ + return &d->properties; +} + +bool S3M::File::save() +{ + if(readOnly()) { + debug("S3M::File::save() - Cannot save to a read only file."); + return false; + } + // note: if title starts with "Extended Module: " + // the file would look like an .xm file + seek(0); + writeString(d->tag.title(), 27); + // string terminating NUL is not optional: + writeByte(0); + + seek(32); + + ushort length = 0; + ushort sampleCount = 0; + + if(!readU16L(length) || !readU16L(sampleCount)) + return false; + + seek(28, Current); + + int channels = 0; + for(int i = 0; i < 32; ++ i) { + uchar setting = 0; + if(!readByte(setting)) + return false; + // or if(setting >= 128)? + // or channels = i + 1;? + // need a better spec! + if(setting != 0xff) ++ channels; + } + + seek(channels, Current); + + StringList lines = d->tag.comment().split("\n"); + // write comment as sample names: + for(ushort i = 0; i < sampleCount; ++ i) { + seek(96L + length + ((long)i << 1)); + + ushort instrumentOffset = 0; + if(!readU16L(instrumentOffset)) + return false; + seek(((long)instrumentOffset << 4) + 48); + + if(i < lines.size()) + writeString(lines[i], 27); + else + writeString(String::null, 27); + // string terminating NUL is not optional: + writeByte(0); + } + return true; +} + +void S3M::File::read(bool) +{ + if(!isOpen()) + return; + + READ_STRING(d->tag.setTitle, 28); + READ_BYTE_AS(mark); + READ_BYTE_AS(type); + + READ_ASSERT(mark == 0x1A && type == 0x10); + + seek(32); + + READ_U16L_AS(length); + READ_U16L_AS(sampleCount); + + d->properties.setSampleCount(sampleCount); + + READ_U16L(d->properties.setPatternCount); + READ_U16L(d->properties.setFlags); + READ_U16L(d->properties.setTrackerVersion); + READ_U16L(d->properties.setFileFormatVersion); + + READ_ASSERT(readBlock(4) == "SCRM"); + + READ_BYTE(d->properties.setGlobalVolume); + READ_BYTE(d->properties.setBpmSpeed); + READ_BYTE(d->properties.setTempo); + + READ_BYTE_AS(masterVolume); + d->properties.setMasterVolume(masterVolume & 0x7f); + d->properties.setStereo((masterVolume & 0x80) != 0); + + // I've seen players who call the next two bytes + // "ultra click" and "use panning values" (if == 0xFC). + // I don't see them in any spec, though. + // Hm, but there is "UltraClick-removal" and some other + // variables in ScreamTracker IIIs GUI. + + seek(12, Current); + + int channels = 0; + for(int i = 0; i < 32; ++ i) { + READ_BYTE_AS(setting); + // or if(setting >= 128)? + // or channels = i + 1;? + // need a better spec! + if(setting != 0xff) ++ channels; + } + d->properties.setChannels(channels); + + seek(96); + ushort realLength = 0; + for(ushort i = 0; i < length; ++ i) { + READ_BYTE_AS(order); + if(order == 255) break; + if(order != 254) ++ realLength; + } + d->properties.setLengthInPatterns(realLength); + + seek(channels, Current); + + // Note: The S3M spec mentions samples and instruments, but in + // the header there are only pointers to instruments. + // However, there I never found instruments (SCRI) but + // instead samples (SCRS). + StringList comment; + for(ushort i = 0; i < sampleCount; ++ i) { + seek(96L + length + ((long)i << 1)); + + READ_U16L_AS(sampleHeaderOffset); + seek((long)sampleHeaderOffset << 4); + + READ_BYTE_AS(sampleType); + READ_STRING_AS(dosFileName, 13); + READ_U16L_AS(sampleDataOffset); + READ_U32L_AS(sampleLength); + READ_U32L_AS(repeatStart); + READ_U32L_AS(repeatStop); + READ_BYTE_AS(sampleVolume); + + seek(1, Current); + + READ_BYTE_AS(packing); + READ_BYTE_AS(sampleFlags); + READ_U32L_AS(baseFrequency); + + seek(12, Current); + + READ_STRING_AS(sampleName, 28); + // The next 4 bytes should be "SCRS", but I've found + // files that are otherwise ok with 4 nils instead. + // READ_ASSERT(readBlock(4) == "SCRS"); + + comment.append(sampleName); + } + + d->tag.setComment(comment.toString("\n")); + d->tag.setTrackerName("ScreamTracker III"); +} diff -Nru taglib-1.7.2/taglib/s3m/s3mfile.h taglib-1.8/taglib/s3m/s3mfile.h --- taglib-1.7.2/taglib/s3m/s3mfile.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/s3m/s3mfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,104 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_S3MFILE_H +#define TAGLIB_S3MFILE_H + +#include "tfile.h" +#include "audioproperties.h" +#include "taglib_export.h" +#include "modfilebase.h" +#include "modtag.h" +#include "s3mproperties.h" + +namespace TagLib { + + namespace S3M { + + class TAGLIB_EXPORT File : public Mod::FileBase { + public: + /*! + * Contructs a ScreamTracker III file from \a file. If \a readProperties + * is true the file's audio properties will also be read using + * \a propertiesStyle. If false, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + AudioProperties::ReadStyle propertiesStyle = + AudioProperties::Average); + + /*! + * Contructs a ScreamTracker III file from \a stream. If \a readProperties + * is true the file's audio properties will also be read using + * \a propertiesStyle. If false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + AudioProperties::ReadStyle propertiesStyle = + AudioProperties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + Mod::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * Forwards to Mod::Tag::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * Forwards to Mod::Tag::setProperties(). + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the S3M::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + S3M::Properties *audioProperties() const; + + /*! + * Save the file. + * This is the same as calling save(AllTags); + * + * \note Saving ScreamTracker III tags is not supported. + */ + bool save(); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff -Nru taglib-1.7.2/taglib/s3m/s3mproperties.cpp taglib-1.8/taglib/s3m/s3mproperties.cpp --- taglib-1.7.2/taglib/s3m/s3mproperties.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/s3m/s3mproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,204 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "s3mproperties.h" + +using namespace TagLib; +using namespace S3M; + +class S3M::Properties::PropertiesPrivate +{ +public: + PropertiesPrivate() : + lengthInPatterns(0), + channels(0), + stereo(false), + sampleCount(0), + patternCount(0), + flags(0), + trackerVersion(0), + fileFormatVersion(0), + globalVolume(0), + masterVolume(0), + tempo(0), + bpmSpeed(0) + { + } + + ushort lengthInPatterns; + int channels; + bool stereo; + ushort sampleCount; + ushort patternCount; + ushort flags; + ushort trackerVersion; + ushort fileFormatVersion; + uchar globalVolume; + uchar masterVolume; + uchar tempo; + uchar bpmSpeed; +}; + +S3M::Properties::Properties(AudioProperties::ReadStyle propertiesStyle) : + AudioProperties(propertiesStyle), + d(new PropertiesPrivate) +{ +} + +S3M::Properties::~Properties() +{ + delete d; +} + +int S3M::Properties::length() const +{ + return 0; +} + +int S3M::Properties::bitrate() const +{ + return 0; +} + +int S3M::Properties::sampleRate() const +{ + return 0; +} + +int S3M::Properties::channels() const +{ + return d->channels; +} + +TagLib::ushort S3M::Properties::lengthInPatterns() const +{ + return d->lengthInPatterns; +} + +bool S3M::Properties::stereo() const +{ + return d->stereo; +} + +TagLib::ushort S3M::Properties::sampleCount() const +{ + return d->sampleCount; +} + +TagLib::ushort S3M::Properties::patternCount() const +{ + return d->patternCount; +} + +TagLib::ushort S3M::Properties::flags() const +{ + return d->flags; +} + +TagLib::ushort S3M::Properties::trackerVersion() const +{ + return d->trackerVersion; +} + +TagLib::ushort S3M::Properties::fileFormatVersion() const +{ + return d->fileFormatVersion; +} + +uchar S3M::Properties::globalVolume() const +{ + return d->globalVolume; +} + +uchar S3M::Properties::masterVolume() const +{ + return d->masterVolume; +} + +uchar S3M::Properties::tempo() const +{ + return d->tempo; +} + +uchar S3M::Properties::bpmSpeed() const +{ + return d->bpmSpeed; +} + +void S3M::Properties::setLengthInPatterns(ushort lengthInPatterns) +{ + d->lengthInPatterns = lengthInPatterns; +} + +void S3M::Properties::setChannels(int channels) +{ + d->channels = channels; +} + +void S3M::Properties::setStereo(bool stereo) +{ + d->stereo = stereo; +} + +void S3M::Properties::setSampleCount(ushort sampleCount) +{ + d->sampleCount = sampleCount; +} + +void S3M::Properties::setPatternCount(ushort patternCount) +{ + d->patternCount = patternCount; +} + +void S3M::Properties::setFlags(ushort flags) +{ + d->flags = flags; +} + +void S3M::Properties::setTrackerVersion(ushort trackerVersion) +{ + d->trackerVersion = trackerVersion; +} + +void S3M::Properties::setFileFormatVersion(ushort fileFormatVersion) +{ + d->fileFormatVersion = fileFormatVersion; +} + +void S3M::Properties::setGlobalVolume(uchar globalVolume) +{ + d->globalVolume = globalVolume; +} + +void S3M::Properties::setMasterVolume(uchar masterVolume) +{ + d->masterVolume = masterVolume; +} + +void S3M::Properties::setTempo(uchar tempo) +{ + d->tempo = tempo; +} + +void S3M::Properties::setBpmSpeed(uchar bpmSpeed) +{ + d->bpmSpeed = bpmSpeed; +} diff -Nru taglib-1.7.2/taglib/s3m/s3mproperties.h taglib-1.8/taglib/s3m/s3mproperties.h --- taglib-1.7.2/taglib/s3m/s3mproperties.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/s3m/s3mproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,88 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_S3MPROPERTIES_H +#define TAGLIB_S3MPROPERTIES_H + +#include "taglib.h" +#include "audioproperties.h" + +namespace TagLib { + namespace S3M { + class TAGLIB_EXPORT Properties : public AudioProperties { + friend class File; + public: + /*! Flag bits. */ + enum { + ST2Vibrato = 1, + ST2Tempo = 2, + AmigaSlides = 4, + Vol0MixOptimizations = 8, + AmigaLimits = 16, + EnableFilter = 32, + CustomData = 128 + }; + + Properties(AudioProperties::ReadStyle propertiesStyle); + virtual ~Properties(); + + int length() const; + int bitrate() const; + int sampleRate() const; + int channels() const; + + ushort lengthInPatterns() const; + bool stereo() const; + ushort sampleCount() const; + ushort patternCount() const; + ushort flags() const; + ushort trackerVersion() const; + ushort fileFormatVersion() const; + uchar globalVolume() const; + uchar masterVolume() const; + uchar tempo() const; + uchar bpmSpeed() const; + + void setChannels(int channels); + + void setLengthInPatterns (ushort lengthInPatterns); + void setStereo (bool stereo); + void setSampleCount (ushort sampleCount); + void setPatternCount (ushort patternCount); + void setFlags (ushort flags); + void setTrackerVersion (ushort trackerVersion); + void setFileFormatVersion(ushort fileFormatVersion); + void setGlobalVolume (uchar globalVolume); + void setMasterVolume (uchar masterVolume); + void setTempo (uchar tempo); + void setBpmSpeed (uchar bpmSpeed); + + private: + Properties(const Properties&); + Properties &operator=(const Properties&); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff -Nru taglib-1.7.2/taglib/tag.cpp taglib-1.8/taglib/tag.cpp --- taglib-1.7.2/taglib/tag.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/tag.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -24,6 +24,8 @@ ***************************************************************************/ #include "tag.h" +#include "tstringlist.h" +#include "tpropertymap.h" using namespace TagLib; @@ -53,6 +55,101 @@ track() == 0); } +PropertyMap Tag::properties() const +{ + PropertyMap map; + if(!(title().isNull())) + map["TITLE"].append(title()); + if(!(artist().isNull())) + map["ARTIST"].append(artist()); + if(!(album().isNull())) + map["ALBUM"].append(album()); + if(!(comment().isNull())) + map["COMMENT"].append(comment()); + if(!(genre().isNull())) + map["GENRE"].append(genre()); + if(!(year() == 0)) + map["DATE"].append(String::number(year())); + if(!(track() == 0)) + map["TRACKNUMBER"].append(String::number(track())); + return map; +} + +void Tag::removeUnsupportedProperties(const StringList&) +{ +} + +PropertyMap Tag::setProperties(const PropertyMap &origProps) +{ + PropertyMap properties(origProps); + properties.removeEmpty(); + StringList oneValueSet; + // can this be simplified by using some preprocessor defines / function pointers? + if(properties.contains("TITLE")) { + setTitle(properties["TITLE"].front()); + oneValueSet.append("TITLE"); + } else + setTitle(String::null); + + if(properties.contains("ARTIST")) { + setArtist(properties["ARTIST"].front()); + oneValueSet.append("ARTIST"); + } else + setArtist(String::null); + + if(properties.contains("ALBUM")) { + setAlbum(properties["ALBUM"].front()); + oneValueSet.append("ALBUM"); + } else + setAlbum(String::null); + + if(properties.contains("COMMENT")) { + setComment(properties["COMMENT"].front()); + oneValueSet.append("COMMENT"); + } else + setComment(String::null); + + if(properties.contains("GENRE")) { + setGenre(properties["GENRE"].front()); + oneValueSet.append("GENRE"); + } else + setGenre(String::null); + + if(properties.contains("DATE")) { + bool ok; + int date = properties["DATE"].front().toInt(&ok); + if(ok) { + setYear(date); + oneValueSet.append("DATE"); + } else + setYear(0); + } + else + setYear(0); + + if(properties.contains("TRACKNUMBER")) { + bool ok; + int track = properties["TRACKNUMBER"].front().toInt(&ok); + if(ok) { + setTrack(track); + oneValueSet.append("TRACKNUMBER"); + } else + setTrack(0); + } + else + setYear(0); + + // for each tag that has been set above, remove the first entry in the corresponding + // value list. The others will be returned as unsupported by this format. + for(StringList::Iterator it = oneValueSet.begin(); it != oneValueSet.end(); ++it) { + if(properties[*it].size() == 1) + properties.erase(*it); + else + properties[*it].erase( properties[*it].begin() ); + } + return properties; +} + void Tag::duplicate(const Tag *source, Tag *target, bool overwrite) // static { if(overwrite) { diff -Nru taglib-1.7.2/taglib/tag.h taglib-1.8/taglib/tag.h --- taglib-1.7.2/taglib/tag.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/tag.h 2012-09-06 18:03:15.000000000 +0000 @@ -41,6 +41,8 @@ * in TagLib::AudioProperties, TagLib::File and TagLib::FileRef. */ + class PropertyMap; + class TAGLIB_EXPORT Tag { public: @@ -51,6 +53,32 @@ virtual ~Tag(); /*! + * Exports the tags of the file as dictionary mapping (human readable) tag + * names (Strings) to StringLists of tag values. + * The default implementation in this class considers only the usual built-in + * tags (artist, album, ...) and only one value per key. + */ + PropertyMap properties() const; + + /*! + * Removes unsupported properties, or a subset of them, from the tag. + * The parameter \a properties must contain only entries from + * properties().unsupportedData(). + * BIC: Will become virtual in future releases. Currently the non-virtual + * standard implementation of TagLib::Tag does nothing, since there are + * no unsupported elements. + */ + void removeUnsupportedProperties(const StringList& properties); + + /*! + * Sets the tags of this File to those specified in \a properties. This default + * implementation sets only the tags for which setter methods exist in this class + * (artist, album, ...), and only one value per key; the rest will be contained + * in the returned PropertyMap. + */ + PropertyMap setProperties(const PropertyMap &properties); + + /*! * Returns the track name; if no track name is present in the tag * String::null will be returned. */ diff -Nru taglib-1.7.2/taglib/taglib.pro taglib-1.8/taglib/taglib.pro --- taglib-1.7.2/taglib/taglib.pro 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/taglib.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,275 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Fri Feb 1 15:35:13 2008 -###################################################################### - -TEMPLATE = lib -CONFIG += lib_bundle staticlib -CONFIG += x86 x86_64 ppc -CONFIG -= qt -DEFINES += HAVE_ZLIB=1 NDEBUG WITH_ASF WITH_MP4 TAGLIB_NO_CONFIG -LIBS += -lz -TARGET = TagLib -VERSION = 1.6.3 -DEPENDPATH += . \ - ape \ - asf \ - flac \ - mp4 \ - mpc \ - mpeg \ - mpeg/id3v1 \ - mpeg/id3v2 \ - mpeg/id3v2/frames \ - ogg \ - ogg/flac \ - ogg/speex \ - ogg/vorbis \ - riff \ - riff/aiff \ - riff/wav \ - toolkit \ - trueaudio \ - wavpack - -INCLUDEPATH += . \ - ape \ - asf \ - flac \ - mp4 \ - mpc \ - mpeg \ - mpeg/id3v1 \ - mpeg/id3v2 \ - mpeg/id3v2/frames \ - ogg \ - ogg/flac \ - ogg/speex \ - ogg/vorbis \ - riff \ - riff/aiff \ - riff/wav \ - toolkit \ - trueaudio \ - wavpack - -# Input -HEADERS += audioproperties.h \ - fileref.h \ - tag.h \ - taglib_export.h \ - tagunion.h \ - ape/apefooter.h \ - ape/apeitem.h \ - ape/apetag.h \ - flac/flacfile.h \ - flac/flacproperties.h \ - flac/flacpicture.h \ - mpc/mpcfile.h \ - mpc/mpcproperties.h \ - mp4/mp4atom.h \ - mp4/mp4item.h \ - mp4/mp4file.h \ - mp4/mp4properties.h \ - mpeg/mpegfile.h \ - mpeg/mpegheader.h \ - mpeg/mpegproperties.h \ - mpeg/xingheader.h \ - ogg/oggfile.h \ - ogg/oggpage.h \ - ogg/oggpageheader.h \ - ogg/xiphcomment.h \ - ogg/speex/speexfile.h \ - ogg/speex/speexproperties.h \ - toolkit/taglib.h \ - toolkit/tbytevector.h \ - toolkit/tbytevectorlist.h \ - toolkit/tdebug.h \ - toolkit/tfile.h \ - toolkit/tlist.h \ - toolkit/tmap.h \ - toolkit/tstring.h \ - toolkit/tstringlist.h \ - toolkit/unicode.h \ - trueaudio/trueaudiofile.h \ - trueaudio/trueaudioproperties.h \ - wavpack/wavpackfile.h \ - wavpack/wavpackproperties.h \ - mpeg/id3v1/id3v1genres.h \ - mpeg/id3v1/id3v1tag.h \ - mpeg/id3v2/id3v2extendedheader.h \ - mpeg/id3v2/id3v2footer.h \ - mpeg/id3v2/id3v2frame.h \ - mpeg/id3v2/id3v2framefactory.h \ - mpeg/id3v2/id3v2header.h \ - mpeg/id3v2/id3v2synchdata.h \ - mpeg/id3v2/id3v2tag.h \ - ogg/flac/oggflacfile.h \ - ogg/vorbis/vorbisfile.h \ - ogg/vorbis/vorbisproperties.h \ - mpeg/id3v2/frames/attachedpictureframe.h \ - mpeg/id3v2/frames/commentsframe.h \ - mpeg/id3v2/frames/generalencapsulatedobjectframe.h \ - mpeg/id3v2/frames/popularimeterframe.h \ - mpeg/id3v2/frames/relativevolumeframe.h \ - mpeg/id3v2/frames/textidentificationframe.h \ - mpeg/id3v2/frames/uniquefileidentifierframe.h \ - mpeg/id3v2/frames/unknownframe.h \ - mpeg/id3v2/frames/unsynchronizedlyricsframe.h \ - mpeg/id3v2/frames/urllinkframe.h \ - toolkit/tlist.tcc \ - toolkit/tmap.tcc -SOURCES += ape/apefooter.cpp \ - ape/apeitem.cpp \ - ape/apetag.cpp \ - asf/asfattribute.cpp \ - asf/asffile.cpp \ - asf/asfproperties.cpp \ - asf/asftag.cpp \ - asf/asfpicture.cpp \ - audioproperties.cpp \ - fileref.cpp \ - flac/flacfile.cpp \ - flac/flacproperties.cpp \ - flac/flacpicture.cpp \ - mp4/mp4atom.cpp \ - mp4/mp4coverart.cpp \ - mp4/mp4file.cpp \ - mp4/mp4item.cpp \ - mp4/mp4properties.cpp \ - mp4/mp4tag.cpp \ - mpc/mpcfile.cpp \ - mpc/mpcproperties.cpp \ - mpeg/id3v1/id3v1genres.cpp \ - mpeg/id3v1/id3v1tag.cpp \ - mpeg/id3v2/frames/attachedpictureframe.cpp \ - mpeg/id3v2/frames/commentsframe.cpp \ - mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp \ - mpeg/id3v2/frames/popularimeterframe.cpp \ - mpeg/id3v2/frames/privateframe.cpp \ - mpeg/id3v2/frames/relativevolumeframe.cpp \ - mpeg/id3v2/frames/textidentificationframe.cpp \ - mpeg/id3v2/frames/uniquefileidentifierframe.cpp \ - mpeg/id3v2/frames/unknownframe.cpp \ - mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp \ - mpeg/id3v2/frames/urllinkframe.cpp \ - mpeg/id3v2/id3v2extendedheader.cpp \ - mpeg/id3v2/id3v2footer.cpp \ - mpeg/id3v2/id3v2frame.cpp \ - mpeg/id3v2/id3v2framefactory.cpp \ - mpeg/id3v2/id3v2header.cpp \ - mpeg/id3v2/id3v2synchdata.cpp \ - mpeg/id3v2/id3v2tag.cpp \ - mpeg/mpegfile.cpp \ - mpeg/mpegheader.cpp \ - mpeg/mpegproperties.cpp \ - mpeg/xingheader.cpp \ - ogg/flac/oggflacfile.cpp \ - ogg/oggfile.cpp \ - ogg/oggpage.cpp \ - ogg/oggpageheader.cpp \ - ogg/speex/speexfile.cpp \ - ogg/speex/speexproperties.cpp \ - ogg/vorbis/vorbisfile.cpp \ - ogg/vorbis/vorbisproperties.cpp \ - ogg/xiphcomment.cpp \ - riff/aiff/aifffile.cpp \ - riff/aiff/aiffproperties.cpp \ - riff/rifffile.cpp \ - riff/wav/wavfile.cpp \ - riff/wav/wavproperties.cpp \ - tag.cpp \ - tagunion.cpp \ - toolkit/tbytevector.cpp \ - toolkit/tbytevectorlist.cpp \ - toolkit/tdebug.cpp \ - toolkit/tfile.cpp \ - toolkit/tstring.cpp \ - toolkit/tstringlist.cpp \ - toolkit/unicode.cpp \ - trueaudio/trueaudiofile.cpp \ - trueaudio/trueaudioproperties.cpp \ - wavpack/wavpackfile.cpp \ - wavpack/wavpackproperties.cpp - -FRAMEWORK_HEADERS.version = Versions -FRAMEWORK_HEADERS.files = \ - ape/apefooter.h \ - ape/apeitem.h \ - ape/apetag.h \ - asf/asfattribute.h \ - asf/asffile.h \ - asf/asfproperties.h \ - asf/asftag.h \ - asf/asfpicture.h \ - audioproperties.h \ - fileref.h \ - flac/flacfile.h \ - flac/flacproperties.h \ - mp4/mp4atom.h \ - mp4/mp4coverart.h \ - mp4/mp4file.h \ - mp4/mp4item.h \ - mp4/mp4properties.h \ - mp4/mp4tag.h \ - mpc/mpcfile.h \ - mpc/mpcproperties.h \ - mpeg/id3v1/id3v1genres.h \ - mpeg/id3v1/id3v1tag.h \ - mpeg/id3v2/frames/attachedpictureframe.h \ - mpeg/id3v2/frames/commentsframe.h \ - mpeg/id3v2/frames/generalencapsulatedobjectframe.h \ - mpeg/id3v2/frames/popularimeterframe.h \ - mpeg/id3v2/frames/privateframe.h \ - mpeg/id3v2/frames/relativevolumeframe.h \ - mpeg/id3v2/frames/textidentificationframe.h \ - mpeg/id3v2/frames/uniquefileidentifierframe.h \ - mpeg/id3v2/frames/unknownframe.h \ - mpeg/id3v2/frames/unsynchronizedlyricsframe.h \ - mpeg/id3v2/frames/urllinkframe.h \ - mpeg/id3v2/id3v2extendedheader.h \ - mpeg/id3v2/id3v2footer.h \ - mpeg/id3v2/id3v2frame.h \ - mpeg/id3v2/id3v2framefactory.h \ - mpeg/id3v2/id3v2header.h \ - mpeg/id3v2/id3v2synchdata.h \ - mpeg/id3v2/id3v2tag.h \ - mpeg/mpegfile.h \ - mpeg/mpegheader.h \ - mpeg/mpegproperties.h \ - mpeg/xingheader.h \ - ogg/flac/oggflacfile.h \ - ogg/oggfile.h \ - ogg/oggpage.h \ - ogg/oggpageheader.h \ - ogg/speex/speexfile.h \ - ogg/speex/speexproperties.h \ - ogg/vorbis/vorbisfile.h \ - ogg/vorbis/vorbisproperties.h \ - ogg/xiphcomment.h \ - riff/aiff/aifffile.h \ - riff/aiff/aiffproperties.h \ - riff/rifffile.h \ - riff/wav/wavfile.h \ - riff/wav/wavproperties.h \ - tag.h \ - taglib_export.h \ - tagunion.h \ - toolkit/taglib.h \ - toolkit/tbytevector.h \ - toolkit/tbytevectorlist.h \ - toolkit/tdebug.h \ - toolkit/tfile.h \ - toolkit/tlist.h \ - toolkit/tlist.tcc \ - toolkit/tmap.h \ - toolkit/tmap.tcc \ - toolkit/tstring.h \ - toolkit/tstringlist.h \ - toolkit/unicode.h \ - trueaudio/trueaudiofile.h \ - trueaudio/trueaudioproperties.h \ - wavpack/wavpackfile.h \ - wavpack/wavpackproperties.h - - FRAMEWORK_HEADERS.path = Headers - QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS diff -Nru taglib-1.7.2/taglib/taglib_config.h.cmake taglib-1.8/taglib/taglib_config.h.cmake --- taglib-1.7.2/taglib/taglib_config.h.cmake 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/taglib_config.h.cmake 2012-09-06 18:03:15.000000000 +0000 @@ -1,4 +1,4 @@ /* taglib_config.h. Generated by cmake from taglib_config.h.cmake */ -#cmakedefine TAGLIB_WITH_ASF 1 -#cmakedefine TAGLIB_WITH_MP4 1 +#define TAGLIB_WITH_ASF 1 +#define TAGLIB_WITH_MP4 1 diff -Nru taglib-1.7.2/taglib/tagunion.cpp taglib-1.8/taglib/tagunion.cpp --- taglib-1.7.2/taglib/tagunion.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/tagunion.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -24,6 +24,7 @@ ***************************************************************************/ #include "tagunion.h" +#include "tstringlist.h" using namespace TagLib; diff -Nru taglib-1.7.2/taglib/toolkit/CMakeLists.txt taglib-1.8/taglib/toolkit/CMakeLists.txt --- taglib-1.7.2/taglib/toolkit/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/toolkit/taglib.h taglib-1.8/taglib/toolkit/taglib.h --- taglib-1.7.2/taglib/toolkit/taglib.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/taglib.h 2012-09-06 18:03:15.000000000 +0000 @@ -44,11 +44,28 @@ #include +#ifdef __APPLE__ +# include +# define TAGLIB_ATOMIC_MAC +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define NOMINMAX +# include +# define TAGLIB_ATOMIC_WIN +#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 401) \ + && (defined(__i386__) || defined(__i486__) || defined(__i586__) || \ + defined(__i686__) || defined(__x86_64) || defined(__ia64)) \ + && !defined(__INTEL_COMPILER) +# define TAGLIB_ATOMIC_GCC +#elif defined(__ia64) && defined(__INTEL_COMPILER) +# include +# define TAGLIB_ATOMIC_GCC +#endif + //! A namespace for all TagLib related classes and functions /*! * This namespace contains everything in TagLib. For projects working with - * TagLib extensively it may be conveniten to add a + * TagLib extensively it may be convenient to add a * \code * using namespace TagLib; * \endcode @@ -59,9 +76,10 @@ class String; typedef wchar_t wchar; - typedef unsigned char uchar; - typedef unsigned int uint; - typedef unsigned long ulong; + typedef unsigned char uchar; + typedef unsigned short ushort; + typedef unsigned int uint; + typedef unsigned long ulong; /*! * Unfortunately std::wstring isn't defined on some systems, (i.e. GCC < 3) @@ -81,11 +99,33 @@ { public: RefCounter() : refCount(1) {} + +#ifdef TAGLIB_ATOMIC_MAC + void ref() { OSAtomicIncrement32Barrier(const_cast(&refCount)); } + bool deref() { return ! OSAtomicDecrement32Barrier(const_cast(&refCount)); } + int32_t count() { return refCount; } + private: + volatile int32_t refCount; +#elif defined(TAGLIB_ATOMIC_WIN) + void ref() { InterlockedIncrement(&refCount); } + bool deref() { return ! InterlockedDecrement(&refCount); } + long count() { return refCount; } + private: + volatile long refCount; +#elif defined(TAGLIB_ATOMIC_GCC) + void ref() { __sync_add_and_fetch(&refCount, 1); } + bool deref() { return ! __sync_sub_and_fetch(&refCount, 1); } + int count() { return refCount; } + private: + volatile int refCount; +#else void ref() { refCount++; } - bool deref() { return ! --refCount ; } + bool deref() { return ! --refCount; } int count() { return refCount; } private: uint refCount; +#endif + }; #endif // DO_NOT_DOCUMENT diff -Nru taglib-1.7.2/taglib/toolkit/tbytevector.cpp taglib-1.8/taglib/toolkit/tbytevector.cpp --- taglib-1.7.2/taglib/toolkit/tbytevector.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tbytevector.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -431,28 +431,62 @@ if(pattern.size() == 0 || pattern.size() > size()) return *this; - const int patternSize = pattern.size(); - const int withSize = with.size(); - - int offset = find(pattern); - - while(offset >= 0) { - - const int originalSize = size(); - - if(withSize > patternSize) - resize(originalSize + withSize - patternSize); + const uint withSize = with.size(); + const uint patternSize = pattern.size(); + int offset = 0; + + if(withSize == patternSize) { + // I think this case might be common enough to optimize it + detach(); + offset = find(pattern); + while(offset >= 0) { + ::memcpy(data() + offset, with.data(), withSize); + offset = find(pattern, offset + withSize); + } + return *this; + } - if(patternSize != withSize) - ::memcpy(data() + offset + withSize, mid(offset + patternSize).data(), originalSize - offset - patternSize); + // calculate new size: + uint newSize = 0; + for(;;) { + int next = find(pattern, offset); + if(next < 0) { + if(offset == 0) + // pattern not found, do nothing: + return *this; + newSize += size() - offset; + break; + } + newSize += (next - offset) + withSize; + offset = next + patternSize; + } - if(withSize < patternSize) - resize(originalSize + withSize - patternSize); + // new private data of appropriate size: + ByteVectorPrivate *newData = new ByteVectorPrivate(newSize, 0); + char *target = DATA(newData); + const char *source = data(); + + // copy modified data into new private data: + offset = 0; + for(;;) { + int next = find(pattern, offset); + if(next < 0) { + ::memcpy(target, source + offset, size() - offset); + break; + } + int chunkSize = next - offset; + ::memcpy(target, source + offset, chunkSize); + target += chunkSize; + ::memcpy(target, with.data(), withSize); + target += withSize; + offset += chunkSize + patternSize; + } - ::memcpy(data() + offset, with.data(), withSize); + // replace private data: + if(d->deref()) + delete d; - offset = find(pattern, offset + withSize); - } + d = newData; return *this; } diff -Nru taglib-1.7.2/taglib/toolkit/tbytevector.h taglib-1.8/taglib/toolkit/tbytevector.h --- taglib-1.7.2/taglib/toolkit/tbytevector.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tbytevector.h 2012-09-06 18:03:15.000000000 +0000 @@ -397,8 +397,8 @@ static ByteVector null; /*! - * Returns a hex-encoded copy of the byte vector. - */ + * Returns a hex-encoded copy of the byte vector. + */ ByteVector toHex() const; protected: diff -Nru taglib-1.7.2/taglib/toolkit/tbytevectorstream.cpp taglib-1.8/taglib/toolkit/tbytevectorstream.cpp --- taglib-1.7.2/taglib/toolkit/tbytevectorstream.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tbytevectorstream.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,167 @@ +/*************************************************************************** + copyright : (C) 2011 by Lukas Lalinsky + email : lalinsky@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "tbytevectorstream.h" +#include "tstring.h" +#include "tdebug.h" + +#include +#include + +#include + +using namespace TagLib; + +class ByteVectorStream::ByteVectorStreamPrivate +{ +public: + ByteVectorStreamPrivate(const ByteVector &data); + + ByteVector data; + long position; +}; + +ByteVectorStream::ByteVectorStreamPrivate::ByteVectorStreamPrivate(const ByteVector &data) : + data(data), + position(0) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +ByteVectorStream::ByteVectorStream(const ByteVector &data) +{ + d = new ByteVectorStreamPrivate(data); +} + +ByteVectorStream::~ByteVectorStream() +{ + delete d; +} + +FileName ByteVectorStream::name() const +{ + return FileName(""); // XXX do we need a name? +} + +ByteVector ByteVectorStream::readBlock(ulong length) +{ + if(length == 0) + return ByteVector::null; + + ByteVector v = d->data.mid(d->position, length); + d->position += v.size(); + return v; +} + +void ByteVectorStream::writeBlock(const ByteVector &data) +{ + uint size = data.size(); + if(long(d->position + size) > length()) { + truncate(d->position + size); + } + memcpy(d->data.data() + d->position, data.data(), size); + d->position += size; +} + +void ByteVectorStream::insert(const ByteVector &data, ulong start, ulong replace) +{ + long sizeDiff = data.size() - replace; + if(sizeDiff < 0) { + removeBlock(start + data.size(), -sizeDiff); + } + else if(sizeDiff > 0) { + truncate(length() + sizeDiff); + ulong readPosition = start + replace; + ulong writePosition = start + data.size(); + memmove(d->data.data() + writePosition, d->data.data() + readPosition, length() - sizeDiff - readPosition); + } + seek(start); + writeBlock(data); +} + +void ByteVectorStream::removeBlock(ulong start, ulong length) +{ + ulong readPosition = start + length; + ulong writePosition = start; + if(readPosition < ulong(ByteVectorStream::length())) { + ulong bytesToMove = ByteVectorStream::length() - readPosition; + memmove(d->data.data() + writePosition, d->data.data() + readPosition, bytesToMove); + writePosition += bytesToMove; + } + d->position = writePosition; + truncate(writePosition); +} + +bool ByteVectorStream::readOnly() const +{ + return false; +} + +bool ByteVectorStream::isOpen() const +{ + return true; +} + +void ByteVectorStream::seek(long offset, Position p) +{ + switch(p) { + case Beginning: + d->position = offset; + break; + case Current: + d->position += offset; + break; + case End: + d->position = length() - offset; + break; + } +} + +void ByteVectorStream::clear() +{ +} + +long ByteVectorStream::tell() const +{ + return d->position; +} + +long ByteVectorStream::length() +{ + return d->data.size(); +} + +void ByteVectorStream::truncate(long length) +{ + d->data.resize(length); +} + +ByteVector *ByteVectorStream::data() +{ + return &d->data; +} diff -Nru taglib-1.7.2/taglib/toolkit/tbytevectorstream.h taglib-1.8/taglib/toolkit/tbytevectorstream.h --- taglib-1.7.2/taglib/toolkit/tbytevectorstream.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tbytevectorstream.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,145 @@ +/*************************************************************************** + copyright : (C) 2011 by Lukas Lalinsky + email : lalinsky@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_BYTEVECTORSTREAM_H +#define TAGLIB_BYTEVECTORSTREAM_H + +#include "taglib_export.h" +#include "taglib.h" +#include "tbytevector.h" +#include "tiostream.h" + +namespace TagLib { + + class String; + class Tag; + class AudioProperties; + + //! In-memory Stream class using ByteVector for its storage. + + class TAGLIB_EXPORT ByteVectorStream : public IOStream + { + public: + /*! + * Construct a File object and opens the \a file. \a file should be a + * be a C-string in the local file system encoding. + */ + ByteVectorStream(const ByteVector &data); + + /*! + * Destroys this ByteVectorStream instance. + */ + virtual ~ByteVectorStream(); + + /*! + * Returns the file name in the local file system encoding. + */ + FileName name() const; + + /*! + * Reads a block of size \a length at the current get pointer. + */ + ByteVector readBlock(ulong length); + + /*! + * Attempts to write the block \a data at the current get pointer. If the + * file is currently only opened read only -- i.e. readOnly() returns true -- + * this attempts to reopen the file in read/write mode. + * + * \note This should be used instead of using the streaming output operator + * for a ByteVector. And even this function is significantly slower than + * doing output with a char[]. + */ + void writeBlock(const ByteVector &data); + + /*! + * Insert \a data at position \a start in the file overwriting \a replace + * bytes of the original content. + * + * \note This method is slow since it requires rewriting all of the file + * after the insertion point. + */ + void insert(const ByteVector &data, ulong start = 0, ulong replace = 0); + + /*! + * Removes a block of the file starting a \a start and continuing for + * \a length bytes. + * + * \note This method is slow since it involves rewriting all of the file + * after the removed portion. + */ + void removeBlock(ulong start = 0, ulong length = 0); + + /*! + * Returns true if the file is read only (or if the file can not be opened). + */ + bool readOnly() const; + + /*! + * Since the file can currently only be opened as an argument to the + * constructor (sort-of by design), this returns if that open succeeded. + */ + bool isOpen() const; + + /*! + * Move the I/O pointer to \a offset in the file from position \a p. This + * defaults to seeking from the beginning of the file. + * + * \see Position + */ + void seek(long offset, Position p = Beginning); + + /*! + * Reset the end-of-file and error flags on the file. + */ + void clear(); + + /*! + * Returns the current offset within the file. + */ + long tell() const; + + /*! + * Returns the length of the file. + */ + long length(); + + /*! + * Truncates the file to a \a length. + */ + void truncate(long length); + + ByteVector *data(); + + protected: + + private: + class ByteVectorStreamPrivate; + ByteVectorStreamPrivate *d; + }; + +} + +#endif diff -Nru taglib-1.7.2/taglib/toolkit/tfile.cpp taglib-1.8/taglib/toolkit/tfile.cpp --- taglib-1.7.2/taglib/toolkit/tfile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -24,8 +24,10 @@ ***************************************************************************/ #include "tfile.h" +#include "tfilestream.h" #include "tstring.h" #include "tdebug.h" +#include "tpropertymap.h" #include #include @@ -49,134 +51,196 @@ # define W_OK 2 #endif -using namespace TagLib; - -#ifdef _WIN32 - -typedef FileName FileNameHandle; +#include "asffile.h" +#include "mpegfile.h" +#include "vorbisfile.h" +#include "flacfile.h" +#include "oggflacfile.h" +#include "mpcfile.h" +#include "mp4file.h" +#include "wavpackfile.h" +#include "speexfile.h" +#include "trueaudiofile.h" +#include "aifffile.h" +#include "wavfile.h" +#include "apefile.h" +#include "modfile.h" +#include "s3mfile.h" +#include "itfile.h" +#include "xmfile.h" -#else - -struct FileNameHandle : public std::string -{ - FileNameHandle(FileName name) : std::string(name) {} - operator FileName () const { return c_str(); } -}; - -#endif +using namespace TagLib; class File::FilePrivate { public: - FilePrivate(FileName fileName); - - FILE *file; + FilePrivate(IOStream *stream, bool owner); - FileNameHandle name; - - bool readOnly; + IOStream *stream; + bool streamOwner; bool valid; - ulong size; static const uint bufferSize = 1024; }; -File::FilePrivate::FilePrivate(FileName fileName) : - file(0), - name(fileName), - readOnly(true), - valid(true), - size(0) +File::FilePrivate::FilePrivate(IOStream *stream, bool owner) : + stream(stream), + streamOwner(owner), + valid(true) { - // First try with read / write mode, if that fails, fall back to read only. - -#ifdef _WIN32 - - if(wcslen((const wchar_t *) fileName) > 0) { - - file = _wfopen(name, L"rb+"); - - if(file) - readOnly = false; - else - file = _wfopen(name, L"rb"); - - if(file) - return; - - } - -#endif - - file = fopen(name, "rb+"); - - if(file) - readOnly = false; - else - file = fopen(name, "rb"); - - if(!file) - debug("Could not open file " + String((const char *) name)); } //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// -File::File(FileName file) +File::File(FileName fileName) +{ + IOStream *stream = new FileStream(fileName); + d = new FilePrivate(stream, true); +} + +File::File(IOStream *stream) { - d = new FilePrivate(file); + d = new FilePrivate(stream, false); } File::~File() { - if(d->file) - fclose(d->file); + if(d->stream && d->streamOwner) + delete d->stream; delete d; } FileName File::name() const { - return d->name; + return d->stream->name(); } -ByteVector File::readBlock(ulong length) +PropertyMap File::properties() const { - if(!d->file) { - debug("File::readBlock() -- Invalid File"); - return ByteVector::null; - } - - if(length == 0) - return ByteVector::null; + // ugly workaround until this method is virtual + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + if(dynamic_cast(this)) + return dynamic_cast(this)->properties(); + // no specialized implementation available -> use generic one + // - ASF: ugly format, largely undocumented, not worth implementing + // dict interface ... + // - MP4: taglib's MP4::Tag does not really support anything beyond + // the basic implementation, therefor we use just the default Tag + // interface + return tag()->properties(); +} + +void File::removeUnsupportedProperties(const StringList &properties) +{ + // here we only consider those formats that could possibly contain + // unsupported properties + if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else if(dynamic_cast(this)) + dynamic_cast(this)->removeUnsupportedProperties(properties); + else + tag()->removeUnsupportedProperties(properties); +} - if(length > FilePrivate::bufferSize && - length > ulong(File::length())) - { - length = File::length(); - } +PropertyMap File::setProperties(const PropertyMap &properties) +{ + if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else if(dynamic_cast(this)) + return dynamic_cast(this)->setProperties(properties); + else + return tag()->setProperties(properties); +} - ByteVector v(static_cast(length)); - const int count = fread(v.data(), sizeof(char), length, d->file); - v.resize(count); - return v; +ByteVector File::readBlock(ulong length) +{ + return d->stream->readBlock(length); } void File::writeBlock(const ByteVector &data) { - if(!d->file) - return; - - if(d->readOnly) { - debug("File::writeBlock() -- attempted to write to a file that is not writable"); - return; - } - - fwrite(data.data(), sizeof(char), data.size(), d->file); + d->stream->writeBlock(data); } long File::find(const ByteVector &pattern, long fromOffset, const ByteVector &before) { - if(!d->file || pattern.size() > d->bufferSize) + if(!d->stream || pattern.size() > d->bufferSize) return -1; // The position in the file that the current buffer starts at. @@ -272,7 +336,7 @@ long File::rfind(const ByteVector &pattern, long fromOffset, const ByteVector &before) { - if(!d->file || pattern.size() > d->bufferSize) + if(!d->stream || pattern.size() > d->bufferSize) return -1; // The position in the file that the current buffer starts at. @@ -340,147 +404,22 @@ void File::insert(const ByteVector &data, ulong start, ulong replace) { - if(!d->file) - return; - - if(data.size() == replace) { - seek(start); - writeBlock(data); - return; - } - else if(data.size() < replace) { - seek(start); - writeBlock(data); - removeBlock(start + data.size(), replace - data.size()); - return; - } - - // Woohoo! Faster (about 20%) than id3lib at last. I had to get hardcore - // and avoid TagLib's high level API for rendering just copying parts of - // the file that don't contain tag data. - // - // Now I'll explain the steps in this ugliness: - - // First, make sure that we're working with a buffer that is longer than - // the *differnce* in the tag sizes. We want to avoid overwriting parts - // that aren't yet in memory, so this is necessary. - - ulong bufferLength = bufferSize(); - - while(data.size() - replace > bufferLength) - bufferLength += bufferSize(); - - // Set where to start the reading and writing. - - long readPosition = start + replace; - long writePosition = start; - - ByteVector buffer; - ByteVector aboutToOverwrite(static_cast(bufferLength)); - - // This is basically a special case of the loop below. Here we're just - // doing the same steps as below, but since we aren't using the same buffer - // size -- instead we're using the tag size -- this has to be handled as a - // special case. We're also using File::writeBlock() just for the tag. - // That's a bit slower than using char *'s so, we're only doing it here. - - seek(readPosition); - int bytesRead = fread(aboutToOverwrite.data(), sizeof(char), bufferLength, d->file); - readPosition += bufferLength; - - seek(writePosition); - writeBlock(data); - writePosition += data.size(); - - buffer = aboutToOverwrite; - - // In case we've already reached the end of file... - - buffer.resize(bytesRead); - - // Ok, here's the main loop. We want to loop until the read fails, which - // means that we hit the end of the file. - - while(!buffer.isEmpty()) { - - // Seek to the current read position and read the data that we're about - // to overwrite. Appropriately increment the readPosition. - - seek(readPosition); - bytesRead = fread(aboutToOverwrite.data(), sizeof(char), bufferLength, d->file); - aboutToOverwrite.resize(bytesRead); - readPosition += bufferLength; - - // Check to see if we just read the last block. We need to call clear() - // if we did so that the last write succeeds. - - if(ulong(bytesRead) < bufferLength) - clear(); - - // Seek to the write position and write our buffer. Increment the - // writePosition. - - seek(writePosition); - fwrite(buffer.data(), sizeof(char), buffer.size(), d->file); - writePosition += buffer.size(); - - // Make the current buffer the data that we read in the beginning. - - buffer = aboutToOverwrite; - - // Again, we need this for the last write. We don't want to write garbage - // at the end of our file, so we need to set the buffer size to the amount - // that we actually read. - - bufferLength = bytesRead; - } + d->stream->insert(data, start, replace); } void File::removeBlock(ulong start, ulong length) { - if(!d->file) - return; - - ulong bufferLength = bufferSize(); - - long readPosition = start + length; - long writePosition = start; - - ByteVector buffer(static_cast(bufferLength)); - - ulong bytesRead = 1; - - while(bytesRead != 0) { - seek(readPosition); - bytesRead = fread(buffer.data(), sizeof(char), bufferLength, d->file); - readPosition += bytesRead; - - // Check to see if we just read the last block. We need to call clear() - // if we did so that the last write succeeds. - - if(bytesRead < bufferLength) - clear(); - - seek(writePosition); - fwrite(buffer.data(), sizeof(char), bytesRead, d->file); - writePosition += bytesRead; - } - truncate(writePosition); + d->stream->removeBlock(start, length); } bool File::readOnly() const { - return d->readOnly; -} - -bool File::isReadable(const char *file) -{ - return access(file, R_OK) == 0; + return d->stream->readOnly(); } bool File::isOpen() const { - return (d->file != NULL); + return d->stream->isOpen(); } bool File::isValid() const @@ -490,75 +429,70 @@ void File::seek(long offset, Position p) { - if(!d->file) { - debug("File::seek() -- trying to seek in a file that isn't opened."); - return; - } + d->stream->seek(offset, IOStream::Position(p)); +} - switch(p) { - case Beginning: - fseek(d->file, offset, SEEK_SET); - break; - case Current: - fseek(d->file, offset, SEEK_CUR); - break; - case End: - fseek(d->file, offset, SEEK_END); - break; - } +void File::truncate(long length) +{ + d->stream->truncate(length); } void File::clear() { - clearerr(d->file); + d->stream->clear(); } long File::tell() const { - return ftell(d->file); + return d->stream->tell(); } long File::length() { - // Do some caching in case we do multiple calls. + return d->stream->length(); +} - if(d->size > 0) - return d->size; +bool File::isReadable(const char *file) +{ - if(!d->file) - return 0; +#if defined(_MSC_VER) && (_MSC_VER >= 1400) // VC++2005 or later - long curpos = tell(); + return _access_s(file, R_OK) == 0; - seek(0, End); - long endpos = tell(); +#else - seek(curpos, Beginning); + return access(file, R_OK) == 0; + +#endif - d->size = endpos; - return endpos; } bool File::isWritable(const char *file) { + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) // VC++2005 or later + + return _access_s(file, W_OK) == 0; + +#else + return access(file, W_OK) == 0; + +#endif + } //////////////////////////////////////////////////////////////////////////////// // protected members //////////////////////////////////////////////////////////////////////////////// -void File::setValid(bool valid) +TagLib::uint File::bufferSize() { - d->valid = valid; + return FilePrivate::bufferSize; } -void File::truncate(long length) +void File::setValid(bool valid) { - ftruncate(fileno(d->file), length); + d->valid = valid; } -TagLib::uint File::bufferSize() -{ - return FilePrivate::bufferSize; -} diff -Nru taglib-1.7.2/taglib/toolkit/tfile.h taglib-1.8/taglib/toolkit/tfile.h --- taglib-1.7.2/taglib/toolkit/tfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -28,29 +28,16 @@ #include "taglib_export.h" #include "taglib.h" +#include "tag.h" #include "tbytevector.h" +#include "tiostream.h" namespace TagLib { class String; class Tag; class AudioProperties; - -#ifdef _WIN32 - class TAGLIB_EXPORT FileName - { - public: - FileName(const wchar_t *name) : m_wname(name) {} - FileName(const char *name) : m_name(name) {} - operator const wchar_t *() const { return m_wname.c_str(); } - operator const char *() const { return m_name.c_str(); } - private: - std::string m_name; - std::wstring m_wname; - }; -#else - typedef const char *FileName; -#endif + class PropertyMap; //! A file class with some useful methods for tag manipulation @@ -92,6 +79,36 @@ virtual Tag *tag() const = 0; /*! + * Exports the tags of the file as dictionary mapping (human readable) tag + * names (Strings) to StringLists of tag values. Calls the according specialization + * in the File subclasses. + * For each metadata object of the file that could not be parsed into the PropertyMap + * format, the returend map's unsupportedData() list will contain one entry identifying + * that object (e.g. the frame type for ID3v2 tags). Use removeUnsupportedProperties() + * to remove (a subset of) them. + * BIC: Will be made virtual in future releases. + */ + PropertyMap properties() const; + + /*! + * Removes unsupported properties, or a subset of them, from the file's metadata. + * The parameter \a properties must contain only entries from + * properties().unsupportedData(). + * BIC: Will be mad virtual in future releases. + */ + void removeUnsupportedProperties(const StringList& properties); + + /*! + * Sets the tags of this File to those specified in \a properties. Calls the + * according specialization method in the subclasses of File to do the translation + * into the format-specific details. + * If some value(s) could not be written imported to the specific metadata format, + * the returned PropertyMap will contain those value(s). Otherwise it will be empty, + * indicating that no problems occured. + * BIC: will become pure virtual in the future + */ + PropertyMap setProperties(const PropertyMap &properties); + /*! * Returns a pointer to this file's audio properties. This should be * reimplemented in the concrete subclasses. If no audio properties were * read then this will return a null pointer. @@ -241,6 +258,17 @@ File(FileName file); /*! + * Construct a File object and use the \a stream instance. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note Constructor is protected since this class should only be + * instantiated through subclasses. + */ + File(IOStream *stream); + + /*! * Marks the file as valid or invalid. * * \see isValid() diff -Nru taglib-1.7.2/taglib/toolkit/tfilestream.cpp taglib-1.8/taglib/toolkit/tfilestream.cpp --- taglib-1.7.2/taglib/toolkit/tfilestream.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tfilestream.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,417 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.org + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "tfilestream.h" +#include "tstring.h" +#include "tdebug.h" + +#include +#include +#include + +#ifdef _WIN32 +# include +# include +# include +# define ftruncate _chsize +#else +# include +#endif + +#include + +#ifndef R_OK +# define R_OK 4 +#endif +#ifndef W_OK +# define W_OK 2 +#endif + +using namespace TagLib; + +#ifdef _WIN32 + +typedef FileName FileNameHandle; + +#else + +struct FileNameHandle : public std::string +{ + FileNameHandle(FileName name) : std::string(name) {} + operator FileName () const { return c_str(); } +}; + +#endif + +namespace { + FILE *openFile(const FileName &path, bool readOnly) + { + // Calls a proper variation of fopen() depending on the compiling environment. + +#if defined(_WIN32) + +# if defined(_MSC_VER) && (_MSC_VER >= 1400) + + // Visual C++ 2005 or later. + + FILE *file; + errno_t err; + + if(wcslen(path) > 0) + err = _wfopen_s(&file, path, readOnly ? L"rb" : L"rb+"); + else + err = fopen_s(&file, path, readOnly ? "rb" : "rb+"); + + if(err == 0) + return file; + else + return NULL; + +# else // defined(_MSC_VER) && (_MSC_VER >= 1400) + + // Visual C++.NET 2003 or earlier. + + if(wcslen(path) > 0) + return _wfopen(path, readOnly ? L"rb" : L"rb+"); + else + return fopen(path, readOnly ? "rb" : "rb+"); + +# endif // defined(_MSC_VER) && (_MSC_VER >= 1400) + +#else // defined(_WIN32) + + // Non-Win32 + + return fopen(path, readOnly ? "rb" : "rb+"); + +#endif // defined(_WIN32) + } +} + +class FileStream::FileStreamPrivate +{ +public: + FileStreamPrivate(FileName fileName, bool openReadOnly); + + FILE *file; + + FileNameHandle name; + + bool readOnly; + ulong size; + static const uint bufferSize = 1024; +}; + +FileStream::FileStreamPrivate::FileStreamPrivate(FileName fileName, bool openReadOnly) : + file(0), + name(fileName), + readOnly(true), + size(0) +{ + // First try with read / write mode, if that fails, fall back to read only. + + if(!openReadOnly) + file = openFile(name, false); + + if(file) + readOnly = false; + else + file = openFile(name, true); + + if(!file) { + debug("Could not open file " + String((const char *) name)); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +FileStream::FileStream(FileName file, bool openReadOnly) +{ + d = new FileStreamPrivate(file, openReadOnly); +} + +FileStream::~FileStream() +{ + if(d->file) + fclose(d->file); + delete d; +} + +FileName FileStream::name() const +{ + return d->name; +} + +ByteVector FileStream::readBlock(ulong length) +{ + if(!d->file) { + debug("FileStream::readBlock() -- Invalid File"); + return ByteVector::null; + } + + if(length == 0) + return ByteVector::null; + + if(length > FileStreamPrivate::bufferSize && + length > ulong(FileStream::length())) + { + length = FileStream::length(); + } + + ByteVector v(static_cast(length)); + const int count = fread(v.data(), sizeof(char), length, d->file); + v.resize(count); + return v; +} + +void FileStream::writeBlock(const ByteVector &data) +{ + if(!d->file) + return; + + if(d->readOnly) { + debug("File::writeBlock() -- attempted to write to a file that is not writable"); + return; + } + + fwrite(data.data(), sizeof(char), data.size(), d->file); +} + +void FileStream::insert(const ByteVector &data, ulong start, ulong replace) +{ + if(!d->file) + return; + + if(data.size() == replace) { + seek(start); + writeBlock(data); + return; + } + else if(data.size() < replace) { + seek(start); + writeBlock(data); + removeBlock(start + data.size(), replace - data.size()); + return; + } + + // Woohoo! Faster (about 20%) than id3lib at last. I had to get hardcore + // and avoid TagLib's high level API for rendering just copying parts of + // the file that don't contain tag data. + // + // Now I'll explain the steps in this ugliness: + + // First, make sure that we're working with a buffer that is longer than + // the *differnce* in the tag sizes. We want to avoid overwriting parts + // that aren't yet in memory, so this is necessary. + + ulong bufferLength = bufferSize(); + + while(data.size() - replace > bufferLength) + bufferLength += bufferSize(); + + // Set where to start the reading and writing. + + long readPosition = start + replace; + long writePosition = start; + + ByteVector buffer; + ByteVector aboutToOverwrite(static_cast(bufferLength)); + + // This is basically a special case of the loop below. Here we're just + // doing the same steps as below, but since we aren't using the same buffer + // size -- instead we're using the tag size -- this has to be handled as a + // special case. We're also using File::writeBlock() just for the tag. + // That's a bit slower than using char *'s so, we're only doing it here. + + seek(readPosition); + int bytesRead = fread(aboutToOverwrite.data(), sizeof(char), bufferLength, d->file); + readPosition += bufferLength; + + seek(writePosition); + writeBlock(data); + writePosition += data.size(); + + buffer = aboutToOverwrite; + + // In case we've already reached the end of file... + + buffer.resize(bytesRead); + + // Ok, here's the main loop. We want to loop until the read fails, which + // means that we hit the end of the file. + + while(!buffer.isEmpty()) { + + // Seek to the current read position and read the data that we're about + // to overwrite. Appropriately increment the readPosition. + + seek(readPosition); + bytesRead = fread(aboutToOverwrite.data(), sizeof(char), bufferLength, d->file); + aboutToOverwrite.resize(bytesRead); + readPosition += bufferLength; + + // Check to see if we just read the last block. We need to call clear() + // if we did so that the last write succeeds. + + if(ulong(bytesRead) < bufferLength) + clear(); + + // Seek to the write position and write our buffer. Increment the + // writePosition. + + seek(writePosition); + fwrite(buffer.data(), sizeof(char), buffer.size(), d->file); + writePosition += buffer.size(); + + // Make the current buffer the data that we read in the beginning. + + buffer = aboutToOverwrite; + + // Again, we need this for the last write. We don't want to write garbage + // at the end of our file, so we need to set the buffer size to the amount + // that we actually read. + + bufferLength = bytesRead; + } +} + +void FileStream::removeBlock(ulong start, ulong length) +{ + if(!d->file) + return; + + ulong bufferLength = bufferSize(); + + long readPosition = start + length; + long writePosition = start; + + ByteVector buffer(static_cast(bufferLength)); + + ulong bytesRead = 1; + + while(bytesRead != 0) { + seek(readPosition); + bytesRead = fread(buffer.data(), sizeof(char), bufferLength, d->file); + readPosition += bytesRead; + + // Check to see if we just read the last block. We need to call clear() + // if we did so that the last write succeeds. + + if(bytesRead < bufferLength) + clear(); + + seek(writePosition); + fwrite(buffer.data(), sizeof(char), bytesRead, d->file); + writePosition += bytesRead; + } + truncate(writePosition); +} + +bool FileStream::readOnly() const +{ + return d->readOnly; +} + +bool FileStream::isOpen() const +{ + return (d->file != NULL); +} + +void FileStream::seek(long offset, Position p) +{ + if(!d->file) { + debug("File::seek() -- trying to seek in a file that isn't opened."); + return; + } + + switch(p) { + case Beginning: + fseek(d->file, offset, SEEK_SET); + break; + case Current: + fseek(d->file, offset, SEEK_CUR); + break; + case End: + fseek(d->file, offset, SEEK_END); + break; + } +} + +void FileStream::clear() +{ + clearerr(d->file); +} + +long FileStream::tell() const +{ + return ftell(d->file); +} + +long FileStream::length() +{ + // Do some caching in case we do multiple calls. + + if(d->size > 0) + return d->size; + + if(!d->file) + return 0; + + long curpos = tell(); + + seek(0, End); + long endpos = tell(); + + seek(curpos, Beginning); + + d->size = endpos; + return endpos; +} + +//////////////////////////////////////////////////////////////////////////////// +// protected members +//////////////////////////////////////////////////////////////////////////////// + +void FileStream::truncate(long length) +{ + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) // VC++2005 or later + + ftruncate(_fileno(d->file), length); + +#else + + ftruncate(fileno(d->file), length); + +#endif + +} + +TagLib::uint FileStream::bufferSize() +{ + return FileStreamPrivate::bufferSize; +} diff -Nru taglib-1.7.2/taglib/toolkit/tfilestream.h taglib-1.8/taglib/toolkit/tfilestream.h --- taglib-1.7.2/taglib/toolkit/tfilestream.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tfilestream.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,154 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.org + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_FILESTREAM_H +#define TAGLIB_FILESTREAM_H + +#include "taglib_export.h" +#include "taglib.h" +#include "tbytevector.h" +#include "tiostream.h" + +namespace TagLib { + + class String; + class Tag; + class AudioProperties; + + //! A file class with some useful methods for tag manipulation + + /*! + * This class is a basic file class with some methods that are particularly + * useful for tag editors. It has methods to take advantage of + * ByteVector and a binary search method for finding patterns in a file. + */ + + class TAGLIB_EXPORT FileStream : public IOStream + { + public: + /*! + * Construct a File object and opens the \a file. \a file should be a + * be a C-string in the local file system encoding. + */ + FileStream(FileName file, bool openReadOnly = false); + + /*! + * Destroys this FileStream instance. + */ + virtual ~FileStream(); + + /*! + * Returns the file name in the local file system encoding. + */ + FileName name() const; + + /*! + * Reads a block of size \a length at the current get pointer. + */ + ByteVector readBlock(ulong length); + + /*! + * Attempts to write the block \a data at the current get pointer. If the + * file is currently only opened read only -- i.e. readOnly() returns true -- + * this attempts to reopen the file in read/write mode. + * + * \note This should be used instead of using the streaming output operator + * for a ByteVector. And even this function is significantly slower than + * doing output with a char[]. + */ + void writeBlock(const ByteVector &data); + + /*! + * Insert \a data at position \a start in the file overwriting \a replace + * bytes of the original content. + * + * \note This method is slow since it requires rewriting all of the file + * after the insertion point. + */ + void insert(const ByteVector &data, ulong start = 0, ulong replace = 0); + + /*! + * Removes a block of the file starting a \a start and continuing for + * \a length bytes. + * + * \note This method is slow since it involves rewriting all of the file + * after the removed portion. + */ + void removeBlock(ulong start = 0, ulong length = 0); + + /*! + * Returns true if the file is read only (or if the file can not be opened). + */ + bool readOnly() const; + + /*! + * Since the file can currently only be opened as an argument to the + * constructor (sort-of by design), this returns if that open succeeded. + */ + bool isOpen() const; + + /*! + * Move the I/O pointer to \a offset in the file from position \a p. This + * defaults to seeking from the beginning of the file. + * + * \see Position + */ + void seek(long offset, Position p = Beginning); + + /*! + * Reset the end-of-file and error flags on the file. + */ + void clear(); + + /*! + * Returns the current offset within the file. + */ + long tell() const; + + /*! + * Returns the length of the file. + */ + long length(); + + /*! + * Truncates the file to a \a length. + */ + void truncate(long length); + + protected: + + /*! + * Returns the buffer size that is used for internal buffering. + */ + static uint bufferSize(); + + private: + class FileStreamPrivate; + FileStreamPrivate *d; + }; + +} + +#endif diff -Nru taglib-1.7.2/taglib/toolkit/tiostream.cpp taglib-1.8/taglib/toolkit/tiostream.cpp --- taglib-1.7.2/taglib/toolkit/tiostream.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tiostream.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,45 @@ +/*************************************************************************** + copyright : (C) 2011 by Lukas Lalinsky + email : lalinsky@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "tiostream.h" + +using namespace TagLib; + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +IOStream::IOStream() +{ +} + +IOStream::~IOStream() +{ +} + +void IOStream::clear() +{ +} + diff -Nru taglib-1.7.2/taglib/toolkit/tiostream.h taglib-1.8/taglib/toolkit/tiostream.h --- taglib-1.7.2/taglib/toolkit/tiostream.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tiostream.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,160 @@ +/*************************************************************************** + copyright : (C) 2011 by Lukas Lalinsky + email : lalinsky@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_IOSTREAM_H +#define TAGLIB_IOSTREAM_H + +#include "taglib_export.h" +#include "taglib.h" +#include "tbytevector.h" + +namespace TagLib { + +#ifdef _WIN32 + class TAGLIB_EXPORT FileName + { + public: + FileName(const wchar_t *name) : m_wname(name) {} + FileName(const char *name) : m_name(name) {} + operator const wchar_t *() const { return m_wname.c_str(); } + operator const char *() const { return m_name.c_str(); } + private: + std::string m_name; + std::wstring m_wname; + }; +#else + typedef const char *FileName; +#endif + + //! An abstract class that provides operations on a sequence of bytes + + class TAGLIB_EXPORT IOStream + { + public: + /*! + * Position in the file used for seeking. + */ + enum Position { + //! Seek from the beginning of the file. + Beginning, + //! Seek from the current position in the file. + Current, + //! Seek from the end of the file. + End + }; + + IOStream(); + + /*! + * Destroys this IOStream instance. + */ + virtual ~IOStream(); + + /*! + * Returns the stream name in the local file system encoding. + */ + virtual FileName name() const = 0; + + /*! + * Reads a block of size \a length at the current get pointer. + */ + virtual ByteVector readBlock(ulong length) = 0; + + /*! + * Attempts to write the block \a data at the current get pointer. If the + * file is currently only opened read only -- i.e. readOnly() returns true -- + * this attempts to reopen the file in read/write mode. + * + * \note This should be used instead of using the streaming output operator + * for a ByteVector. And even this function is significantly slower than + * doing output with a char[]. + */ + virtual void writeBlock(const ByteVector &data) = 0; + + /*! + * Insert \a data at position \a start in the file overwriting \a replace + * bytes of the original content. + * + * \note This method is slow since it requires rewriting all of the file + * after the insertion point. + */ + virtual void insert(const ByteVector &data, ulong start = 0, ulong replace = 0) = 0; + + /*! + * Removes a block of the file starting a \a start and continuing for + * \a length bytes. + * + * \note This method is slow since it involves rewriting all of the file + * after the removed portion. + */ + virtual void removeBlock(ulong start = 0, ulong length = 0) = 0; + + /*! + * Returns true if the file is read only (or if the file can not be opened). + */ + virtual bool readOnly() const = 0; + + /*! + * Since the file can currently only be opened as an argument to the + * constructor (sort-of by design), this returns if that open succeeded. + */ + virtual bool isOpen() const = 0; + + /*! + * Move the I/O pointer to \a offset in the stream from position \a p. This + * defaults to seeking from the beginning of the stream. + * + * \see Position + */ + virtual void seek(long offset, Position p = Beginning) = 0; + + /*! + * Reset the end-of-stream and error flags on the stream. + */ + virtual void clear(); + + /*! + * Returns the current offset within the stream. + */ + virtual long tell() const = 0; + + /*! + * Returns the length of the stream. + */ + virtual long length() = 0; + + /*! + * Truncates the stream to a \a length. + */ + virtual void truncate(long length) = 0; + + private: + IOStream(const IOStream &); + IOStream &operator=(const IOStream &); + }; + +} + +#endif diff -Nru taglib-1.7.2/taglib/toolkit/tlist.h taglib-1.8/taglib/toolkit/tlist.h --- taglib-1.7.2/taglib/toolkit/tlist.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tlist.h 2012-09-06 18:03:15.000000000 +0000 @@ -227,6 +227,11 @@ */ bool operator==(const List &l) const; + /*! + * Compares this list with \a l and returns true if the lists differ. + */ + bool operator!=(const List &l) const; + protected: /* * If this List is being shared via implicit sharing, do a deep copy of the diff -Nru taglib-1.7.2/taglib/toolkit/tlist.tcc taglib-1.8/taglib/toolkit/tlist.tcc --- taglib-1.7.2/taglib/toolkit/tlist.tcc 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tlist.tcc 2012-09-06 18:03:15.000000000 +0000 @@ -300,6 +300,12 @@ return d->list == l.d->list; } +template +bool List::operator!=(const List &l) const +{ + return d->list != l.d->list; +} + //////////////////////////////////////////////////////////////////////////////// // protected members //////////////////////////////////////////////////////////////////////////////// diff -Nru taglib-1.7.2/taglib/toolkit/tmap.h taglib-1.8/taglib/toolkit/tmap.h --- taglib-1.7.2/taglib/toolkit/tmap.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tmap.h 2012-09-06 18:03:15.000000000 +0000 @@ -27,7 +27,6 @@ #define TAGLIB_MAP_H #include -using namespace std; #include "taglib.h" diff -Nru taglib-1.7.2/taglib/toolkit/tpropertymap.cpp taglib-1.8/taglib/toolkit/tpropertymap.cpp --- taglib-1.7.2/taglib/toolkit/tpropertymap.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tpropertymap.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,173 @@ +/*************************************************************************** + copyright : (C) 2012 by Michael Helmling + email : helmling@mathematik.uni-kl.de + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "tpropertymap.h" +using namespace TagLib; + + +PropertyMap::PropertyMap() : SimplePropertyMap() +{ +} + +PropertyMap::PropertyMap(const PropertyMap &m) : SimplePropertyMap(m), unsupported(m.unsupported) +{ +} + +PropertyMap::PropertyMap(const SimplePropertyMap &m) +{ + for(SimplePropertyMap::ConstIterator it = m.begin(); it != m.end(); ++it){ + String key = it->first.upper(); + if(!key.isNull()) + insert(it->first, it->second); + else + unsupported.append(it->first); + } +} + +PropertyMap::~PropertyMap() +{ +} + +bool PropertyMap::insert(const String &key, const StringList &values) +{ + String realKey = key.upper(); + Iterator result = SimplePropertyMap::find(realKey); + if(result == end()) + SimplePropertyMap::insert(realKey, values); + else + SimplePropertyMap::operator[](realKey).append(values); + return true; +} + +bool PropertyMap::replace(const String &key, const StringList &values) +{ + String realKey = key.upper(); + SimplePropertyMap::erase(realKey); + SimplePropertyMap::insert(realKey, values); + return true; +} + +PropertyMap::Iterator PropertyMap::find(const String &key) +{ + return SimplePropertyMap::find(key.upper()); +} + +PropertyMap::ConstIterator PropertyMap::find(const String &key) const +{ + return SimplePropertyMap::find(key.upper()); +} + +bool PropertyMap::contains(const String &key) const +{ + return SimplePropertyMap::contains(key.upper()); +} + +bool PropertyMap::contains(const PropertyMap &other) const +{ + for(ConstIterator it = other.begin(); it != other.end(); ++it) { + if(!SimplePropertyMap::contains(it->first)) + return false; + if ((*this)[it->first] != it->second) + return false; + } + return true; +} + +PropertyMap &PropertyMap::erase(const String &key) +{ + SimplePropertyMap::erase(key.upper()); + return *this; +} + +PropertyMap &PropertyMap::erase(const PropertyMap &other) +{ + for(ConstIterator it = other.begin(); it != other.end(); ++it) + erase(it->first); + return *this; +} + +PropertyMap &PropertyMap::merge(const PropertyMap &other) +{ + for(PropertyMap::ConstIterator it = other.begin(); it != other.end(); ++it) + insert(it->first, it->second); + unsupported.append(other.unsupported); + return *this; +} + +const StringList &PropertyMap::operator[](const String &key) const +{ + return SimplePropertyMap::operator[](key.upper()); +} + +StringList &PropertyMap::operator[](const String &key) +{ + return SimplePropertyMap::operator[](key.upper()); +} + +bool PropertyMap::operator==(const PropertyMap &other) const +{ + for(ConstIterator it = other.begin(); it != other.end(); ++it) { + ConstIterator thisFind = find(it->first); + if( thisFind == end() || (thisFind->second != it->second) ) + return false; + } + for(ConstIterator it = begin(); it != end(); ++it) { + ConstIterator otherFind = other.find(it->first); + if( otherFind == other.end() || (otherFind->second != it->second) ) + return false; + } + return unsupported == other.unsupported; +} + +bool PropertyMap::operator!=(const PropertyMap &other) const +{ + return !(*this == other); +} + +String PropertyMap::toString() const +{ + String ret = ""; + for(ConstIterator it = begin(); it != end(); ++it) + ret += it->first+"="+it->second.toString(", ") + "\n"; + if(!unsupported.isEmpty()) + ret += "Unsupported Data: " + unsupported.toString(", ") + "\n"; + return ret; +} + +void PropertyMap::removeEmpty() +{ + StringList emptyKeys; + for(Iterator it = begin(); it != end(); ++it) + if(it->second.isEmpty()) + emptyKeys.append(it->first); + for(StringList::Iterator emptyIt = emptyKeys.begin(); emptyIt != emptyKeys.end(); emptyIt++ ) + erase(*emptyIt); +} + +StringList &PropertyMap::unsupportedData() +{ + return unsupported; +} + +const StringList &PropertyMap::unsupportedData() const +{ + return unsupported; +} diff -Nru taglib-1.7.2/taglib/toolkit/tpropertymap.h taglib-1.8/taglib/toolkit/tpropertymap.h --- taglib-1.7.2/taglib/toolkit/tpropertymap.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tpropertymap.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,174 @@ +/*************************************************************************** + copyright : (C) 2012 by Michael Helmling + email : helmling@mathematik.uni-kl.de + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef PROPERTYMAP_H_ +#define PROPERTYMAP_H_ + +#include "tmap.h" +#include "tstringlist.h" + +namespace TagLib { + + typedef Map SimplePropertyMap; + + //! A map for format-independent tag representations. + + /*! + * This map implements a generic representation of textual audio metadata + * ("tags") realized as pairs of a case-insensitive key + * and a nonempty list of corresponding values, each value being an an arbitrary + * unicode String. + * + * Note that most metadata formats pose additional conditions on the tag keys. The + * most popular ones (Vorbis, APE, ID3v2) should support all ASCII only words of + * length between 2 and 16. + */ + + class TAGLIB_EXPORT PropertyMap: public SimplePropertyMap + { + public: + + typedef SimplePropertyMap::Iterator Iterator; + typedef SimplePropertyMap::ConstIterator ConstIterator; + + PropertyMap(); + + PropertyMap(const PropertyMap &m); + + /*! + * Creates a PropertyMap initialized from a SimplePropertyMap. Copies all + * entries from \a m that have valid keys. + * Invalid keys will be appended to the unsupportedData() list. + */ + PropertyMap(const SimplePropertyMap &m); + + virtual ~PropertyMap(); + + /*! + * Inserts \a values under \a key in the map. If \a key already exists, + * then \values will be appended to the existing StringList. + * The returned value indicates success, i.e. whether \a key is a + * valid key. + */ + bool insert(const String &key, const StringList &values); + + /*! + * Replaces any existing values for \a key with the given \a values, + * and simply insert them if \a key did not exist before. + * The returned value indicates success, i.e. whether \a key is a + * valid key. + */ + bool replace(const String &key, const StringList &values); + + /*! + * Find the first occurrence of \a key. + */ + Iterator find(const String &key); + + /*! + * Find the first occurrence of \a key. + */ + ConstIterator find(const String &key) const; + + /*! + * Returns true if the map contains values for \a key. + */ + bool contains(const String &key) const; + + /*! + * Returns true if this map contains all keys of \a other + * and the values coincide for that keys. Does not take + * the unsupportedData list into account. + */ + bool contains(const PropertyMap &other) const; + + /*! + * Erase the \a key and its values from the map. + */ + PropertyMap &erase(const String &key); + + /*! + * Erases from this map all keys that appear in \a other. + */ + PropertyMap &erase(const PropertyMap &other); + + /*! + * Merge the contents of \a other into this PropertyMap. + * If a key is contained in both maps, the values of the second + * are appended to that of the first. + * The unsupportedData() lists are concatenated as well. + */ + PropertyMap &merge(const PropertyMap &other); + + /*! + * Returns a reference to the value associated with \a key. + * + * \note: If \a key is not contained in the map, an empty + * StringList is returned without error. + */ + const StringList &operator[](const String &key) const; + + /*! + * Returns a reference to the value associated with \a key. + * + * \note: If \a key is not contained in the map, an empty + * StringList is returned. You can also directly add entries + * by using this function as an lvalue. + */ + StringList &operator[](const String &key); + + /*! + * Returns true if and only if \other has the same contents as this map. + */ + bool operator==(const PropertyMap &other) const; + + /*! + * Returns false if and only \other has the same contents as this map. + */ + bool operator!=(const PropertyMap &other) const; + + /*! + * If a PropertyMap is read from a File object using File::properties(), + * the StringList returned from this function will represent metadata + * that could not be parsed into the PropertyMap representation. This could + * be e.g. binary data, unknown ID3 frames, etc. + * You can remove items from the returned list, which tells TagLib to remove + * those unsupported elements if you call File::setProperties() with the + * same PropertyMap as argument. + */ + StringList &unsupportedData(); + const StringList &unsupportedData() const; + + /*! + * Removes all entries which have an empty value list. + */ + void removeEmpty(); + + String toString() const; + + private: + + + StringList unsupported; + }; + +} +#endif /* PROPERTYMAP_H_ */ diff -Nru taglib-1.7.2/taglib/toolkit/tstring.cpp taglib-1.8/taglib/toolkit/tstring.cpp --- taglib-1.7.2/taglib/toolkit/tstring.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tstring.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -26,6 +26,7 @@ #include "tstring.h" #include "unicode.h" #include "tdebug.h" +#include "tstringlist.h" #include @@ -232,8 +233,9 @@ &target, targetBuffer + outputBufferSize, Unicode::lenientConversion); - if(result != Unicode::conversionOK) + if(result != Unicode::conversionOK) { debug("String::to8Bit() - Unicode conversion error."); + } int newSize = target - targetBuffer; s.resize(newSize); @@ -258,8 +260,17 @@ std::string buffer = to8Bit(unicode); d->CString = new char[buffer.size() + 1]; + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) // VC++2005 or later + + strcpy_s(d->CString, buffer.size() + 1, buffer.c_str()); + +#else + strcpy(d->CString, buffer.c_str()); +#endif + return d->CString; } @@ -304,6 +315,26 @@ return -1; } +StringList String::split(const String &separator) const +{ + StringList list; + for(int index = 0;;) + { + int sep = find(separator, index); + if(sep < 0) + { + list.append(substr(index, size() - index)); + break; + } + else + { + list.append(substr(index, sep - index)); + index = sep + separator.size(); + } + } + return list; +} + bool String::startsWith(const String &s) const { if(s.length() > length()) @@ -314,9 +345,6 @@ String String::substr(uint position, uint n) const { - if(n > position + d->data.size()) - n = d->data.size() - position; - String s; s.d->data = d->data.substr(position, n); return s; @@ -546,6 +574,11 @@ return d == s.d || d->data == s.d->data; } +bool String::operator!=(const String &s) const +{ + return !operator==(s); +} + String &String::operator+=(const String &s) { detach(); @@ -753,9 +786,9 @@ &target, targetBuffer + bufferSize, Unicode::lenientConversion); - if(result != Unicode::conversionOK) + if(result != Unicode::conversionOK) { debug("String::prepare() - Unicode conversion error."); - + } int newSize = target != targetBuffer ? target - targetBuffer - 1 : 0; d->data.resize(newSize); diff -Nru taglib-1.7.2/taglib/toolkit/tstring.h taglib-1.8/taglib/toolkit/tstring.h --- taglib-1.7.2/taglib/toolkit/tstring.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/tstring.h 2012-09-06 18:03:15.000000000 +0000 @@ -56,6 +56,8 @@ namespace TagLib { + class StringList; + //! A \e wide string class suitable for unicode. /*! @@ -240,6 +242,11 @@ int rfind(const String &s, int offset = -1) const; /*! + * Splits the string on each occurrence of \a separator. + */ + StringList split(const String &separator = " ") const; + + /*! * Returns true if the strings starts with the substring \a s. */ bool startsWith(const String &s) const; @@ -351,6 +358,12 @@ bool operator==(const String &s) const; /*! + * Compares each character of the String with each character of \a s and + * returns false if the strings match. + */ + bool operator!=(const String &s) const; + + /*! * Appends \a s to the end of the String. */ String &operator+=(const String &s); diff -Nru taglib-1.7.2/taglib/toolkit/unicode.cpp taglib-1.8/taglib/toolkit/unicode.cpp --- taglib-1.7.2/taglib/toolkit/unicode.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/toolkit/unicode.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -155,7 +155,7 @@ case 4: *--target = (ch | byteMark) & byteMask; ch >>= 6; case 3: *--target = (ch | byteMark) & byteMask; ch >>= 6; case 2: *--target = (ch | byteMark) & byteMask; ch >>= 6; - case 1: *--target = ch | firstByteMark[bytesToWrite]; + case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); } target += bytesToWrite; } @@ -253,7 +253,7 @@ result = sourceIllegal; break; } else { - *target++ = ch; /* normal case */ + *target++ = (UTF16)ch; /* normal case */ } } else if (ch > UNI_MAX_UTF16) { if (flags == strictConversion) { @@ -270,7 +270,7 @@ result = targetExhausted; break; } ch -= halfBase; - *target++ = (ch >> halfShift) + UNI_SUR_HIGH_START; + *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); *target++ = (ch & halfMask) + UNI_SUR_LOW_START; } } diff -Nru taglib-1.7.2/taglib/trueaudio/CMakeLists.txt taglib-1.8/taglib/trueaudio/CMakeLists.txt --- taglib-1.7.2/taglib/trueaudio/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/trueaudio/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES trueaudiofile.h trueaudioproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/trueaudio/trueaudiofile.cpp taglib-1.8/taglib/trueaudio/trueaudiofile.cpp --- taglib-1.7.2/taglib/trueaudio/trueaudiofile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/trueaudio/trueaudiofile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include "trueaudiofile.h" #include "id3v1tag.h" @@ -41,7 +43,7 @@ namespace { - enum { ID3v2Index = 0, ID3v1Index = 1 }; + enum { TrueAudioID3v2Index = 0, TrueAudioID3v1Index = 1 }; } class TrueAudio::File::FilePrivate @@ -99,6 +101,23 @@ read(readProperties, propertiesStyle); } +TrueAudio::File::File(IOStream *stream, bool readProperties, + Properties::ReadStyle propertiesStyle) : TagLib::File(stream) +{ + d = new FilePrivate; + if(isOpen()) + read(readProperties, propertiesStyle); +} + +TrueAudio::File::File(IOStream *stream, ID3v2::FrameFactory *frameFactory, + bool readProperties, Properties::ReadStyle propertiesStyle) : + TagLib::File(stream) +{ + d = new FilePrivate(frameFactory); + if(isOpen()) + read(readProperties, propertiesStyle); +} + TrueAudio::File::~File() { delete d; @@ -109,6 +128,27 @@ return &d->tag; } +PropertyMap TrueAudio::File::properties() const +{ + // once Tag::properties() is virtual, this case distinction could actually be done + // within TagUnion. + if(d->hasID3v2) + return d->tag.access(TrueAudioID3v2Index, false)->properties(); + if(d->hasID3v1) + return d->tag.access(TrueAudioID3v1Index, false)->properties(); + return PropertyMap(); +} + +PropertyMap TrueAudio::File::setProperties(const PropertyMap &properties) +{ + if(d->hasID3v2) + return d->tag.access(TrueAudioID3v2Index, false)->setProperties(properties); + else if(d->hasID3v1) + return d->tag.access(TrueAudioID3v1Index, false)->setProperties(properties); + else + return d->tag.access(TrueAudioID3v2Index, true)->setProperties(properties); +} + TrueAudio::Properties *TrueAudio::File::audioProperties() const { return d->properties; @@ -170,23 +210,23 @@ ID3v1::Tag *TrueAudio::File::ID3v1Tag(bool create) { - return d->tag.access(ID3v1Index, create); + return d->tag.access(TrueAudioID3v1Index, create); } ID3v2::Tag *TrueAudio::File::ID3v2Tag(bool create) { - return d->tag.access(ID3v2Index, create); + return d->tag.access(TrueAudioID3v2Index, create); } void TrueAudio::File::strip(int tags) { if(tags & ID3v1) { - d->tag.set(ID3v1Index, 0); + d->tag.set(TrueAudioID3v1Index, 0); ID3v2Tag(true); } if(tags & ID3v2) { - d->tag.set(ID3v2Index, 0); + d->tag.set(TrueAudioID3v2Index, 0); if(!ID3v1Tag()) ID3v2Tag(true); @@ -206,12 +246,12 @@ if(d->ID3v2Location >= 0) { - d->tag.set(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory)); + d->tag.set(TrueAudioID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory)); d->ID3v2OriginalSize = ID3v2Tag()->header()->completeTagSize(); if(ID3v2Tag()->header()->tagSize() <= 0) - d->tag.set(ID3v2Index, 0); + d->tag.set(TrueAudioID3v2Index, 0); else d->hasID3v2 = true; } @@ -221,7 +261,7 @@ d->ID3v1Location = findID3v1(); if(d->ID3v1Location >= 0) { - d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); + d->tag.set(TrueAudioID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); d->hasID3v1 = true; } diff -Nru taglib-1.7.2/taglib/trueaudio/trueaudiofile.h taglib-1.8/taglib/trueaudio/trueaudiofile.h --- taglib-1.7.2/taglib/trueaudio/trueaudiofile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/trueaudio/trueaudiofile.h 2012-09-06 18:03:15.000000000 +0000 @@ -97,6 +97,30 @@ Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs an TrueAudio file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Contructs an TrueAudio file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. The frames will be created using + * \a frameFactory. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, ID3v2::FrameFactory *frameFactory, + bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); @@ -107,6 +131,20 @@ virtual TagLib::Tag *tag() const; /*! + * Implements the unified property interface -- export function. + * If the file contains both ID3v1 and v2 tags, only ID3v2 will be + * converted to the PropertyMap. + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * As with the export, only one tag is taken into account. If the file + * has no tag at all, ID3v2 will be created. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! * Returns the TrueAudio::Properties for this file. If no audio properties * were read then this will return a null pointer. */ diff -Nru taglib-1.7.2/taglib/trueaudio/trueaudioproperties.cpp taglib-1.8/taglib/trueaudio/trueaudioproperties.cpp --- taglib-1.7.2/taglib/trueaudio/trueaudioproperties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/trueaudio/trueaudioproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -48,7 +48,8 @@ bitrate(0), sampleRate(0), channels(0), - bitsPerSample(0) {} + bitsPerSample(0), + sampleFrames(0) {} ByteVector data; long streamLength; @@ -59,6 +60,7 @@ int sampleRate; int channels; int bitsPerSample; + uint sampleFrames; }; //////////////////////////////////////////////////////////////////////////////// @@ -101,6 +103,11 @@ return d->channels; } +TagLib::uint TrueAudio::Properties::sampleFrames() const +{ + return d->sampleFrames; +} + int TrueAudio::Properties::ttaVersion() const { return d->version; @@ -135,8 +142,8 @@ d->sampleRate = d->data.mid(pos, 4).toUInt(false); pos += 4; - uint sampleFrames = d->data.mid(pos, 4).toUInt(false); - d->length = d->sampleRate > 0 ? sampleFrames / d->sampleRate : 0; + d->sampleFrames = d->data.mid(pos, 4).toUInt(false); + d->length = d->sampleRate > 0 ? d->sampleFrames / d->sampleRate : 0; d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0; } diff -Nru taglib-1.7.2/taglib/trueaudio/trueaudioproperties.h taglib-1.8/taglib/trueaudio/trueaudioproperties.h --- taglib-1.7.2/taglib/trueaudio/trueaudioproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/trueaudio/trueaudioproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -74,6 +74,11 @@ int bitsPerSample() const; /*! + * Returns the total number of sample frames + */ + uint sampleFrames() const; + + /*! * Returns the major version number. */ int ttaVersion() const; diff -Nru taglib-1.7.2/taglib/wavpack/CMakeLists.txt taglib-1.8/taglib/wavpack/CMakeLists.txt --- taglib-1.7.2/taglib/wavpack/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/wavpack/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -INSTALL( FILES wavpackfile.h wavpackproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) diff -Nru taglib-1.7.2/taglib/wavpack/wavpackfile.cpp taglib-1.8/taglib/wavpack/wavpackfile.cpp --- taglib-1.7.2/taglib/wavpack/wavpackfile.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/wavpack/wavpackfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -31,6 +31,7 @@ #include #include #include +#include #include "wavpackfile.h" #include "id3v1tag.h" @@ -42,7 +43,7 @@ namespace { - enum { APEIndex, ID3v1Index }; + enum { WavAPEIndex, WavID3v1Index }; } class WavPack::File::FilePrivate @@ -88,6 +89,13 @@ read(readProperties, propertiesStyle); } +WavPack::File::File(IOStream *stream, bool readProperties, + Properties::ReadStyle propertiesStyle) : TagLib::File(stream) +{ + d = new FilePrivate; + read(readProperties, propertiesStyle); +} + WavPack::File::~File() { delete d; @@ -98,6 +106,25 @@ return &d->tag; } +PropertyMap WavPack::File::properties() const +{ + if(d->hasAPE) + return d->tag.access(WavAPEIndex, false)->properties(); + if(d->hasID3v1) + return d->tag.access(WavID3v1Index, false)->properties(); + return PropertyMap(); +} + +PropertyMap WavPack::File::setProperties(const PropertyMap &properties) +{ + if(d->hasAPE) + return d->tag.access(WavAPEIndex, false)->setProperties(properties); + else if(d->hasID3v1) + return d->tag.access(WavID3v1Index, false)->setProperties(properties); + else + return d->tag.access(APE, true)->setProperties(properties); +} + WavPack::Properties *WavPack::File::audioProperties() const { return d->properties; @@ -174,23 +201,23 @@ ID3v1::Tag *WavPack::File::ID3v1Tag(bool create) { - return d->tag.access(ID3v1Index, create); + return d->tag.access(WavID3v1Index, create); } APE::Tag *WavPack::File::APETag(bool create) { - return d->tag.access(APEIndex, create); + return d->tag.access(WavAPEIndex, create); } void WavPack::File::strip(int tags) { if(tags & ID3v1) { - d->tag.set(ID3v1Index, 0); + d->tag.set(WavID3v1Index, 0); APETag(true); } if(tags & APE) { - d->tag.set(APEIndex, 0); + d->tag.set(WavAPEIndex, 0); if(!ID3v1Tag()) APETag(true); @@ -208,7 +235,7 @@ d->ID3v1Location = findID3v1(); if(d->ID3v1Location >= 0) { - d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); + d->tag.set(WavID3v1Index, new ID3v1::Tag(this, d->ID3v1Location)); d->hasID3v1 = true; } @@ -217,7 +244,7 @@ d->APELocation = findAPE(); if(d->APELocation >= 0) { - d->tag.set(APEIndex, new APE::Tag(this, d->APELocation)); + d->tag.set(WavAPEIndex, new APE::Tag(this, d->APELocation)); d->APESize = APETag()->footer()->completeTagSize(); d->APELocation = d->APELocation + APETag()->footer()->size() - d->APESize; d->hasAPE = true; diff -Nru taglib-1.7.2/taglib/wavpack/wavpackfile.h taglib-1.8/taglib/wavpack/wavpackfile.h --- taglib-1.7.2/taglib/wavpack/wavpackfile.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/wavpack/wavpackfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -88,6 +88,17 @@ Properties::ReadStyle propertiesStyle = Properties::Average); /*! + * Contructs an WavPack file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! * Destroys this instance of the File. */ virtual ~File(); @@ -99,6 +110,20 @@ virtual TagLib::Tag *tag() const; /*! + * Implements the unified property interface -- export function. + * If the file contains both an APE and an ID3v1 tag, only APE + * will be converted to the PropertyMap. + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * As for the export, only one tag is taken into account. If the file + * has no tag at all, APE will be created. + */ + PropertyMap setProperties(const PropertyMap&); + + /*! * Returns the MPC::Properties for this file. If no audio properties * were read then this will return a null pointer. */ diff -Nru taglib-1.7.2/taglib/wavpack/wavpackproperties.cpp taglib-1.8/taglib/wavpack/wavpackproperties.cpp --- taglib-1.7.2/taglib/wavpack/wavpackproperties.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/wavpack/wavpackproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -48,6 +48,7 @@ channels(0), version(0), bitsPerSample(0), + sampleFrames(0), file(0) {} ByteVector data; @@ -59,6 +60,7 @@ int channels; int version; int bitsPerSample; + uint sampleFrames; File *file; }; @@ -115,6 +117,11 @@ return d->bitsPerSample; } +TagLib::uint WavPack::Properties::sampleFrames() const +{ + return d->sampleFrames; +} + //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// @@ -154,13 +161,14 @@ unsigned int samples = d->data.mid(12, 4).toUInt(false); if(samples == ~0u) { if(d->file && d->style != Fast) { - samples = seekFinalIndex(); + samples = seekFinalIndex(); } else { samples = 0; } } d->length = d->sampleRate > 0 ? (samples + (d->sampleRate / 2)) / d->sampleRate : 0; + d->sampleFrames = samples; d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0; } diff -Nru taglib-1.7.2/taglib/wavpack/wavpackproperties.h taglib-1.8/taglib/wavpack/wavpackproperties.h --- taglib-1.7.2/taglib/wavpack/wavpackproperties.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/taglib/wavpack/wavpackproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -82,6 +82,7 @@ * Returns number of bits per sample. */ int bitsPerSample() const; + uint sampleFrames() const; /*! * Returns WavPack version. diff -Nru taglib-1.7.2/taglib/xm/xmfile.cpp taglib-1.8/taglib/xm/xmfile.cpp --- taglib-1.7.2/taglib/xm/xmfile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/xm/xmfile.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,648 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "tstringlist.h" +#include "tdebug.h" +#include "xmfile.h" +#include "modfileprivate.h" +#include "tpropertymap.h" + +#include +#include + +using namespace TagLib; +using namespace XM; +using TagLib::uint; +using TagLib::ushort; +using TagLib::ulong; + +/*! + * The Reader classes are helpers to make handling of the stripped XM + * format more easy. In the stripped XM format certain header sizes might + * be smaller than one would expect. The fields that are not included + * are then just some predefined valued (e.g. 0). + * + * Using these classes this code: + * + * if(headerSize >= 4) { + * if(!readU16L(value1)) ERROR(); + * if(headerSize >= 8) { + * if(!readU16L(value2)) ERROR(); + * if(headerSize >= 12) { + * if(!readString(value3, 22)) ERROR(); + * ... + * } + * } + * } + * + * Becomes: + * + * StructReader header; + * header.u16L(value1).u16L(value2).string(value3, 22). ...; + * if(header.read(*this, headerSize) < std::min(header.size(), headerSize)) + * ERROR(); + * + * Maybe if this is useful to other formats these classes can be moved to + * their own public files. + */ +class Reader +{ +public: + virtual ~Reader() + { + } + + /*! + * Reads associated values from \a file, but never reads more + * then \a limit bytes. + */ + virtual uint read(TagLib::File &file, uint limit) = 0; + + /*! + * Returns the number of bytes this reader would like to read. + */ + virtual uint size() const = 0; +}; + +class SkipReader : public Reader +{ +public: + SkipReader(uint size) : m_size(size) + { + } + + uint read(TagLib::File &file, uint limit) + { + uint count = std::min(m_size, limit); + file.seek(count, TagLib::File::Current); + return count; + } + + uint size() const + { + return m_size; + } + +private: + uint m_size; +}; + +template +class ValueReader : public Reader +{ +public: + ValueReader(T &value) : value(value) + { + } + +protected: + T &value; +}; + +class StringReader : public ValueReader +{ +public: + StringReader(String &string, uint size) : + ValueReader(string), m_size(size) + { + } + + uint read(TagLib::File &file, uint limit) + { + ByteVector data = file.readBlock(std::min(m_size, limit)); + uint count = data.size(); + int index = data.find((char) 0); + if(index > -1) { + data.resize(index); + } + data.replace((char) 0xff, ' '); + value = data; + return count; + } + + uint size() const + { + return m_size; + } + +private: + uint m_size; +}; + +class ByteReader : public ValueReader +{ +public: + ByteReader(uchar &byte) : ValueReader(byte) {} + + uint read(TagLib::File &file, uint limit) + { + ByteVector data = file.readBlock(std::min(1U,limit)); + if(data.size() > 0) { + value = data[0]; + } + return data.size(); + } + + uint size() const + { + return 1; + } +}; + +template +class NumberReader : public ValueReader +{ +public: + NumberReader(T &value, bool bigEndian) : + ValueReader(value), bigEndian(bigEndian) + { + } + +protected: + bool bigEndian; +}; + +class U16Reader : public NumberReader +{ +public: + U16Reader(ushort &value, bool bigEndian) + : NumberReader(value, bigEndian) {} + + uint read(TagLib::File &file, uint limit) + { + ByteVector data = file.readBlock(std::min(2U,limit)); + value = data.toUShort(bigEndian); + return data.size(); + } + + uint size() const + { + return 2; + } +}; + +class U32Reader : public NumberReader +{ +public: + U32Reader(ulong &value, bool bigEndian = true) : + NumberReader(value, bigEndian) + { + } + + uint read(TagLib::File &file, uint limit) + { + ByteVector data = file.readBlock(std::min(4U,limit)); + value = data.toUInt(bigEndian); + return data.size(); + } + + uint size() const + { + return 4; + } +}; + +class StructReader : public Reader +{ +public: + StructReader() + { + m_readers.setAutoDelete(true); + } + + /*! + * Add a nested reader. This reader takes ownership. + */ + StructReader &reader(Reader *reader) + { + m_readers.append(reader); + return *this; + } + + /*! + * Don't read anything but skip \a size bytes. + */ + StructReader &skip(uint size) + { + m_readers.append(new SkipReader(size)); + return *this; + } + + /*! + * Read a string of \a size characters (bytes) into \a string. + */ + StructReader &string(String &string, uint size) + { + m_readers.append(new StringReader(string, size)); + return *this; + } + + /*! + * Read a byte into \a byte. + */ + StructReader &byte(uchar &byte) + { + m_readers.append(new ByteReader(byte)); + return *this; + } + + /*! + * Read a unsigned 16 Bit integer into \a number. The byte order + * is controlled by \a bigEndian. + */ + StructReader &u16(ushort &number, bool bigEndian) + { + m_readers.append(new U16Reader(number, bigEndian)); + return *this; + } + + /*! + * Read a unsigned 16 Bit little endian integer into \a number. + */ + StructReader &u16L(ushort &number) + { + return u16(number, false); + } + + /*! + * Read a unsigned 16 Bit big endian integer into \a number. + */ + StructReader &u16B(ushort &number) + { + return u16(number, true); + } + + /*! + * Read a unsigned 32 Bit integer into \a number. The byte order + * is controlled by \a bigEndian. + */ + StructReader &u32(ulong &number, bool bigEndian) + { + m_readers.append(new U32Reader(number, bigEndian)); + return *this; + } + + /*! + * Read a unsigned 32 Bit little endian integer into \a number. + */ + StructReader &u32L(ulong &number) + { + return u32(number, false); + } + + /*! + * Read a unsigned 32 Bit big endian integer into \a number. + */ + StructReader &u32B(ulong &number) + { + return u32(number, true); + } + + uint size() const + { + uint size = 0; + for(List::ConstIterator i = m_readers.begin(); + i != m_readers.end(); ++ i) { + size += (*i)->size(); + } + return size; + } + + uint read(TagLib::File &file, uint limit) + { + uint sumcount = 0; + for(List::Iterator i = m_readers.begin(); + limit > 0 && i != m_readers.end(); ++ i) { + uint count = (*i)->read(file, limit); + limit -= count; + sumcount += count; + } + return sumcount; + } + +private: + List m_readers; +}; + +class XM::File::FilePrivate +{ +public: + FilePrivate(AudioProperties::ReadStyle propertiesStyle) + : tag(), properties(propertiesStyle) + { + } + + Mod::Tag tag; + XM::Properties properties; +}; + +XM::File::File(FileName file, bool readProperties, + AudioProperties::ReadStyle propertiesStyle) : + Mod::FileBase(file), + d(new FilePrivate(propertiesStyle)) +{ + read(readProperties); +} + +XM::File::File(IOStream *stream, bool readProperties, + AudioProperties::ReadStyle propertiesStyle) : + Mod::FileBase(stream), + d(new FilePrivate(propertiesStyle)) +{ + read(readProperties); +} + +XM::File::~File() +{ + delete d; +} + +Mod::Tag *XM::File::tag() const +{ + return &d->tag; +} + +PropertyMap XM::File::properties() const +{ + return d->tag.properties(); +} + +PropertyMap XM::File::setProperties(const PropertyMap &properties) +{ + return d->tag.setProperties(properties); +} + +XM::Properties *XM::File::audioProperties() const +{ + return &d->properties; +} + +bool XM::File::save() +{ + if(readOnly()) { + debug("XM::File::save() - Cannot save to a read only file."); + return false; + } + seek(17); + writeString(d->tag.title(), 20); + seek(1, Current); + writeString(d->tag.trackerName(), 20); + seek(2, Current); + ulong headerSize = 0; + if(!readU32L(headerSize)) + return false; + seek(2+2+2, Current); + + ushort patternCount = 0; + ushort instrumentCount = 0; + if(!readU16L(patternCount) || !readU16L(instrumentCount)) + return false; + + seek(60 + headerSize); + + // need to read patterns again in order to seek to the instruments: + for(ushort i = 0; i < patternCount; ++ i) { + ulong patternHeaderLength = 0; + if(!readU32L(patternHeaderLength) || patternHeaderLength < 4) + return false; + + ushort dataSize = 0; + StructReader pattern; + pattern.skip(3).u16L(dataSize); + + uint count = pattern.read(*this, patternHeaderLength - 4U); + if(count != std::min(patternHeaderLength - 4U, (ulong)pattern.size())) + return false; + + seek(patternHeaderLength - (4 + count) + dataSize, Current); + } + + StringList lines = d->tag.comment().split("\n"); + uint sampleNameIndex = instrumentCount; + for(ushort i = 0; i < instrumentCount; ++ i) { + ulong instrumentHeaderSize = 0; + if(!readU32L(instrumentHeaderSize) || instrumentHeaderSize < 4) + return false; + + uint len = std::min(22UL, instrumentHeaderSize - 4U); + if(i > lines.size()) + writeString(String::null, len); + else + writeString(lines[i], len); + + long offset = 0; + if(instrumentHeaderSize >= 29U) { + ushort sampleCount = 0; + seek(1, Current); + if(!readU16L(sampleCount)) + return false; + + if(sampleCount > 0) { + ulong sampleHeaderSize = 0; + if(instrumentHeaderSize < 33U || !readU32L(sampleHeaderSize)) + return false; + // skip unhandeled header proportion: + seek(instrumentHeaderSize - 33, Current); + + for(ushort j = 0; j < sampleCount; ++ j) { + if(sampleHeaderSize > 4U) { + ulong sampleLength = 0; + if(!readU32L(sampleLength)) + return false; + offset += sampleLength; + + seek(std::min(sampleHeaderSize, 14UL), Current); + if(sampleHeaderSize > 18U) { + uint len = std::min(sampleHeaderSize - 18U, 22UL); + if(sampleNameIndex >= lines.size()) + writeString(String::null, len); + else + writeString(lines[sampleNameIndex ++], len); + seek(sampleHeaderSize - (18U + len), Current); + } + } + else { + seek(sampleHeaderSize, Current); + } + } + } + else { + offset = instrumentHeaderSize - 29; + } + } + else { + offset = instrumentHeaderSize - (4 + len); + } + seek(offset, Current); + } + + return true; +} + +void XM::File::read(bool) +{ + if(!isOpen()) + return; + + seek(0); + ByteVector magic = readBlock(17); + // it's all 0x00 for stripped XM files: + READ_ASSERT(magic == "Extended Module: " || magic == ByteVector(17, 0)); + + READ_STRING(d->tag.setTitle, 20); + READ_BYTE_AS(escape); + // in stripped XM files this is 0x00: + READ_ASSERT(escape == 0x1A || escape == 0x00); + + READ_STRING(d->tag.setTrackerName, 20); + READ_U16L(d->properties.setVersion); + + READ_U32L_AS(headerSize); + READ_ASSERT(headerSize >= 4); + + ushort length = 0; + ushort restartPosition = 0; + ushort channels = 0; + ushort patternCount = 0; + ushort instrumentCount = 0; + ushort flags = 0; + ushort tempo = 0; + ushort bpmSpeed = 0; + + StructReader header; + header.u16L(length) + .u16L(restartPosition) + .u16L(channels) + .u16L(patternCount) + .u16L(instrumentCount) + .u16L(flags) + .u16L(tempo) + .u16L(bpmSpeed); + + uint count = header.read(*this, headerSize - 4U); + uint size = std::min(headerSize - 4U, (ulong)header.size()); + + READ_ASSERT(count == size); + + d->properties.setLengthInPatterns(length); + d->properties.setRestartPosition(restartPosition); + d->properties.setChannels(channels); + d->properties.setPatternCount(patternCount); + d->properties.setInstrumentCount(instrumentCount); + d->properties.setFlags(flags); + d->properties.setTempo(tempo); + d->properties.setBpmSpeed(bpmSpeed); + + seek(60 + headerSize); + + // read patterns: + for(ushort i = 0; i < patternCount; ++ i) { + READ_U32L_AS(patternHeaderLength); + READ_ASSERT(patternHeaderLength >= 4); + + uchar packingType = 0; + ushort rowCount = 0; + ushort dataSize = 0; + StructReader pattern; + pattern.byte(packingType).u16L(rowCount).u16L(dataSize); + + uint count = pattern.read(*this, patternHeaderLength - 4U); + READ_ASSERT(count == std::min(patternHeaderLength - 4U, (ulong)pattern.size())); + + seek(patternHeaderLength - (4 + count) + dataSize, Current); + } + + StringList intrumentNames; + StringList sampleNames; + uint sumSampleCount = 0; + + // read instruments: + for(ushort i = 0; i < instrumentCount; ++ i) { + READ_U32L_AS(instrumentHeaderSize); + READ_ASSERT(instrumentHeaderSize >= 4); + + String instrumentName; + uchar instrumentType = 0; + ushort sampleCount = 0; + + StructReader instrument; + instrument.string(instrumentName, 22).byte(instrumentType).u16L(sampleCount); + + // 4 for instrumentHeaderSize + uint count = 4 + instrument.read(*this, instrumentHeaderSize - 4U); + READ_ASSERT(count == std::min(instrumentHeaderSize, (ulong)instrument.size() + 4)); + + ulong sampleHeaderSize = 0; + long offset = 0; + if(sampleCount > 0) { + sumSampleCount += sampleCount; + // wouldn't know which header size to assume otherwise: + READ_ASSERT(instrumentHeaderSize >= count + 4 && readU32L(sampleHeaderSize)); + // skip unhandeled header proportion: + seek(instrumentHeaderSize - count - 4, Current); + + for(ushort j = 0; j < sampleCount; ++ j) { + ulong sampleLength = 0; + ulong loopStart = 0; + ulong loopLength = 0; + uchar volume = 0; + uchar finetune = 0; + uchar sampleType = 0; + uchar panning = 0; + uchar noteNumber = 0; + uchar compression = 0; + String sampleName; + StructReader sample; + sample.u32L(sampleLength) + .u32L(loopStart) + .u32L(loopLength) + .byte(volume) + .byte(finetune) + .byte(sampleType) + .byte(panning) + .byte(noteNumber) + .byte(compression) + .string(sampleName, 22); + + uint count = sample.read(*this, sampleHeaderSize); + READ_ASSERT(count == std::min(sampleHeaderSize, (ulong)sample.size())); + // skip unhandeled header proportion: + seek(sampleHeaderSize - count, Current); + + offset += sampleLength; + sampleNames.append(sampleName); + } + } + else { + offset = instrumentHeaderSize - count; + } + intrumentNames.append(instrumentName); + seek(offset, Current); + } + + d->properties.setSampleCount(sumSampleCount); + String comment(intrumentNames.toString("\n")); + if(sampleNames.size() > 0) { + comment += "\n"; + comment += sampleNames.toString("\n"); + } + d->tag.setComment(comment); +} diff -Nru taglib-1.7.2/taglib/xm/xmfile.h taglib-1.8/taglib/xm/xmfile.h --- taglib-1.7.2/taglib/xm/xmfile.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/xm/xmfile.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,104 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_XMFILE_H +#define TAGLIB_XMFILE_H + +#include "tfile.h" +#include "audioproperties.h" +#include "taglib_export.h" +#include "modfilebase.h" +#include "modtag.h" +#include "xmproperties.h" + +namespace TagLib { + + namespace XM { + + class TAGLIB_EXPORT File : public Mod::FileBase { + public: + /*! + * Contructs a Extended Module file from \a file. If \a readProperties + * is true the file's audio properties will also be read using + * \a propertiesStyle. If false, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + AudioProperties::ReadStyle propertiesStyle = + AudioProperties::Average); + + /*! + * Contructs a Extended Module file from \a stream. If \a readProperties + * is true the file's audio properties will also be read using + * \a propertiesStyle. If false, \a propertiesStyle is ignored. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream, bool readProperties = true, + AudioProperties::ReadStyle propertiesStyle = + AudioProperties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + Mod::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * Forwards to Mod::Tag::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * Forwards to Mod::Tag::setProperties(). + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the XM::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + XM::Properties *audioProperties() const; + + /*! + * Save the file. + * This is the same as calling save(AllTags); + * + * \note Saving Extended Module tags is not supported. + */ + bool save(); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff -Nru taglib-1.7.2/taglib/xm/xmproperties.cpp taglib-1.8/taglib/xm/xmproperties.cpp --- taglib-1.7.2/taglib/xm/xmproperties.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/xm/xmproperties.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,180 @@ +/*************************************************************************** + copyright :(C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "xmproperties.h" + +using namespace TagLib; +using namespace XM; + +class XM::Properties::PropertiesPrivate +{ +public: + PropertiesPrivate() : + lengthInPatterns(0), + channels(0), + version(0), + restartPosition(0), + patternCount(0), + instrumentCount(0), + sampleCount(0), + flags(0), + tempo(0), + bpmSpeed(0) + { + } + + ushort lengthInPatterns; + int channels; + ushort version; + ushort restartPosition; + ushort patternCount; + ushort instrumentCount; + uint sampleCount; + ushort flags; + ushort tempo; + ushort bpmSpeed; +}; + +XM::Properties::Properties(AudioProperties::ReadStyle propertiesStyle) : + AudioProperties(propertiesStyle), + d(new PropertiesPrivate) +{ +} + +XM::Properties::~Properties() +{ + delete d; +} + +int XM::Properties::length() const +{ + return 0; +} + +int XM::Properties::bitrate() const +{ + return 0; +} + +int XM::Properties::sampleRate() const +{ + return 0; +} + +int XM::Properties::channels() const +{ + return d->channels; +} + +TagLib::ushort XM::Properties::lengthInPatterns() const +{ + return d->lengthInPatterns; +} + +TagLib::ushort XM::Properties::version() const +{ + return d->version; +} + +TagLib::ushort XM::Properties::restartPosition() const +{ + return d->restartPosition; +} + +TagLib::ushort XM::Properties::patternCount() const +{ + return d->patternCount; +} + +TagLib::ushort XM::Properties::instrumentCount() const +{ + return d->instrumentCount; +} + +TagLib::uint XM::Properties::sampleCount() const +{ + return d->sampleCount; +} + +TagLib::ushort XM::Properties::flags() const +{ + return d->flags; +} + +TagLib::ushort XM::Properties::tempo() const +{ + return d->tempo; +} + +TagLib::ushort XM::Properties::bpmSpeed() const +{ + return d->bpmSpeed; +} + +void XM::Properties::setLengthInPatterns(ushort lengthInPatterns) +{ + d->lengthInPatterns = lengthInPatterns; +} + +void XM::Properties::setChannels(int channels) +{ + d->channels = channels; +} + +void XM::Properties::setVersion(ushort version) +{ + d->version = version; +} + +void XM::Properties::setRestartPosition(ushort restartPosition) +{ + d->restartPosition = restartPosition; +} + +void XM::Properties::setPatternCount(ushort patternCount) +{ + d->patternCount = patternCount; +} + +void XM::Properties::setInstrumentCount(ushort instrumentCount) +{ + d->instrumentCount = instrumentCount; +} + +void XM::Properties::setSampleCount(uint sampleCount) +{ + d->sampleCount = sampleCount; +} + +void XM::Properties::setFlags(ushort flags) +{ + d->flags = flags; +} + +void XM::Properties::setTempo(ushort tempo) +{ + d->tempo = tempo; +} + +void XM::Properties::setBpmSpeed(ushort bpmSpeed) +{ + d->bpmSpeed = bpmSpeed; +} diff -Nru taglib-1.7.2/taglib/xm/xmproperties.h taglib-1.8/taglib/xm/xmproperties.h --- taglib-1.7.2/taglib/xm/xmproperties.h 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/taglib/xm/xmproperties.h 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,79 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_XMPROPERTIES_H +#define TAGLIB_XMPROPERTIES_H + +#include "taglib.h" +#include "tstring.h" +#include "audioproperties.h" + +namespace TagLib { + namespace XM { + class Properties : public AudioProperties { + friend class File; + public: + /*! Flag bits. */ + enum { + LinearFreqTable = 1 // otherwise its the amiga freq. table + }; + + Properties(AudioProperties::ReadStyle propertiesStyle); + virtual ~Properties(); + + int length() const; + int bitrate() const; + int sampleRate() const; + int channels() const; + + ushort lengthInPatterns() const; + ushort version() const; + ushort restartPosition() const; + ushort patternCount() const; + ushort instrumentCount() const; + uint sampleCount() const; + ushort flags() const; + ushort tempo() const; + ushort bpmSpeed() const; + + void setChannels(int channels); + + void setLengthInPatterns(ushort lengthInPatterns); + void setVersion(ushort version); + void setRestartPosition(ushort restartPosition); + void setPatternCount(ushort patternCount); + void setInstrumentCount(ushort instrumentCount); + void setSampleCount(uint sampleCount); + void setFlags(ushort flags); + void setTempo(ushort tempo); + void setBpmSpeed(ushort bpmSpeed); + + private: + Properties(const Properties&); + Properties &operator=(const Properties&); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff -Nru taglib-1.7.2/tests/CMakeLists.txt taglib-1.8/tests/CMakeLists.txt --- taglib-1.7.2/tests/CMakeLists.txt 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/CMakeLists.txt 2012-09-06 18:03:15.000000000 +0000 @@ -1,5 +1,3 @@ -if(BUILD_TESTS) - INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../taglib ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/toolkit @@ -9,6 +7,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v2 ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v2/frames ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg + ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpc ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mp4 ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff/aiff @@ -19,6 +18,10 @@ ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/flac ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/flac ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/wavpack + ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mod + ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/s3m + ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/it + ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/xm ) SET(test_runner_SRCS @@ -30,7 +33,9 @@ test_trueaudio.cpp test_bytevector.cpp test_bytevectorlist.cpp + test_bytevectorstream.cpp test_string.cpp + test_propertymap.cpp test_fileref.cpp test_id3v1.cpp test_id3v2.cpp @@ -46,25 +51,20 @@ test_apetag.cpp test_wav.cpp test_wavpack.cpp + test_mp4.cpp + test_mp4item.cpp + test_mp4coverart.cpp + test_asf.cpp + test_mod.cpp + test_s3m.cpp + test_it.cpp + test_xm.cpp + test_mpc.cpp ) -IF(WITH_MP4) - SET(test_runner_SRCS ${test_runner_SRCS} - test_mp4.cpp - test_mp4item.cpp - test_mp4coverart.cpp - ) -ENDIF(WITH_MP4) - -IF(WITH_ASF) - SET(test_runner_SRCS ${test_runner_SRCS} test_asf.cpp) -ENDIF(WITH_ASF) ADD_EXECUTABLE(test_runner ${test_runner_SRCS}) TARGET_LINK_LIBRARIES(test_runner tag ${CPPUNIT_LIBRARIES}) -ADD_CUSTOM_TARGET(check - ./test_runner - DEPENDS test_runner -) - -endif(BUILD_TESTS) +ADD_TEST(test_runner test_runner) +ADD_CUSTOM_TARGET(check COMMAND ${CMAKE_CTEST_COMMAND} -V + DEPENDS test_runner) Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/changed.mod and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/changed.mod differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/changed.s3m and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/changed.s3m differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/changed.xm and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/changed.xm differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/empty_alac.m4a and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/empty_alac.m4a differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/rare_frames.mp3 and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/rare_frames.mp3 differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/stripped.xm and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/stripped.xm differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/sv4_header.mpc and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/sv4_header.mpc differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/sv5_header.mpc and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/sv5_header.mpc differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/sv8_header.mpc and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/sv8_header.mpc differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/test.it and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/test.it differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/test.mod and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/test.mod differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/test.ogg and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/test.ogg differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/test.s3m and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/test.s3m differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/test.xm and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/test.xm differ Binary files /tmp/TRIUAQYhuV/taglib-1.7.2/tests/data/w000.mp3 and /tmp/i8nDSRkmvf/taglib-1.8/tests/data/w000.mp3 differ diff -Nru taglib-1.7.2/tests/main.cpp taglib-1.8/tests/main.cpp --- taglib-1.7.2/tests/main.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/main.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -1,3 +1,6 @@ +#include +#include +#include #include #include #include @@ -5,6 +8,7 @@ #include #include #include +#include int main(int argc, char* argv[]) { @@ -34,6 +38,13 @@ // Print test in a compiler compatible format. CppUnit::CompilerOutputter outputter(&result, std::cerr); outputter.write(); + + char *xml = ::getenv("CPPUNIT_XML"); + if(xml && !::strcmp(xml, "1")) { + std::ofstream xmlfileout("cpptestresults.xml"); + CppUnit::XmlOutputter xmlout(&result, xmlfileout); + xmlout.write(); + } } catch(std::invalid_argument &e){ std::cerr << std::endl diff -Nru taglib-1.7.2/tests/test_ape.cpp taglib-1.8/tests/test_ape.cpp --- taglib-1.7.2/tests/test_ape.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_ape.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -22,7 +22,7 @@ void testProperties399() { - APE::File f("data/mac-399.ape"); + APE::File f(TEST_FILE_PATH_C("mac-399.ape")); CPPUNIT_ASSERT_EQUAL(3, f.audioProperties()->length()); CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->bitrate()); CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); @@ -31,7 +31,7 @@ void testProperties396() { - APE::File f("data/mac-396.ape"); + APE::File f(TEST_FILE_PATH_C("mac-396.ape")); CPPUNIT_ASSERT_EQUAL(3, f.audioProperties()->length()); CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->bitrate()); CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); @@ -40,7 +40,7 @@ void testProperties390() { - APE::File f("data/mac-390-hdr.ape"); + APE::File f(TEST_FILE_PATH_C("mac-390-hdr.ape")); CPPUNIT_ASSERT_EQUAL(15, f.audioProperties()->length()); CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->bitrate()); CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); diff -Nru taglib-1.7.2/tests/test_apetag.cpp taglib-1.8/tests/test_apetag.cpp --- taglib-1.7.2/tests/test_apetag.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_apetag.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -4,7 +4,9 @@ #include #include #include +#include #include +#include #include "utils.h" using namespace std; @@ -15,6 +17,9 @@ CPPUNIT_TEST_SUITE(TestAPETag); CPPUNIT_TEST(testIsEmpty); CPPUNIT_TEST(testIsEmpty2); + CPPUNIT_TEST(testPropertyInterface1); + CPPUNIT_TEST(testPropertyInterface2); + CPPUNIT_TEST(testInvalidKeys); CPPUNIT_TEST_SUITE_END(); public: @@ -35,6 +40,65 @@ CPPUNIT_ASSERT(!tag.isEmpty()); } + void testPropertyInterface1() + { + APE::Tag tag; + PropertyMap dict = tag.properties(); + CPPUNIT_ASSERT(dict.isEmpty()); + dict["ARTIST"] = String("artist 1"); + dict["ARTIST"].append("artist 2"); + dict["TRACKNUMBER"].append("17"); + tag.setProperties(dict); + CPPUNIT_ASSERT_EQUAL(String("17"), tag.itemListMap()["TRACK"].values()[0]); + CPPUNIT_ASSERT_EQUAL(2u, tag.itemListMap()["ARTIST"].values().size()); + CPPUNIT_ASSERT_EQUAL(String("artist 1"), tag.artist()); + CPPUNIT_ASSERT_EQUAL(17u, tag.track()); + } + + void testPropertyInterface2() + { + APE::Tag tag; + APE::Item item1 = APE::Item("TRACK", "17"); + tag.setItem("TRACK", item1); + + APE::Item item2 = APE::Item(); + item2.setType(APE::Item::Binary); + tag.setItem("TESTBINARY", item2); + + PropertyMap properties = tag.properties(); + CPPUNIT_ASSERT_EQUAL(1u, properties.unsupportedData().size()); + CPPUNIT_ASSERT(properties.contains("TRACKNUMBER")); + CPPUNIT_ASSERT(!properties.contains("TRACK")); + CPPUNIT_ASSERT(tag.itemListMap().contains("TESTBINARY")); + + tag.removeUnsupportedProperties(properties.unsupportedData()); + CPPUNIT_ASSERT(!tag.itemListMap().contains("TESTBINARY")); + + APE::Item item3 = APE::Item("TRACKNUMBER", "29"); + tag.setItem("TRACKNUMBER", item3); + properties = tag.properties(); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), properties["TRACKNUMBER"].size()); + CPPUNIT_ASSERT_EQUAL(String("17"), properties["TRACKNUMBER"][0]); + CPPUNIT_ASSERT_EQUAL(String("29"), properties["TRACKNUMBER"][1]); + + } + + void testInvalidKeys() + { + PropertyMap properties; + properties["A"] = String("invalid key: one character"); + properties["MP+"] = String("invalid key: forbidden string"); + properties["A B~C"] = String("valid key: space and tilde"); + properties["ARTIST"] = String("valid key: normal one"); + + APE::Tag tag; + PropertyMap unsuccessful = tag.setProperties(properties); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), unsuccessful.size()); + CPPUNIT_ASSERT(unsuccessful.contains("A")); + CPPUNIT_ASSERT(unsuccessful.contains("MP+")); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestAPETag); + diff -Nru taglib-1.7.2/tests/test_asf.cpp taglib-1.8/tests/test_asf.cpp --- taglib-1.7.2/tests/test_asf.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_asf.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -28,7 +28,7 @@ void testProperties() { - ASF::File f("data/silence-1.wma"); + ASF::File f(TEST_FILE_PATH_C("silence-1.wma")); CPPUNIT_ASSERT_EQUAL(4, f.audioProperties()->length()); CPPUNIT_ASSERT_EQUAL(64, f.audioProperties()->bitrate()); CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); @@ -37,7 +37,7 @@ void testRead() { - ASF::File f("data/silence-1.wma"); + ASF::File f(TEST_FILE_PATH_C("silence-1.wma")); CPPUNIT_ASSERT_EQUAL(String("test"), f.tag()->title()); } @@ -164,7 +164,7 @@ f = new ASF::File(newname.c_str()); ASF::AttributeList values2 = f->tag()->attributeListMap()["WM/Picture"]; CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), values2.size()); - ASF::Attribute attr2 = values2.front(); + ASF::Attribute attr2 = values2.front(); ASF::Picture picture2 = attr2.toPicture(); CPPUNIT_ASSERT(picture2.isValid()); CPPUNIT_ASSERT_EQUAL(String("image/jpeg"), picture2.mimeType()); diff -Nru taglib-1.7.2/tests/test_bytevector.cpp taglib-1.8/tests/test_bytevector.cpp --- taglib-1.7.2/tests/test_bytevector.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_bytevector.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -39,6 +39,7 @@ CPPUNIT_TEST(testRfind2); CPPUNIT_TEST(testToHex); CPPUNIT_TEST(testToUShort); + CPPUNIT_TEST(testReplace); CPPUNIT_TEST_SUITE_END(); public: @@ -191,6 +192,50 @@ CPPUNIT_ASSERT_EQUAL((unsigned short)0x01FF, ByteVector("\xFF\x01", 2).toUShort(false)); } + void testReplace() + { + { + ByteVector a("abcdabf"); + a.replace(ByteVector(""), ByteVector("")); + CPPUNIT_ASSERT_EQUAL(ByteVector("abcdabf"), a); + } + { + ByteVector a("abcdabf"); + a.replace(ByteVector("foobartoolong"), ByteVector("")); + CPPUNIT_ASSERT_EQUAL(ByteVector("abcdabf"), a); + } + { + ByteVector a("abcdabf"); + a.replace(ByteVector("xx"), ByteVector("yy")); + CPPUNIT_ASSERT_EQUAL(ByteVector("abcdabf"), a); + } + { + ByteVector a("abcdabf"); + a.replace(ByteVector("a"), ByteVector("x")); + CPPUNIT_ASSERT_EQUAL(ByteVector("xbcdxbf"), a); + } + { + ByteVector a("abcdabf"); + a.replace(ByteVector("ab"), ByteVector("xy")); + CPPUNIT_ASSERT_EQUAL(ByteVector("xycdxyf"), a); + } + { + ByteVector a("abcdabf"); + a.replace(ByteVector("a"), ByteVector("")); + CPPUNIT_ASSERT_EQUAL(ByteVector("bcdbf"), a); + } + { + ByteVector a("abcdabf"); + a.replace(ByteVector("ab"), ByteVector("x")); + CPPUNIT_ASSERT_EQUAL(ByteVector("xcdxf"), a); + } + { + ByteVector a("abcdabf"); + a.replace(ByteVector("ab"), ByteVector()); + CPPUNIT_ASSERT_EQUAL(ByteVector("cdf"), a); + } + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestByteVector); diff -Nru taglib-1.7.2/tests/test_bytevectorstream.cpp taglib-1.8/tests/test_bytevectorstream.cpp --- taglib-1.7.2/tests/test_bytevectorstream.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/tests/test_bytevectorstream.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,92 @@ +#include +#include + +using namespace std; +using namespace TagLib; + +class TestByteVectorStream : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(TestByteVectorStream); + CPPUNIT_TEST(testInitialData); + CPPUNIT_TEST(testWriteBlock); + CPPUNIT_TEST(testWriteBlockResize); + CPPUNIT_TEST(testReadBlock); + CPPUNIT_TEST(testRemoveBlock); + CPPUNIT_TEST(testInsert); + CPPUNIT_TEST_SUITE_END(); + +public: + + void testInitialData() + { + ByteVector v("abcd"); + ByteVectorStream stream(v); + + CPPUNIT_ASSERT_EQUAL(ByteVector("abcd"), *stream.data()); + } + + void testWriteBlock() + { + ByteVector v("abcd"); + ByteVectorStream stream(v); + + stream.seek(1); + stream.writeBlock(ByteVector("xx")); + CPPUNIT_ASSERT_EQUAL(ByteVector("axxd"), *stream.data()); + } + + void testWriteBlockResize() + { + ByteVector v("abcd"); + ByteVectorStream stream(v); + + stream.seek(3); + stream.writeBlock(ByteVector("xx")); + CPPUNIT_ASSERT_EQUAL(ByteVector("abcxx"), *stream.data()); + stream.seek(5); + stream.writeBlock(ByteVector("yy")); + CPPUNIT_ASSERT_EQUAL(ByteVector("abcxxyy"), *stream.data()); + } + + void testReadBlock() + { + ByteVector v("abcd"); + ByteVectorStream stream(v); + + CPPUNIT_ASSERT_EQUAL(ByteVector("a"), stream.readBlock(1)); + CPPUNIT_ASSERT_EQUAL(ByteVector("bc"), stream.readBlock(2)); + CPPUNIT_ASSERT_EQUAL(ByteVector("d"), stream.readBlock(3)); + CPPUNIT_ASSERT_EQUAL(ByteVector::null, stream.readBlock(3)); + } + + void testRemoveBlock() + { + ByteVector v("abcd"); + ByteVectorStream stream(v); + + stream.removeBlock(1, 1); + CPPUNIT_ASSERT_EQUAL(ByteVector("acd"), *stream.data()); + stream.removeBlock(0, 2); + CPPUNIT_ASSERT_EQUAL(ByteVector("d"), *stream.data()); + stream.removeBlock(0, 2); + CPPUNIT_ASSERT_EQUAL(ByteVector(""), *stream.data()); + } + + void testInsert() + { + ByteVector v("abcd"); + ByteVectorStream stream(v); + + stream.insert(ByteVector("xx"), 1, 1); + CPPUNIT_ASSERT_EQUAL(ByteVector("axxcd"), *stream.data()); + stream.insert(ByteVector("yy"), 0, 2); + CPPUNIT_ASSERT_EQUAL(ByteVector("yyxcd"), *stream.data()); + stream.insert(ByteVector("foa"), 3, 2); + CPPUNIT_ASSERT_EQUAL(ByteVector("yyxfoa"), *stream.data()); + stream.insert(ByteVector("123"), 3, 0); + CPPUNIT_ASSERT_EQUAL(ByteVector("yyx123foa"), *stream.data()); + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(TestByteVectorStream); diff -Nru taglib-1.7.2/tests/test_fileref.cpp taglib-1.8/tests/test_fileref.cpp --- taglib-1.7.2/tests/test_fileref.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_fileref.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -16,9 +16,7 @@ class TestFileRef : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestFileRef); -#ifdef TAGLIB_WITH_ASF CPPUNIT_TEST(testASF); -#endif CPPUNIT_TEST(testMusepack); CPPUNIT_TEST(testVorbis); CPPUNIT_TEST(testSpeex); @@ -26,11 +24,9 @@ CPPUNIT_TEST(testMP3); CPPUNIT_TEST(testOGA_FLAC); CPPUNIT_TEST(testOGA_Vorbis); -#ifdef TAGLIB_WITH_MP4 CPPUNIT_TEST(testMP4_1); CPPUNIT_TEST(testMP4_2); CPPUNIT_TEST(testMP4_3); -#endif CPPUNIT_TEST(testTrueAudio); CPPUNIT_TEST(testAPE); CPPUNIT_TEST_SUITE_END(); @@ -86,12 +82,10 @@ fileRefSave("click", ".mpc"); } -#ifdef TAGLIB_WITH_ASF void testASF() { fileRefSave("silence-1", ".wma"); } -#endif void testVorbis() { @@ -118,7 +112,6 @@ fileRefSave("empty", ".tta"); } -#ifdef TAGLIB_WITH_MP4 void testMP4_1() { fileRefSave("has-tags", ".m4a"); @@ -133,18 +126,17 @@ { fileRefSave("no-tags", ".3g2"); } -#endif void testOGA_FLAC() { - FileRef *f = new FileRef("data/empty_flac.oga"); + FileRef *f = new FileRef(TEST_FILE_PATH_C("empty_flac.oga")); CPPUNIT_ASSERT(dynamic_cast(f->file()) == NULL); CPPUNIT_ASSERT(dynamic_cast(f->file()) != NULL); } void testOGA_Vorbis() { - FileRef *f = new FileRef("data/empty_vorbis.oga"); + FileRef *f = new FileRef(TEST_FILE_PATH_C("empty_vorbis.oga")); CPPUNIT_ASSERT(dynamic_cast(f->file()) != NULL); CPPUNIT_ASSERT(dynamic_cast(f->file()) == NULL); } diff -Nru taglib-1.7.2/tests/test_flac.cpp taglib-1.8/tests/test_flac.cpp --- taglib-1.7.2/tests/test_flac.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_flac.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include "utils.h" @@ -22,13 +23,14 @@ CPPUNIT_TEST(testRemoveAllPictures); CPPUNIT_TEST(testRepeatedSave); CPPUNIT_TEST(testSaveMultipleValues); + CPPUNIT_TEST(testDict); CPPUNIT_TEST_SUITE_END(); public: void testSignature() { - FLAC::File f("data/no-tags.flac"); + FLAC::File f(TEST_FILE_PATH_C("no-tags.flac")); CPPUNIT_ASSERT_EQUAL(ByteVector("a1b141f766e9849ac3db1030a20a3c77"), f.audioProperties()->signature().toHex()); } @@ -190,7 +192,7 @@ void testSaveMultipleValues() { - ScopedFileCopy copy("silence-44-s", ".flac", false); + ScopedFileCopy copy("silence-44-s", ".flac"); string newname = copy.fileName(); FLAC::File *f = new FLAC::File(newname.c_str()); @@ -208,6 +210,27 @@ CPPUNIT_ASSERT_EQUAL(String("artist 2"), m["ARTIST"][1]); } + void testDict() + { + // test unicode & multiple values with dict interface + ScopedFileCopy copy("silence-44-s", ".flac"); + string newname = copy.fileName(); + + FLAC::File *f = new FLAC::File(newname.c_str()); + PropertyMap dict; + dict["ARTIST"].append("artøst 1"); + dict["ARTIST"].append("artöst 2"); + f->setProperties(dict); + f->save(); + delete f; + + f = new FLAC::File(newname.c_str()); + dict = f->properties(); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), dict["ARTIST"].size()); + CPPUNIT_ASSERT_EQUAL(String("artøst 1"), dict["ARTIST"][0]); + CPPUNIT_ASSERT_EQUAL(String("artöst 2"), dict["ARTIST"][1]); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestFLAC); diff -Nru taglib-1.7.2/tests/test_id3v2.cpp taglib-1.8/tests/test_id3v2.cpp --- taglib-1.7.2/tests/test_id3v2.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_id3v2.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -1,17 +1,23 @@ #include #include #include +// so evil :( +#define protected public #include #include #include +#undef protected #include #include #include +#include #include #include #include #include +#include #include +#include #include "utils.h" using namespace std; @@ -33,6 +39,7 @@ { CPPUNIT_TEST_SUITE(TestID3v2); CPPUNIT_TEST(testUnsynchDecode); + CPPUNIT_TEST(testDowngradeUTF8ForID3v23); CPPUNIT_TEST(testUTF16BEDelimiter); CPPUNIT_TEST(testUTF16Delimiter); CPPUNIT_TEST(testReadStringField); @@ -55,24 +62,46 @@ CPPUNIT_TEST(testRenderUrlLinkFrame); CPPUNIT_TEST(testParseUserUrlLinkFrame); CPPUNIT_TEST(testRenderUserUrlLinkFrame); + CPPUNIT_TEST(testParseOwnershipFrame); + CPPUNIT_TEST(testRenderOwnershipFrame); CPPUNIT_TEST(testSaveUTF16Comment); CPPUNIT_TEST(testUpdateGenre23_1); CPPUNIT_TEST(testUpdateGenre23_2); CPPUNIT_TEST(testUpdateGenre24); CPPUNIT_TEST(testUpdateDate22); + CPPUNIT_TEST(testDowngradeTo23); // CPPUNIT_TEST(testUpdateFullDate22); TODO TYE+TDA should be upgraded to TDRC together CPPUNIT_TEST(testCompressedFrameWithBrokenLength); + CPPUNIT_TEST(testW000); + CPPUNIT_TEST(testPropertyInterface); + CPPUNIT_TEST(testPropertyInterface2); + CPPUNIT_TEST(testDeleteFrame); + CPPUNIT_TEST(testSaveAndStripID3v1ShouldNotAddFrameFromID3v1ToId3v2); CPPUNIT_TEST_SUITE_END(); public: void testUnsynchDecode() { - MPEG::File f("data/unsynch.id3", false); + MPEG::File f(TEST_FILE_PATH_C("unsynch.id3"), false); CPPUNIT_ASSERT(f.tag()); CPPUNIT_ASSERT_EQUAL(String("My babe just cares for me"), f.tag()->title()); } + void testDowngradeUTF8ForID3v23() + { + ID3v2::TextIdentificationFrame f(ByteVector("TPE1"), String::UTF8); + StringList sl; + sl.append("Foo"); + f.setText(sl); + f.header()->setVersion(3); + ByteVector data = f.render(); + CPPUNIT_ASSERT_EQUAL((unsigned int)(4+4+2+1+6+2), data.size()); + ID3v2::TextIdentificationFrame f2(data); + CPPUNIT_ASSERT_EQUAL(sl, f2.fieldList()); + CPPUNIT_ASSERT_EQUAL(String::UTF16, f2.textEncoding()); + } + void testUTF16BEDelimiter() { ID3v2::TextIdentificationFrame f(ByteVector("TPE1"), String::UTF16BE); @@ -95,7 +124,7 @@ void testBrokenFrame1() { - MPEG::File f("data/broken-tenc.id3", false); + MPEG::File f(TEST_FILE_PATH_C("broken-tenc.id3"), false); CPPUNIT_ASSERT(f.tag()); CPPUNIT_ASSERT(!f.ID3v2Tag()->frameListMap().contains("TENC")); } @@ -360,10 +389,42 @@ "http://example.com", 33), // URL f.render()); } + + void testParseOwnershipFrame() + { + ID3v2::OwnershipFrame f( + ByteVector("OWNE" // Frame ID + "\x00\x00\x00\x19" // Frame size + "\x00\x00" // Frame flags + "\x00" // Text encoding + "GBP1.99\x00" // Price paid + "20120905" // Date of purchase + "Beatport", 35)); // Seller + CPPUNIT_ASSERT_EQUAL(String("GBP1.99"), f.pricePaid()); + CPPUNIT_ASSERT_EQUAL(String("20120905"), f.datePurchased()); + CPPUNIT_ASSERT_EQUAL(String("Beatport"), f.seller()); + } + + void testRenderOwnershipFrame() + { + ID3v2::OwnershipFrame f; + f.setPricePaid("GBP1.99"); + f.setDatePurchased("20120905"); + f.setSeller("Beatport"); + CPPUNIT_ASSERT_EQUAL( + ByteVector("OWNE" // Frame ID + "\x00\x00\x00\x19" // Frame size + "\x00\x00" // Frame flags + "\x00" // Text encoding + "GBP1.99\x00" // Price paid + "20120905" // Date of purchase + "Beatport", 35), // URL + f.render()); + } void testItunes24FrameSize() { - MPEG::File f("data/005411.id3", false); + MPEG::File f(TEST_FILE_PATH_C("005411.id3"), false); CPPUNIT_ASSERT(f.tag()); CPPUNIT_ASSERT(f.ID3v2Tag()->frameListMap().contains("TIT2")); CPPUNIT_ASSERT_EQUAL(String("Sunshine Superman"), f.ID3v2Tag()->frameListMap()["TIT2"].front()->toString()); @@ -444,21 +505,80 @@ void testUpdateDate22() { - MPEG::File f("data/id3v22-tda.mp3", false); + MPEG::File f(TEST_FILE_PATH_C("id3v22-tda.mp3"), false); CPPUNIT_ASSERT(f.tag()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(2010), f.tag()->year()); } void testUpdateFullDate22() { - MPEG::File f("data/id3v22-tda.mp3", false); + MPEG::File f(TEST_FILE_PATH_C("id3v22-tda.mp3"), false); CPPUNIT_ASSERT(f.tag()); CPPUNIT_ASSERT_EQUAL(String("2010-04-03"), f.ID3v2Tag()->frameListMap()["TDRC"].front()->toString()); } + void testDowngradeTo23() + { + ScopedFileCopy copy("xing", ".mp3"); + string newname = copy.fileName(); + + ID3v2::TextIdentificationFrame *tf; + MPEG::File foo(newname.c_str()); + tf = new ID3v2::TextIdentificationFrame("TDOR", String::Latin1); + tf->setText("2011-03-16"); + foo.ID3v2Tag()->addFrame(tf); + tf = new ID3v2::TextIdentificationFrame("TDRC", String::Latin1); + tf->setText("2012-04-17T12:01"); + foo.ID3v2Tag()->addFrame(tf); + tf = new ID3v2::TextIdentificationFrame("TMCL", String::Latin1); + tf->setText(StringList().append("Guitar").append("Artist 1").append("Drums").append("Artist 2")); + foo.ID3v2Tag()->addFrame(tf); + tf = new ID3v2::TextIdentificationFrame("TIPL", String::Latin1); + tf->setText(StringList().append("Producer").append("Artist 3").append("Mastering").append("Artist 4")); + foo.ID3v2Tag()->addFrame(tf); + foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TDRL", String::Latin1)); + foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TDTG", String::Latin1)); + foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TMOO", String::Latin1)); + foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TPRO", String::Latin1)); + foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOA", String::Latin1)); + foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOT", String::Latin1)); + foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSST", String::Latin1)); + foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOP", String::Latin1)); + foo.save(MPEG::File::AllTags, true, 3); + + MPEG::File bar(newname.c_str()); + tf = static_cast(bar.ID3v2Tag()->frameList("TDOR").front()); + CPPUNIT_ASSERT(tf); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), tf->fieldList().size()); + CPPUNIT_ASSERT_EQUAL(String("2011"), tf->fieldList().front()); + tf = static_cast(bar.ID3v2Tag()->frameList("TDRC").front()); + CPPUNIT_ASSERT(tf); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), tf->fieldList().size()); + CPPUNIT_ASSERT_EQUAL(String("2012"), tf->fieldList().front()); + tf = dynamic_cast(bar.ID3v2Tag()->frameList("TIPL").front()); + CPPUNIT_ASSERT(tf); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(8), tf->fieldList().size()); + CPPUNIT_ASSERT_EQUAL(String("Guitar"), tf->fieldList()[0]); + CPPUNIT_ASSERT_EQUAL(String("Artist 1"), tf->fieldList()[1]); + CPPUNIT_ASSERT_EQUAL(String("Drums"), tf->fieldList()[2]); + CPPUNIT_ASSERT_EQUAL(String("Artist 2"), tf->fieldList()[3]); + CPPUNIT_ASSERT_EQUAL(String("Producer"), tf->fieldList()[4]); + CPPUNIT_ASSERT_EQUAL(String("Artist 3"), tf->fieldList()[5]); + CPPUNIT_ASSERT_EQUAL(String("Mastering"), tf->fieldList()[6]); + CPPUNIT_ASSERT_EQUAL(String("Artist 4"), tf->fieldList()[7]); + CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TDRL")); + CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TDTG")); + CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TMOO")); + CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TPRO")); + CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOA")); + CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOT")); + CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSST")); + CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOP")); + } + void testCompressedFrameWithBrokenLength() { - MPEG::File f("data/compressed_id3_frame.mp3", false); + MPEG::File f(TEST_FILE_PATH_C("compressed_id3_frame.mp3"), false); CPPUNIT_ASSERT(f.ID3v2Tag()->frameListMap().contains("APIC")); ID3v2::AttachedPictureFrame *frame = static_cast(f.ID3v2Tag()->frameListMap()["APIC"].front()); @@ -468,6 +588,131 @@ CPPUNIT_ASSERT_EQUAL(String(""), frame->description()); CPPUNIT_ASSERT_EQUAL(TagLib::uint(86414), frame->picture().size()); } + + void testW000() + { + MPEG::File f(TEST_FILE_PATH_C("w000.mp3"), false); + CPPUNIT_ASSERT(f.ID3v2Tag()->frameListMap().contains("W000")); + ID3v2::UrlLinkFrame *frame = + dynamic_cast(f.ID3v2Tag()->frameListMap()["W000"].front()); + CPPUNIT_ASSERT(frame); + CPPUNIT_ASSERT_EQUAL(String("lukas.lalinsky@example.com____"), frame->url()); + } + + void testPropertyInterface() + { + ScopedFileCopy copy("rare_frames", ".mp3"); + string newname = copy.fileName(); + MPEG::File f(newname.c_str()); + PropertyMap dict = f.ID3v2Tag(false)->properties(); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(6), dict.size()); + + CPPUNIT_ASSERT(dict.contains("USERTEXTDESCRIPTION1")); + CPPUNIT_ASSERT(dict.contains("QuodLibet::USERTEXTDESCRIPTION2")); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), dict["USERTEXTDESCRIPTION1"].size()); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), dict["QuodLibet::USERTEXTDESCRIPTION2"].size()); + CPPUNIT_ASSERT_EQUAL(String("userTextData1"), dict["USERTEXTDESCRIPTION1"][0]); + CPPUNIT_ASSERT_EQUAL(String("userTextData2"), dict["USERTEXTDESCRIPTION1"][1]); + CPPUNIT_ASSERT_EQUAL(String("userTextData1"), dict["QuodLibet::USERTEXTDESCRIPTION2"][0]); + CPPUNIT_ASSERT_EQUAL(String("userTextData2"), dict["QuodLibet::USERTEXTDESCRIPTION2"][1]); + + CPPUNIT_ASSERT_EQUAL(String("Pop"), dict["GENRE"].front()); + + CPPUNIT_ASSERT_EQUAL(String("http://a.user.url"), dict["URL:USERURL"].front()); + + CPPUNIT_ASSERT_EQUAL(String("http://a.user.url/with/empty/description"), dict["URL"].front()); + CPPUNIT_ASSERT_EQUAL(String("A COMMENT"), dict["COMMENT"].front()); + + CPPUNIT_ASSERT_EQUAL(1u, dict.unsupportedData().size()); + CPPUNIT_ASSERT_EQUAL(String("UFID"), dict.unsupportedData().front()); + } + + void testPropertyInterface2() + { + ID3v2::Tag tag; + ID3v2::UnsynchronizedLyricsFrame *frame1 = new ID3v2::UnsynchronizedLyricsFrame(); + frame1->setDescription("test"); + frame1->setText("la-la-la test"); + tag.addFrame(frame1); + + ID3v2::UnsynchronizedLyricsFrame *frame2 = new ID3v2::UnsynchronizedLyricsFrame(); + frame2->setDescription(""); + frame2->setText("la-la-la nodescription"); + tag.addFrame(frame2); + + ID3v2::AttachedPictureFrame *frame3 = new ID3v2::AttachedPictureFrame(); + frame3->setDescription("test picture"); + tag.addFrame(frame3); + + ID3v2::TextIdentificationFrame *frame4 = new ID3v2::TextIdentificationFrame("TIPL"); + frame4->setText("single value is invalid for TIPL"); + tag.addFrame(frame4); + + ID3v2::TextIdentificationFrame *frame5 = new ID3v2::TextIdentificationFrame("TMCL"); + StringList tmclData; + tmclData.append("VIOLIN"); + tmclData.append("a violinist"); + tmclData.append("PIANO"); + tmclData.append("a pianist"); + frame5->setText(tmclData); + tag.addFrame(frame5); + + PropertyMap properties = tag.properties(); + + CPPUNIT_ASSERT_EQUAL(2u, properties.unsupportedData().size()); + CPPUNIT_ASSERT(properties.unsupportedData().contains("TIPL")); + CPPUNIT_ASSERT(properties.unsupportedData().contains("APIC")); + + CPPUNIT_ASSERT(properties.contains("PERFORMER:VIOLIN")); + CPPUNIT_ASSERT(properties.contains("PERFORMER:PIANO")); + CPPUNIT_ASSERT_EQUAL(String("a violinist"), properties["PERFORMER:VIOLIN"].front()); + CPPUNIT_ASSERT_EQUAL(String("a pianist"), properties["PERFORMER:PIANO"].front()); + + CPPUNIT_ASSERT(properties.contains("LYRICS")); + CPPUNIT_ASSERT(properties.contains("LYRICS:TEST")); + + tag.removeUnsupportedProperties(properties.unsupportedData()); + CPPUNIT_ASSERT(tag.frameList("APIC").isEmpty()); + CPPUNIT_ASSERT(tag.frameList("TIPL").isEmpty()); + } + + void testDeleteFrame() + { + ScopedFileCopy copy("rare_frames", ".mp3"); + string newname = copy.fileName(); + MPEG::File f(newname.c_str()); + ID3v2::Tag *t = f.ID3v2Tag(); + ID3v2::Frame *frame = t->frameList("TCON")[0]; + CPPUNIT_ASSERT_EQUAL(1u, t->frameList("TCON").size()); + t->removeFrame(frame, true); + f.save(MPEG::File::ID3v2); + + MPEG::File f2(newname.c_str()); + t = f2.ID3v2Tag(); + CPPUNIT_ASSERT(t->frameList("TCON").isEmpty()); + } + + void testSaveAndStripID3v1ShouldNotAddFrameFromID3v1ToId3v2() + { + ScopedFileCopy copy("xing", ".mp3"); + string newname = copy.fileName(); + + { + MPEG::File foo(newname.c_str()); + foo.tag()->setArtist("Artist"); + foo.save(MPEG::File::ID3v1 | MPEG::File::ID3v2); + } + + { + MPEG::File bar(newname.c_str()); + bar.ID3v2Tag()->removeFrames("TPE1"); + // Should strip ID3v1 here and not add old values to ID3v2 again + bar.save(MPEG::File::ID3v2, true); + } + + MPEG::File f(newname.c_str()); + CPPUNIT_ASSERT(!f.ID3v2Tag()->frameListMap().contains("TPE1")); + } }; diff -Nru taglib-1.7.2/tests/test_it.cpp taglib-1.8/tests/test_it.cpp --- taglib-1.7.2/tests/test_it.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/tests/test_it.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,136 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include +#include +#include +#include "utils.h" + +using namespace std; +using namespace TagLib; +using TagLib::uint; + +static const String titleBefore("test song name"); +static const String titleAfter("changed title"); + +static const String commentBefore( + "This is a sample name.\n" + "In module file formats\n" + "sample names are abused\n" + "as multiline comments.\n" + " "); + +static const String newComment( + "This is a sample name!\n" + "In module file formats\n" + "sample names are abused\n" + "as multiline comments.\n" + "-----------------------------------\n" + "The previous line is truncated but starting with this line\n" + "the comment is not limeted in the line length but to 8000\n" + "additional characters (bytes).\n" + "\n" + "This is because it is saved in the 'message' proportion of\n" + "IT files."); + +static const String commentAfter( + "This is a sample name!\n" + "In module file formats\n" + "sample names are abused\n" + "as multiline comments.\n" + "-------------------------\n" + "The previous line is truncated but starting with this line\n" + "the comment is not limeted in the line length but to 8000\n" + "additional characters (bytes).\n" + "\n" + "This is because it is saved in the 'message' proportion of\n" + "IT files."); + +class TestIT : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(TestIT); + CPPUNIT_TEST(testReadTags); + CPPUNIT_TEST(testWriteTags); + CPPUNIT_TEST_SUITE_END(); + +public: + void testReadTags() + { + testRead(TEST_FILE_PATH_C("test.it"), titleBefore, commentBefore); + } + + void testWriteTags() + { + ScopedFileCopy copy("test", ".it"); + { + IT::File file(copy.fileName().c_str()); + CPPUNIT_ASSERT(file.tag() != 0); + file.tag()->setTitle(titleAfter); + file.tag()->setComment(newComment); + file.tag()->setTrackerName("won't be saved"); + CPPUNIT_ASSERT(file.save()); + } + testRead(copy.fileName().c_str(), titleAfter, commentAfter); + } + +private: + void testRead(FileName fileName, const String &title, const String &comment) + { + IT::File file(fileName); + + CPPUNIT_ASSERT(file.isValid()); + + IT::Properties *p = file.audioProperties(); + Mod::Tag *t = file.tag(); + + CPPUNIT_ASSERT(0 != p); + CPPUNIT_ASSERT(0 != t); + + CPPUNIT_ASSERT_EQUAL( 0, p->length()); + CPPUNIT_ASSERT_EQUAL( 0, p->bitrate()); + CPPUNIT_ASSERT_EQUAL( 0, p->sampleRate()); + CPPUNIT_ASSERT_EQUAL(64, p->channels()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 0, p->lengthInPatterns()); + CPPUNIT_ASSERT_EQUAL(true, p->stereo()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 0, p->instrumentCount()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 5, p->sampleCount()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 1, p->patternCount()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort)535, p->version()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort)532, p->compatibleVersion()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 9, p->flags()); + CPPUNIT_ASSERT_EQUAL((TagLib::uchar)128, p->globalVolume()); + CPPUNIT_ASSERT_EQUAL((TagLib::uchar) 48, p->mixVolume()); + CPPUNIT_ASSERT_EQUAL((TagLib::uchar)125, p->tempo()); + CPPUNIT_ASSERT_EQUAL((TagLib::uchar) 6, p->bpmSpeed()); + CPPUNIT_ASSERT_EQUAL((TagLib::uchar)128, p->panningSeparation()); + CPPUNIT_ASSERT_EQUAL((TagLib::uchar) 0, p->pitchWheelDepth()); + CPPUNIT_ASSERT_EQUAL(title, t->title()); + CPPUNIT_ASSERT_EQUAL(String::null, t->artist()); + CPPUNIT_ASSERT_EQUAL(String::null, t->album()); + CPPUNIT_ASSERT_EQUAL(comment, t->comment()); + CPPUNIT_ASSERT_EQUAL(String::null, t->genre()); + CPPUNIT_ASSERT_EQUAL(0U, t->year()); + CPPUNIT_ASSERT_EQUAL(0U, t->track()); + CPPUNIT_ASSERT_EQUAL(String("Impulse Tracker"), t->trackerName()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(TestIT); diff -Nru taglib-1.7.2/tests/test_mod.cpp taglib-1.8/tests/test_mod.cpp --- taglib-1.7.2/tests/test_mod.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/tests/test_mod.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,126 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include +#include +#include +#include "utils.h" + +using namespace std; +using namespace TagLib; + +static const String titleBefore("title of song"); +static const String titleAfter("changed title"); + +static const String commentBefore( + "Instrument names\n" + "are abused as\n" + "comments in\n" + "module file formats.\n" + "-+-+-+-+-+-+-+-+-+-+-+\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + +static const String newComment( + "This line will be truncated because it is too long for a mod instrument name.\n" + "This line is ok."); + +static const String commentAfter( + "This line will be trun\n" + "This line is ok.\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + +class TestMod : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(TestMod); + CPPUNIT_TEST(testReadTags); + CPPUNIT_TEST(testWriteTags); + CPPUNIT_TEST(testPropertyInterface); + CPPUNIT_TEST_SUITE_END(); + +public: + void testReadTags() + { + testRead(TEST_FILE_PATH_C("test.mod"), titleBefore, commentBefore); + } + + void testWriteTags() + { + ScopedFileCopy copy("test", ".mod"); + { + Mod::File file(copy.fileName().c_str()); + CPPUNIT_ASSERT(file.tag() != 0); + file.tag()->setTitle(titleAfter); + file.tag()->setComment(newComment); + CPPUNIT_ASSERT(file.save()); + } + testRead(copy.fileName().c_str(), titleAfter, commentAfter); + CPPUNIT_ASSERT(fileEqual( + copy.fileName(), + TEST_FILE_PATH_C("changed.mod"))); + } + + void testPropertyInterface() + { + Mod::Tag t; + PropertyMap properties; + properties["BLA"] = String("bla"); + properties["ARTIST"] = String("artist1"); + properties["ARTIST"].append("artist2"); + properties["TITLE"] = String("title"); + + PropertyMap unsupported = t.setProperties(properties); + CPPUNIT_ASSERT(unsupported.contains("BLA")); + CPPUNIT_ASSERT(unsupported.contains("ARTIST")); + CPPUNIT_ASSERT_EQUAL(properties["ARTIST"], unsupported["ARTIST"]); + CPPUNIT_ASSERT(!unsupported.contains("TITLE")); + } + +private: + void testRead(FileName fileName, const String &title, const String &comment) + { + Mod::File file(fileName); + + CPPUNIT_ASSERT(file.isValid()); + + Mod::Properties *p = file.audioProperties(); + Mod::Tag *t = file.tag(); + + CPPUNIT_ASSERT(0 != p); + CPPUNIT_ASSERT(0 != t); + + CPPUNIT_ASSERT_EQUAL(0, p->length()); + CPPUNIT_ASSERT_EQUAL(0, p->bitrate()); + CPPUNIT_ASSERT_EQUAL(0, p->sampleRate()); + CPPUNIT_ASSERT_EQUAL(8, p->channels()); + CPPUNIT_ASSERT_EQUAL(31U, p->instrumentCount()); + CPPUNIT_ASSERT_EQUAL((uchar)1, p->lengthInPatterns()); + CPPUNIT_ASSERT_EQUAL(title, t->title()); + CPPUNIT_ASSERT_EQUAL(String::null, t->artist()); + CPPUNIT_ASSERT_EQUAL(String::null, t->album()); + CPPUNIT_ASSERT_EQUAL(comment, t->comment()); + CPPUNIT_ASSERT_EQUAL(String::null, t->genre()); + CPPUNIT_ASSERT_EQUAL(0U, t->year()); + CPPUNIT_ASSERT_EQUAL(0U, t->track()); + CPPUNIT_ASSERT_EQUAL(String("StarTrekker"), t->trackerName()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(TestMod); diff -Nru taglib-1.7.2/tests/test_mp4.cpp taglib-1.8/tests/test_mp4.cpp --- taglib-1.7.2/tests/test_mp4.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_mp4.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -14,7 +14,8 @@ class TestMP4 : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestMP4); - CPPUNIT_TEST(testProperties); + CPPUNIT_TEST(testPropertiesAAC); + CPPUNIT_TEST(testPropertiesALAC); CPPUNIT_TEST(testFreeForm); CPPUNIT_TEST(testCheckValid); CPPUNIT_TEST(testUpdateStco); @@ -28,9 +29,9 @@ public: - void testProperties() + void testPropertiesAAC() { - MP4::File f("data/has-tags.m4a"); + MP4::File f(TEST_FILE_PATH_C("has-tags.m4a")); CPPUNIT_ASSERT_EQUAL(3, f.audioProperties()->length()); CPPUNIT_ASSERT_EQUAL(3, f.audioProperties()->bitrate()); CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); @@ -38,11 +39,21 @@ CPPUNIT_ASSERT_EQUAL(16, ((MP4::Properties *)f.audioProperties())->bitsPerSample()); } + void testPropertiesALAC() + { + MP4::File f(TEST_FILE_PATH_C("empty_alac.m4a")); + CPPUNIT_ASSERT_EQUAL(3, f.audioProperties()->length()); + CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->bitrate()); + CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); + CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate()); + CPPUNIT_ASSERT_EQUAL(16, ((MP4::Properties *)f.audioProperties())->bitsPerSample()); + } + void testCheckValid() { - MP4::File f("data/empty.aiff"); + MP4::File f(TEST_FILE_PATH_C("empty.aiff")); CPPUNIT_ASSERT(!f.isValid()); - MP4::File f2("data/has-tags.m4a"); + MP4::File f2(TEST_FILE_PATH_C("has-tags.m4a")); CPPUNIT_ASSERT(f2.isValid()); } @@ -156,14 +167,14 @@ void testGnre() { - MP4::File *f = new MP4::File("data/gnre.m4a"); + MP4::File *f = new MP4::File(TEST_FILE_PATH_C("gnre.m4a")); CPPUNIT_ASSERT_EQUAL(TagLib::String("Ska"), f->tag()->genre()); delete f; } void testCovrRead() { - MP4::File *f = new MP4::File("data/has-tags.m4a"); + MP4::File *f = new MP4::File(TEST_FILE_PATH_C("has-tags.m4a")); CPPUNIT_ASSERT(f->tag()->itemListMap().contains("covr")); MP4::CoverArtList l = f->tag()->itemListMap()["covr"].toCoverArtList(); CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), l.size()); @@ -202,7 +213,7 @@ void testCovrRead2() { - MP4::File *f = new MP4::File("data/covr-junk.m4a"); + MP4::File *f = new MP4::File(TEST_FILE_PATH_C("covr-junk.m4a")); CPPUNIT_ASSERT(f->tag()->itemListMap().contains("covr")); MP4::CoverArtList l = f->tag()->itemListMap()["covr"].toCoverArtList(); CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), l.size()); diff -Nru taglib-1.7.2/tests/test_mpc.cpp taglib-1.8/tests/test_mpc.cpp --- taglib-1.7.2/tests/test_mpc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/tests/test_mpc.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" + +using namespace std; +using namespace TagLib; + +class TestMPC : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(TestMPC); + CPPUNIT_TEST(testPropertiesSV8); + CPPUNIT_TEST(testPropertiesSV7); + CPPUNIT_TEST(testPropertiesSV5); + CPPUNIT_TEST(testPropertiesSV4); + CPPUNIT_TEST_SUITE_END(); + +public: + + void testPropertiesSV8() + { + MPC::File f(TEST_FILE_PATH_C("sv8_header.mpc")); + CPPUNIT_ASSERT_EQUAL(8, f.audioProperties()->mpcVersion()); + CPPUNIT_ASSERT_EQUAL(1, f.audioProperties()->length()); + CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->bitrate()); + CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); + CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate()); + } + + void testPropertiesSV7() + { + MPC::File f(TEST_FILE_PATH_C("click.mpc")); + CPPUNIT_ASSERT_EQUAL(7, f.audioProperties()->mpcVersion()); + CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->length()); + CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->bitrate()); + CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); + CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate()); + } + + void testPropertiesSV5() + { + MPC::File f(TEST_FILE_PATH_C("sv5_header.mpc")); + CPPUNIT_ASSERT_EQUAL(5, f.audioProperties()->mpcVersion()); + CPPUNIT_ASSERT_EQUAL(26, f.audioProperties()->length()); + CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->bitrate()); + CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); + CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate()); + } + + void testPropertiesSV4() + { + MPC::File f(TEST_FILE_PATH_C("sv4_header.mpc")); + CPPUNIT_ASSERT_EQUAL(4, f.audioProperties()->mpcVersion()); + CPPUNIT_ASSERT_EQUAL(26, f.audioProperties()->length()); + CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->bitrate()); + CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels()); + CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate()); + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(TestMPC); diff -Nru taglib-1.7.2/tests/test_mpeg.cpp taglib-1.8/tests/test_mpeg.cpp --- taglib-1.7.2/tests/test_mpeg.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_mpeg.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -2,6 +2,8 @@ #include #include #include +#include +#include "utils.h" using namespace std; using namespace TagLib; @@ -10,16 +12,70 @@ { CPPUNIT_TEST_SUITE(TestMPEG); CPPUNIT_TEST(testVersion2DurationWithXingHeader); + CPPUNIT_TEST(testSaveID3v24); + CPPUNIT_TEST(testSaveID3v24WrongParam); + CPPUNIT_TEST(testSaveID3v23); CPPUNIT_TEST_SUITE_END(); public: void testVersion2DurationWithXingHeader() { - MPEG::File f("data/mpeg2.mp3"); + MPEG::File f(TEST_FILE_PATH_C("mpeg2.mp3")); CPPUNIT_ASSERT_EQUAL(5387, f.audioProperties()->length()); } + void testSaveID3v24() + { + ScopedFileCopy copy("xing", ".mp3"); + string newname = copy.fileName(); + + String xxx = ByteVector(254, 'X'); + MPEG::File f(newname.c_str()); + f.tag()->setTitle(xxx); + f.tag()->setArtist("Artist A"); + f.save(MPEG::File::AllTags, true, 4); + + MPEG::File f2(newname.c_str()); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(4), f2.ID3v2Tag()->header()->majorVersion()); + CPPUNIT_ASSERT_EQUAL(String("Artist A"), f2.tag()->artist()); + CPPUNIT_ASSERT_EQUAL(xxx, f2.tag()->title()); + } + + void testSaveID3v24WrongParam() + { + ScopedFileCopy copy("xing", ".mp3"); + string newname = copy.fileName(); + + String xxx = ByteVector(254, 'X'); + MPEG::File f(newname.c_str()); + f.tag()->setTitle(xxx); + f.tag()->setArtist("Artist A"); + f.save(MPEG::File::AllTags, true, 8); + + MPEG::File f2(newname.c_str()); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(4), f2.ID3v2Tag()->header()->majorVersion()); + CPPUNIT_ASSERT_EQUAL(String("Artist A"), f2.tag()->artist()); + CPPUNIT_ASSERT_EQUAL(xxx, f2.tag()->title()); + } + + void testSaveID3v23() + { + ScopedFileCopy copy("xing", ".mp3"); + string newname = copy.fileName(); + + String xxx = ByteVector(254, 'X'); + MPEG::File f(newname.c_str()); + f.tag()->setTitle(xxx); + f.tag()->setArtist("Artist A"); + f.save(MPEG::File::AllTags, true, 3); + + MPEG::File f2(newname.c_str()); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), f2.ID3v2Tag()->header()->majorVersion()); + CPPUNIT_ASSERT_EQUAL(String("Artist A"), f2.tag()->artist()); + CPPUNIT_ASSERT_EQUAL(xxx, f2.tag()->title()); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestMPEG); diff -Nru taglib-1.7.2/tests/test_ogg.cpp taglib-1.8/tests/test_ogg.cpp --- taglib-1.7.2/tests/test_ogg.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_ogg.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +18,8 @@ CPPUNIT_TEST_SUITE(TestOGG); CPPUNIT_TEST(testSimple); CPPUNIT_TEST(testSplitPackets); + CPPUNIT_TEST(testDictInterface1); + CPPUNIT_TEST(testDictInterface2); CPPUNIT_TEST_SUITE_END(); public: @@ -51,6 +54,51 @@ delete f; } + void testDictInterface1() + { + ScopedFileCopy copy("empty", ".ogg"); + string newname = copy.fileName(); + + Vorbis::File *f = new Vorbis::File(newname.c_str()); + + CPPUNIT_ASSERT_EQUAL(TagLib::uint(0), f->tag()->properties().size()); + + PropertyMap newTags; + StringList values("value 1"); + values.append("value 2"); + newTags["ARTIST"] = values; + f->tag()->setProperties(newTags); + + PropertyMap map = f->tag()->properties(); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), map.size()); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), map["ARTIST"].size()); + CPPUNIT_ASSERT_EQUAL(String("value 1"), map["ARTIST"][0]); + delete f; + + } + + void testDictInterface2() + { + ScopedFileCopy copy("test", ".ogg"); + string newname = copy.fileName(); + + Vorbis::File *f = new Vorbis::File(newname.c_str()); + PropertyMap tags = f->tag()->properties(); + + CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), tags["UNUSUALTAG"].size()); + CPPUNIT_ASSERT_EQUAL(String("usual value"), tags["UNUSUALTAG"][0]); + CPPUNIT_ASSERT_EQUAL(String("another value"), tags["UNUSUALTAG"][1]); + CPPUNIT_ASSERT_EQUAL(String(L"öäüoΣø"), tags["UNICODETAG"][0]); + + tags["UNICODETAG"][0] = L"νεω ναλυε"; + tags.erase("UNUSUALTAG"); + f->tag()->setProperties(tags); + CPPUNIT_ASSERT_EQUAL(String(L"νεω ναλυε"), f->tag()->properties()["UNICODETAG"][0]); + CPPUNIT_ASSERT_EQUAL(false, f->tag()->properties().contains("UNUSUALTAG")); + + delete f; + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestOGG); diff -Nru taglib-1.7.2/tests/test_propertymap.cpp taglib-1.8/tests/test_propertymap.cpp --- taglib-1.7.2/tests/test_propertymap.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/tests/test_propertymap.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,32 @@ +#include +#include +class TestPropertyMap : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(TestPropertyMap); + CPPUNIT_TEST(testInvalidKeys); + CPPUNIT_TEST_SUITE_END(); + +public: + void testInvalidKeys() + { + TagLib::PropertyMap map1; + CPPUNIT_ASSERT(map1.isEmpty()); + map1["ÄÖÜ"].append("test"); + CPPUNIT_ASSERT_EQUAL(map1.size(), 1u); + + TagLib::PropertyMap map2; + map2["ÄÖÜ"].append("test"); + CPPUNIT_ASSERT(map1 == map2); + CPPUNIT_ASSERT(map1.contains(map2)); + + map2["ARTIST"] = TagLib::String("Test Artist"); + CPPUNIT_ASSERT(map1 != map2); + CPPUNIT_ASSERT(map2.contains(map1)); + + map2["ÄÖÜ"].append("test 2"); + CPPUNIT_ASSERT(!map2.contains(map1)); + + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(TestPropertyMap); diff -Nru taglib-1.7.2/tests/test_s3m.cpp taglib-1.8/tests/test_s3m.cpp --- taglib-1.7.2/tests/test_s3m.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/tests/test_s3m.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,123 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include +#include +#include "utils.h" + +using namespace std; +using namespace TagLib; + +static const String titleBefore("test song name"); +static const String titleAfter("changed title"); + +static const String commentBefore( + "This is an instrument name.\n" + "Module file formats\n" + "abuse instrument names\n" + "as multiline comments.\n" + " "); + +static const String newComment( + "This is an instrument name!\n" + "Module file formats\n" + "abuse instrument names\n" + "as multiline comments.\n" + "-----------------------------------\n" + "This line will be dropped and the previous is truncated."); + +static const String commentAfter( + "This is an instrument name!\n" + "Module file formats\n" + "abuse instrument names\n" + "as multiline comments.\n" + "---------------------------"); + +class TestS3M : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(TestS3M); + CPPUNIT_TEST(testReadTags); + CPPUNIT_TEST(testWriteTags); + CPPUNIT_TEST_SUITE_END(); + +public: + void testReadTags() + { + testRead(TEST_FILE_PATH_C("test.s3m"), titleBefore, commentBefore); + } + + void testWriteTags() + { + ScopedFileCopy copy("test", ".s3m"); + { + S3M::File file(copy.fileName().c_str()); + CPPUNIT_ASSERT(file.tag() != 0); + file.tag()->setTitle(titleAfter); + file.tag()->setComment(newComment); + file.tag()->setTrackerName("won't be saved"); + CPPUNIT_ASSERT(file.save()); + } + testRead(copy.fileName().c_str(), titleAfter, commentAfter); + CPPUNIT_ASSERT(fileEqual( + copy.fileName(), + TEST_FILE_PATH_C("changed.s3m"))); + } + +private: + void testRead(FileName fileName, const String &title, const String &comment) + { + S3M::File file(fileName); + + CPPUNIT_ASSERT(file.isValid()); + + S3M::Properties *p = file.audioProperties(); + Mod::Tag *t = file.tag(); + + CPPUNIT_ASSERT(0 != p); + CPPUNIT_ASSERT(0 != t); + + CPPUNIT_ASSERT_EQUAL( 0, p->length()); + CPPUNIT_ASSERT_EQUAL( 0, p->bitrate()); + CPPUNIT_ASSERT_EQUAL( 0, p->sampleRate()); + CPPUNIT_ASSERT_EQUAL(16, p->channels()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 0, p->lengthInPatterns()); + CPPUNIT_ASSERT_EQUAL(false, p->stereo()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 5, p->sampleCount()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 1, p->patternCount()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 0, p->flags()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort)4896, p->trackerVersion()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 2, p->fileFormatVersion()); + CPPUNIT_ASSERT_EQUAL((TagLib::uchar) 64, p->globalVolume()); + CPPUNIT_ASSERT_EQUAL((TagLib::uchar) 48, p->masterVolume()); + CPPUNIT_ASSERT_EQUAL((TagLib::uchar)125, p->tempo()); + CPPUNIT_ASSERT_EQUAL((TagLib::uchar) 6, p->bpmSpeed()); + CPPUNIT_ASSERT_EQUAL(title, t->title()); + CPPUNIT_ASSERT_EQUAL(String::null, t->artist()); + CPPUNIT_ASSERT_EQUAL(String::null, t->album()); + CPPUNIT_ASSERT_EQUAL(comment, t->comment()); + CPPUNIT_ASSERT_EQUAL(String::null, t->genre()); + CPPUNIT_ASSERT_EQUAL(0U, t->year()); + CPPUNIT_ASSERT_EQUAL(0U, t->track()); + CPPUNIT_ASSERT_EQUAL(String("ScreamTracker III"), t->trackerName()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(TestS3M); diff -Nru taglib-1.7.2/tests/test_string.cpp taglib-1.8/tests/test_string.cpp --- taglib-1.7.2/tests/test_string.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_string.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -41,6 +41,7 @@ CPPUNIT_TEST(testAppendCharDetach); CPPUNIT_TEST(testAppendStringDetach); CPPUNIT_TEST(testToInt); + CPPUNIT_TEST(testSubstr); CPPUNIT_TEST_SUITE_END(); public: @@ -193,6 +194,13 @@ CPPUNIT_ASSERT_EQUAL(String("-123aa").toInt(), -123); } + void testSubstr() + { + CPPUNIT_ASSERT_EQUAL(String("01"), String("0123456").substr(0, 2)); + CPPUNIT_ASSERT_EQUAL(String("12"), String("0123456").substr(1, 2)); + CPPUNIT_ASSERT_EQUAL(String("123456"), String("0123456").substr(1, 200)); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestString); diff -Nru taglib-1.7.2/tests/test_trueaudio.cpp taglib-1.8/tests/test_trueaudio.cpp --- taglib-1.7.2/tests/test_trueaudio.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_trueaudio.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -2,6 +2,7 @@ #include #include #include +#include "utils.h" using namespace std; using namespace TagLib; @@ -16,7 +17,7 @@ void testReadPropertiesWithoutID3v2() { - TrueAudio::File f("data/empty.tta"); + TrueAudio::File f(TEST_FILE_PATH_C("empty.tta")); CPPUNIT_ASSERT(f.audioProperties()); CPPUNIT_ASSERT_EQUAL(3, f.audioProperties()->length()); } diff -Nru taglib-1.7.2/tests/test_wav.cpp taglib-1.8/tests/test_wav.cpp --- taglib-1.7.2/tests/test_wav.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_wav.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -20,14 +20,14 @@ void testLength() { - RIFF::WAV::File f("data/empty.wav"); + RIFF::WAV::File f(TEST_FILE_PATH_C("empty.wav")); CPPUNIT_ASSERT_EQUAL(true, f.isValid()); CPPUNIT_ASSERT_EQUAL(3, f.audioProperties()->length()); } void testZeroSizeDataChunk() { - RIFF::WAV::File f("data/zero-size-chunk.wav"); + RIFF::WAV::File f(TEST_FILE_PATH_C("zero-size-chunk.wav")); CPPUNIT_ASSERT_EQUAL(false, f.isValid()); } diff -Nru taglib-1.7.2/tests/test_wavpack.cpp taglib-1.8/tests/test_wavpack.cpp --- taglib-1.7.2/tests/test_wavpack.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_wavpack.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -20,7 +20,7 @@ void testBasic() { - WavPack::File f("data/no_length.wv"); + WavPack::File f(TEST_FILE_PATH_C("no_length.wv")); WavPack::Properties *props = f.audioProperties(); CPPUNIT_ASSERT_EQUAL(44100, props->sampleRate()); CPPUNIT_ASSERT_EQUAL(2, props->channels()); @@ -30,7 +30,7 @@ void testLengthScan() { - WavPack::File f("data/no_length.wv"); + WavPack::File f(TEST_FILE_PATH_C("no_length.wv")); WavPack::Properties *props = f.audioProperties(); CPPUNIT_ASSERT_EQUAL(4, props->length()); } diff -Nru taglib-1.7.2/tests/test_xiphcomment.cpp taglib-1.8/tests/test_xiphcomment.cpp --- taglib-1.7.2/tests/test_xiphcomment.cpp 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/test_xiphcomment.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "utils.h" @@ -15,6 +16,7 @@ CPPUNIT_TEST(testSetYear); CPPUNIT_TEST(testTrack); CPPUNIT_TEST(testSetTrack); + CPPUNIT_TEST(testInvalidKeys); CPPUNIT_TEST_SUITE_END(); public: @@ -59,6 +61,19 @@ CPPUNIT_ASSERT_EQUAL(String("3"), cmt.fieldListMap()["TRACKNUMBER"].front()); } + void testInvalidKeys() + { + PropertyMap map; + map[""] = String("invalid key: empty string"); + map["A=B"] = String("invalid key: contains '='"); + map["A~B"] = String("invalid key: contains '~'"); + + Ogg::XiphComment cmt; + PropertyMap unsuccessful = cmt.setProperties(map); + CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), unsuccessful.size()); + CPPUNIT_ASSERT(cmt.properties().isEmpty()); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestXiphComment); diff -Nru taglib-1.7.2/tests/test_xm.cpp taglib-1.8/tests/test_xm.cpp --- taglib-1.7.2/tests/test_xm.cpp 1970-01-01 00:00:00.000000000 +0000 +++ taglib-1.8/tests/test_xm.cpp 2012-09-06 18:03:15.000000000 +0000 @@ -0,0 +1,216 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include +#include +#include "utils.h" + +using namespace std; +using namespace TagLib; + +static const String titleBefore("title of song"); +static const String titleAfter("changed title"); + +static const String trackerNameBefore("MilkyTracker "); +static const String trackerNameAfter("TagLib"); + +static const String commentBefore( + "Instrument names\n" + "are abused as\n" + "comments in\n" + "module file formats.\n" + "-+-+-+-+-+-+-+-+-+-+-+\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n" + "Sample\n" + "names\n" + "are sometimes\n" + "also abused as\n" + "comments."); + +static const String newCommentShort( + "Instrument names\n" + "are abused as\n" + "comments in\n" + "module file formats.\n" + "======================\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n" + "Sample names\n" + "are sometimes\n" + "also abused as\n" + "comments."); + +static const String newCommentLong( + "Instrument names\n" + "are abused as\n" + "comments in\n" + "module file formats.\n" + "======================\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n" + "Sample names\n" + "are sometimes\n" + "also abused as\n" + "comments.\n" + "\n\n\n\n\n\n\n" + "TEST"); + +static const String commentAfter( + "Instrument names\n" + "are abused as\n" + "comments in\n" + "module file formats.\n" + "======================\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n" + "Sample names\n" + "are sometimes\n" + "also abused as\n" + "comments.\n"); + +class TestXM : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(TestXM); + CPPUNIT_TEST(testReadTags); + CPPUNIT_TEST(testReadStrippedTags); + CPPUNIT_TEST(testWriteTagsShort); + CPPUNIT_TEST(testWriteTagsLong); + CPPUNIT_TEST_SUITE_END(); + +public: + void testReadTags() + { + testRead(TEST_FILE_PATH_C("test.xm"), titleBefore, + commentBefore, trackerNameBefore); + } + + void testReadStrippedTags() + { + XM::File file(TEST_FILE_PATH_C("stripped.xm")); + CPPUNIT_ASSERT(file.isValid()); + + XM::Properties *p = file.audioProperties(); + Mod::Tag *t = file.tag(); + + CPPUNIT_ASSERT(0 != p); + CPPUNIT_ASSERT(0 != t); + + CPPUNIT_ASSERT_EQUAL(0, p->length()); + CPPUNIT_ASSERT_EQUAL(0, p->bitrate()); + CPPUNIT_ASSERT_EQUAL(0, p->sampleRate()); + CPPUNIT_ASSERT_EQUAL(8, p->channels()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 1, p->lengthInPatterns()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 0, p->version()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 0 , p->restartPosition()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 1, p->patternCount()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 0, p->instrumentCount()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 1, p->flags()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 6, p->tempo()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort)125, p->bpmSpeed()); + CPPUNIT_ASSERT_EQUAL(titleBefore, t->title()); + CPPUNIT_ASSERT_EQUAL(String::null, t->artist()); + CPPUNIT_ASSERT_EQUAL(String::null, t->album()); + CPPUNIT_ASSERT_EQUAL(String::null, t->comment()); + CPPUNIT_ASSERT_EQUAL(String::null, t->genre()); + CPPUNIT_ASSERT_EQUAL(0U, t->year()); + CPPUNIT_ASSERT_EQUAL(0U, t->track()); + CPPUNIT_ASSERT_EQUAL(String::null, t->trackerName()); + } + + void testWriteTagsShort() + { + testWriteTags(newCommentShort); + } + + void testWriteTagsLong() + { + testWriteTags(newCommentLong); + } + +private: + void testRead(FileName fileName, const String &title, + const String &comment, const String &trackerName) + { + XM::File file(fileName); + + CPPUNIT_ASSERT(file.isValid()); + + XM::Properties *p = file.audioProperties(); + Mod::Tag *t = file.tag(); + + CPPUNIT_ASSERT(0 != p); + CPPUNIT_ASSERT(0 != t); + + CPPUNIT_ASSERT_EQUAL(0, p->length()); + CPPUNIT_ASSERT_EQUAL(0, p->bitrate()); + CPPUNIT_ASSERT_EQUAL(0, p->sampleRate()); + CPPUNIT_ASSERT_EQUAL(8, p->channels()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 1, p->lengthInPatterns()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort)260, p->version()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 0, p->restartPosition()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 1, p->patternCount()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort)128, p->instrumentCount()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 1, p->flags()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort) 6, p->tempo()); + CPPUNIT_ASSERT_EQUAL((TagLib::ushort)125, p->bpmSpeed()); + CPPUNIT_ASSERT_EQUAL(title, t->title()); + CPPUNIT_ASSERT_EQUAL(String::null, t->artist()); + CPPUNIT_ASSERT_EQUAL(String::null, t->album()); + CPPUNIT_ASSERT_EQUAL(comment, t->comment()); + CPPUNIT_ASSERT_EQUAL(String::null, t->genre()); + CPPUNIT_ASSERT_EQUAL(0U, t->year()); + CPPUNIT_ASSERT_EQUAL(0U, t->track()); + CPPUNIT_ASSERT_EQUAL(trackerName, t->trackerName()); + } + + void testWriteTags(const String &comment) + { + ScopedFileCopy copy("test", ".xm"); + { + XM::File file(copy.fileName().c_str()); + CPPUNIT_ASSERT(file.tag() != 0); + file.tag()->setTitle(titleAfter); + file.tag()->setComment(comment); + file.tag()->setTrackerName(trackerNameAfter); + CPPUNIT_ASSERT(file.save()); + } + testRead(copy.fileName().c_str(), titleAfter, + commentAfter, trackerNameAfter); + CPPUNIT_ASSERT(fileEqual( + copy.fileName(), + TEST_FILE_PATH_C("changed.xm"))); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(TestXM); diff -Nru taglib-1.7.2/tests/utils.h taglib-1.8/tests/utils.h --- taglib-1.7.2/tests/utils.h 2012-04-20 15:57:13.000000000 +0000 +++ taglib-1.8/tests/utils.h 2012-09-06 18:03:15.000000000 +0000 @@ -1,3 +1,6 @@ +#ifdef HAVE_CONFIG_H +#include +#endif #ifdef _WIN32 #include #else @@ -6,14 +9,23 @@ #include #endif #include +#include #include +#include using namespace std; +inline string testFilePath(const string &filename) +{ + return string(TESTS_DIR "data/") + filename; +} + +#define TEST_FILE_PATH_C(f) testFilePath(f).c_str() + inline string copyFile(const string &filename, const string &ext) { string newname = string(tempnam(NULL, NULL)) + ext; - string oldname = string("data/") + filename + ext; + string oldname = testFilePath(filename) + ext; #ifdef _WIN32 CopyFile(oldname.c_str(), newname.c_str(), FALSE); SetFileAttributes(newname.c_str(), GetFileAttributes(newname.c_str()) & ~FILE_ATTRIBUTE_READONLY); @@ -35,6 +47,35 @@ remove(filename.c_str()); } +inline bool fileEqual(const string &filename1, const string &filename2) +{ + char buf1[BUFSIZ]; + char buf2[BUFSIZ]; + + ifstream stream1(filename1.c_str(), ios_base::in | ios_base::binary); + ifstream stream2(filename2.c_str(), ios_base::in | ios_base::binary); + + if(!stream1 && !stream2) return true; + if(!stream1 || !stream2) return false; + + for(;;) + { + stream1.read(buf1, BUFSIZ); + stream2.read(buf2, BUFSIZ); + + streamsize n1 = stream1.gcount(); + streamsize n2 = stream2.gcount(); + + if(n1 != n2) return false; + + if(n1 == 0) break; + + if(memcmp(buf1, buf2, n1) != 0) return false; + } + + return stream1.good() == stream2.good(); +} + class ScopedFileCopy { public: