Audio file detection by content

This commit is contained in:
Jonas Kvinge
2018-05-10 15:29:28 +02:00
parent 7b2d1d95d3
commit 5392cc4109
232 changed files with 55355 additions and 133 deletions

351
3rdparty/taglib/asf/asfattribute.cpp vendored Normal file
View File

@@ -0,0 +1,351 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
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 <taglib.h>
#include <tdebug.h>
#include <trefcounter.h>
#include "asfattribute.h"
#include "asffile.h"
#include "asfutils.h"
using namespace TagLib;
class ASF::Attribute::AttributePrivate : public RefCounter
{
public:
AttributePrivate() :
pictureValue(ASF::Picture::fromInvalid()),
numericValue(0),
stream(0),
language(0) {}
AttributeTypes type;
String stringValue;
ByteVector byteVectorValue;
ASF::Picture pictureValue;
unsigned long long numericValue;
int stream;
int language;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
ASF::Attribute::Attribute() :
d(new AttributePrivate())
{
d->type = UnicodeType;
}
ASF::Attribute::Attribute(const ASF::Attribute &other) :
d(other.d)
{
d->ref();
}
ASF::Attribute::Attribute(const String &value) :
d(new AttributePrivate())
{
d->type = UnicodeType;
d->stringValue = value;
}
ASF::Attribute::Attribute(const ByteVector &value) :
d(new AttributePrivate())
{
d->type = BytesType;
d->byteVectorValue = value;
}
ASF::Attribute::Attribute(const ASF::Picture &value) :
d(new AttributePrivate())
{
d->type = BytesType;
d->pictureValue = value;
}
ASF::Attribute::Attribute(unsigned int value) :
d(new AttributePrivate())
{
d->type = DWordType;
d->numericValue = value;
}
ASF::Attribute::Attribute(unsigned long long value) :
d(new AttributePrivate())
{
d->type = QWordType;
d->numericValue = value;
}
ASF::Attribute::Attribute(unsigned short value) :
d(new AttributePrivate())
{
d->type = WordType;
d->numericValue = value;
}
ASF::Attribute::Attribute(bool value) :
d(new AttributePrivate())
{
d->type = BoolType;
d->numericValue = value;
}
ASF::Attribute &ASF::Attribute::operator=(const ASF::Attribute &other)
{
Attribute(other).swap(*this);
return *this;
}
void ASF::Attribute::swap(Attribute &other)
{
using std::swap;
swap(d, other.d);
}
ASF::Attribute::~Attribute()
{
if(d->deref())
delete d;
}
ASF::Attribute::AttributeTypes ASF::Attribute::type() const
{
return d->type;
}
String ASF::Attribute::toString() const
{
return d->stringValue;
}
ByteVector ASF::Attribute::toByteVector() const
{
if(d->pictureValue.isValid())
return d->pictureValue.render();
return d->byteVectorValue;
}
unsigned short ASF::Attribute::toBool() const
{
return d->numericValue ? 1 : 0;
}
unsigned short ASF::Attribute::toUShort() const
{
return static_cast<unsigned short>(d->numericValue);
}
unsigned int ASF::Attribute::toUInt() const
{
return static_cast<unsigned int>(d->numericValue);
}
unsigned long long ASF::Attribute::toULongLong() const
{
return static_cast<unsigned long long>(d->numericValue);
}
ASF::Picture ASF::Attribute::toPicture() const
{
return d->pictureValue;
}
String ASF::Attribute::parse(ASF::File &f, int kind)
{
unsigned int size, nameLength;
String name;
d->pictureValue = Picture::fromInvalid();
// extended content descriptor
if(kind == 0) {
nameLength = readWORD(&f);
name = readString(&f, nameLength);
d->type = ASF::Attribute::AttributeTypes(readWORD(&f));
size = readWORD(&f);
}
// metadata & metadata library
else {
int temp = readWORD(&f);
// metadata library
if(kind == 2) {
d->language = temp;
}
d->stream = readWORD(&f);
nameLength = readWORD(&f);
d->type = ASF::Attribute::AttributeTypes(readWORD(&f));
size = readDWORD(&f);
name = readString(&f, nameLength);
}
if(kind != 2 && size > 65535) {
debug("ASF::Attribute::parse() -- Value larger than 64kB");
}
switch(d->type) {
case WordType:
d->numericValue = readWORD(&f);
break;
case BoolType:
if(kind == 0) {
d->numericValue = (readDWORD(&f) != 0);
}
else {
d->numericValue = (readWORD(&f) != 0);
}
break;
case DWordType:
d->numericValue = readDWORD(&f);
break;
case QWordType:
d->numericValue = readQWORD(&f);
break;
case UnicodeType:
d->stringValue = readString(&f, size);
break;
case BytesType:
case GuidType:
d->byteVectorValue = f.readBlock(size);
break;
}
if(d->type == BytesType && name == "WM/Picture") {
d->pictureValue.parse(d->byteVectorValue);
if(d->pictureValue.isValid()) {
d->byteVectorValue.clear();
}
}
return name;
}
int ASF::Attribute::dataSize() const
{
switch (d->type) {
case WordType:
return 2;
case BoolType:
return 4;
case DWordType:
return 4;
case QWordType:
return 5;
case UnicodeType:
return d->stringValue.size() * 2 + 2;
case BytesType:
if(d->pictureValue.isValid())
return d->pictureValue.dataSize();
case GuidType:
return d->byteVectorValue.size();
}
return 0;
}
ByteVector ASF::Attribute::render(const String &name, int kind) const
{
ByteVector data;
switch (d->type) {
case WordType:
data.append(ByteVector::fromShort(toUShort(), false));
break;
case BoolType:
if(kind == 0) {
data.append(ByteVector::fromUInt(toBool(), false));
}
else {
data.append(ByteVector::fromShort(toBool(), false));
}
break;
case DWordType:
data.append(ByteVector::fromUInt(toUInt(), false));
break;
case QWordType:
data.append(ByteVector::fromLongLong(toULongLong(), false));
break;
case UnicodeType:
data.append(renderString(d->stringValue));
break;
case BytesType:
if(d->pictureValue.isValid()) {
data.append(d->pictureValue.render());
break;
}
case GuidType:
data.append(d->byteVectorValue);
break;
}
if(kind == 0) {
data = renderString(name, true) +
ByteVector::fromShort((int)d->type, false) +
ByteVector::fromShort(data.size(), false) +
data;
}
else {
ByteVector nameData = renderString(name);
data = ByteVector::fromShort(kind == 2 ? d->language : 0, false) +
ByteVector::fromShort(d->stream, false) +
ByteVector::fromShort(nameData.size(), false) +
ByteVector::fromShort((int)d->type, false) +
ByteVector::fromUInt(data.size(), false) +
nameData +
data;
}
return data;
}
int ASF::Attribute::language() const
{
return d->language;
}
void ASF::Attribute::setLanguage(int value)
{
d->language = value;
}
int ASF::Attribute::stream() const
{
return d->stream;
}
void ASF::Attribute::setStream(int value)
{
d->stream = value;
}

208
3rdparty/taglib/asf/asfattribute.h vendored Normal file
View File

@@ -0,0 +1,208 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
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_ASFATTRIBUTE_H
#define TAGLIB_ASFATTRIBUTE_H
#include "tstring.h"
#include "tbytevector.h"
#include "taglib_export.h"
#include "asfpicture.h"
namespace TagLib
{
namespace ASF
{
class File;
class Picture;
class TAGLIB_EXPORT Attribute
{
public:
/*!
* Enum of types an Attribute can have.
*/
enum AttributeTypes {
UnicodeType = 0,
BytesType = 1,
BoolType = 2,
DWordType = 3,
QWordType = 4,
WordType = 5,
GuidType = 6
};
/*!
* Constructs an empty attribute.
*/
Attribute();
/*!
* Constructs an attribute with \a key and a UnicodeType \a value.
*/
Attribute(const String &value);
/*!
* Constructs an attribute with \a key and a BytesType \a value.
*/
Attribute(const ByteVector &value);
/*!
* Constructs an attribute with \a key and a Picture \a value.
*
* This attribute is compatible with the ID3 frame, APIC. The ID3 specification for the APIC frame stipulates that,
* while there may be any number of APIC frames associated with a file,
* only one may be of type 1 and only one may be of type 2.
*
* The specification also states that the description of the picture can be no longer than 64 characters, but can be empty.
* WM/Picture attributes added with TagLib::ASF are not automatically validated to conform to ID3 specifications.
* You must add code in your application to perform validations if you want to maintain complete compatibility with ID3.
*/
Attribute(const Picture &value);
/*!
* Constructs an attribute with \a key and a DWordType \a value.
*/
Attribute(unsigned int value);
/*!
* Constructs an attribute with \a key and a QWordType \a value.
*/
Attribute(unsigned long long value);
/*!
* Constructs an attribute with \a key and a WordType \a value.
*/
Attribute(unsigned short value);
/*!
* Constructs an attribute with \a key and a BoolType \a value.
*/
Attribute(bool value);
/*!
* Construct an attribute as a copy of \a other.
*/
Attribute(const Attribute &item);
/*!
* Copies the contents of \a other into this item.
*/
Attribute &operator=(const Attribute &other);
/*!
* Exchanges the content of the Attribute by the content of \a other.
*/
void swap(Attribute &other);
/*!
* Destroys the attribute.
*/
virtual ~Attribute();
/*!
* Returns type of the value.
*/
AttributeTypes type() const;
/*!
* Returns the BoolType \a value.
*/
unsigned short toBool() const;
/*!
* Returns the WordType \a value.
*/
unsigned short toUShort() const;
/*!
* Returns the DWordType \a value.
*/
unsigned int toUInt() const;
/*!
* Returns the QWordType \a value.
*/
unsigned long long toULongLong() const;
/*!
* Returns the UnicodeType \a value.
*/
String toString() const;
/*!
* Returns the BytesType \a value.
*/
ByteVector toByteVector() const;
/*!
* Returns the Picture \a value.
*/
Picture toPicture() const;
/*!
* Returns the language number, or 0 is no stream number was set.
*/
int language() const;
/*!
* Sets the language number.
*/
void setLanguage(int value);
/*!
* Returns the stream number, or 0 is no stream number was set.
*/
int stream() const;
/*!
* Sets the stream number.
*/
void setStream(int value);
#ifndef DO_NOT_DOCUMENT
/* THIS IS PRIVATE, DON'T TOUCH IT! */
String parse(ASF::File &file, int kind = 0);
#endif
//! Returns the size of the stored data
int dataSize() const;
private:
friend class File;
ByteVector render(const String &name, int kind = 0) const;
class AttributePrivate;
AttributePrivate *d;
};
}
}
#endif

705
3rdparty/taglib/asf/asffile.cpp vendored Normal file
View File

@@ -0,0 +1,705 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
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 <tdebug.h>
#include <tbytevectorlist.h>
#include <tpropertymap.h>
#include <tstring.h>
#include <tagutils.h>
#include "asffile.h"
#include "asftag.h"
#include "asfproperties.h"
#include "asfutils.h"
using namespace TagLib;
class ASF::File::FilePrivate
{
public:
class BaseObject;
class UnknownObject;
class FilePropertiesObject;
class StreamPropertiesObject;
class ContentDescriptionObject;
class ExtendedContentDescriptionObject;
class HeaderExtensionObject;
class CodecListObject;
class MetadataObject;
class MetadataLibraryObject;
FilePrivate():
headerSize(0),
tag(0),
properties(0),
contentDescriptionObject(0),
extendedContentDescriptionObject(0),
headerExtensionObject(0),
metadataObject(0),
metadataLibraryObject(0)
{
objects.setAutoDelete(true);
}
~FilePrivate()
{
delete tag;
delete properties;
}
unsigned long long headerSize;
ASF::Tag *tag;
ASF::Properties *properties;
List<BaseObject *> objects;
ContentDescriptionObject *contentDescriptionObject;
ExtendedContentDescriptionObject *extendedContentDescriptionObject;
HeaderExtensionObject *headerExtensionObject;
MetadataObject *metadataObject;
MetadataLibraryObject *metadataLibraryObject;
};
namespace
{
const ByteVector headerGuid("\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C", 16);
const ByteVector filePropertiesGuid("\xA1\xDC\xAB\x8C\x47\xA9\xCF\x11\x8E\xE4\x00\xC0\x0C\x20\x53\x65", 16);
const ByteVector streamPropertiesGuid("\x91\x07\xDC\xB7\xB7\xA9\xCF\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65", 16);
const ByteVector contentDescriptionGuid("\x33\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C", 16);
const ByteVector extendedContentDescriptionGuid("\x40\xA4\xD0\xD2\x07\xE3\xD2\x11\x97\xF0\x00\xA0\xC9\x5E\xA8\x50", 16);
const ByteVector headerExtensionGuid("\xb5\x03\xbf_.\xa9\xcf\x11\x8e\xe3\x00\xc0\x0c Se", 16);
const ByteVector metadataGuid("\xEA\xCB\xF8\xC5\xAF[wH\204g\xAA\214D\xFAL\xCA", 16);
const ByteVector metadataLibraryGuid("\224\034#D\230\224\321I\241A\x1d\x13NEpT", 16);
const ByteVector codecListGuid("\x40\x52\xd1\x86\x1d\x31\xd0\x11\xa3\xa4\x00\xa0\xc9\x03\x48\xf6", 16);
const ByteVector contentEncryptionGuid("\xFB\xB3\x11\x22\x23\xBD\xD2\x11\xB4\xB7\x00\xA0\xC9\x55\xFC\x6E", 16);
const ByteVector extendedContentEncryptionGuid("\x14\xE6\x8A\x29\x22\x26 \x17\x4C\xB9\x35\xDA\xE0\x7E\xE9\x28\x9C", 16);
const ByteVector advancedContentEncryptionGuid("\xB6\x9B\x07\x7A\xA4\xDA\x12\x4E\xA5\xCA\x91\xD3\x8D\xC1\x1A\x8D", 16);
}
class ASF::File::FilePrivate::BaseObject
{
public:
ByteVector data;
virtual ~BaseObject() {}
virtual ByteVector guid() const = 0;
virtual void parse(ASF::File *file, unsigned int size);
virtual ByteVector render(ASF::File *file);
};
class ASF::File::FilePrivate::UnknownObject : public ASF::File::FilePrivate::BaseObject
{
ByteVector myGuid;
public:
UnknownObject(const ByteVector &guid);
ByteVector guid() const;
};
class ASF::File::FilePrivate::FilePropertiesObject : public ASF::File::FilePrivate::BaseObject
{
public:
ByteVector guid() const;
void parse(ASF::File *file, unsigned int size);
};
class ASF::File::FilePrivate::StreamPropertiesObject : public ASF::File::FilePrivate::BaseObject
{
public:
ByteVector guid() const;
void parse(ASF::File *file, unsigned int size);
};
class ASF::File::FilePrivate::ContentDescriptionObject : public ASF::File::FilePrivate::BaseObject
{
public:
ByteVector guid() const;
void parse(ASF::File *file, unsigned int size);
ByteVector render(ASF::File *file);
};
class ASF::File::FilePrivate::ExtendedContentDescriptionObject : public ASF::File::FilePrivate::BaseObject
{
public:
ByteVectorList attributeData;
ByteVector guid() const;
void parse(ASF::File *file, unsigned int size);
ByteVector render(ASF::File *file);
};
class ASF::File::FilePrivate::MetadataObject : public ASF::File::FilePrivate::BaseObject
{
public:
ByteVectorList attributeData;
ByteVector guid() const;
void parse(ASF::File *file, unsigned int size);
ByteVector render(ASF::File *file);
};
class ASF::File::FilePrivate::MetadataLibraryObject : public ASF::File::FilePrivate::BaseObject
{
public:
ByteVectorList attributeData;
ByteVector guid() const;
void parse(ASF::File *file, unsigned int size);
ByteVector render(ASF::File *file);
};
class ASF::File::FilePrivate::HeaderExtensionObject : public ASF::File::FilePrivate::BaseObject
{
public:
List<ASF::File::FilePrivate::BaseObject *> objects;
HeaderExtensionObject();
ByteVector guid() const;
void parse(ASF::File *file, unsigned int size);
ByteVector render(ASF::File *file);
};
class ASF::File::FilePrivate::CodecListObject : public ASF::File::FilePrivate::BaseObject
{
public:
ByteVector guid() const;
void parse(ASF::File *file, unsigned int size);
private:
enum CodecType
{
Video = 0x0001,
Audio = 0x0002,
Unknown = 0xFFFF
};
};
void ASF::File::FilePrivate::BaseObject::parse(ASF::File *file, unsigned int size)
{
data.clear();
if(size > 24 && size <= (unsigned int)(file->length()))
data = file->readBlock(size - 24);
else
data = ByteVector();
}
ByteVector ASF::File::FilePrivate::BaseObject::render(ASF::File * /*file*/)
{
return guid() + ByteVector::fromLongLong(data.size() + 24, false) + data;
}
ASF::File::FilePrivate::UnknownObject::UnknownObject(const ByteVector &guid) : myGuid(guid)
{
}
ByteVector ASF::File::FilePrivate::UnknownObject::guid() const
{
return myGuid;
}
ByteVector ASF::File::FilePrivate::FilePropertiesObject::guid() const
{
return filePropertiesGuid;
}
void ASF::File::FilePrivate::FilePropertiesObject::parse(ASF::File *file, unsigned int size)
{
BaseObject::parse(file, size);
if(data.size() < 64) {
debug("ASF::File::FilePrivate::FilePropertiesObject::parse() -- data is too short.");
return;
}
const long long duration = data.toLongLong(40, false);
const long long preroll = data.toLongLong(56, false);
file->d->properties->setLengthInMilliseconds(static_cast<int>(duration / 10000.0 - preroll + 0.5));
}
ByteVector ASF::File::FilePrivate::StreamPropertiesObject::guid() const
{
return streamPropertiesGuid;
}
void ASF::File::FilePrivate::StreamPropertiesObject::parse(ASF::File *file, unsigned int size)
{
BaseObject::parse(file, size);
if(data.size() < 70) {
debug("ASF::File::FilePrivate::StreamPropertiesObject::parse() -- data is too short.");
return;
}
file->d->properties->setCodec(data.toUShort(54, false));
file->d->properties->setChannels(data.toUShort(56, false));
file->d->properties->setSampleRate(data.toUInt(58, false));
file->d->properties->setBitrate(static_cast<int>(data.toUInt(62, false) * 8.0 / 1000.0 + 0.5));
file->d->properties->setBitsPerSample(data.toUShort(68, false));
}
ByteVector ASF::File::FilePrivate::ContentDescriptionObject::guid() const
{
return contentDescriptionGuid;
}
void ASF::File::FilePrivate::ContentDescriptionObject::parse(ASF::File *file, unsigned int /*size*/)
{
const int titleLength = readWORD(file);
const int artistLength = readWORD(file);
const int copyrightLength = readWORD(file);
const int commentLength = readWORD(file);
const int ratingLength = readWORD(file);
file->d->tag->setTitle(readString(file,titleLength));
file->d->tag->setArtist(readString(file,artistLength));
file->d->tag->setCopyright(readString(file,copyrightLength));
file->d->tag->setComment(readString(file,commentLength));
file->d->tag->setRating(readString(file,ratingLength));
}
ByteVector ASF::File::FilePrivate::ContentDescriptionObject::render(ASF::File *file)
{
const ByteVector v1 = renderString(file->d->tag->title());
const ByteVector v2 = renderString(file->d->tag->artist());
const ByteVector v3 = renderString(file->d->tag->copyright());
const ByteVector v4 = renderString(file->d->tag->comment());
const ByteVector v5 = renderString(file->d->tag->rating());
data.clear();
data.append(ByteVector::fromShort(v1.size(), false));
data.append(ByteVector::fromShort(v2.size(), false));
data.append(ByteVector::fromShort(v3.size(), false));
data.append(ByteVector::fromShort(v4.size(), false));
data.append(ByteVector::fromShort(v5.size(), false));
data.append(v1);
data.append(v2);
data.append(v3);
data.append(v4);
data.append(v5);
return BaseObject::render(file);
}
ByteVector ASF::File::FilePrivate::ExtendedContentDescriptionObject::guid() const
{
return extendedContentDescriptionGuid;
}
void ASF::File::FilePrivate::ExtendedContentDescriptionObject::parse(ASF::File *file, unsigned int /*size*/)
{
int count = readWORD(file);
while(count--) {
ASF::Attribute attribute;
String name = attribute.parse(*file);
file->d->tag->addAttribute(name, attribute);
}
}
ByteVector ASF::File::FilePrivate::ExtendedContentDescriptionObject::render(ASF::File *file)
{
data.clear();
data.append(ByteVector::fromShort(attributeData.size(), false));
data.append(attributeData.toByteVector(""));
return BaseObject::render(file);
}
ByteVector ASF::File::FilePrivate::MetadataObject::guid() const
{
return metadataGuid;
}
void ASF::File::FilePrivate::MetadataObject::parse(ASF::File *file, unsigned int /*size*/)
{
int count = readWORD(file);
while(count--) {
ASF::Attribute attribute;
String name = attribute.parse(*file, 1);
file->d->tag->addAttribute(name, attribute);
}
}
ByteVector ASF::File::FilePrivate::MetadataObject::render(ASF::File *file)
{
data.clear();
data.append(ByteVector::fromShort(attributeData.size(), false));
data.append(attributeData.toByteVector(""));
return BaseObject::render(file);
}
ByteVector ASF::File::FilePrivate::MetadataLibraryObject::guid() const
{
return metadataLibraryGuid;
}
void ASF::File::FilePrivate::MetadataLibraryObject::parse(ASF::File *file, unsigned int /*size*/)
{
int count = readWORD(file);
while(count--) {
ASF::Attribute attribute;
String name = attribute.parse(*file, 2);
file->d->tag->addAttribute(name, attribute);
}
}
ByteVector ASF::File::FilePrivate::MetadataLibraryObject::render(ASF::File *file)
{
data.clear();
data.append(ByteVector::fromShort(attributeData.size(), false));
data.append(attributeData.toByteVector(""));
return BaseObject::render(file);
}
ASF::File::FilePrivate::HeaderExtensionObject::HeaderExtensionObject()
{
objects.setAutoDelete(true);
}
ByteVector ASF::File::FilePrivate::HeaderExtensionObject::guid() const
{
return headerExtensionGuid;
}
void ASF::File::FilePrivate::HeaderExtensionObject::parse(ASF::File *file, unsigned int /*size*/)
{
file->seek(18, File::Current);
long long dataSize = readDWORD(file);
long long dataPos = 0;
while(dataPos < dataSize) {
ByteVector guid = file->readBlock(16);
if(guid.size() != 16) {
file->setValid(false);
break;
}
bool ok;
long long size = readQWORD(file, &ok);
if(!ok) {
file->setValid(false);
break;
}
BaseObject *obj;
if(guid == metadataGuid) {
file->d->metadataObject = new MetadataObject();
obj = file->d->metadataObject;
}
else if(guid == metadataLibraryGuid) {
file->d->metadataLibraryObject = new MetadataLibraryObject();
obj = file->d->metadataLibraryObject;
}
else {
obj = new UnknownObject(guid);
}
obj->parse(file, (unsigned int)size);
objects.append(obj);
dataPos += size;
}
}
ByteVector ASF::File::FilePrivate::HeaderExtensionObject::render(ASF::File *file)
{
data.clear();
for(List<BaseObject *>::ConstIterator it = objects.begin(); it != objects.end(); ++it) {
data.append((*it)->render(file));
}
data = ByteVector("\x11\xD2\xD3\xAB\xBA\xA9\xcf\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65\x06\x00", 18) + ByteVector::fromUInt(data.size(), false) + data;
return BaseObject::render(file);
}
ByteVector ASF::File::FilePrivate::CodecListObject::guid() const
{
return codecListGuid;
}
void ASF::File::FilePrivate::CodecListObject::parse(ASF::File *file, unsigned int size)
{
BaseObject::parse(file, size);
if(data.size() <= 20) {
debug("ASF::File::FilePrivate::CodecListObject::parse() -- data is too short.");
return;
}
unsigned int pos = 16;
const int count = data.toUInt(pos, false);
pos += 4;
for(int i = 0; i < count; ++i) {
if(pos >= data.size())
break;
const CodecType type = static_cast<CodecType>(data.toUShort(pos, false));
pos += 2;
int nameLength = data.toUShort(pos, false);
pos += 2;
const unsigned int namePos = pos;
pos += nameLength * 2;
const int descLength = data.toUShort(pos, false);
pos += 2;
const unsigned int descPos = pos;
pos += descLength * 2;
const int infoLength = data.toUShort(pos, false);
pos += 2 + infoLength * 2;
if(type == CodecListObject::Audio) {
// First audio codec found.
const String name(data.mid(namePos, nameLength * 2), String::UTF16LE);
file->d->properties->setCodecName(name.stripWhiteSpace());
const String desc(data.mid(descPos, descLength * 2), String::UTF16LE);
file->d->properties->setCodecDescription(desc.stripWhiteSpace());
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////
// static members
////////////////////////////////////////////////////////////////////////////////
bool ASF::File::isSupported(IOStream *stream)
{
// An ASF file has to start with the designated GUID.
const ByteVector id = Utils::readHeader(stream, 16, false);
return (id == headerGuid);
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
ASF::File::File(FileName file, bool, Properties::ReadStyle) :
TagLib::File(file),
d(new FilePrivate())
{
if(isOpen())
read();
}
ASF::File::File(IOStream *stream, bool, Properties::ReadStyle) :
TagLib::File(stream),
d(new FilePrivate())
{
if(isOpen())
read();
}
ASF::File::~File()
{
delete d;
}
ASF::Tag *ASF::File::tag() const
{
return d->tag;
}
PropertyMap ASF::File::properties() const
{
return d->tag->properties();
}
void ASF::File::removeUnsupportedProperties(const StringList &properties)
{
d->tag->removeUnsupportedProperties(properties);
}
PropertyMap ASF::File::setProperties(const PropertyMap &properties)
{
return d->tag->setProperties(properties);
}
ASF::Properties *ASF::File::audioProperties() const
{
return d->properties;
}
bool ASF::File::save()
{
if(readOnly()) {
debug("ASF::File::save() -- File is read only.");
return false;
}
if(!isValid()) {
debug("ASF::File::save() -- Trying to save invalid file.");
return false;
}
if(!d->contentDescriptionObject) {
d->contentDescriptionObject = new FilePrivate::ContentDescriptionObject();
d->objects.append(d->contentDescriptionObject);
}
if(!d->extendedContentDescriptionObject) {
d->extendedContentDescriptionObject = new FilePrivate::ExtendedContentDescriptionObject();
d->objects.append(d->extendedContentDescriptionObject);
}
if(!d->headerExtensionObject) {
d->headerExtensionObject = new FilePrivate::HeaderExtensionObject();
d->objects.append(d->headerExtensionObject);
}
if(!d->metadataObject) {
d->metadataObject = new FilePrivate::MetadataObject();
d->headerExtensionObject->objects.append(d->metadataObject);
}
if(!d->metadataLibraryObject) {
d->metadataLibraryObject = new FilePrivate::MetadataLibraryObject();
d->headerExtensionObject->objects.append(d->metadataLibraryObject);
}
d->extendedContentDescriptionObject->attributeData.clear();
d->metadataObject->attributeData.clear();
d->metadataLibraryObject->attributeData.clear();
const AttributeListMap allAttributes = d->tag->attributeListMap();
for(AttributeListMap::ConstIterator it = allAttributes.begin(); it != allAttributes.end(); ++it) {
const String &name = it->first;
const AttributeList &attributes = it->second;
bool inExtendedContentDescriptionObject = false;
bool inMetadataObject = false;
for(AttributeList::ConstIterator jt = attributes.begin(); jt != attributes.end(); ++jt) {
const Attribute &attribute = *jt;
const bool largeValue = (attribute.dataSize() > 65535);
const bool guid = (attribute.type() == Attribute::GuidType);
if(!inExtendedContentDescriptionObject && !guid && !largeValue && attribute.language() == 0 && attribute.stream() == 0) {
d->extendedContentDescriptionObject->attributeData.append(attribute.render(name));
inExtendedContentDescriptionObject = true;
}
else if(!inMetadataObject && !guid && !largeValue && attribute.language() == 0 && attribute.stream() != 0) {
d->metadataObject->attributeData.append(attribute.render(name, 1));
inMetadataObject = true;
}
else {
d->metadataLibraryObject->attributeData.append(attribute.render(name, 2));
}
}
}
ByteVector data;
for(List<FilePrivate::BaseObject *>::ConstIterator it = d->objects.begin(); it != d->objects.end(); ++it) {
data.append((*it)->render(this));
}
seek(16);
writeBlock(ByteVector::fromLongLong(data.size() + 30, false));
writeBlock(ByteVector::fromUInt(d->objects.size(), false));
writeBlock(ByteVector("\x01\x02", 2));
insert(data, 30, static_cast<unsigned long>(d->headerSize - 30));
d->headerSize = data.size() + 30;
return true;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void ASF::File::read()
{
if(!isValid())
return;
if(readBlock(16) != headerGuid) {
debug("ASF::File::read(): Not an ASF file.");
setValid(false);
return;
}
d->tag = new ASF::Tag();
d->properties = new ASF::Properties();
bool ok;
d->headerSize = readQWORD(this, &ok);
if(!ok) {
setValid(false);
return;
}
int numObjects = readDWORD(this, &ok);
if(!ok) {
setValid(false);
return;
}
seek(2, Current);
FilePrivate::FilePropertiesObject *filePropertiesObject = 0;
FilePrivate::StreamPropertiesObject *streamPropertiesObject = 0;
for(int i = 0; i < numObjects; i++) {
const ByteVector guid = readBlock(16);
if(guid.size() != 16) {
setValid(false);
break;
}
long size = (long)readQWORD(this, &ok);
if(!ok) {
setValid(false);
break;
}
FilePrivate::BaseObject *obj;
if(guid == filePropertiesGuid) {
filePropertiesObject = new FilePrivate::FilePropertiesObject();
obj = filePropertiesObject;
}
else if(guid == streamPropertiesGuid) {
streamPropertiesObject = new FilePrivate::StreamPropertiesObject();
obj = streamPropertiesObject;
}
else if(guid == contentDescriptionGuid) {
d->contentDescriptionObject = new FilePrivate::ContentDescriptionObject();
obj = d->contentDescriptionObject;
}
else if(guid == extendedContentDescriptionGuid) {
d->extendedContentDescriptionObject = new FilePrivate::ExtendedContentDescriptionObject();
obj = d->extendedContentDescriptionObject;
}
else if(guid == headerExtensionGuid) {
d->headerExtensionObject = new FilePrivate::HeaderExtensionObject();
obj = d->headerExtensionObject;
}
else if(guid == codecListGuid) {
obj = new FilePrivate::CodecListObject();
}
else {
if(guid == contentEncryptionGuid ||
guid == extendedContentEncryptionGuid ||
guid == advancedContentEncryptionGuid) {
d->properties->setEncrypted(true);
}
obj = new FilePrivate::UnknownObject(guid);
}
obj->parse(this, size);
d->objects.append(obj);
}
if(!filePropertiesObject || !streamPropertiesObject) {
debug("ASF::File::read(): Missing mandatory header objects.");
setValid(false);
return;
}
}

138
3rdparty/taglib/asf/asffile.h vendored Normal file
View File

@@ -0,0 +1,138 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
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_ASFFILE_H
#define TAGLIB_ASFFILE_H
#include "tag.h"
#include "tfile.h"
#include "taglib_export.h"
#include "asfproperties.h"
#include "asftag.h"
namespace TagLib {
//! An implementation of ASF (WMA) metadata
namespace ASF {
/*!
* This implements and provides an interface for ASF files to the
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
* the abstract TagLib::File API as well as providing some additional
* information specific to ASF files.
*/
class TAGLIB_EXPORT File : public TagLib::File
{
public:
/*!
* Constructs an ASF file from \a file.
*
* \note In the current implementation, both \a readProperties and
* \a propertiesStyle are ignored. The audio properties are always
* read.
*/
File(FileName file, bool readProperties = true,
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Constructs an ASF file from \a stream.
*
* \note In the current implementation, both \a readProperties and
* \a propertiesStyle are ignored. The audio properties are always
* read.
*
* \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();
/*!
* Returns a pointer to the ASF tag of the file.
*
* ASF::Tag implements the tag interface, so this serves as the
* reimplementation of TagLib::File::tag().
*
* \note The Tag <b>is still</b> owned by the ASF::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*/
virtual Tag *tag() const;
/*!
* Implements the unified property interface -- export function.
*/
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.
*/
PropertyMap setProperties(const PropertyMap &);
/*!
* Returns the ASF audio properties for this file.
*/
virtual Properties *audioProperties() const;
/*!
* Save the file.
*
* This returns true if the save was successful.
*/
virtual bool save();
/*!
* Returns whether or not the given \a stream can be opened as an ASF
* file.
*
* \note This method is designed to do a quick check. The result may
* not necessarily be correct.
*/
static bool isSupported(IOStream *stream);
private:
void read();
class FilePrivate;
FilePrivate *d;
};
}
}
#endif

183
3rdparty/taglib/asf/asfpicture.cpp vendored Normal file
View File

@@ -0,0 +1,183 @@
/**************************************************************************
copyright : (C) 2010 by Anton Sergunov
email : setosha@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 <taglib.h>
#include <tdebug.h>
#include <trefcounter.h>
#include "asfattribute.h"
#include "asffile.h"
#include "asfpicture.h"
#include "asfutils.h"
using namespace TagLib;
class ASF::Picture::PicturePrivate : public RefCounter
{
public:
bool valid;
Type type;
String mimeType;
String description;
ByteVector picture;
};
////////////////////////////////////////////////////////////////////////////////
// Picture class members
////////////////////////////////////////////////////////////////////////////////
ASF::Picture::Picture() :
d(new PicturePrivate())
{
d->valid = true;
}
ASF::Picture::Picture(const Picture& other) :
d(other.d)
{
d->ref();
}
ASF::Picture::~Picture()
{
if(d->deref())
delete d;
}
bool ASF::Picture::isValid() const
{
return d->valid;
}
String ASF::Picture::mimeType() const
{
return d->mimeType;
}
void ASF::Picture::setMimeType(const String &value)
{
d->mimeType = value;
}
ASF::Picture::Type ASF::Picture::type() const
{
return d->type;
}
void ASF::Picture::setType(const ASF::Picture::Type& t)
{
d->type = t;
}
String ASF::Picture::description() const
{
return d->description;
}
void ASF::Picture::setDescription(const String &desc)
{
d->description = desc;
}
ByteVector ASF::Picture::picture() const
{
return d->picture;
}
void ASF::Picture::setPicture(const ByteVector &p)
{
d->picture = p;
}
int ASF::Picture::dataSize() const
{
return
9 + (d->mimeType.length() + d->description.length()) * 2 +
d->picture.size();
}
ASF::Picture& ASF::Picture::operator=(const ASF::Picture& other)
{
Picture(other).swap(*this);
return *this;
}
void ASF::Picture::swap(Picture &other)
{
using std::swap;
swap(d, other.d);
}
ByteVector ASF::Picture::render() const
{
if(!isValid())
return ByteVector();
return
ByteVector((char)d->type) +
ByteVector::fromUInt(d->picture.size(), false) +
renderString(d->mimeType) +
renderString(d->description) +
d->picture;
}
void ASF::Picture::parse(const ByteVector& bytes)
{
d->valid = false;
if(bytes.size() < 9)
return;
int pos = 0;
d->type = (Type)bytes[0]; ++pos;
const unsigned int dataLen = bytes.toUInt(pos, false); pos+=4;
const ByteVector nullStringTerminator(2, 0);
int endPos = bytes.find(nullStringTerminator, pos, 2);
if(endPos < 0)
return;
d->mimeType = String(bytes.mid(pos, endPos - pos), String::UTF16LE);
pos = endPos+2;
endPos = bytes.find(nullStringTerminator, pos, 2);
if(endPos < 0)
return;
d->description = String(bytes.mid(pos, endPos - pos), String::UTF16LE);
pos = endPos+2;
if(dataLen + pos != bytes.size())
return;
d->picture = bytes.mid(pos, dataLen);
d->valid = true;
return;
}
ASF::Picture ASF::Picture::fromInvalid()
{
Picture ret;
ret.d->valid = false;
return ret;
}

222
3rdparty/taglib/asf/asfpicture.h vendored Normal file
View File

@@ -0,0 +1,222 @@
/**************************************************************************
copyright : (C) 2010 by Anton Sergunov
email : setosha@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 ASFPICTURE_H
#define ASFPICTURE_H
#include "tstring.h"
#include "tbytevector.h"
#include "taglib_export.h"
#include "attachedpictureframe.h"
namespace TagLib
{
namespace ASF
{
//! An ASF attached picture interface implementation
/*!
* This is an implementation of ASF attached pictures interface. Pictures may be
* included in attributes, one per WM/Picture attribute (but there may be multiple WM/Picture
* attribute in a single tag). These pictures are usually in either JPEG or
* PNG format.
* \see Attribute::toPicture()
* \see Attribute::Attribute(const Picture& picture)
*/
class TAGLIB_EXPORT Picture {
public:
/*!
* This describes the function or content of the picture.
*/
enum Type {
//! A type not enumerated below
Other = 0x00,
//! 32x32 PNG image that should be used as the file icon
FileIcon = 0x01,
//! File icon of a different size or format
OtherFileIcon = 0x02,
//! Front cover image of the album
FrontCover = 0x03,
//! Back cover image of the album
BackCover = 0x04,
//! Inside leaflet page of the album
LeafletPage = 0x05,
//! Image from the album itself
Media = 0x06,
//! Picture of the lead artist or soloist
LeadArtist = 0x07,
//! Picture of the artist or performer
Artist = 0x08,
//! Picture of the conductor
Conductor = 0x09,
//! Picture of the band or orchestra
Band = 0x0A,
//! Picture of the composer
Composer = 0x0B,
//! Picture of the lyricist or text writer
Lyricist = 0x0C,
//! Picture of the recording location or studio
RecordingLocation = 0x0D,
//! Picture of the artists during recording
DuringRecording = 0x0E,
//! Picture of the artists during performance
DuringPerformance = 0x0F,
//! Picture from a movie or video related to the track
MovieScreenCapture = 0x10,
//! Picture of a large, coloured fish
ColouredFish = 0x11,
//! Illustration related to the track
Illustration = 0x12,
//! Logo of the band or performer
BandLogo = 0x13,
//! Logo of the publisher (record company)
PublisherLogo = 0x14
};
/*!
* Constructs an empty picture.
*/
Picture();
/*!
* Construct an picture as a copy of \a other.
*/
Picture(const Picture& other);
/*!
* Destroys the picture.
*/
virtual ~Picture();
/*!
* Copies the contents of \a other into this picture.
*/
Picture& operator=(const Picture& other);
/*!
* Exchanges the content of the Picture by the content of \a other.
*/
void swap(Picture &other);
/*!
* Returns true if Picture stores valid picture
*/
bool isValid() const;
/*!
* Returns the mime type of the image. This should in most cases be
* "image/png" or "image/jpeg".
* \see setMimeType(const String &)
* \see picture()
* \see setPicture(const ByteArray&)
*/
String mimeType() const;
/*!
* Sets the mime type of the image. This should in most cases be
* "image/png" or "image/jpeg".
* \see setMimeType(const String &)
* \see picture()
* \see setPicture(const ByteArray&)
*/
void setMimeType(const String &value);
/*!
* Returns the type of the image.
*
* \see Type
* \see setType()
*/
Type type() const;
/*!
* Sets the type for the image.
*
* \see Type
* \see type()
*/
void setType(const ASF::Picture::Type& t);
/*!
* Returns a text description of the image.
*
* \see setDescription()
*/
String description() const;
/*!
* Sets a textual description of the image to \a desc.
*
* \see description()
*/
void setDescription(const String &desc);
/*!
* Returns the image data as a ByteVector.
*
* \note ByteVector has a data() method that returns a const char * which
* should make it easy to export this data to external programs.
*
* \see setPicture()
* \see mimeType()
*/
ByteVector picture() const;
/*!
* Sets the image data to \a p. \a p should be of the type specified in
* this frame's mime-type specification.
*
* \see picture()
* \see mimeType()
* \see setMimeType()
*/
void setPicture(const ByteVector &p);
/*!
* Returns picture as binary raw data \a value
*/
ByteVector render() const;
/*!
* Returns picture as binary raw data \a value
*/
int dataSize() const;
#ifndef DO_NOT_DOCUMENT
/* THIS IS PRIVATE, DON'T TOUCH IT! */
void parse(const ByteVector& );
static Picture fromInvalid();
#endif
private:
class PicturePrivate;
PicturePrivate *d;
};
}
}
#endif // ASFPICTURE_H

194
3rdparty/taglib/asf/asfproperties.cpp vendored Normal file
View File

@@ -0,0 +1,194 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
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 <tdebug.h>
#include <tstring.h>
#include "asfproperties.h"
using namespace TagLib;
class ASF::Properties::PropertiesPrivate
{
public:
PropertiesPrivate() :
length(0),
bitrate(0),
sampleRate(0),
channels(0),
bitsPerSample(0),
codec(ASF::Properties::Unknown),
encrypted(false) {}
int length;
int bitrate;
int sampleRate;
int channels;
int bitsPerSample;
ASF::Properties::Codec codec;
String codecName;
String codecDescription;
bool encrypted;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
ASF::Properties::Properties() :
AudioProperties(AudioProperties::Average),
d(new PropertiesPrivate())
{
}
ASF::Properties::~Properties()
{
delete d;
}
int ASF::Properties::length() const
{
return lengthInSeconds();
}
int ASF::Properties::lengthInSeconds() const
{
return d->length / 1000;
}
int ASF::Properties::lengthInMilliseconds() const
{
return d->length;
}
int ASF::Properties::bitrate() const
{
return d->bitrate;
}
int ASF::Properties::sampleRate() const
{
return d->sampleRate;
}
int ASF::Properties::channels() const
{
return d->channels;
}
int ASF::Properties::bitsPerSample() const
{
return d->bitsPerSample;
}
ASF::Properties::Codec ASF::Properties::codec() const
{
return d->codec;
}
String ASF::Properties::codecName() const
{
return d->codecName;
}
String ASF::Properties::codecDescription() const
{
return d->codecDescription;
}
bool ASF::Properties::isEncrypted() const
{
return d->encrypted;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void ASF::Properties::setLength(int /*length*/)
{
debug("ASF::Properties::setLength() -- This method is deprecated. Do not use.");
}
void ASF::Properties::setLengthInMilliseconds(int value)
{
d->length = value;
}
void ASF::Properties::setBitrate(int value)
{
d->bitrate = value;
}
void ASF::Properties::setSampleRate(int value)
{
d->sampleRate = value;
}
void ASF::Properties::setChannels(int value)
{
d->channels = value;
}
void ASF::Properties::setBitsPerSample(int value)
{
d->bitsPerSample = value;
}
void ASF::Properties::setCodec(int value)
{
switch(value)
{
case 0x0160:
d->codec = WMA1;
break;
case 0x0161:
d->codec = WMA2;
break;
case 0x0162:
d->codec = WMA9Pro;
break;
case 0x0163:
d->codec = WMA9Lossless;
break;
default:
d->codec = Unknown;
break;
}
}
void ASF::Properties::setCodecName(const String &value)
{
d->codecName = value;
}
void ASF::Properties::setCodecDescription(const String &value)
{
d->codecDescription = value;
}
void ASF::Properties::setEncrypted(bool value)
{
d->encrypted = value;
}

186
3rdparty/taglib/asf/asfproperties.h vendored Normal file
View File

@@ -0,0 +1,186 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
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_ASFPROPERTIES_H
#define TAGLIB_ASFPROPERTIES_H
#include "audioproperties.h"
#include "tstring.h"
#include "taglib_export.h"
namespace TagLib {
namespace ASF {
//! An implementation of ASF audio properties
class TAGLIB_EXPORT Properties : public AudioProperties
{
public:
/*!
* Audio codec types can be used in ASF file.
*/
enum Codec
{
/*!
* Couldn't detect the codec.
*/
Unknown = 0,
/*!
* Windows Media Audio 1
*/
WMA1,
/*!
* Windows Media Audio 2 or above
*/
WMA2,
/*!
* Windows Media Audio 9 Professional
*/
WMA9Pro,
/*!
* Windows Media Audio 9 Lossless
*/
WMA9Lossless,
};
/*!
* Creates an instance of ASF::Properties.
*/
Properties();
/*!
* Destroys this ASF::Properties instance.
*/
virtual ~Properties();
/*!
* Returns the length of the file in seconds. The length is rounded down to
* the nearest whole second.
*
* \note This method is just an alias of lengthInSeconds().
*
* \deprecated
*/
virtual int length() const;
/*!
* Returns the length of the file in seconds. The length is rounded down to
* the nearest whole second.
*
* \see lengthInMilliseconds()
*/
// BIC: make virtual
int lengthInSeconds() const;
/*!
* Returns the length of the file in milliseconds.
*
* \see lengthInSeconds()
*/
// BIC: make virtual
int lengthInMilliseconds() const;
/*!
* Returns the average bit rate of the file in kb/s.
*/
virtual int bitrate() const;
/*!
* Returns the sample rate in Hz.
*/
virtual int sampleRate() const;
/*!
* Returns the number of audio channels.
*/
virtual int channels() const;
/*!
* Returns the number of bits per audio sample.
*/
int bitsPerSample() const;
/*!
* Returns the codec used in the file.
*
* \see codecName()
* \see codecDescription()
*/
Codec codec() const;
/*!
* Returns the concrete codec name, for example "Windows Media Audio 9.1"
* used in the file if available, otherwise an empty string.
*
* \see codec()
* \see codecDescription()
*/
String codecName() const;
/*!
* Returns the codec description, typically contains the encoder settings,
* for example "VBR Quality 50, 44kHz, stereo 1-pass VBR" if available,
* otherwise an empty string.
*
* \see codec()
* \see codecName()
*/
String codecDescription() const;
/*!
* Returns whether or not the file is encrypted.
*/
bool isEncrypted() const;
#ifndef DO_NOT_DOCUMENT
// deprecated
void setLength(int value);
void setLengthInMilliseconds(int value);
void setBitrate(int value);
void setSampleRate(int value);
void setChannels(int value);
void setBitsPerSample(int value);
void setCodec(int value);
void setCodecName(const String &value);
void setCodecDescription(const String &value);
void setEncrypted(bool value);
#endif
private:
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
#endif

378
3rdparty/taglib/asf/asftag.cpp vendored Normal file
View File

@@ -0,0 +1,378 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
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 <tpropertymap.h>
#include "asftag.h"
using namespace TagLib;
class ASF::Tag::TagPrivate
{
public:
String title;
String artist;
String copyright;
String comment;
String rating;
AttributeListMap attributeListMap;
};
ASF::Tag::Tag() :
TagLib::Tag(),
d(new TagPrivate())
{
}
ASF::Tag::~Tag()
{
delete d;
}
String ASF::Tag::title() const
{
return d->title;
}
String ASF::Tag::artist() const
{
return d->artist;
}
String ASF::Tag::album() const
{
if(d->attributeListMap.contains("WM/AlbumTitle"))
return d->attributeListMap["WM/AlbumTitle"][0].toString();
return String();
}
String ASF::Tag::copyright() const
{
return d->copyright;
}
String ASF::Tag::comment() const
{
return d->comment;
}
String ASF::Tag::rating() const
{
return d->rating;
}
unsigned int ASF::Tag::year() const
{
if(d->attributeListMap.contains("WM/Year"))
return d->attributeListMap["WM/Year"][0].toString().toInt();
return 0;
}
unsigned int ASF::Tag::track() const
{
if(d->attributeListMap.contains("WM/TrackNumber")) {
const ASF::Attribute attr = d->attributeListMap["WM/TrackNumber"][0];
if(attr.type() == ASF::Attribute::DWordType)
return attr.toUInt();
else
return attr.toString().toInt();
}
if(d->attributeListMap.contains("WM/Track"))
return d->attributeListMap["WM/Track"][0].toUInt();
return 0;
}
String ASF::Tag::genre() const
{
if(d->attributeListMap.contains("WM/Genre"))
return d->attributeListMap["WM/Genre"][0].toString();
return String();
}
void ASF::Tag::setTitle(const String &value)
{
d->title = value;
}
void ASF::Tag::setArtist(const String &value)
{
d->artist = value;
}
void ASF::Tag::setCopyright(const String &value)
{
d->copyright = value;
}
void ASF::Tag::setComment(const String &value)
{
d->comment = value;
}
void ASF::Tag::setRating(const String &value)
{
d->rating = value;
}
void ASF::Tag::setAlbum(const String &value)
{
setAttribute("WM/AlbumTitle", value);
}
void ASF::Tag::setGenre(const String &value)
{
setAttribute("WM/Genre", value);
}
void ASF::Tag::setYear(unsigned int value)
{
setAttribute("WM/Year", String::number(value));
}
void ASF::Tag::setTrack(unsigned int value)
{
setAttribute("WM/TrackNumber", String::number(value));
}
ASF::AttributeListMap& ASF::Tag::attributeListMap()
{
return d->attributeListMap;
}
const ASF::AttributeListMap &ASF::Tag::attributeListMap() const
{
return d->attributeListMap;
}
bool ASF::Tag::contains(const String &key) const
{
return d->attributeListMap.contains(key);
}
void ASF::Tag::removeItem(const String &key)
{
d->attributeListMap.erase(key);
}
ASF::AttributeList ASF::Tag::attribute(const String &name) const
{
return d->attributeListMap[name];
}
void ASF::Tag::setAttribute(const String &name, const Attribute &attribute)
{
AttributeList value;
value.append(attribute);
d->attributeListMap.insert(name, value);
}
void ASF::Tag::setAttribute(const String &name, const AttributeList &values)
{
d->attributeListMap.insert(name, values);
}
void ASF::Tag::addAttribute(const String &name, const Attribute &attribute)
{
if(d->attributeListMap.contains(name)) {
d->attributeListMap[name].append(attribute);
}
else {
setAttribute(name, attribute);
}
}
bool ASF::Tag::isEmpty() const
{
return TagLib::Tag::isEmpty() &&
copyright().isEmpty() &&
rating().isEmpty() &&
d->attributeListMap.isEmpty();
}
namespace
{
const char *keyTranslation[][2] = {
{ "WM/AlbumTitle", "ALBUM" },
{ "WM/AlbumArtist", "ALBUMARTIST" },
{ "WM/Composer", "COMPOSER" },
{ "WM/Writer", "WRITER" },
{ "WM/Conductor", "CONDUCTOR" },
{ "WM/ModifiedBy", "REMIXER" },
{ "WM/Year", "DATE" },
{ "WM/OriginalReleaseYear", "ORIGINALDATE" },
{ "WM/Producer", "PRODUCER" },
{ "WM/ContentGroupDescription", "GROUPING" },
{ "WM/SubTitle", "SUBTITLE" },
{ "WM/SetSubTitle", "DISCSUBTITLE" },
{ "WM/TrackNumber", "TRACKNUMBER" },
{ "WM/PartOfSet", "DISCNUMBER" },
{ "WM/Genre", "GENRE" },
{ "WM/BeatsPerMinute", "BPM" },
{ "WM/Mood", "MOOD" },
{ "WM/ISRC", "ISRC" },
{ "WM/Lyrics", "LYRICS" },
{ "WM/Media", "MEDIA" },
{ "WM/Publisher", "LABEL" },
{ "WM/CatalogNo", "CATALOGNUMBER" },
{ "WM/Barcode", "BARCODE" },
{ "WM/EncodedBy", "ENCODEDBY" },
{ "WM/AlbumSortOrder", "ALBUMSORT" },
{ "WM/AlbumArtistSortOrder", "ALBUMARTISTSORT" },
{ "WM/ArtistSortOrder", "ARTISTSORT" },
{ "WM/TitleSortOrder", "TITLESORT" },
{ "WM/Script", "SCRIPT" },
{ "WM/Language", "LANGUAGE" },
{ "MusicBrainz/Track Id", "MUSICBRAINZ_TRACKID" },
{ "MusicBrainz/Artist Id", "MUSICBRAINZ_ARTISTID" },
{ "MusicBrainz/Album Id", "MUSICBRAINZ_ALBUMID" },
{ "MusicBrainz/Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
{ "MusicBrainz/Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
{ "MusicBrainz/Work Id", "MUSICBRAINZ_WORKID" },
{ "MusicIP/PUID", "MUSICIP_PUID" },
{ "Acoustid/Id", "ACOUSTID_ID" },
{ "Acoustid/Fingerprint", "ACOUSTID_FINGERPRINT" },
};
const size_t keyTranslationSize = sizeof(keyTranslation) / sizeof(keyTranslation[0]);
String translateKey(const String &key)
{
for(size_t i = 0; i < keyTranslationSize; ++i) {
if(key == keyTranslation[i][0])
return keyTranslation[i][1];
}
return String();
}
}
PropertyMap ASF::Tag::properties() const
{
PropertyMap props;
if(!d->title.isEmpty()) {
props["TITLE"] = d->title;
}
if(!d->artist.isEmpty()) {
props["ARTIST"] = d->artist;
}
if(!d->copyright.isEmpty()) {
props["COPYRIGHT"] = d->copyright;
}
if(!d->comment.isEmpty()) {
props["COMMENT"] = d->comment;
}
ASF::AttributeListMap::ConstIterator it = d->attributeListMap.begin();
for(; it != d->attributeListMap.end(); ++it) {
const String key = translateKey(it->first);
if(!key.isEmpty()) {
AttributeList::ConstIterator it2 = it->second.begin();
for(; it2 != it->second.end(); ++it2) {
if(key == "TRACKNUMBER") {
if(it2->type() == ASF::Attribute::DWordType)
props.insert(key, String::number(it2->toUInt()));
else
props.insert(key, it2->toString());
}
else {
props.insert(key, it2->toString());
}
}
}
else {
props.unsupportedData().append(it->first);
}
}
return props;
}
void ASF::Tag::removeUnsupportedProperties(const StringList &props)
{
StringList::ConstIterator it = props.begin();
for(; it != props.end(); ++it)
d->attributeListMap.erase(*it);
}
PropertyMap ASF::Tag::setProperties(const PropertyMap &props)
{
static Map<String, String> reverseKeyMap;
if(reverseKeyMap.isEmpty()) {
int numKeys = sizeof(keyTranslation) / sizeof(keyTranslation[0]);
for(int i = 0; i < numKeys; i++) {
reverseKeyMap[keyTranslation[i][1]] = keyTranslation[i][0];
}
}
PropertyMap origProps = properties();
PropertyMap::ConstIterator it = origProps.begin();
for(; it != origProps.end(); ++it) {
if(!props.contains(it->first) || props[it->first].isEmpty()) {
if(it->first == "TITLE") {
d->title.clear();
}
else if(it->first == "ARTIST") {
d->artist.clear();
}
else if(it->first == "COMMENT") {
d->comment.clear();
}
else if(it->first == "COPYRIGHT") {
d->copyright.clear();
}
else {
d->attributeListMap.erase(reverseKeyMap[it->first]);
}
}
}
PropertyMap ignoredProps;
it = props.begin();
for(; it != props.end(); ++it) {
if(reverseKeyMap.contains(it->first)) {
String name = reverseKeyMap[it->first];
removeItem(name);
StringList::ConstIterator it2 = it->second.begin();
for(; it2 != it->second.end(); ++it2) {
addAttribute(name, *it2);
}
}
else if(it->first == "TITLE") {
d->title = it->second.toString();
}
else if(it->first == "ARTIST") {
d->artist = it->second.toString();
}
else if(it->first == "COMMENT") {
d->comment = it->second.toString();
}
else if(it->first == "COPYRIGHT") {
d->copyright = it->second.toString();
}
else {
ignoredProps.insert(it->first, it->second);
}
}
return ignoredProps;
}

209
3rdparty/taglib/asf/asftag.h vendored Normal file
View File

@@ -0,0 +1,209 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
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_ASFTAG_H
#define TAGLIB_ASFTAG_H
#include "tag.h"
#include "tlist.h"
#include "tmap.h"
#include "taglib_export.h"
#include "asfattribute.h"
namespace TagLib {
namespace ASF {
typedef List<Attribute> AttributeList;
typedef Map<String, AttributeList> AttributeListMap;
class TAGLIB_EXPORT Tag : public TagLib::Tag {
friend class File;
public:
Tag();
virtual ~Tag();
/*!
* Returns the track name.
*/
virtual String title() const;
/*!
* Returns the artist name.
*/
virtual String artist() const;
/*!
* Returns the album name; if no album name is present in the tag
* String::null will be returned.
*/
virtual String album() const;
/*!
* Returns the track comment.
*/
virtual String comment() const;
/*!
* Returns the genre name; if no genre is present in the tag String::null
* will be returned.
*/
virtual String genre() const;
/*!
* Returns the rating.
*/
virtual String rating() const;
/*!
* Returns the genre name; if no genre is present in the tag String::null
* will be returned.
*/
virtual String copyright() const;
/*!
* Returns the year; if there is no year set, this will return 0.
*/
virtual unsigned int year() const;
/*!
* Returns the track number; if there is no track number set, this will
* return 0.
*/
virtual unsigned int track() const;
/*!
* Sets the title to \a s.
*/
virtual void setTitle(const String &s);
/*!
* Sets the artist to \a s.
*/
virtual void setArtist(const String &s);
/*!
* Sets the album to \a s. If \a s is String::null then this value will be
* cleared.
*/
virtual void setAlbum(const String &s);
/*!
* Sets the comment to \a s.
*/
virtual void setComment(const String &s);
/*!
* Sets the rating to \a s.
*/
virtual void setRating(const String &s);
/*!
* Sets the copyright to \a s.
*/
virtual void setCopyright(const String &s);
/*!
* Sets the genre to \a s.
*/
virtual void setGenre(const String &s);
/*!
* Sets the year to \a i. If \a s is 0 then this value will be cleared.
*/
virtual void setYear(unsigned int i);
/*!
* Sets the track to \a i. If \a s is 0 then this value will be cleared.
*/
virtual void setTrack(unsigned int i);
/*!
* Returns true if the tag does not contain any data. This should be
* reimplemented in subclasses that provide more than the basic tagging
* abilities in this class.
*/
virtual bool isEmpty() const;
/*!
* \deprecated
*/
AttributeListMap &attributeListMap();
/*!
* Returns a reference to the item list map. This is an AttributeListMap of
* all of the items in the tag.
*/
const AttributeListMap &attributeListMap() const;
/*!
* \return True if a value for \a attribute is currently set.
*/
bool contains(const String &name) const;
/*!
* Removes the \a key attribute from the tag
*/
void removeItem(const String &name);
/*!
* \return The list of values for the key \a name, or an empty list if no
* values have been set.
*/
AttributeList attribute(const String &name) const;
/*!
* Sets the \a key attribute to the value of \a attribute. If an attribute
* with the \a key is already present, it will be replaced.
*/
void setAttribute(const String &name, const Attribute &attribute);
/*!
* Sets multiple \a values to the key \a name.
*/
void setAttribute(const String &name, const AttributeList &values);
/*!
* Sets the \a key attribute to the value of \a attribute. If an attribute
* with the \a key is already present, it will be added to the list.
*/
void addAttribute(const String &name, const Attribute &attribute);
PropertyMap properties() const;
void removeUnsupportedProperties(const StringList& properties);
PropertyMap setProperties(const PropertyMap &properties);
private:
class TagPrivate;
TagPrivate *d;
};
}
}
#endif

104
3rdparty/taglib/asf/asfutils.h vendored Normal file
View File

@@ -0,0 +1,104 @@
/***************************************************************************
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_ASFUTILS_H
#define TAGLIB_ASFUTILS_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 ASF
{
namespace
{
inline unsigned short readWORD(File *file, bool *ok = 0)
{
const ByteVector v = file->readBlock(2);
if(v.size() != 2) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v.toUShort(false);
}
inline unsigned int readDWORD(File *file, bool *ok = 0)
{
const ByteVector v = file->readBlock(4);
if(v.size() != 4) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v.toUInt(false);
}
inline long long readQWORD(File *file, bool *ok = 0)
{
const ByteVector v = file->readBlock(8);
if(v.size() != 8) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v.toLongLong(false);
}
inline String readString(File *file, int length)
{
ByteVector data = file->readBlock(length);
unsigned int size = data.size();
while (size >= 2) {
if(data[size - 1] != '\0' || data[size - 2] != '\0') {
break;
}
size -= 2;
}
if(size != data.size()) {
data.resize(size);
}
return String(data, String::UTF16LE);
}
inline ByteVector renderString(const String &str, bool includeLength = false)
{
ByteVector data = str.data(String::UTF16LE) + ByteVector::fromShort(0, false);
if(includeLength) {
data = ByteVector::fromShort(data.size(), false) + data;
}
return data;
}
}
}
}
#endif
#endif