mirror of
https://github.com/taglib/taglib.git
synced 2026-06-08 07:19:20 -04:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa61823432 | ||
|
|
2f7af42092 | ||
|
|
2d5abd46d2 | ||
|
|
9b5869ea37 | ||
|
|
02ebd0bcbe | ||
|
|
5693ab0403 | ||
|
|
27000438f5 | ||
|
|
a6f759cc9a | ||
|
|
a175b8356b | ||
|
|
873df184fe | ||
|
|
079e3e0b87 | ||
|
|
cf892f2cb8 |
@@ -48,7 +48,7 @@ endif()
|
||||
|
||||
set(TAGLIB_LIB_MAJOR_VERSION "1")
|
||||
set(TAGLIB_LIB_MINOR_VERSION "9")
|
||||
set(TAGLIB_LIB_PATCH_VERSION "0")
|
||||
set(TAGLIB_LIB_PATCH_VERSION "1")
|
||||
|
||||
set(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}")
|
||||
|
||||
@@ -56,9 +56,9 @@ set(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VE
|
||||
# 2. If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0.
|
||||
# 3. If any interfaces have been added since the last public release, then increment age.
|
||||
# 4. If any interfaces have been removed since the last public release, then set age to 0.
|
||||
set(TAGLIB_SOVERSION_CURRENT 14)
|
||||
set(TAGLIB_SOVERSION_CURRENT 15)
|
||||
set(TAGLIB_SOVERSION_REVISION 0)
|
||||
set(TAGLIB_SOVERSION_AGE 13)
|
||||
set(TAGLIB_SOVERSION_AGE 14)
|
||||
|
||||
math(EXPR TAGLIB_SOVERSION_MAJOR "${TAGLIB_SOVERSION_CURRENT} - ${TAGLIB_SOVERSION_AGE}")
|
||||
math(EXPR TAGLIB_SOVERSION_MINOR "${TAGLIB_SOVERSION_AGE}")
|
||||
|
||||
11
NEWS
11
NEWS
@@ -1,6 +1,15 @@
|
||||
TagLib 1.9 (Oct 6, 2013)
|
||||
TagLib 1.9.1 (Oct 8, 2013)
|
||||
==========================
|
||||
|
||||
* Fixed binary incompatible change in TagLib::Map and TagLib::List.
|
||||
* Fixed constructing String from ByteVector.
|
||||
* Fixed compilation on MSVC with the /Zc:wchar_t- option.
|
||||
* Fixed detecting of RIFF files with invalid chunk sizes.
|
||||
* Added TagLib::MP4::PropertyMap::codec().
|
||||
|
||||
TagLib 1.9 (Oct 6, 2013)
|
||||
========================
|
||||
|
||||
* Added support for the Ogg Opus file format.
|
||||
* Added support for INFO tags in WAV files.
|
||||
* Changed FileStream to use Windows file API.
|
||||
|
||||
0
taglib/CMakeLists.txt
Executable file → Normal file
0
taglib/CMakeLists.txt
Executable file → Normal file
0
taglib/fileref.h
Executable file → Normal file
0
taglib/fileref.h
Executable file → Normal file
@@ -34,7 +34,7 @@ using namespace TagLib;
|
||||
class MP4::Properties::PropertiesPrivate
|
||||
{
|
||||
public:
|
||||
PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), bitsPerSample(0), encrypted(false) {}
|
||||
PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), bitsPerSample(0), encrypted(false), codec(MP4::Properties::Unknown) {}
|
||||
|
||||
int length;
|
||||
int bitrate;
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
int channels;
|
||||
int bitsPerSample;
|
||||
bool encrypted;
|
||||
Codec codec;
|
||||
};
|
||||
|
||||
MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style)
|
||||
@@ -114,6 +115,7 @@ MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style)
|
||||
file->seek(atom->offset);
|
||||
data = file->readBlock(atom->length);
|
||||
if(data.mid(20, 4) == "mp4a") {
|
||||
d->codec = AAC;
|
||||
d->channels = data.toShort(40U);
|
||||
d->bitsPerSample = data.toShort(42U);
|
||||
d->sampleRate = data.toUInt(46U);
|
||||
@@ -135,10 +137,11 @@ MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style)
|
||||
}
|
||||
else if (data.mid(20, 4) == "alac") {
|
||||
if (atom->length == 88 && data.mid(56, 4) == "alac") {
|
||||
d->codec = ALAC;
|
||||
d->bitsPerSample = data.at(69);
|
||||
d->channels = data.at(73);
|
||||
d->bitrate = data.toUInt(80U) / 1000;
|
||||
d->sampleRate = data.toUInt(84U);
|
||||
d->channels = data.at(73);
|
||||
d->bitrate = data.toUInt(80U) / 1000;
|
||||
d->sampleRate = data.toUInt(84U);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,3 +192,8 @@ MP4::Properties::isEncrypted() const
|
||||
return d->encrypted;
|
||||
}
|
||||
|
||||
MP4::Properties::Codec MP4::Properties::codec() const
|
||||
{
|
||||
return d->codec;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,12 @@ namespace TagLib {
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties
|
||||
{
|
||||
public:
|
||||
enum Codec {
|
||||
Unknown = 0,
|
||||
AAC,
|
||||
ALAC
|
||||
};
|
||||
|
||||
Properties(File *file, Atoms *atoms, ReadStyle style = Average);
|
||||
virtual ~Properties();
|
||||
|
||||
@@ -50,6 +56,9 @@ namespace TagLib {
|
||||
virtual int bitsPerSample() const;
|
||||
bool isEncrypted() const;
|
||||
|
||||
//! Audio codec used in the MP4 file
|
||||
Codec codec() const;
|
||||
|
||||
private:
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
|
||||
@@ -392,7 +392,7 @@ static const char *frameTranslation[][2] = {
|
||||
//{ "USLT", "LYRICS" }, handled specially
|
||||
};
|
||||
|
||||
static const TagLib::uint txxxFrameTranslationSize = 7;
|
||||
static const TagLib::uint txxxFrameTranslationSize = 8;
|
||||
static const char *txxxFrameTranslation[][2] = {
|
||||
{ "MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
|
||||
@@ -273,7 +273,7 @@ void RIFF::File::read()
|
||||
break;
|
||||
}
|
||||
|
||||
if(tell() + chunkSize > uint(length())) {
|
||||
if(static_cast<ulonglong>(tell()) + chunkSize > static_cast<ulonglong>(length())) {
|
||||
debug("RIFF::File::read() -- Chunk '" + chunkName + "' has invalid size (larger than the file size)");
|
||||
setValid(false);
|
||||
break;
|
||||
|
||||
2
taglib/toolkit/taglib.h
Executable file → Normal file
2
taglib/toolkit/taglib.h
Executable file → Normal file
@@ -30,7 +30,7 @@
|
||||
|
||||
#define TAGLIB_MAJOR_VERSION 1
|
||||
#define TAGLIB_MINOR_VERSION 9
|
||||
#define TAGLIB_PATCH_VERSION 0
|
||||
#define TAGLIB_PATCH_VERSION 1
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1))
|
||||
#define TAGLIB_IGNORE_MISSING_DESTRUCTOR _Pragma("GCC diagnostic ignored \"-Wnon-virtual-dtor\"")
|
||||
|
||||
@@ -39,7 +39,8 @@ namespace TagLib {
|
||||
// A base for the generic and specialized private class types. New
|
||||
// non-templatized members should be added here.
|
||||
|
||||
class ListPrivateBase : public RefCounter
|
||||
// BIC change to RefCounter
|
||||
class ListPrivateBase : public RefCounterOld
|
||||
{
|
||||
public:
|
||||
ListPrivateBase() : autoDelete(false) {}
|
||||
|
||||
@@ -31,17 +31,18 @@ namespace TagLib {
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// BIC change to RefCounter
|
||||
template <class Key, class T>
|
||||
template <class KeyP, class TP>
|
||||
class Map<Key, T>::MapPrivate : public RefCounter
|
||||
class Map<Key, T>::MapPrivate : public RefCounterOld
|
||||
{
|
||||
public:
|
||||
MapPrivate() : RefCounter() {}
|
||||
MapPrivate() : RefCounterOld() {}
|
||||
#ifdef WANT_CLASS_INSTANTIATION_OF_MAP
|
||||
MapPrivate(const std::map<class KeyP, class TP>& m) : RefCounter(), map(m) {}
|
||||
MapPrivate(const std::map<class KeyP, class TP>& m) : RefCounterOld(), map(m) {}
|
||||
std::map<class KeyP, class TP> map;
|
||||
#else
|
||||
MapPrivate(const std::map<KeyP, TP>& m) : RefCounter(), map(m) {}
|
||||
MapPrivate(const std::map<KeyP, TP>& m) : RefCounterOld(), map(m) {}
|
||||
std::map<KeyP, TP> map;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -29,6 +29,23 @@
|
||||
#include "taglib_export.h"
|
||||
#include "taglib.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <libkern/OSAtomic.h>
|
||||
# define TAGLIB_ATOMIC_MAC
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
# define NOMINMAX
|
||||
# include <windows.h>
|
||||
# define TAGLIB_ATOMIC_WIN
|
||||
#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 401) \
|
||||
&& (defined(__i386__) || defined(__i486__) || defined(__i586__) || \
|
||||
defined(__i686__) || defined(__x86_64) || defined(__ia64)) \
|
||||
&& !defined(__INTEL_COMPILER)
|
||||
# define TAGLIB_ATOMIC_GCC
|
||||
#elif defined(__ia64) && defined(__INTEL_COMPILER)
|
||||
# include <ia64intrin.h>
|
||||
# define TAGLIB_ATOMIC_GCC
|
||||
#endif
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class.
|
||||
/*!
|
||||
* \internal
|
||||
@@ -38,6 +55,7 @@
|
||||
*/
|
||||
namespace TagLib
|
||||
{
|
||||
|
||||
class TAGLIB_EXPORT RefCounter
|
||||
{
|
||||
public:
|
||||
@@ -52,7 +70,42 @@ namespace TagLib
|
||||
class RefCounterPrivate;
|
||||
RefCounterPrivate *d;
|
||||
};
|
||||
|
||||
// BIC this old class is needed by tlist.tcc and tmap.tcc
|
||||
class RefCounterOld
|
||||
{
|
||||
public:
|
||||
RefCounterOld() : refCount(1) {}
|
||||
|
||||
#ifdef TAGLIB_ATOMIC_MAC
|
||||
void ref() { OSAtomicIncrement32Barrier(const_cast<int32_t*>(&refCount)); }
|
||||
bool deref() { return ! OSAtomicDecrement32Barrier(const_cast<int32_t*>(&refCount)); }
|
||||
int32_t count() { return refCount; }
|
||||
private:
|
||||
volatile int32_t refCount;
|
||||
#elif defined(TAGLIB_ATOMIC_WIN)
|
||||
void ref() { InterlockedIncrement(&refCount); }
|
||||
bool deref() { return ! InterlockedDecrement(&refCount); }
|
||||
long count() { return refCount; }
|
||||
private:
|
||||
volatile long refCount;
|
||||
#elif defined(TAGLIB_ATOMIC_GCC)
|
||||
void ref() { __sync_add_and_fetch(&refCount, 1); }
|
||||
bool deref() { return ! __sync_sub_and_fetch(&refCount, 1); }
|
||||
int count() { return refCount; }
|
||||
private:
|
||||
volatile int refCount;
|
||||
#else
|
||||
void ref() { refCount++; }
|
||||
bool deref() { return ! --refCount; }
|
||||
int count() { return refCount; }
|
||||
private:
|
||||
uint refCount;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DO_NOT_DOCUMENT
|
||||
#endif
|
||||
|
||||
|
||||
@@ -268,6 +268,9 @@ String::String(const ByteVector &v, Type t)
|
||||
copyFromUTF8(v.data(), v.size());
|
||||
else
|
||||
copyFromUTF16(v.data(), v.size(), t);
|
||||
|
||||
// If we hit a null in the ByteVector, shrink the string again.
|
||||
d->data.resize(::wcslen(d->data.c_str()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -106,6 +106,11 @@
|
||||
bit mask & shift operations.
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
// Workaround for when MSVC doesn't have wchar_t as a built-in type.
|
||||
#if defined(_MSC_VER) && !defined(_WCHAR_T_DEFINED)
|
||||
# include <wchar.h>
|
||||
#endif
|
||||
|
||||
/* Some fundamental constants */
|
||||
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
|
||||
#define UNI_MAX_BMP (UTF32)0x0000FFFF
|
||||
@@ -114,10 +119,10 @@
|
||||
|
||||
namespace Unicode {
|
||||
|
||||
typedef unsigned long UTF32; /* at least 32 bits */
|
||||
typedef wchar_t UTF16; /* TagLib assumes that wchar_t is sufficient for UTF-16. */
|
||||
typedef unsigned long UTF32; /* at least 32 bits */
|
||||
typedef wchar_t UTF16; /* TagLib assumes that wchar_t is sufficient for UTF-16. */
|
||||
typedef unsigned char UTF8; /* typically 8 bits */
|
||||
typedef unsigned char Boolean; /* 0 or 1 */
|
||||
typedef unsigned char Boolean; /* 0 or 1 */
|
||||
|
||||
typedef enum {
|
||||
conversionOK = 0, /* conversion successful */
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <tstring.h>
|
||||
#include <mpegfile.h>
|
||||
#include <id3v1tag.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace TagLib;
|
||||
@@ -16,8 +19,20 @@ public:
|
||||
|
||||
void testStripWhiteSpace()
|
||||
{
|
||||
ID3v1::StringHandler h;
|
||||
CPPUNIT_ASSERT_EQUAL(String("Foo"), h.parse(ByteVector("Foo ")));
|
||||
ScopedFileCopy copy("xing", ".mp3");
|
||||
string newname = copy.fileName();
|
||||
|
||||
{
|
||||
MPEG::File f(newname.c_str());
|
||||
f.ID3v1Tag(true)->setArtist("Artist ");
|
||||
f.save();
|
||||
}
|
||||
|
||||
{
|
||||
MPEG::File f(newname.c_str());
|
||||
CPPUNIT_ASSERT(f.ID3v1Tag(false));
|
||||
CPPUNIT_ASSERT_EQUAL(String("Artist"), f.ID3v1Tag(false)->artist());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels());
|
||||
CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate());
|
||||
CPPUNIT_ASSERT_EQUAL(16, ((MP4::Properties *)f.audioProperties())->bitsPerSample());
|
||||
CPPUNIT_ASSERT_EQUAL(MP4::Properties::AAC, ((MP4::Properties *)f.audioProperties())->codec());
|
||||
}
|
||||
|
||||
void testPropertiesALAC()
|
||||
@@ -49,6 +50,7 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels());
|
||||
CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate());
|
||||
CPPUNIT_ASSERT_EQUAL(16, ((MP4::Properties *)f.audioProperties())->bitsPerSample());
|
||||
CPPUNIT_ASSERT_EQUAL(MP4::Properties::ALAC, ((MP4::Properties *)f.audioProperties())->codec());
|
||||
}
|
||||
|
||||
void testCheckValid()
|
||||
|
||||
Reference in New Issue
Block a user