mirror of
https://github.com/taglib/taglib.git
synced 2025-06-04 01:28:21 -04:00
Merge branch 'master' into merge-master-to-taglib2
# Conflicts: # taglib/ape/apetag.cpp # taglib/ape/apetag.h # taglib/flac/flacproperties.cpp # taglib/mpeg/id3v1/id3v1tag.cpp # taglib/mpeg/id3v2/id3v2tag.cpp # taglib/riff/rifffile.cpp # taglib/riff/wav/infotag.cpp # taglib/toolkit/tbytevector.cpp
This commit is contained in:
commit
d36550f96d
@ -7,5 +7,5 @@ Name: TagLib
|
||||
Description: Audio meta-data library
|
||||
Requires:
|
||||
Version: ${TAGLIB_LIB_VERSION_STRING}
|
||||
Libs: -L${LIB_INSTALL_DIR} -ltag
|
||||
Cflags: -I${INCLUDE_INSTALL_DIR}/taglib
|
||||
Libs: -L${dollar}{libdir} -ltag
|
||||
Cflags: -I${dollar}{includedir}/taglib
|
||||
|
@ -48,7 +48,6 @@ class APE::Tag::TagPrivate
|
||||
{
|
||||
public:
|
||||
Footer footer;
|
||||
|
||||
ItemListMap itemListMap;
|
||||
};
|
||||
|
||||
|
@ -160,7 +160,7 @@ namespace
|
||||
return new Ogg::Opus::File(arg, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "TTA")
|
||||
return new TrueAudio::File(arg, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "M4A" || ext == "M4R" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2")
|
||||
if(ext == "M4A" || ext == "M4R" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2" || ext == "M4V")
|
||||
return new MP4::File(arg, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "WMA" || ext == "ASF")
|
||||
return new ASF::File(arg, readAudioProperties, audioPropertiesStyle);
|
||||
@ -319,6 +319,7 @@ StringList FileRef::defaultFileExtensions()
|
||||
l.append("m4p");
|
||||
l.append("3g2");
|
||||
l.append("mp4");
|
||||
l.append("m4v");
|
||||
l.append("wma");
|
||||
l.append("asf");
|
||||
l.append("aif");
|
||||
|
@ -152,8 +152,8 @@ void FLAC::AudioProperties::read(const ByteVector &data, long long streamLength)
|
||||
// The last 4 bits are the most significant 4 bits for the 36 bit
|
||||
// stream length in samples. (Audio files measured in days)
|
||||
|
||||
const ulonglong hi = flags & 0xf;
|
||||
const ulonglong lo = data.toUInt32BE(pos);
|
||||
const unsigned long long hi = flags & 0xf;
|
||||
const unsigned long long lo = data.toUInt32BE(pos);
|
||||
pos += 4;
|
||||
|
||||
d->sampleFrames = (hi << 32) | lo;
|
||||
|
@ -62,10 +62,9 @@ namespace
|
||||
class ID3v1::Tag::TagPrivate
|
||||
{
|
||||
public:
|
||||
TagPrivate() : file(0), tagOffset(-1), track(0), genre(255) {}
|
||||
|
||||
File *file;
|
||||
long long tagOffset;
|
||||
TagPrivate() :
|
||||
track(0),
|
||||
genre(255) {}
|
||||
|
||||
String title;
|
||||
String artist;
|
||||
@ -80,18 +79,17 @@ public:
|
||||
// public methods
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ID3v1::Tag::Tag() : TagLib::Tag()
|
||||
ID3v1::Tag::Tag() :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
d = new TagPrivate;
|
||||
}
|
||||
|
||||
ID3v1::Tag::Tag(File *file, long long tagOffset) : TagLib::Tag()
|
||||
ID3v1::Tag::Tag(File *file, long long tagOffset) :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
d = new TagPrivate;
|
||||
d->file = file;
|
||||
d->tagOffset = tagOffset;
|
||||
|
||||
read();
|
||||
read(file, tagOffset);
|
||||
}
|
||||
|
||||
ID3v1::Tag::~Tag()
|
||||
@ -222,12 +220,12 @@ void ID3v1::Tag::setStringHandler(const TagLib::StringHandler *handler)
|
||||
// protected methods
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ID3v1::Tag::read()
|
||||
void ID3v1::Tag::read(File *file, long tagOffset)
|
||||
{
|
||||
if(d->file && d->file->isValid()) {
|
||||
d->file->seek(d->tagOffset);
|
||||
if(file && file->isValid()) {
|
||||
file->seek(tagOffset);
|
||||
// read the tag -- always 128 bytes
|
||||
ByteVector data = d->file->readBlock(128);
|
||||
const ByteVector data = file->readBlock(128);
|
||||
|
||||
// some initial sanity checking
|
||||
if(data.size() == 128 && data.startsWith("TAG"))
|
||||
|
@ -140,7 +140,7 @@ namespace TagLib {
|
||||
/*!
|
||||
* Reads from the file specified in the constructor.
|
||||
*/
|
||||
void read();
|
||||
void read(File *file, long tagOffset);
|
||||
/*!
|
||||
* Pareses the body of the tag in \a data.
|
||||
*/
|
||||
|
@ -84,8 +84,7 @@ class ID3v2::Tag::TagPrivate
|
||||
{
|
||||
public:
|
||||
TagPrivate() :
|
||||
file(0),
|
||||
tagOffset(-1),
|
||||
fileLength(0),
|
||||
extendedHeader(0),
|
||||
footer(0)
|
||||
{
|
||||
@ -98,8 +97,7 @@ public:
|
||||
delete footer;
|
||||
}
|
||||
|
||||
File *file;
|
||||
long long tagOffset;
|
||||
long long fileLength;
|
||||
const FrameFactory *factory;
|
||||
|
||||
Header header;
|
||||
@ -125,11 +123,9 @@ ID3v2::Tag::Tag(File *file, long long tagOffset, const FrameFactory *factory) :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
d->file = file;
|
||||
d->tagOffset = tagOffset;
|
||||
d->factory = factory;
|
||||
|
||||
read();
|
||||
read(file, tagOffset);
|
||||
}
|
||||
|
||||
ID3v2::Tag::~Tag()
|
||||
@ -794,7 +790,8 @@ ByteVector ID3v2::Tag::render(int version) const
|
||||
|
||||
// Compute the amount of padding, and append that to tagData.
|
||||
|
||||
long long paddingSize = d->header.tagSize() - (tagData.size() - Header::size());
|
||||
long long originalSize = d->header.tagSize();
|
||||
long long paddingSize = originalSize - (tagData.size() - Header::size());
|
||||
|
||||
if(paddingSize <= 0) {
|
||||
paddingSize = MinPaddingSize;
|
||||
@ -802,7 +799,7 @@ ByteVector ID3v2::Tag::render(int version) const
|
||||
else {
|
||||
// Padding won't increase beyond 1% of the file size or 1MB.
|
||||
|
||||
long long threshold = d->file ? d->file->length() / 100 : 0;
|
||||
long long threshold = d->fileLength / 100;
|
||||
threshold = std::max(threshold, MinPaddingSize);
|
||||
threshold = std::min(threshold, MaxPaddingSize);
|
||||
|
||||
@ -816,6 +813,9 @@ ByteVector ID3v2::Tag::render(int version) const
|
||||
d->header.setMajorVersion(version);
|
||||
d->header.setTagSize(static_cast<TagLib::uint>(tagData.size() - Header::size()));
|
||||
|
||||
if(d->fileLength > 0)
|
||||
d->fileLength += (d->header.tagSize() - originalSize);
|
||||
|
||||
// TODO: This should eventually include d->footer->render().
|
||||
const ByteVector headerData = d->header.render();
|
||||
std::copy(headerData.begin(), headerData.end(), tagData.begin());
|
||||
@ -840,22 +840,24 @@ void ID3v2::Tag::setLatin1StringHandler(const TagLib::StringHandler *handler)
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ID3v2::Tag::read()
|
||||
void ID3v2::Tag::read(TagLib::File *file, long offset)
|
||||
{
|
||||
if(!d->file)
|
||||
if(!file)
|
||||
return;
|
||||
|
||||
if(!d->file->isOpen())
|
||||
if(!file->isOpen())
|
||||
return;
|
||||
|
||||
d->file->seek(d->tagOffset);
|
||||
d->header.setData(d->file->readBlock(Header::size()));
|
||||
d->fileLength = file->length();
|
||||
|
||||
file->seek(offset);
|
||||
d->header.setData(file->readBlock(Header::size()));
|
||||
|
||||
// If the tag size is 0, then this is an invalid tag (tags must contain at
|
||||
// least one frame)
|
||||
|
||||
if(d->header.tagSize() != 0)
|
||||
parse(d->file->readBlock(d->header.tagSize()));
|
||||
parse(file->readBlock(d->header.tagSize()));
|
||||
|
||||
// Look for duplicate ID3v2 tags and treat them as an extra blank of this one.
|
||||
// It leads to overwriting them with zero when saving the tag.
|
||||
@ -867,9 +869,9 @@ void ID3v2::Tag::read()
|
||||
|
||||
while(true) {
|
||||
|
||||
d->file->seek(d->tagOffset + d->header.completeTagSize() + extraSize);
|
||||
file->seek(offset + d->header.completeTagSize() + extraSize);
|
||||
|
||||
const ByteVector data = d->file->readBlock(Header::size());
|
||||
const ByteVector data = file->readBlock(Header::size());
|
||||
if(data.size() < Header::size() || !data.startsWith(Header::fileIdentifier()))
|
||||
break;
|
||||
|
||||
|
@ -356,7 +356,7 @@ namespace TagLib {
|
||||
* the Header, the body of the tag (which contains the ExtendedHeader and
|
||||
* frames) and Footer.
|
||||
*/
|
||||
void read();
|
||||
void read(TagLib::File *file, long offset);
|
||||
|
||||
/*!
|
||||
* This is called by read to parse the body of the tag. It determines if an
|
||||
|
@ -100,11 +100,16 @@ bool RIFF::AIFF::File::save()
|
||||
return false;
|
||||
}
|
||||
|
||||
removeChunk("ID3 ");
|
||||
removeChunk("id3 ");
|
||||
if(d->hasID3v2) {
|
||||
removeChunk("ID3 ");
|
||||
removeChunk("id3 ");
|
||||
d->hasID3v2 = false;
|
||||
}
|
||||
|
||||
setChunkData("ID3 ", d->tag->render());
|
||||
d->hasID3v2 = true;
|
||||
if(tag() && !tag()->isEmpty()) {
|
||||
setChunkData("ID3 ", d->tag->render());
|
||||
d->hasID3v2 = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -23,13 +23,15 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <tbytevector.h>
|
||||
#include <tdebug.h>
|
||||
#include <tstring.h>
|
||||
|
||||
#include "rifffile.h"
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include "riffutils.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
@ -47,13 +49,11 @@ namespace
|
||||
class RIFF::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate() :
|
||||
endianness(BigEndian),
|
||||
size(0)
|
||||
{
|
||||
}
|
||||
FilePrivate(ByteOrder endianness) :
|
||||
endianness(endianness),
|
||||
size(0) {}
|
||||
|
||||
ByteOrder endianness;
|
||||
const ByteOrder endianness;
|
||||
ByteVector type;
|
||||
TagLib::uint size;
|
||||
ByteVector format;
|
||||
@ -88,20 +88,18 @@ bool RIFF::File::isValidChunkName(const ByteVector &name) // static
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RIFF::File::File(FileName file, ByteOrder endianness) : TagLib::File(file)
|
||||
RIFF::File::File(FileName file, ByteOrder endianness) :
|
||||
TagLib::File(file),
|
||||
d(new FilePrivate(endianness))
|
||||
{
|
||||
d = new FilePrivate;
|
||||
d->endianness = endianness;
|
||||
|
||||
if(isOpen())
|
||||
read();
|
||||
}
|
||||
|
||||
RIFF::File::File(IOStream *stream, ByteOrder endianness) : TagLib::File(stream)
|
||||
RIFF::File::File(IOStream *stream, ByteOrder endianness) :
|
||||
TagLib::File(stream),
|
||||
d(new FilePrivate(endianness))
|
||||
{
|
||||
d = new FilePrivate;
|
||||
d->endianness = endianness;
|
||||
|
||||
if(isOpen())
|
||||
read();
|
||||
}
|
||||
@ -288,7 +286,7 @@ void RIFF::File::read()
|
||||
break;
|
||||
}
|
||||
|
||||
if(static_cast<ulonglong>(tell()) + chunkSize > static_cast<ulonglong>(length())) {
|
||||
if(tell() + chunkSize > length()) {
|
||||
debug("RIFF::File::read() -- Chunk '" + chunkName + "' has invalid size (larger than the file size)");
|
||||
setValid(false);
|
||||
break;
|
||||
@ -314,8 +312,8 @@ void RIFF::File::read()
|
||||
chunk.padding = 1;
|
||||
}
|
||||
}
|
||||
d->chunks.push_back(chunk);
|
||||
|
||||
d->chunks.push_back(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
55
taglib/riff/riffutils.h
Normal file
55
taglib/riff/riffutils.h
Normal file
@ -0,0 +1,55 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2015 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@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_RIFFUTILS_H
|
||||
#define TAGLIB_RIFFUTILS_H
|
||||
|
||||
// THIS FILE IS NOT A PART OF THE TAGLIB API
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT // tell Doxygen not to document this header
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace RIFF
|
||||
{
|
||||
static bool isValidChunkName(const ByteVector &name)
|
||||
{
|
||||
if(name.size() != 4)
|
||||
return false;
|
||||
|
||||
for(ByteVector::ConstIterator it = name.begin(); it != name.end(); ++it) {
|
||||
const uchar c = static_cast<uchar>(*it);
|
||||
if(c < 32 || 127 < c)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "rifffile.h"
|
||||
#include "infotag.h"
|
||||
#include "riffutils.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace RIFF::Info;
|
||||
@ -66,16 +67,16 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RIFF::Info::Tag::Tag(const ByteVector &data)
|
||||
: TagLib::Tag()
|
||||
, d(new TagPrivate())
|
||||
RIFF::Info::Tag::Tag(const ByteVector &data) :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
parse(data);
|
||||
}
|
||||
|
||||
RIFF::Info::Tag::Tag()
|
||||
: TagLib::Tag()
|
||||
, d(new TagPrivate())
|
||||
RIFF::Info::Tag::Tag() :
|
||||
TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
@ -189,8 +190,8 @@ String RIFF::Info::Tag::fieldText(const ByteVector &id) const
|
||||
|
||||
void RIFF::Info::Tag::setFieldText(const ByteVector &id, const String &s)
|
||||
{
|
||||
// id must be four-byte long pure ASCII string.
|
||||
if(!RIFF::File::isValidChunkName(id))
|
||||
// id must be four-byte long pure ascii string.
|
||||
if(!isValidChunkName(id))
|
||||
return;
|
||||
|
||||
if(!s.isEmpty())
|
||||
@ -209,8 +210,7 @@ ByteVector RIFF::Info::Tag::render() const
|
||||
{
|
||||
ByteVector data("INFO");
|
||||
|
||||
FieldMap::ConstIterator it = d->fieldMap.begin();
|
||||
for(; it != d->fieldMap.end(); ++it) {
|
||||
for(FieldMap::ConstIterator it = d->fieldMap.begin(); it != d->fieldMap.end(); ++it) {
|
||||
ByteVector text = stringHandler->render(it->second);
|
||||
if(text.isEmpty())
|
||||
continue;
|
||||
@ -251,7 +251,7 @@ void RIFF::Info::Tag::parse(const ByteVector &data)
|
||||
break;
|
||||
|
||||
const ByteVector id = data.mid(p, 4);
|
||||
if(RIFF::File::isValidChunkName(id)) {
|
||||
if(isValidChunkName(id)) {
|
||||
const String text = stringHandler->parse(data.mid(p + 8, size));
|
||||
d->fieldMap[id] = text;
|
||||
}
|
||||
|
@ -265,15 +265,15 @@ long double toFloat80(const ByteVector &v, size_t offset)
|
||||
const int exponent = ((bytes[0] & 0x7F) << 8) | bytes[1];
|
||||
|
||||
// 64-bit fraction. Leading 1 is explicit.
|
||||
const ulonglong fraction
|
||||
= (static_cast<ulonglong>(bytes[2]) << 56)
|
||||
| (static_cast<ulonglong>(bytes[3]) << 48)
|
||||
| (static_cast<ulonglong>(bytes[4]) << 40)
|
||||
| (static_cast<ulonglong>(bytes[5]) << 32)
|
||||
| (static_cast<ulonglong>(bytes[6]) << 24)
|
||||
| (static_cast<ulonglong>(bytes[7]) << 16)
|
||||
| (static_cast<ulonglong>(bytes[8]) << 8)
|
||||
| (static_cast<ulonglong>(bytes[9]));
|
||||
const unsigned long long fraction
|
||||
= (static_cast<unsigned long long>(bytes[2]) << 56)
|
||||
| (static_cast<unsigned long long>(bytes[3]) << 48)
|
||||
| (static_cast<unsigned long long>(bytes[4]) << 40)
|
||||
| (static_cast<unsigned long long>(bytes[5]) << 32)
|
||||
| (static_cast<unsigned long long>(bytes[6]) << 24)
|
||||
| (static_cast<unsigned long long>(bytes[7]) << 16)
|
||||
| (static_cast<unsigned long long>(bytes[8]) << 8)
|
||||
| (static_cast<unsigned long long>(bytes[9]));
|
||||
|
||||
long double val;
|
||||
if(exponent == 0 && fraction == 0)
|
||||
@ -382,12 +382,12 @@ ByteVector ByteVector::fromFloat32BE(float value)
|
||||
|
||||
ByteVector ByteVector::fromFloat64LE(double value)
|
||||
{
|
||||
return fromFloat<double, ulonglong, LittleEndian>(value);
|
||||
return fromFloat<double, unsigned long long, LittleEndian>(value);
|
||||
}
|
||||
|
||||
ByteVector ByteVector::fromFloat64BE(double value)
|
||||
{
|
||||
return fromFloat<double, ulonglong, BigEndian>(value);
|
||||
return fromFloat<double, unsigned long long, BigEndian>(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -755,12 +755,12 @@ float ByteVector::toFloat32BE(size_t offset) const
|
||||
|
||||
double ByteVector::toFloat64LE(size_t offset) const
|
||||
{
|
||||
return toFloat<double, ulonglong, LittleEndian>(*this, offset);
|
||||
return toFloat<double, unsigned long long, LittleEndian>(*this, offset);
|
||||
}
|
||||
|
||||
double ByteVector::toFloat64BE(size_t offset) const
|
||||
{
|
||||
return toFloat<double, ulonglong, BigEndian>(*this, offset);
|
||||
return toFloat<double, unsigned long long, BigEndian>(*this, offset);
|
||||
}
|
||||
|
||||
long double ByteVector::toFloat80LE(size_t offset) const
|
||||
|
@ -174,7 +174,7 @@ namespace
|
||||
if(length > 0) {
|
||||
if(swap) {
|
||||
for(size_t i = 0; i < length; ++i)
|
||||
data[i] = Utils::byteSwap(static_cast<ushort>(s[i]));
|
||||
data[i] = Utils::byteSwap(static_cast<TagLib::ushort>(s[i]));
|
||||
}
|
||||
else {
|
||||
::wmemcpy(&data[0], s, length);
|
||||
@ -194,7 +194,7 @@ namespace
|
||||
}
|
||||
|
||||
// Uses memcpy instead of reinterpret_cast to avoid an alignment exception.
|
||||
ushort bom;
|
||||
TagLib::ushort bom;
|
||||
::memcpy(&bom, s, 2);
|
||||
|
||||
if(bom == 0xfeff)
|
||||
@ -215,7 +215,7 @@ namespace
|
||||
|
||||
data.resize(length / 2);
|
||||
for(size_t i = 0; i < length / 2; ++i) {
|
||||
ushort c;
|
||||
TagLib::ushort c;
|
||||
::memcpy(&c, s, 2);
|
||||
if(swap)
|
||||
c = Utils::byteSwap(c);
|
||||
|
@ -134,7 +134,7 @@ namespace TagLib
|
||||
/*!
|
||||
* Reverses the order of bytes in an 64-bit integer.
|
||||
*/
|
||||
inline ulonglong byteSwap(ulonglong x)
|
||||
inline unsigned long long byteSwap(unsigned long long x)
|
||||
{
|
||||
#if defined(HAVE_BOOST_BYTESWAP)
|
||||
|
||||
|
BIN
tests/data/blank_video.m4v
Normal file
BIN
tests/data/blank_video.m4v
Normal file
Binary file not shown.
@ -64,14 +64,23 @@ public:
|
||||
{
|
||||
RIFF::AIFF::File f(newname.c_str());
|
||||
CPPUNIT_ASSERT(!f.hasID3v2Tag());
|
||||
|
||||
f.tag()->setTitle(L"TitleXXX");
|
||||
f.save();
|
||||
CPPUNIT_ASSERT(f.hasID3v2Tag());
|
||||
}
|
||||
|
||||
{
|
||||
RIFF::AIFF::File f(newname.c_str());
|
||||
CPPUNIT_ASSERT(f.hasID3v2Tag());
|
||||
CPPUNIT_ASSERT_EQUAL(String(L"TitleXXX"), f.tag()->title());
|
||||
|
||||
f.tag()->setTitle("");
|
||||
f.save();
|
||||
CPPUNIT_ASSERT(!f.hasID3v2Tag());
|
||||
}
|
||||
{
|
||||
RIFF::AIFF::File f(newname.c_str());
|
||||
CPPUNIT_ASSERT(!f.hasID3v2Tag());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ class TestFileRef : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testMP4_1);
|
||||
CPPUNIT_TEST(testMP4_2);
|
||||
CPPUNIT_TEST(testMP4_3);
|
||||
CPPUNIT_TEST(testMP4_4);
|
||||
CPPUNIT_TEST(testTrueAudio);
|
||||
CPPUNIT_TEST(testAPE);
|
||||
CPPUNIT_TEST(testWav);
|
||||
@ -155,6 +156,11 @@ public:
|
||||
fileRefSave("no-tags", ".3g2");
|
||||
}
|
||||
|
||||
void testMP4_4()
|
||||
{
|
||||
fileRefSave("blank_video", ".m4v");
|
||||
}
|
||||
|
||||
void testWav()
|
||||
{
|
||||
fileRefSave("empty", ".wav");
|
||||
|
@ -17,6 +17,7 @@ class TestMP4 : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST_SUITE(TestMP4);
|
||||
CPPUNIT_TEST(testPropertiesAAC);
|
||||
CPPUNIT_TEST(testPropertiesALAC);
|
||||
CPPUNIT_TEST(testPropertiesM4V);
|
||||
CPPUNIT_TEST(testFreeForm);
|
||||
CPPUNIT_TEST(testCheckValid);
|
||||
CPPUNIT_TEST(testHasTag);
|
||||
@ -64,6 +65,21 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(MP4::AudioProperties::ALAC, f.audioProperties()->codec());
|
||||
}
|
||||
|
||||
void testPropertiesM4V()
|
||||
{
|
||||
MP4::File f(TEST_FILE_PATH_C("blank_video.m4v"));
|
||||
CPPUNIT_ASSERT(f.audioProperties());
|
||||
CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->length());
|
||||
CPPUNIT_ASSERT_EQUAL(0, f.audioProperties()->lengthInSeconds());
|
||||
CPPUNIT_ASSERT_EQUAL(975, f.audioProperties()->lengthInMilliseconds());
|
||||
CPPUNIT_ASSERT_EQUAL(96, f.audioProperties()->bitrate());
|
||||
CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels());
|
||||
CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate());
|
||||
CPPUNIT_ASSERT_EQUAL(16, f.audioProperties()->bitsPerSample());
|
||||
CPPUNIT_ASSERT_EQUAL(false, f.audioProperties()->isEncrypted());
|
||||
CPPUNIT_ASSERT_EQUAL(MP4::AudioProperties::AAC, f.audioProperties()->codec());
|
||||
}
|
||||
|
||||
void testCheckValid()
|
||||
{
|
||||
MP4::File f(TEST_FILE_PATH_C("empty.aiff"));
|
||||
|
@ -91,26 +91,29 @@ public:
|
||||
{
|
||||
RIFF::WAV::File f(filename.c_str());
|
||||
CPPUNIT_ASSERT(f.isValid());
|
||||
CPPUNIT_ASSERT(!f.hasID3v2Tag());
|
||||
|
||||
f.ID3v2Tag()->setTitle(L"Title");
|
||||
f.ID3v2Tag()->setArtist(L"Artist");
|
||||
f.save();
|
||||
CPPUNIT_ASSERT(f.hasID3v2Tag());
|
||||
}
|
||||
|
||||
{
|
||||
RIFF::WAV::File f(filename.c_str());
|
||||
CPPUNIT_ASSERT(f.isValid());
|
||||
CPPUNIT_ASSERT(f.hasID3v2Tag());
|
||||
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();
|
||||
CPPUNIT_ASSERT(!f.hasID3v2Tag());
|
||||
}
|
||||
|
||||
{
|
||||
RIFF::WAV::File f(filename.c_str());
|
||||
CPPUNIT_ASSERT(f.isValid());
|
||||
CPPUNIT_ASSERT(!f.hasID3v2Tag());
|
||||
CPPUNIT_ASSERT_EQUAL(String(L""), f.ID3v2Tag()->title());
|
||||
CPPUNIT_ASSERT_EQUAL(String(L""), f.ID3v2Tag()->artist());
|
||||
}
|
||||
@ -124,26 +127,30 @@ public:
|
||||
{
|
||||
RIFF::WAV::File f(filename.c_str());
|
||||
CPPUNIT_ASSERT(f.isValid());
|
||||
CPPUNIT_ASSERT(!f.hasInfoTag());
|
||||
|
||||
f.InfoTag()->setTitle(L"Title");
|
||||
f.InfoTag()->setArtist(L"Artist");
|
||||
f.save();
|
||||
CPPUNIT_ASSERT(f.hasInfoTag());
|
||||
}
|
||||
|
||||
{
|
||||
RIFF::WAV::File f(filename.c_str());
|
||||
CPPUNIT_ASSERT(f.isValid());
|
||||
CPPUNIT_ASSERT(f.hasInfoTag());
|
||||
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();
|
||||
CPPUNIT_ASSERT(!f.hasInfoTag());
|
||||
}
|
||||
|
||||
{
|
||||
RIFF::WAV::File f(filename.c_str());
|
||||
CPPUNIT_ASSERT(f.isValid());
|
||||
CPPUNIT_ASSERT(!f.hasInfoTag());
|
||||
CPPUNIT_ASSERT_EQUAL(String(L""), f.InfoTag()->title());
|
||||
CPPUNIT_ASSERT_EQUAL(String(L""), f.InfoTag()->artist());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user