From 2b5ee8deb93fd08da1351cd3e746125cb83a157d Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Fri, 30 Jan 2015 14:43:05 +0900 Subject: [PATCH] Fix saving ID3v2/INFO tags of WAV files. The old tag won't be removed when the new tag is empty. --- taglib/riff/wav/wavfile.cpp | 37 +++++++++++------- tests/test_wav.cpp | 76 +++++++++++++++++++++++++++++++++++-- 2 files changed, 96 insertions(+), 17 deletions(-) diff --git a/taglib/riff/wav/wavfile.cpp b/taglib/riff/wav/wavfile.cpp index c8d0578c..6c835e70 100644 --- a/taglib/riff/wav/wavfile.cpp +++ b/taglib/riff/wav/wavfile.cpp @@ -57,7 +57,7 @@ public: } Properties *properties; - + ByteVector tagChunkID; TagUnion tag; @@ -146,21 +146,30 @@ bool RIFF::WAV::File::save(TagTypes tags, bool stripOthers, int id3v2Version) if(stripOthers) strip(static_cast(AllTags & ~tags)); - ID3v2::Tag *id3v2tag = d->tag.access(ID3v2Index, false); - if((tags & ID3v2) && !id3v2tag->isEmpty()) { - setChunkData(d->tagChunkID, id3v2tag->render(id3v2Version)); - d->hasID3v2 = true; + const ID3v2::Tag *id3v2tag = d->tag.access(ID3v2Index, false); + if(tags & ID3v2) { + if(d->hasID3v2) { + removeChunk(d->tagChunkID); + d->hasID3v2 = false; + } + + if(!id3v2tag->isEmpty()) { + setChunkData(d->tagChunkID, id3v2tag->render(id3v2Version)); + d->hasID3v2 = true; + } } - Info::Tag *infotag = d->tag.access(InfoIndex, false); - if((tags & Info) && !infotag->isEmpty()) { - int chunkId = findInfoTagChunk(); - if(chunkId != -1) - setChunkData(chunkId, infotag->render()); - else - setChunkData("LIST", infotag->render(), true); + const Info::Tag *infotag = d->tag.access(InfoIndex, false); + if(tags & Info) { + if(d->hasInfo) { + removeChunk(findInfoTagChunk()); + d->hasInfo = false; + } - d->hasInfo = true; + if(!infotag->isEmpty()) { + setChunkData("LIST", infotag->render(), true); + d->hasInfo = true; + } } return true; @@ -239,6 +248,6 @@ TagLib::uint RIFF::WAV::File::findInfoTagChunk() return i; } } - + return TagLib::uint(-1); } diff --git a/tests/test_wav.cpp b/tests/test_wav.cpp index 7367357a..a962ca23 100644 --- a/tests/test_wav.cpp +++ b/tests/test_wav.cpp @@ -1,9 +1,11 @@ -#include #include #include #include +#include +#include #include #include +#include #include "utils.h" using namespace std; @@ -14,6 +16,8 @@ class TestWAV : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(TestWAV); CPPUNIT_TEST(testLength); CPPUNIT_TEST(testZeroSizeDataChunk); + CPPUNIT_TEST(testID3v2Tag); + CPPUNIT_TEST(testInfoTag); CPPUNIT_TEST(testStripTags); CPPUNIT_TEST(testFuzzedFile1); CPPUNIT_TEST(testFuzzedFile2); @@ -24,14 +28,80 @@ public: void testLength() { RIFF::WAV::File f(TEST_FILE_PATH_C("empty.wav")); - CPPUNIT_ASSERT_EQUAL(true, f.isValid()); + CPPUNIT_ASSERT(f.isValid()); CPPUNIT_ASSERT_EQUAL(3, f.audioProperties()->length()); } void testZeroSizeDataChunk() { RIFF::WAV::File f(TEST_FILE_PATH_C("zero-size-chunk.wav")); - CPPUNIT_ASSERT_EQUAL(false, f.isValid()); + CPPUNIT_ASSERT(!f.isValid()); + } + + void testID3v2Tag() + { + ScopedFileCopy copy("empty", ".wav"); + string filename = copy.fileName(); + + { + RIFF::WAV::File f(filename.c_str()); + CPPUNIT_ASSERT(f.isValid()); + + f.ID3v2Tag()->setTitle(L"Title"); + f.ID3v2Tag()->setArtist(L"Artist"); + f.save(); + } + + { + RIFF::WAV::File f(filename.c_str()); + CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT_EQUAL(String(L"Title"), f.ID3v2Tag()->title()); + CPPUNIT_ASSERT_EQUAL(String(L"Artist"), f.ID3v2Tag()->artist()); + + f.ID3v2Tag()->setTitle(L""); + f.ID3v2Tag()->setArtist(L""); + f.save(); + } + + { + RIFF::WAV::File f(filename.c_str()); + CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT_EQUAL(String(L""), f.ID3v2Tag()->title()); + CPPUNIT_ASSERT_EQUAL(String(L""), f.ID3v2Tag()->artist()); + } + } + + void testInfoTag() + { + ScopedFileCopy copy("empty", ".wav"); + string filename = copy.fileName(); + + { + RIFF::WAV::File f(filename.c_str()); + CPPUNIT_ASSERT(f.isValid()); + + f.InfoTag()->setTitle(L"Title"); + f.InfoTag()->setArtist(L"Artist"); + f.save(); + } + + { + RIFF::WAV::File f(filename.c_str()); + CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT_EQUAL(String(L"Title"), f.InfoTag()->title()); + CPPUNIT_ASSERT_EQUAL(String(L"Artist"), f.InfoTag()->artist()); + + f.InfoTag()->setTitle(L""); + f.InfoTag()->setArtist(L""); + f.save(); + } + + { + RIFF::WAV::File f(filename.c_str()); + CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT_EQUAL(String(L""), f.InfoTag()->title()); + CPPUNIT_ASSERT_EQUAL(String(L""), f.InfoTag()->artist()); + } } void testStripTags()