From a27199b7722b857bc6c4bc4cad5afa6bebc5c5d2 Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu <tsuda.kageyu@gmail.com> Date: Wed, 24 Feb 2016 00:26:37 +0900 Subject: [PATCH] Support Boost iostreams library to decode compressed ID3v2 frames in additiion to zlib. This will help Windows users build TagLib without zlib source. --- ConfigureChecks.cmake | 9 ++++++++ config.h.cmake | 1 + taglib/CMakeLists.txt | 6 ++++- taglib/toolkit/tzlib.cpp | 47 +++++++++++++++++++++++++++++++++++----- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index 0f2b6d87..ee4fdc2e 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -225,6 +225,15 @@ if(NOT ZLIB_SOURCE) else() set(HAVE_ZLIB 0) endif() + + if(NOT HAVE_ZLIB) + find_package(Boost COMPONENTS iostreams zlib) + if(Boost_IOSTREAMS_FOUND AND Boost_ZLIB_FOUND) + set(HAVE_BOOST_ZLIB 1) + else() + set(HAVE_BOOST_ZLIB 0) + endif() + endif() endif() # Determine whether CppUnit is installed. diff --git a/config.h.cmake b/config.h.cmake index 7ac72410..7eb5993f 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -25,6 +25,7 @@ /* Defined if zlib is installed */ #cmakedefine HAVE_ZLIB 1 +#cmakedefine HAVE_BOOST_ZLIB 1 /* Indicates whether debug messages are shown even in release mode */ #cmakedefine TRACE_IN_RELEASE 1 diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt index f248d0d1..000f7937 100644 --- a/taglib/CMakeLists.txt +++ b/taglib/CMakeLists.txt @@ -32,7 +32,7 @@ elseif(HAVE_ZLIB_SOURCE) include_directories(${ZLIB_SOURCE}) endif() -if(HAVE_BOOST_BYTESWAP OR HAVE_BOOST_ATOMIC) +if(HAVE_BOOST_BYTESWAP OR HAVE_BOOST_ATOMIC OR HAVE_BOOST_ZLIB) include_directories(${Boost_INCLUDE_DIR}) endif() @@ -352,6 +352,10 @@ if(HAVE_BOOST_ATOMIC) target_link_libraries(tag ${Boost_ATOMIC_LIBRARY}) endif() +if(HAVE_BOOST_ZLIB) + target_link_libraries(tag ${Boost_IOSTREAMS_LIBRARY} ${Boost_ZLIB_LIBRARY}) +endif() + set_target_properties(tag PROPERTIES VERSION ${TAGLIB_SOVERSION_MAJOR}.${TAGLIB_SOVERSION_MINOR}.${TAGLIB_SOVERSION_PATCH} SOVERSION ${TAGLIB_SOVERSION_MAJOR} diff --git a/taglib/toolkit/tzlib.cpp b/taglib/toolkit/tzlib.cpp index 3d49732a..40158fd2 100644 --- a/taglib/toolkit/tzlib.cpp +++ b/taglib/toolkit/tzlib.cpp @@ -27,8 +27,11 @@ # include <config.h> #endif -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) # include <zlib.h> +#elif defined(HAVE_BOOST_ZLIB) +# include <boost/iostreams/filtering_streambuf.hpp> +# include <boost/iostreams/filter/zlib.hpp> #endif #include <tstring.h> @@ -40,7 +43,7 @@ using namespace TagLib; bool zlib::isAvailable() { -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BOOST_ZLIB) return true; @@ -53,7 +56,7 @@ bool zlib::isAvailable() ByteVector zlib::decompress(const ByteVector &data) { -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) z_stream stream = {}; @@ -81,9 +84,9 @@ ByteVector zlib::decompress(const ByteVector &data) const int result = inflate(&stream, Z_NO_FLUSH); if(result == Z_STREAM_ERROR || - result == Z_NEED_DICT || - result == Z_DATA_ERROR || - result == Z_MEM_ERROR) + result == Z_NEED_DICT || + result == Z_DATA_ERROR || + result == Z_MEM_ERROR) { if(result != Z_STREAM_ERROR) inflateEnd(&stream); @@ -99,6 +102,38 @@ ByteVector zlib::decompress(const ByteVector &data) return outData; +#elif defined(HAVE_BOOST_ZLIB) + + using namespace boost::iostreams; + + struct : public sink + { + ByteVector data; + + typedef char char_type; + typedef sink_tag category; + + std::streamsize write(char const* s, std::streamsize n) + { + const unsigned int originalSize = data.size(); + + data.resize(static_cast<unsigned int>(originalSize + n)); + ::memcpy(data.data() + originalSize, s, static_cast<size_t>(n)); + + return n; + } + } sink; + + try { + zlib_decompressor().write(sink, data.data(), data.size()); + } + catch(const zlib_error &) { + debug("zlib::decompress() - Error reading compressed stream."); + return ByteVector(); + } + + return sink.data; + #else return ByteVector(); -- 2.40.0