Added taglib from songbird repository for m4a support.

CQTexperiment
vspader 2007-10-16 22:31:23 +00:00
parent da9e4e28fd
commit 8454204f44
182 changed files with 6706 additions and 985 deletions

File diff suppressed because it is too large Load Diff

View File

View File

View File

View File

@ -0,0 +1,6 @@
There are a few other people that have done bindings externally that I have
been made aware of. I have not personally reviewed these bindings, but I'm
listing them here so that those who find them useful are able to find them:
- Ruby - http://www.hakubi.us/ruby-taglib/
- Python - http://namingmuse.berlios.de/

View File

@ -1,4 +1,4 @@
/* config.h. Generated by configure. */
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
@ -28,9 +28,6 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* C++ compiler supports template repository */
#define HAVE_TEMPLATE_REPOSITORY 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
@ -62,4 +59,4 @@
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.1"
#define VERSION "1.4"

View File

@ -19,6 +19,14 @@
* USA *
***************************************************************************/
#ifdef __SUNPRO_CC
// Sun Studio finds multiple specializations of Map because
// it considers specializations with and without class types
// to be different; this define forces Map to use only the
// specialization with the class keyword.
#define WANT_CLASS_INSTANTIATION_OF_MAP (1)
#endif
#include <tdebug.h>
#include <tfile.h>
#include <tstring.h>

View File

@ -22,6 +22,8 @@
#ifndef TAGLIB_AUDIOPROPERTIES_H
#define TAGLIB_AUDIOPROPERTIES_H
#include "taglib_export.h"
namespace TagLib {
//! A simple, abstract interface to common audio properties
@ -33,7 +35,7 @@ namespace TagLib {
* interface that is sufficient for most applications.
*/
class AudioProperties
class TAGLIB_EXPORT AudioProperties
{
public:

View File

@ -27,6 +27,7 @@
#include "vorbisfile.h"
#include "flacfile.h"
#include "mpcfile.h"
#include "mp4file.h"
using namespace TagLib;
@ -109,6 +110,8 @@ StringList FileRef::defaultFileExtensions()
l.append("flac");
l.append("mp3");
l.append("mpc");
l.append("m4a");
//l.append("m4p");
return l;
}
@ -171,6 +174,10 @@ File *FileRef::create(const char *fileName, bool readAudioProperties,
return new FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 4, 4).upper() == ".MPC")
return new MPC::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 4, 4).upper() == ".M4A")
return new MP4::File(fileName, readAudioProperties, audioPropertiesStyle);
//if(s.substr(s.size() - 4, 4).upper() == ".M4P")
//return new MP4::File(fileName, readAudioProperties, audioPropertiesStyle);
}
return 0;

View File

@ -24,6 +24,7 @@
#include <tstringlist.h>
#include "taglib_export.h"
#include "audioproperties.h"
namespace TagLib {
@ -52,7 +53,7 @@ namespace TagLib {
* \see addFileTypeResolver()
*/
class FileRef
class TAGLIB_EXPORT FileRef
{
public:

View File

@ -98,6 +98,13 @@ public:
// public members
////////////////////////////////////////////////////////////////////////////////
FLAC::File::File(ID3v2::FrameFactory *frameFactory) : TagLib::File()
{
d = new FilePrivate;
if (frameFactory)
d->ID3v2FrameFactory = frameFactory;
}
FLAC::File::File(const char *file, bool readProperties,
Properties::ReadStyle propertiesStyle) :
TagLib::File(file)
@ -130,6 +137,52 @@ FLAC::Properties *FLAC::File::audioProperties() const
return d->properties;
}
void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
{
// Look for an ID3v2 tag
d->ID3v2Location = findID3v2();
if(d->ID3v2Location >= 0) {
d->ID3v2Tag = new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory);
d->ID3v2OriginalSize = d->ID3v2Tag->header()->completeTagSize();
if(d->ID3v2Tag->header()->tagSize() <= 0) {
delete d->ID3v2Tag;
d->ID3v2Tag = 0;
}
else
d->hasID3v2 = true;
}
// Look for an ID3v1 tag
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
d->hasID3v1 = true;
}
// Look for FLAC metadata, including vorbis comments
scan();
if (!isValid()) return;
if(d->hasXiphComment)
d->comment = new Ogg::XiphComment(xiphCommentData());
if(d->hasXiphComment || d->hasID3v2 || d->hasID3v1)
d->tag = new FLAC::Tag(d->comment, d->ID3v2Tag, d->ID3v1Tag);
else
d->tag = new FLAC::Tag(new Ogg::XiphComment);
if(readProperties)
d->properties = new Properties(streamInfoData(), streamLength(), propertiesStyle);
}
bool FLAC::File::save()
{
@ -275,53 +328,6 @@ void FLAC::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory)
// private members
////////////////////////////////////////////////////////////////////////////////
void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
{
// Look for an ID3v2 tag
d->ID3v2Location = findID3v2();
if(d->ID3v2Location >= 0) {
d->ID3v2Tag = new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory);
d->ID3v2OriginalSize = d->ID3v2Tag->header()->completeTagSize();
if(d->ID3v2Tag->header()->tagSize() <= 0) {
delete d->ID3v2Tag;
d->ID3v2Tag = 0;
}
else
d->hasID3v2 = true;
}
// Look for an ID3v1 tag
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
d->hasID3v1 = true;
}
// Look for FLAC metadata, including vorbis comments
scan();
if (!isValid()) return;
if(d->hasXiphComment)
d->comment = new Ogg::XiphComment(xiphCommentData());
if(d->hasXiphComment || d->hasID3v2 || d->hasID3v1)
d->tag = new FLAC::Tag(d->comment, d->ID3v2Tag, d->ID3v1Tag);
else
d->tag = new FLAC::Tag(new Ogg::XiphComment);
if(readProperties)
d->properties = new Properties(streamInfoData(), streamLength(), propertiesStyle);
}
ByteVector FLAC::File::streamInfoData()
{
if (isValid())

View File

@ -22,6 +22,7 @@
#ifndef TAGLIB_FLACFILE_H
#define TAGLIB_FLACFILE_H
#include "taglib_export.h"
#include "tfile.h"
#include "flacproperties.h"
@ -56,9 +57,15 @@ namespace TagLib {
* information specific to FLAC files.
*/
class File : public TagLib::File
class TAGLIB_EXPORT File : public TagLib::File
{
public:
/*!
* Contructs a FLAC file object without reading a file. Allows object
* fields to be set up before reading.
*/
File(ID3v2::FrameFactory *frameFactory = NULL);
/*!
* Contructs a FLAC file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
@ -104,6 +111,14 @@ namespace TagLib {
*/
virtual Properties *audioProperties() const;
/*!
* Reads from FLAC file. If \a readProperties is true the file's audio
* properties will also be read using \a propertiesStyle. If false,
* \a propertiesStyle is ignored.
*/
void read(bool readProperties = true,
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Save the file. This will primarily save the XiphComment, but
* will also keep any old ID3-tags up to date. If the file
@ -181,7 +196,6 @@ namespace TagLib {
File(const File &);
File &operator=(const File &);
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
void scan();
long findID3v2();
long findID3v1();

View File

@ -0,0 +1,129 @@
#include <iostream>
#include "tstring.h"
#include "boxfactory.h"
#include "mp4skipbox.h"
#include "mp4moovbox.h"
#include "mp4mvhdbox.h"
#include "mp4trakbox.h"
#include "mp4mdiabox.h"
#include "mp4minfbox.h"
#include "mp4stblbox.h"
#include "mp4stsdbox.h"
#include "mp4hdlrbox.h"
#include "mp4udtabox.h"
#include "mp4metabox.h"
#include "mp4ilstbox.h"
#include "itunesnambox.h"
#include "itunesartbox.h"
#include "itunesalbbox.h"
#include "itunesgenbox.h"
#include "itunesdaybox.h"
#include "itunestrknbox.h"
#include "itunescmtbox.h"
#include "itunesgrpbox.h"
#include "ituneswrtbox.h"
#include "itunesdiskbox.h"
#include "itunestmpobox.h"
#include "itunescvrbox.h"
#include "itunesdatabox.h"
using namespace TagLib;
MP4::BoxFactory::BoxFactory()
{
}
MP4::BoxFactory::~BoxFactory()
{
}
//! factory function
MP4::Mp4IsoBox* MP4::BoxFactory::createInstance( TagLib::File* anyfile, MP4::Fourcc fourcc, uint size, long offset ) const
{
MP4::File * file = static_cast<MP4::File *>(anyfile);
if(!file)
return 0;
//std::cout << "creating box for: " << fourcc.toString() << std::endl;
switch( fourcc )
{
case 0x6d6f6f76: // 'moov'
return new MP4::Mp4MoovBox( file, fourcc, size, offset );
break;
case 0x6d766864: // 'mvhd'
return new MP4::Mp4MvhdBox( file, fourcc, size, offset );
break;
case 0x7472616b: // 'trak'
return new MP4::Mp4TrakBox( file, fourcc, size, offset );
break;
case 0x6d646961: // 'mdia'
return new MP4::Mp4MdiaBox( file, fourcc, size, offset );
break;
case 0x6d696e66: // 'minf'
return new MP4::Mp4MinfBox( file, fourcc, size, offset );
break;
case 0x7374626c: // 'stbl'
return new MP4::Mp4StblBox( file, fourcc, size, offset );
break;
case 0x73747364: // 'stsd'
return new MP4::Mp4StsdBox( file, fourcc, size, offset );
break;
case 0x68646c72: // 'hdlr'
return new MP4::Mp4HdlrBox( file, fourcc, size, offset );
break;
case 0x75647461: // 'udta'
return new MP4::Mp4UdtaBox( file, fourcc, size, offset );
break;
case 0x6d657461: // 'meta'
return new MP4::Mp4MetaBox( file, fourcc, size, offset );
break;
case 0x696c7374: // 'ilst'
return new MP4::Mp4IlstBox( file, fourcc, size, offset );
break;
case 0xa96e616d: // '_nam'
return new MP4::ITunesNamBox( file, fourcc, size, offset );
break;
case 0xa9415254: // '_ART'
return new MP4::ITunesArtBox( file, fourcc, size, offset );
break;
case 0xa9616c62: // '_alb'
return new MP4::ITunesAlbBox( file, fourcc, size, offset );
break;
case 0xa967656e: // '_gen'
return new MP4::ITunesGenBox( file, fourcc, size, offset );
break;
case 0x676e7265: // 'gnre'
return new MP4::ITunesGenBox( file, fourcc, size, offset );
break;
case 0xa9646179: // '_day'
return new MP4::ITunesDayBox( file, fourcc, size, offset );
break;
case 0x74726b6e: // 'trkn'
return new MP4::ITunesTrknBox( file, fourcc, size, offset );
break;
case 0xa9636d74: // '_cmt'
return new MP4::ITunesCmtBox( file, fourcc, size, offset );
break;
case 0xa9677270: // '_grp'
return new MP4::ITunesGrpBox( file, fourcc, size, offset );
break;
case 0xa9777274: // '_wrt'
return new MP4::ITunesWrtBox( file, fourcc, size, offset );
break;
case 0x6469736b: // 'disk'
return new MP4::ITunesDiskBox( file, fourcc, size, offset );
break;
case 0x746d706f: // 'tmpo'
return new MP4::ITunesTmpoBox( file, fourcc, size, offset );
break;
case 0x636f7672: // 'covr'
return new MP4::ITunesCvrBox( file, fourcc, size, offset );
break;
case 0x64616461: // 'data'
return new MP4::ITunesDataBox( file, fourcc, size, offset );
break;
default:
return new MP4::Mp4SkipBox( file, fourcc, size, offset );
}
}

View File

@ -0,0 +1,24 @@
#ifndef BOXFACTORY_H
#define BOXFACTORY_H
#include "taglib.h"
#include "mp4isobox.h"
namespace TagLib
{
namespace MP4
{
class BoxFactory
{
public:
BoxFactory();
~BoxFactory();
//! factory function
Mp4IsoBox* createInstance( TagLib::File* anyfile, MP4::Fourcc fourcc, uint size, long offset ) const;
}; // class BoxFactory
} // namepace MP4
} // namepace TagLib
#endif // BOXFACTORY_H

View File

@ -0,0 +1,68 @@
#include <iostream>
#include "itunesalbbox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesAlbBox::ITunesAlbBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesAlbBox::ITunesAlbBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesAlbBox::ITunesAlbBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesAlbBox::~ITunesAlbBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesAlbBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesAlbBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::album, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::String dataString( d->dataBox->data() );
std::cout << "Content of album box: " << dataString << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESALBBOX_H
#define ITUNESALBBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesAlbBox: public Mp4IsoBox
{
public:
ITunesAlbBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesAlbBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesAlbBoxPrivate;
ITunesAlbBoxPrivate* d;
}; // class ITunesAlbBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESALBBOX_H

View File

@ -0,0 +1,68 @@
#include <iostream>
#include "itunesartbox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesArtBox::ITunesArtBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesArtBox::ITunesArtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesArtBox::ITunesArtBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesArtBox::~ITunesArtBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesArtBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesArtBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::artist, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::String dataString( d->dataBox->data() );
std::cout << "Content of artist box: " << dataString << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESARTBOX_H
#define ITUNESARTBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesArtBox: public Mp4IsoBox
{
public:
ITunesArtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesArtBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesArtBoxPrivate;
ITunesArtBoxPrivate* d;
}; // class ITunesArtBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESARTBOX_H

View File

@ -0,0 +1,68 @@
#include <iostream>
#include "itunescmtbox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesCmtBox::ITunesCmtBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesCmtBox::ITunesCmtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesCmtBox::ITunesCmtBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesCmtBox::~ITunesCmtBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesCmtBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesCmtBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::comment, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::String dataString( d->dataBox->data() );
std::cout << "Content of title box: " << dataString << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESCMTBOX_H
#define ITUNESCMTBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesCmtBox: public Mp4IsoBox
{
public:
ITunesCmtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesCmtBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesCmtBoxPrivate;
ITunesCmtBoxPrivate* d;
}; // class ITunesCmtBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESCMTBOX_H

View File

@ -0,0 +1,68 @@
#include <iostream>
#include "itunescvrbox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesCvrBox::ITunesCvrBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesCvrBox::ITunesCvrBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesCvrBox::ITunesCvrBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesCvrBox::~ITunesCvrBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesCvrBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesCvrBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::cover, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::String dataString( d->dataBox->data() );
std::cout << "Content of album box: " << dataString << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESCVRBOX_H
#define ITUNESCVRBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesCvrBox: public Mp4IsoBox
{
public:
ITunesCvrBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesCvrBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesCvrBoxPrivate;
ITunesCvrBoxPrivate* d;
}; // class ITunesCvrBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESCVRBOX_H

View File

@ -0,0 +1,42 @@
#include <iostream>
#include "itunesdatabox.h"
#include "tbytevector.h"
#include "mp4isobox.h"
#include "tfile.h"
using namespace TagLib;
class MP4::ITunesDataBox::ITunesDataBoxPrivate
{
public:
ByteVector data;
};
MP4::ITunesDataBox::ITunesDataBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoFullBox(file, fourcc, size, offset)
{
d = new MP4::ITunesDataBox::ITunesDataBoxPrivate();
}
MP4::ITunesDataBox::~ITunesDataBox()
{
delete d;
}
ByteVector MP4::ITunesDataBox::data() const
{
return d->data;
}
//! parse the content of the box
void MP4::ITunesDataBox::parse()
{
// skip first 4 byte - don't know what they are supposed to be for - simply 4 zeros
file()->seek( 4, TagLib::File::Current );
// read contents - remaining size is box_size-12-4 (12:fullbox header, 4:starting zeros of data box)
#if 0
std::cout << " reading data box with data length: " << size()-16 << std::endl;
#endif
d->data = file()->readBlock( size()-12-4 );
}

View File

@ -0,0 +1,32 @@
#ifndef ITUNESDATABOX_H
#define ITUNESDATABOX_H
#include "mp4isofullbox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesDataBox: public Mp4IsoFullBox
{
public:
ITunesDataBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesDataBox();
//! get the internal data, which can be txt or binary data as well
ByteVector data() const;
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesDataBoxPrivate;
ITunesDataBoxPrivate* d;
}; // class ITunesDataBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESDATABOX_H

View File

@ -0,0 +1,68 @@
#include <iostream>
#include "itunesdaybox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesDayBox::ITunesDayBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesDayBox::ITunesDayBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesDayBox::ITunesDayBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesDayBox::~ITunesDayBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesDayBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesDayBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::year, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::String dataString( d->dataBox->data() );
std::cout << "Content of day box: " << dataString.substr(0,4) << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESDAYBOX_H
#define ITUNESDAYBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesDayBox: public Mp4IsoBox
{
public:
ITunesDayBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesDayBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesDayBoxPrivate;
ITunesDayBoxPrivate* d;
}; // class ITunesDayBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESDAYBOX_H

View File

@ -0,0 +1,72 @@
#include <iostream>
#include "itunesdiskbox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesDiskBox::ITunesDiskBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesDiskBox::ITunesDiskBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesDiskBox::ITunesDiskBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesDiskBox::~ITunesDiskBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesDiskBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesDiskBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::disk, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::ByteVector trknData = d->dataBox->data();
TagLib::String trknumber = TagLib::String::number( static_cast<int>( static_cast<unsigned char>(trknData[0]) << 24 |
static_cast<unsigned char>(trknData[1]) << 16 |
static_cast<unsigned char>(trknData[2]) << 8 |
static_cast<unsigned char>(trknData[3]) ) );
std::cout << "Content of tracknumber box: " << trknumber << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESDISKBOX_H
#define ITUNESDISKBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesDiskBox: public Mp4IsoBox
{
public:
ITunesDiskBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesDiskBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesDiskBoxPrivate;
ITunesDiskBoxPrivate* d;
}; // class ITunesDiskBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESDISKBOX_H

View File

@ -0,0 +1,68 @@
#include <iostream>
#include "itunesgenbox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesGenBox::ITunesGenBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesGenBox::ITunesGenBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesGenBox::ITunesGenBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesGenBox::~ITunesGenBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesGenBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesGenBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::genre, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::String dataString( d->dataBox->data() );
std::cout << "Content of genre box: " << dataString << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESGENBOX_H
#define ITUNESGENBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesGenBox: public Mp4IsoBox
{
public:
ITunesGenBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesGenBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesGenBoxPrivate;
ITunesGenBoxPrivate* d;
}; // class ITunesGenBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESGENBOX_H

View File

@ -0,0 +1,68 @@
#include <iostream>
#include "itunesgrpbox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesGrpBox::ITunesGrpBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesGrpBox::ITunesGrpBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesGrpBox::ITunesGrpBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesGrpBox::~ITunesGrpBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesGrpBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesGrpBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::grouping, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::String dataString( d->dataBox->data() );
std::cout << "Content of title box: " << dataString << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESGRPBOX_H
#define ITUNESGRPBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesGrpBox: public Mp4IsoBox
{
public:
ITunesGrpBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesGrpBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesGrpBoxPrivate;
ITunesGrpBoxPrivate* d;
}; // class ITunesGrpBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESGRPBOX_H

View File

@ -0,0 +1,68 @@
#include <iostream>
#include "itunesnambox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesNamBox::ITunesNamBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesNamBox::ITunesNamBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesNamBox::ITunesNamBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesNamBox::~ITunesNamBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesNamBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesNamBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::title, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::String dataString( d->dataBox->data() );
std::cout << "Content of title box: " << dataString << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESNAMBOX_H
#define ITUNESNAMBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesNamBox: public Mp4IsoBox
{
public:
ITunesNamBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesNamBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesNamBoxPrivate;
ITunesNamBoxPrivate* d;
}; // class ITunesNamBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESNAMBOX_H

View File

@ -0,0 +1,72 @@
#include <iostream>
#include "itunestmpobox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesTmpoBox::ITunesTmpoBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesTmpoBox::ITunesTmpoBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesTmpoBox::ITunesTmpoBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesTmpoBox::~ITunesTmpoBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesTmpoBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesTmpoBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::bpm, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::ByteVector trknData = d->dataBox->data();
TagLib::String trknumber = TagLib::String::number( static_cast<int>( static_cast<unsigned char>(trknData[0]) << 24 |
static_cast<unsigned char>(trknData[1]) << 16 |
static_cast<unsigned char>(trknData[2]) << 8 |
static_cast<unsigned char>(trknData[3]) ) );
std::cout << "Content of tracknumber box: " << trknumber << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESTMPOBOX_H
#define ITUNESTMPOBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesTmpoBox: public Mp4IsoBox
{
public:
ITunesTmpoBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesTmpoBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesTmpoBoxPrivate;
ITunesTmpoBoxPrivate* d;
}; // class ITunesTmpoBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESTMPOBOX_H

View File

@ -0,0 +1,72 @@
#include <iostream>
#include "itunestrknbox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesTrknBox::ITunesTrknBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesTrknBox::ITunesTrknBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesTrknBox::ITunesTrknBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesTrknBox::~ITunesTrknBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesTrknBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesTrknBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::trackno, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::ByteVector trknData = d->dataBox->data();
TagLib::String trknumber = TagLib::String::number( static_cast<int>( static_cast<unsigned char>(trknData[0]) << 24 |
static_cast<unsigned char>(trknData[1]) << 16 |
static_cast<unsigned char>(trknData[2]) << 8 |
static_cast<unsigned char>(trknData[3]) ) );
std::cout << "Content of tracknumber box: " << trknumber << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESTRKNBOX_H
#define ITUNESTRKNBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesTrknBox: public Mp4IsoBox
{
public:
ITunesTrknBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesTrknBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesTrknBoxPrivate;
ITunesTrknBoxPrivate* d;
}; // class ITunesTrknBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESTRKNBOX_H

View File

@ -0,0 +1,68 @@
#include <iostream>
#include "ituneswrtbox.h"
#include "itunesdatabox.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "tfile.h"
#include "mp4tagsproxy.h"
using namespace TagLib;
class MP4::ITunesWrtBox::ITunesWrtBoxPrivate
{
public:
ITunesDataBox* dataBox;
};
MP4::ITunesWrtBox::ITunesWrtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::ITunesWrtBox::ITunesWrtBoxPrivate();
d->dataBox = 0;
}
MP4::ITunesWrtBox::~ITunesWrtBox()
{
if( d->dataBox != 0 )
delete d->dataBox;
delete d;
}
//! parse the content of the box
void MP4::ITunesWrtBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
// parse data box
TagLib::uint size;
MP4::Fourcc fourcc;
if(mp4file->readSizeAndType( size, fourcc ) == true)
{
// check for type - must be 'data'
if( fourcc != MP4::Fourcc("data") )
{
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
// jump over data tag
mp4file->seek( size-8, TagLib::File::Current );
return;
}
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
d->dataBox->parsebox();
}
else
{
// reading unsuccessful - serious error!
std::cerr << "Error in parsing ITunesWrtBox - serious Error in taglib!" << std::endl;
return;
}
// register data box
mp4file->tagProxy()->registerBox( Mp4TagsProxy::composer, d->dataBox );
#if 0
// get data pointer - just for debuging...
TagLib::String dataString( d->dataBox->data() );
std::cout << "Content of title box: " << dataString << std::endl;
#endif
}

View File

@ -0,0 +1,29 @@
#ifndef ITUNESWRTBOX_H
#define ITUNESWRTBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class ITunesWrtBox: public Mp4IsoBox
{
public:
ITunesWrtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
~ITunesWrtBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class ITunesWrtBoxPrivate;
ITunesWrtBoxPrivate* d;
}; // class ITunesWrtBox
} // namespace MP4
} // namespace TagLib
#endif // ITUNESWRTBOX_H

View File

@ -0,0 +1,54 @@
#include "mp4audioproperties.h"
#include "mp4propsproxy.h"
using namespace TagLib;
class MP4::AudioProperties::AudioPropertiesPrivate
{
public:
MP4::Mp4PropsProxy* propsproxy;
}; // AudioPropertiesPrivate
MP4::AudioProperties::AudioProperties():TagLib::AudioProperties(TagLib::AudioProperties::Average)
{
d = new MP4::AudioProperties::AudioPropertiesPrivate();
}
MP4::AudioProperties::~AudioProperties()
{
delete d;
}
void MP4::AudioProperties::setProxy( Mp4PropsProxy* proxy )
{
d->propsproxy = proxy;
}
int MP4::AudioProperties::length() const
{
if( d->propsproxy == 0 )
return 0;
return d->propsproxy->seconds();
}
int MP4::AudioProperties::bitrate() const
{
if( d->propsproxy == 0 )
return 0;
return d->propsproxy->bitRate()/1000;
}
int MP4::AudioProperties::sampleRate() const
{
if( d->propsproxy == 0 )
return 0;
return d->propsproxy->sampleRate();
}
int MP4::AudioProperties::channels() const
{
if( d->propsproxy == 0 )
return 0;
return d->propsproxy->channels();
}

View File

@ -0,0 +1,52 @@
#ifndef MP4AUDIOPROPERTIES_H
#define MP4AUDIOPROPERTIES_H MP4AUDIOPROPERTIES_H
#include "audioproperties.h"
namespace TagLib
{
namespace MP4
{
class Mp4PropsProxy;
class AudioProperties : public TagLib::AudioProperties
{
public:
//! constructor
AudioProperties();
//! destructor
~AudioProperties();
//! function to set the proxy
void setProxy( Mp4PropsProxy* proxy );
/*!
* Returns the lenght of the file in seconds.
*/
int length() const;
/*!
* Returns the most appropriate bit rate for the file in kb/s. For constant
* bitrate formats this is simply the bitrate of the file. For variable
* bitrate formats this is either the average or nominal bitrate.
*/
int bitrate() const;
/*!
* Returns the sample rate in Hz.
*/
int sampleRate() const;
/*!
* Returns the number of audio channels.
*/
int channels() const;
private:
class AudioPropertiesPrivate;
AudioPropertiesPrivate* d;
};
} // namespace MP4
} // namespace TagLib
#endif // MP4AUDIOPROPERTIES_H

View File

@ -0,0 +1,124 @@
#include <iostream>
#include "mp4audiosampleentry.h"
#include "mp4isobox.h"
#include "mp4file.h"
#include "mp4propsproxy.h"
using namespace TagLib;
class MP4::Mp4AudioSampleEntry::Mp4AudioSampleEntryPrivate
{
public:
TagLib::uint channelcount;
TagLib::uint samplerate;
TagLib::uint bitrate;
};
MP4::Mp4AudioSampleEntry::Mp4AudioSampleEntry( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4SampleEntry(file, fourcc, size, offset)
{
d = new MP4::Mp4AudioSampleEntry::Mp4AudioSampleEntryPrivate();
}
MP4::Mp4AudioSampleEntry::~Mp4AudioSampleEntry()
{
delete d;
}
TagLib::uint MP4::Mp4AudioSampleEntry::channels() const
{
return d->channelcount;
}
TagLib::uint MP4::Mp4AudioSampleEntry::samplerate() const
{
return d->samplerate;
}
TagLib::uint MP4::Mp4AudioSampleEntry::bitrate() const
{
return d->bitrate;
}
void MP4::Mp4AudioSampleEntry::parseEntry()
{
TagLib::MP4::File* mp4file = static_cast<TagLib::MP4::File*>(file());
if(!mp4file)
return;
// read 8 reserved bytes
mp4file->seek( 8, TagLib::File::Current );
// read channelcount
if(!mp4file->readShort( d->channelcount ))
return;
// seek over samplesize, pre_defined and reserved
mp4file->seek( 6, TagLib::File::Current );
// read samplerate
if(!mp4file->readInt( d->samplerate ))
return;
// register box at proxy
mp4file->propProxy()->registerAudioSampleEntry( this );
//std::cout << "fourcc of audio sample entry: " << fourcc().toString() << std::endl;
// check for both mp4a (plain files) and drms (encrypted files)
if( (fourcc() == MP4::Fourcc("mp4a")) ||
(fourcc() == MP4::Fourcc("drms")) )
{
TagLib::MP4::Fourcc fourcc;
TagLib::uint esds_size;
mp4file->readSizeAndType( esds_size, fourcc );
// read esds' main parts
if( size()-48 > 0 )
ByteVector flags_version = mp4file->readBlock(4);
else
return;
ByteVector EsDescrTag = mp4file->readBlock(1);
// first 4 bytes contain full box specifics (version & flags)
// upcoming byte must be ESDescrTag (0x03)
if( EsDescrTag[0] == 0x03 )
{
TagLib::uint descr_len = mp4file->readSystemsLen();
TagLib::uint EsId;
if( !mp4file->readShort( EsId ) )
return;
ByteVector priority = mp4file->readBlock(1);
if( descr_len < 20 )
return;
}
else
{
TagLib::uint EsId;
if( !mp4file->readShort( EsId ) )
return;
}
// read decoder configuration tag (0x04)
ByteVector DecCfgTag = mp4file->readBlock(1);
if( DecCfgTag[0] != 0x04 )
return;
// read decoder configuration length
TagLib::uint deccfg_len = mp4file->readSystemsLen();
// read object type Id
ByteVector objId = mp4file->readBlock(1);
// read stream type id
ByteVector strId = mp4file->readBlock(1);
// read buffer Size DB
ByteVector bufferSizeDB = mp4file->readBlock(3);
// read max bitrate
TagLib::uint max_bitrate;
if( !mp4file->readInt( max_bitrate ) )
return;
// read average bitrate
if( !mp4file->readInt( d->bitrate ) )
return;
// skip the rest
mp4file->seek( offset()+size()-8, File::Beginning );
}
else
mp4file->seek( size()-36, File::Current );
}

View File

@ -0,0 +1,36 @@
#ifndef MP4AUDIOSAMPLEENTRY_H
#define MP4AUDIOSAMPLEENTRY_H
#include "mp4sampleentry.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4AudioSampleEntry: public Mp4SampleEntry
{
public:
Mp4AudioSampleEntry( File* file, MP4::Fourcc fourcc, uint size, long offset );
~Mp4AudioSampleEntry();
//! function to get the number of channels
TagLib::uint channels() const;
//! function to get the sample rate
TagLib::uint samplerate() const;
//! function to get the average bitrate of the audio stream
TagLib::uint bitrate() const;
private:
//! parse the content of the box
void parseEntry();
protected:
class Mp4AudioSampleEntryPrivate;
Mp4AudioSampleEntryPrivate* d;
}; // class Mp4AudioSampleEntry
} // namespace MP4
} // namespace TagLib
#endif // MP4AUDIOSAMPLEENTRY_H

View File

@ -0,0 +1,390 @@
#include <tbytevector.h>
#include <tstring.h>
#include <tdebug.h>
#include "tlist.h"
#include "id3v1genres.h"
#include "mp4itunestag.h"
#include "mp4file.h"
#include "boxfactory.h"
#include "mp4tagsproxy.h"
#include "mp4propsproxy.h"
#include "mp4audioproperties.h"
#include "itunesdatabox.h"
using namespace TagLib;
class MP4::File::FilePrivate
{
public:
//! list for all boxes of the mp4 file
TagLib::List<MP4::Mp4IsoBox*> boxes;
//! the box factory - will create all boxes by tag and size
MP4::BoxFactory boxfactory;
//! proxy for the tags is filled after parsing
MP4::Mp4TagsProxy tagsProxy;
//! proxy for audio properties
MP4::Mp4PropsProxy propsProxy;
//! the tag returned by tag() function
MP4::Tag mp4tag;
//! container for the audio properties returned by properties() function
MP4::AudioProperties mp4audioproperties;
//! is set to valid after successfull parsing
bool isValid;
};
//! function to fill the tags with converted proxy data, which has been parsed out of the file previously
static void fillTagFromProxy( MP4::Mp4TagsProxy& proxy, MP4::Tag& mp4tag );
MP4::File::File() : TagLib::File()
{
// create member container
d = new MP4::File::FilePrivate();
d->isValid = false;
}
MP4::File::File(const char *file, bool , AudioProperties::ReadStyle )
:TagLib::File( file )
{
// create member container
d = new MP4::File::FilePrivate();
read();
}
MP4::File::~File()
{
TagLib::List<Mp4IsoBox*>::Iterator delIter;
for( delIter = d->boxes.begin();
delIter != d->boxes.end();
delIter++ )
{
delete *delIter;
}
delete d;
}
Tag *MP4::File::tag() const
{
return &d->mp4tag;
}
AudioProperties * MP4::File::audioProperties() const
{
d->mp4audioproperties.setProxy( &d->propsProxy );
return &d->mp4audioproperties;
}
void MP4::File::read( bool, TagLib::AudioProperties::ReadStyle )
{
d->isValid = false;
TagLib::uint size;
MP4::Fourcc fourcc;
while( readSizeAndType( size, fourcc ) == true )
{
// create the appropriate subclass and parse it
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( this, fourcc, size, tell() );
curbox->parsebox();
d->boxes.append( curbox );
}
for( TagLib::List<MP4::Mp4IsoBox*>::Iterator iter = d->boxes.begin();
iter != d->boxes.end();
iter++ )
{
if( (*iter)->fourcc() == MP4::Fourcc("moov") )
{
d->isValid = true;
break;
}
}
if( d->isValid )
debug( "file is valid" );
else
debug( "file is NOT valid" );
// fill tags from proxy data
fillTagFromProxy( d->tagsProxy, d->mp4tag );
}
bool MP4::File::save()
{
return false;
}
void MP4::File::remove()
{
}
TagLib::uint MP4::File::readSystemsLen()
{
TagLib::uint length = 0;
TagLib::uint nbytes = 0;
ByteVector input;
TagLib::uchar tmp_input;
do
{
input = readBlock(1);
tmp_input = static_cast<TagLib::uchar>(input[0]);
nbytes++;
length = (length<<7) | (tmp_input&0x7F);
} while( (tmp_input&0x80) && (nbytes<4) );
return length;
}
bool MP4::File::readSizeAndType( TagLib::uint& size, MP4::Fourcc& fourcc )
{
// read the two blocks from file
ByteVector readsize = readBlock(4);
ByteVector readtype = readBlock(4);
if( (readsize.size() != 4) || (readtype.size() != 4) )
return false;
// set size
size = static_cast<unsigned char>(readsize[0]) << 24 |
static_cast<unsigned char>(readsize[1]) << 16 |
static_cast<unsigned char>(readsize[2]) << 8 |
static_cast<unsigned char>(readsize[3]);
if (size == 0)
return false;
// set fourcc
fourcc = readtype.data();
return true;
}
bool MP4::File::readInt( TagLib::uint& toRead )
{
ByteVector readbuffer = readBlock(4);
if( readbuffer.size() != 4 )
return false;
toRead = static_cast<unsigned char>(readbuffer[0]) << 24 |
static_cast<unsigned char>(readbuffer[1]) << 16 |
static_cast<unsigned char>(readbuffer[2]) << 8 |
static_cast<unsigned char>(readbuffer[3]);
return true;
}
bool MP4::File::readShort( TagLib::uint& toRead )
{
ByteVector readbuffer = readBlock(2);
if( readbuffer.size() != 2 )
return false;
toRead = static_cast<unsigned char>(readbuffer[0]) << 8 |
static_cast<unsigned char>(readbuffer[1]);
return true;
}
bool MP4::File::readLongLong( TagLib::ulonglong& toRead )
{
ByteVector readbuffer = readBlock(8);
if( readbuffer.size() != 8 )
return false;
toRead = static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[0])) << 56 |
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[1])) << 48 |
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[2])) << 40 |
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[3])) << 32 |
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[4])) << 24 |
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[5])) << 16 |
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[6])) << 8 |
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[7]));
return true;
}
bool MP4::File::readFourcc( TagLib::MP4::Fourcc& fourcc )
{
ByteVector readtype = readBlock(4);
if( readtype.size() != 4)
return false;
// set fourcc
fourcc = readtype.data();
return true;
}
MP4::Mp4TagsProxy* MP4::File::tagProxy() const
{
return &d->tagsProxy;
}
MP4::Mp4PropsProxy* MP4::File::propProxy() const
{
return &d->propsProxy;
}
/* This function has been updated based on information at */
/* "http://atomicparsley.sourceforge.net/mpeg-4files.html". */
void fillTagFromProxy( MP4::Mp4TagsProxy& proxy, MP4::Tag& mp4tag )
{
// tmp buffer for each tag
MP4::ITunesDataBox* databox;
databox = proxy.titleData();
if( databox != 0 )
{
// convert data to string
TagLib::String datastring( databox->data(), String::UTF8 );
// check if string was set
if( !(datastring == "") )
mp4tag.setTitle( datastring );
}
databox = proxy.artistData();
if( databox != 0 )
{
// convert data to string
TagLib::String datastring( databox->data(), String::UTF8 );
// check if string was set
if( !(datastring == "") )
mp4tag.setArtist( datastring );
}
databox = proxy.albumData();
if( databox != 0 )
{
// convert data to string
TagLib::String datastring( databox->data(), String::UTF8 );
// check if string was set
if( !(datastring == "") )
mp4tag.setAlbum( datastring );
}
databox = proxy.genreData();
if( databox != 0 )
{
if (databox->flags() == 0)
{
// convert data to uint
TagLib::ByteVector datavec = databox->data();
int genreVal = static_cast<int>( datavec[1] );
if (genreVal > 0)
{
TagLib::String datastring = ID3v1::genre( genreVal - 1 );
// check if string was set
if( !(datastring == "") )
mp4tag.setGenre( datastring );
}
}
else
{
// convert data to string
TagLib::String datastring( databox->data(), String::UTF8 );
// check if string was set
if( !(datastring == "") )
mp4tag.setGenre( datastring );
}
}
databox = proxy.yearData();
if( databox != 0 )
{
// convert data to string
TagLib::String datastring( databox->data(), String::UTF8 );
// check if string was set
if( !(datastring == "") )
mp4tag.setYear( datastring.toInt() );
}
databox = proxy.trknData();
if( databox != 0 )
{
// convert data to uint
TagLib::ByteVector datavec = databox->data();
if( datavec.size() >= 6 )
{
TagLib::uint notracks = static_cast<TagLib::uint>( datavec[5] );
mp4tag.setNumTracks( notracks );
}
if( datavec.size() >= 4 )
{
TagLib::uint trackno = static_cast<TagLib::uint>( datavec[3] );
mp4tag.setTrack( trackno );
}
else
mp4tag.setTrack( 0 );
}
databox = proxy.commentData();
if( databox != 0 )
{
// convert data to string
TagLib::String datastring( databox->data(), String::UTF8 );
// check if string was set
if( !(datastring == "") )
mp4tag.setComment( datastring );
}
databox = proxy.groupingData();
if( databox != 0 )
{
// convert data to string
TagLib::String datastring( databox->data(), String::UTF8 );
// check if string was set
if( !(datastring == "") )
mp4tag.setGrouping( datastring );
}
databox = proxy.composerData();
if( databox != 0 )
{
// convert data to string
TagLib::String datastring( databox->data(), String::UTF8 );
// check if string was set
if( !(datastring == "") )
mp4tag.setComposer( datastring );
}
databox = proxy.diskData();
if( databox != 0 )
{
// convert data to uint
TagLib::ByteVector datavec = databox->data();
if( datavec.size() >= 6 )
{
TagLib::uint nodiscs = static_cast<TagLib::uint>( datavec[5] );
mp4tag.setNumDisks( nodiscs );
}
if( datavec.size() >= 4 )
{
TagLib::uint discno = static_cast<TagLib::uint>( datavec[3] );
mp4tag.setDisk( discno );
}
else
mp4tag.setDisk( 0 );
}
databox = proxy.bpmData();
if( databox != 0 )
{
// convert data to uint
TagLib::ByteVector datavec = databox->data();
if( datavec.size() >= 2 )
{
TagLib::uint bpm = static_cast<TagLib::uint>( static_cast<unsigned char>(datavec[0]) << 8 |
static_cast<unsigned char>(datavec[1]) );
mp4tag.setBpm( bpm );
}
else
mp4tag.setBpm( 0 );
}
databox = proxy.coverData();
if( databox != 0 )
{
// get byte vector
mp4tag.setCover( databox->data() );
}
}

View File

@ -0,0 +1,162 @@
/***************************************************************************
copyright : (C) 2002, 2003 by Jochen Issing
email : jochen.issing@isign-softart.de
***************************************************************************/
/***************************************************************************
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
***************************************************************************/
#ifndef TAGLIB_MP4FILE_H
#define TAGLIB_MP4FILE_H
#include <tfile.h>
#include <audioproperties.h>
#include "mp4fourcc.h"
namespace TagLib {
typedef unsigned long long ulonglong;
class Tag;
namespace MP4
{
class Mp4TagsProxy;
class Mp4PropsProxy;
//! An implementation of TagLib::File with mp4 itunes specific methods
/*!
* This implements and provides an interface for mp4 itunes 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 mp4 itunes files. (TODO)
*/
class File : public TagLib::File
{
public:
/*!
* Contructs an mp4 itunes file object without reading a file. Allows object
* fields to be set up before reading.
*/
File();
/*!
* Contructs an mp4 itunes file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \a propertiesStyle is ignored.
*/
File(const char *file, bool readProperties = true,
TagLib::AudioProperties::ReadStyle propertiesStyle = TagLib::AudioProperties::Average);
/*!
* Destroys this instance of the File.
*/
virtual ~File();
/*!
* Returns the Tag for this file. This will be an APE tag, an ID3v1 tag
* or a combination of the two.
*/
virtual TagLib::Tag *tag() const;
/*!
* Returns the mp4 itunes::Properties for this file. If no audio properties
* were read then this will return a null pointer.
*/
virtual AudioProperties *audioProperties() const;
/*!
* Reads from mp4 itunes file. If \a readProperties is true the file's
* audio properties will also be read using \a propertiesStyle. If false,
* \a propertiesStyle is ignored.
*/
void read(bool readProperties = true,
TagLib::AudioProperties::ReadStyle propertiesStyle = TagLib::AudioProperties::Average);
/*!
* Saves the file.
*/
virtual bool save();
/*!
* This will remove all tags.
*
* \note This will also invalidate pointers to the tags
* as their memory will be freed.
* \note In order to make the removal permanent save() still needs to be called
*/
void remove();
/*!
* Helper function for parsing the MP4 file - reads the size and type of the next box.
* Returns true if read succeeded - not at EOF
*/
bool readSizeAndType( TagLib::uint& size, MP4::Fourcc& fourcc );
/*!
* Helper function to read the length of an descriptor in systems manner
*/
TagLib::uint readSystemsLen();
/*!
* Helper function for reading an unsigned int out of the file (big endian method)
*/
bool readInt( TagLib::uint& toRead );
/*!
* Helper function for reading an unsigned short out of the file (big endian method)
*/
bool readShort( TagLib::uint& toRead );
/*!
* Helper function for reading an unsigned long long (64bit) out of the file (big endian method)
*/
bool readLongLong( TagLib::ulonglong& toRead );
/*!
* Helper function to read a fourcc code
*/
bool readFourcc( TagLib::MP4::Fourcc& fourcc );
/*!
* Function to get the tags proxy for registration of the tags boxes.
* The proxy provides direct access to the data boxes of the certain tags - normally
* covered by several levels of subboxes
*/
Mp4TagsProxy* tagProxy() const;
/*!
* Function to get the properties proxy for registration of the properties boxes.
* The proxy provides direct access to the needed boxes describing audio properties.
*/
Mp4PropsProxy* propProxy() const;
private:
File(const File &);
File &operator=(const File &);
class FilePrivate;
FilePrivate *d;
};
} // namespace MP4
} // namespace TagLib
#endif // TAGLIB_MP4FILE_H

View File

@ -0,0 +1,63 @@
#include "mp4fourcc.h"
using namespace TagLib;
MP4::Fourcc::Fourcc()
{
m_fourcc = 0U;
}
MP4::Fourcc::Fourcc( TagLib::String fourcc )
{
m_fourcc = 0U;
if( fourcc.size() >= 4 )
m_fourcc = static_cast<unsigned char>(fourcc[0]) << 24 |
static_cast<unsigned char>(fourcc[1]) << 16 |
static_cast<unsigned char>(fourcc[2]) << 8 |
static_cast<unsigned char>(fourcc[3]);
}
MP4::Fourcc::~Fourcc()
{}
TagLib::String MP4::Fourcc::toString() const
{
TagLib::String fourcc;
fourcc.append(static_cast<char>(m_fourcc >> 24 & 0xFF));
fourcc.append(static_cast<char>(m_fourcc >> 16 & 0xFF));
fourcc.append(static_cast<char>(m_fourcc >> 8 & 0xFF));
fourcc.append(static_cast<char>(m_fourcc & 0xFF));
return fourcc;
}
MP4::Fourcc::operator unsigned int() const
{
return m_fourcc;
}
bool MP4::Fourcc::operator == (unsigned int fourccB ) const
{
return (m_fourcc==fourccB);
}
bool MP4::Fourcc::operator != (unsigned int fourccB ) const
{
return (m_fourcc!=fourccB);
}
MP4::Fourcc& MP4::Fourcc::operator = (unsigned int fourcc )
{
m_fourcc = fourcc;
return *this;
}
MP4::Fourcc& MP4::Fourcc::operator = (char fourcc[4])
{
m_fourcc = static_cast<unsigned char>(fourcc[0]) << 24 |
static_cast<unsigned char>(fourcc[1]) << 16 |
static_cast<unsigned char>(fourcc[2]) << 8 |
static_cast<unsigned char>(fourcc[3]);
return *this;
}

View File

@ -0,0 +1,42 @@
#ifndef MP4FOURCC_H
#define MP4FOURCC_H
#include "tstring.h"
namespace TagLib
{
namespace MP4
{
/*! union for easy fourcc / type handling */
class Fourcc
{
public:
//! std constructor
Fourcc();
//! string constructor
Fourcc(TagLib::String fourcc);
//! destructor
~Fourcc();
//! function to get a string version of the fourcc
TagLib::String toString() const;
//! cast operator to unsigned int
operator unsigned int() const;
//! comparison operator
bool operator == (unsigned int fourccB ) const;
//! comparison operator
bool operator != (unsigned int fourccB ) const;
//! assigment operator for unsigned int
Fourcc& operator = (unsigned int fourcc );
//! assigment operator for character string
Fourcc& operator = (char fourcc[4]);
private:
uint m_fourcc; /*!< integer code of the fourcc */
};
} // namespace MP4
} // namespace TagLib
#endif // MP4FOURCC_H

View File

@ -0,0 +1,54 @@
#include <deque>
#include <iostream>
#include "mp4hdlrbox.h"
#include "boxfactory.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4HdlrBox::Mp4HdlrBoxPrivate
{
public:
TagLib::uint pre_defined;
MP4::Fourcc handler_type;
TagLib::String hdlr_string;
}; // class Mp4HdlrBoxPrivate
MP4::Mp4HdlrBox::Mp4HdlrBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoFullBox( file, fourcc, size, offset )
{
d = new MP4::Mp4HdlrBox::Mp4HdlrBoxPrivate();
}
MP4::Mp4HdlrBox::~Mp4HdlrBox()
{
delete d;
}
MP4::Fourcc MP4::Mp4HdlrBox::hdlr_type() const
{
return d->handler_type;
}
TagLib::String MP4::Mp4HdlrBox::hdlr_string() const
{
return d->hdlr_string;
}
void MP4::Mp4HdlrBox::parse()
{
TagLib::uint totalread = 12+20;
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
if( mp4file->readInt( d->pre_defined ) == false )
return;
if( mp4file->readFourcc( d->handler_type ) == false )
return;
// read reserved into trash
mp4file->seek( 3*4, TagLib::File::Current );
// check if there are bytes remaining - used for hdlr string
if( size() - totalread != 0 )
d->hdlr_string = mp4file->readBlock( size()-totalread );
}

View File

@ -0,0 +1,32 @@
#ifndef MP4HDLRBOX_H
#define MP4HDLRBOX_H
#include "mp4isofullbox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4HdlrBox: public Mp4IsoFullBox
{
public:
Mp4HdlrBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4HdlrBox();
//! parse hdlr contents
void parse();
//! get the handler type
MP4::Fourcc hdlr_type() const;
//! get the hdlr string
TagLib::String hdlr_string() const;
private:
class Mp4HdlrBoxPrivate;
Mp4HdlrBoxPrivate* d;
}; // Mp4HdlrBox
} // namespace MP4
} // namespace TagLib
#endif // MP4HDLRBOX_H

View File

@ -0,0 +1,76 @@
#include "tlist.h"
#include <iostream>
#include "mp4ilstbox.h"
#include "boxfactory.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4IlstBox::Mp4IlstBoxPrivate
{
public:
//! container for all boxes in ilst box
TagLib::List<Mp4IsoBox*> ilstBoxes;
//! a box factory for creating the appropriate boxes
MP4::BoxFactory boxfactory;
}; // class Mp4IlstBoxPrivate
MP4::Mp4IlstBox::Mp4IlstBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoBox( file, fourcc, size, offset )
{
d = new MP4::Mp4IlstBox::Mp4IlstBoxPrivate();
}
MP4::Mp4IlstBox::~Mp4IlstBox()
{
TagLib::List<Mp4IsoBox*>::Iterator delIter;
for( delIter = d->ilstBoxes.begin();
delIter != d->ilstBoxes.end();
delIter++ )
{
delete *delIter;
}
delete d;
}
void MP4::Mp4IlstBox::parse()
{
#if 0
std::cout << " parsing ilst box" << std::endl;
#endif
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
TagLib::uint totalsize = 8;
// parse all contained boxes
TagLib::uint size;
MP4::Fourcc fourcc;
#if 0
std::cout << " ";
#endif
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
{
totalsize += size;
// check for errors
if( totalsize > MP4::Mp4IsoBox::size() )
{
std::cerr << "Error in mp4 file " << mp4file->name() << " ilst box contains bad box with name: " << fourcc.toString() << std::endl;
return;
}
// create the appropriate subclass and parse it
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
curbox->parsebox();
d->ilstBoxes.append( curbox );
// check for end of ilst box
if( totalsize == MP4::Mp4IsoBox::size() )
break;
#if 0
std::cout << " ";
#endif
}
}

View File

@ -0,0 +1,28 @@
#ifndef MP4ILSTBOX_H
#define MP4ILSTBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4IlstBox: public Mp4IsoBox
{
public:
Mp4IlstBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4IlstBox();
//! parse ilst contents
void parse();
private:
class Mp4IlstBoxPrivate;
Mp4IlstBoxPrivate* d;
}; // Mp4IlstBox
} // namespace MP4
} // namespace TagLib
#endif // MP4ILSTBOX_H

View File

@ -0,0 +1,55 @@
#include "mp4isobox.h"
#include "tfile.h"
using namespace TagLib;
class MP4::Mp4IsoBox::Mp4IsoBoxPrivate
{
public:
MP4::Fourcc fourcc;
TagLib::uint size;
long offset;
TagLib::File* file;
};
MP4::Mp4IsoBox::Mp4IsoBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
{
d = new MP4::Mp4IsoBox::Mp4IsoBoxPrivate();
d->file = file;
d->fourcc = fourcc;
d->size = size;
d->offset = offset;
}
MP4::Mp4IsoBox::~Mp4IsoBox()
{
delete d;
}
void MP4::Mp4IsoBox::parsebox()
{
// seek to offset
file()->seek( offset(), File::Beginning );
// simply call parse method of sub class
parse();
}
MP4::Fourcc MP4::Mp4IsoBox::fourcc() const
{
return d->fourcc;
}
TagLib::uint MP4::Mp4IsoBox::size() const
{
return d->size;
}
long MP4::Mp4IsoBox::offset() const
{
return d->offset;
}
TagLib::File* MP4::Mp4IsoBox::file() const
{
return d->file;
}

View File

@ -0,0 +1,46 @@
#ifndef MP4ISOBOX_H
#define MP4ISOBOX_H
#include "taglib.h"
#include "mp4fourcc.h"
namespace TagLib
{
class File;
namespace MP4
{
class Mp4IsoBox
{
public:
//! constructor for base class
Mp4IsoBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
//! destructor - simply freeing private ptr
virtual ~Mp4IsoBox();
//! function to get the fourcc code
MP4::Fourcc fourcc() const;
//! function to get the size of tha atom/box
uint size() const;
//! function to get the offset of the atom in the mp4 file
long offset() const;
//! parse wrapper to get common interface for both box and fullbox
virtual void parsebox();
//! pure virtual function for all subclasses to implement
virtual void parse() = 0;
protected:
//! function to get the file pointer
TagLib::File* file() const;
protected:
class Mp4IsoBoxPrivate;
Mp4IsoBoxPrivate* d;
};
} // namespace MP4
} // namespace TagLib
#endif // MP4ISOBOX_H

View File

@ -0,0 +1,46 @@
#include "mp4isofullbox.h"
#include "tfile.h"
using namespace TagLib;
class MP4::Mp4IsoFullBox::Mp4IsoFullBoxPrivate
{
public:
uchar version;
uint flags;
}; // Mp4IsoFullBoxPrivate
MP4::Mp4IsoFullBox::Mp4IsoFullBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
: Mp4IsoBox( file, fourcc, size, offset )
{
d = new MP4::Mp4IsoFullBox::Mp4IsoFullBoxPrivate();
}
MP4::Mp4IsoFullBox::~Mp4IsoFullBox()
{
delete d;
}
void MP4::Mp4IsoFullBox::parsebox()
{
// seek to offset
Mp4IsoBox::file()->seek(Mp4IsoBox::offset(), File::Beginning );
// parse version and flags
ByteVector version_flags = Mp4IsoBox::file()->readBlock(4);
d->version = version_flags[0];
d->flags = version_flags[1] << 16 || version_flags[2] << 8 || version_flags[3];
// call parse method of subclass
parse();
}
TagLib::uchar MP4::Mp4IsoFullBox::version()
{
return d->version;
}
TagLib::uint MP4::Mp4IsoFullBox::flags()
{
return d->flags;
}

View File

@ -0,0 +1,36 @@
#ifndef MP4ISOFULLBOX_H
#define MP4ISOFULLBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4IsoFullBox : public Mp4IsoBox
{
public:
//! constructor for full box
Mp4IsoFullBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
//! destructor for mp4 iso full box
virtual ~Mp4IsoFullBox();
//! function to get the version of box
uchar version();
//! function to get the flag map
uint flags();
//! parse wrapper to get common interface for both box and fullbox
virtual void parsebox();
protected:
class Mp4IsoFullBoxPrivate;
Mp4IsoFullBoxPrivate* d;
};
} // namespace MP4
} // namespace TagLib
#endif // MP4ISOFULLBOX_H

View File

@ -0,0 +1,202 @@
#include "mp4itunestag.h"
using namespace TagLib;
class MP4::Tag::TagPrivate
{
public:
MP4::File* mp4file;
TagLib::String title;
TagLib::String artist;
TagLib::String album;
TagLib::String genre;
TagLib::uint year;
TagLib::uint track;
TagLib::uint numTracks;
TagLib::String comment;
TagLib::String grouping;
TagLib::String composer;
TagLib::uint disk;
TagLib::uint numDisks;
TagLib::uint bpm;
bool isEmpty;
TagLib::ByteVector cover;
};
MP4::Tag::Tag( )
{
d = new TagPrivate();
d->year = 0;
d->track = 0;
d->numTracks = 0;
d->disk = 0;
d->numTracks = 0;
d->bpm = 0;
d->isEmpty = true;
}
MP4::Tag::~Tag()
{
delete d;
}
String MP4::Tag::title() const
{
return d->title;
}
String MP4::Tag::artist() const
{
return d->artist;
}
String MP4::Tag::album() const
{
return d->album;
}
String MP4::Tag::comment() const
{
return d->comment;
}
String MP4::Tag::genre() const
{
return d->genre;
}
TagLib::uint MP4::Tag::year() const
{
return d->year;
}
TagLib::uint MP4::Tag::track() const
{
return d->track;
}
TagLib::uint MP4::Tag::numTracks() const
{
return d->numTracks;
}
String MP4::Tag::grouping() const
{
return d->grouping;
}
String MP4::Tag::composer() const
{
return d->composer;
}
TagLib::uint MP4::Tag::disk() const
{
return d->disk;
}
TagLib::uint MP4::Tag::numDisks() const
{
return d->numDisks;
}
TagLib::uint MP4::Tag::bpm() const
{
return d->bpm;
}
TagLib::ByteVector MP4::Tag::cover() const
{
return d->cover;
}
void MP4::Tag::setTitle(const String &s)
{
d->title = s;
d->isEmpty = false;
}
void MP4::Tag::setArtist(const String &s)
{
d->artist = s;
d->isEmpty = false;
}
void MP4::Tag::setAlbum(const String &s)
{
d->album = s;
d->isEmpty = false;
}
void MP4::Tag::setComment(const String &s)
{
d->comment = s;
d->isEmpty = false;
}
void MP4::Tag::setGenre(const String &s)
{
d->genre = s;
d->isEmpty = false;
}
void MP4::Tag::setYear(TagLib::uint i)
{
d->year = i;
d->isEmpty = false;
}
void MP4::Tag::setTrack(TagLib::uint i)
{
d->track = i;
d->isEmpty = false;
}
void MP4::Tag::setNumTracks(TagLib::uint i)
{
d->numTracks = i;
d->isEmpty = false;
}
void MP4::Tag::setGrouping(const String &s)
{
d->grouping = s;
d->isEmpty = false;
}
void MP4::Tag::setComposer(const String &s)
{
d->composer = s;
d->isEmpty = false;
}
void MP4::Tag::setDisk(const TagLib::uint i)
{
d->disk = i;
d->isEmpty = false;
}
void MP4::Tag::setNumDisks(const TagLib::uint i)
{
d->numDisks = i;
d->isEmpty = false;
}
void MP4::Tag::setBpm(const TagLib::uint i)
{
d->bpm = i;
d->isEmpty = false;
}
void MP4::Tag::setCover(const TagLib::ByteVector& c)
{
d->cover = c;
d->isEmpty = false;
}
bool MP4::Tag::isEmpty() const
{
return d->isEmpty;
}

View File

@ -0,0 +1,76 @@
#ifndef MP4ITUNESTAG_H
#define MP4ITUNESTAG_H
#include "taglib.h"
#include "tstring.h"
#include "tag.h"
namespace TagLib
{
namespace MP4
{
class File;
class Tag : public TagLib::Tag
{
public:
/*!
* Constructs an empty MP4 iTunes tag.
*/
Tag( );
/*!
* Destroys this Tag instance.
*/
virtual ~Tag();
// Reimplementations.
virtual String title() const;
virtual String artist() const;
virtual String album() const;
virtual String comment() const;
virtual String genre() const;
virtual uint year() const;
virtual uint track() const;
virtual void setTitle(const String &s);
virtual void setArtist(const String &s);
virtual void setAlbum(const String &s);
virtual void setComment(const String &s);
virtual void setGenre(const String &s);
virtual void setYear(uint i);
virtual void setTrack(uint i);
// MP4 specific fields
String grouping() const;
String composer() const;
uint numTracks() const;
uint disk() const;
uint numDisks() const;
uint bpm() const;
ByteVector cover() const;
void setGrouping(const String &s);
void setComposer(const String &s);
void setNumTracks(const uint i);
void setDisk(const uint i);
void setNumDisks(const uint i);
void setBpm(const uint i);
void setCover( const ByteVector& cover );
virtual bool isEmpty() const;
private:
Tag(const Tag &);
Tag &operator=(const Tag &);
class TagPrivate;
TagPrivate *d;
};
} // namespace MP4
} // namespace TagLib
#endif // MP4ITUNESTAG_H

View File

@ -0,0 +1,90 @@
#include "tlist.h"
#include <iostream>
#include "mp4mdiabox.h"
#include "mp4hdlrbox.h"
#include "mp4minfbox.h"
#include "boxfactory.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4MdiaBox::Mp4MdiaBoxPrivate
{
public:
//! container for all boxes in mdia box
TagLib::List<Mp4IsoBox*> mdiaBoxes;
//! a box factory for creating the appropriate boxes
MP4::BoxFactory boxfactory;
}; // class Mp4MdiaBoxPrivate
MP4::Mp4MdiaBox::Mp4MdiaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoBox( file, fourcc, size, offset )
{
d = new MP4::Mp4MdiaBox::Mp4MdiaBoxPrivate();
}
MP4::Mp4MdiaBox::~Mp4MdiaBox()
{
TagLib::List<Mp4IsoBox*>::Iterator delIter;
for( delIter = d->mdiaBoxes.begin();
delIter != d->mdiaBoxes.end();
delIter++ )
{
delete *delIter;
}
delete d;
}
void MP4::Mp4MdiaBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
TagLib::uint totalsize = 8;
// parse all contained boxes
TagLib::uint size;
MP4::Fourcc fourcc;
// stores the current handler type
TagLib::MP4::Fourcc hdlrtype;
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
{
totalsize += size;
// check for errors
if( totalsize > MP4::Mp4IsoBox::size() )
{
std::cerr << "Error in mp4 file " << mp4file->name() << " mdia box contains bad box with name: " << fourcc.toString() << std::endl;
return;
}
// create the appropriate subclass and parse it
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
if( static_cast<TagLib::uint>( fourcc ) == 0x6d696e66 /*"minf"*/ )
{
// cast to minf
Mp4MinfBox* minfbox = static_cast<Mp4MinfBox*>( curbox );
if(!minfbox)
return;
// set handler type
minfbox->setHandlerType( hdlrtype );
}
curbox->parsebox();
d->mdiaBoxes.append( curbox );
if(static_cast<TagLib::uint>( fourcc ) == 0x68646c72 /*"hdlr"*/ )
{
// cast to hdlr box
Mp4HdlrBox* hdlrbox = static_cast<Mp4HdlrBox*>( curbox );
if(!hdlrbox)
return;
// get handler type
hdlrtype = hdlrbox->hdlr_type();
}
// check for end of mdia box
if( totalsize == MP4::Mp4IsoBox::size() )
break;
}
}

View File

@ -0,0 +1,28 @@
#ifndef MP4MDIABOX_H
#define MP4MDIABOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4MdiaBox: public Mp4IsoBox
{
public:
Mp4MdiaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4MdiaBox();
//! parse mdia contents
void parse();
private:
class Mp4MdiaBoxPrivate;
Mp4MdiaBoxPrivate* d;
}; // Mp4MdiaBox
} // namespace MP4
} // namespace TagLib
#endif // MP4MDIABOX_H

View File

@ -0,0 +1,65 @@
#include <tlist.h>
#include <iostream>
#include "mp4metabox.h"
#include "boxfactory.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4MetaBox::Mp4MetaBoxPrivate
{
public:
//! container for all boxes in meta box
TagLib::List<Mp4IsoBox*> metaBoxes;
//! a box factory for creating the appropriate boxes
MP4::BoxFactory boxfactory;
}; // class Mp4MetaBoxPrivate
MP4::Mp4MetaBox::Mp4MetaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoFullBox( file, fourcc, size, offset )
{
d = new MP4::Mp4MetaBox::Mp4MetaBoxPrivate();
}
MP4::Mp4MetaBox::~Mp4MetaBox()
{
TagLib::List<Mp4IsoBox*>::Iterator delIter;
for( delIter = d->metaBoxes.begin();
delIter != d->metaBoxes.end();
delIter++ )
{
delete *delIter;
}
delete d;
}
void MP4::Mp4MetaBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
TagLib::uint totalsize = 12; // initial size of box
// parse all contained boxes
TagLib::uint size;
MP4::Fourcc fourcc;
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
{
totalsize += size;
// check for errors
if( totalsize > MP4::Mp4IsoBox::size() )
{
std::cerr << "Error in mp4 file " << mp4file->name() << " meta box contains bad box with name: " << fourcc.toString() << std::endl;
return;
}
// create the appropriate subclass and parse it
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
curbox->parsebox();
d->metaBoxes.append( curbox );
// check for end of meta box
if( totalsize == MP4::Mp4IsoBox::size() )
break;
}
}

View File

@ -0,0 +1,28 @@
#ifndef MP4METABOX_H
#define MP4METABOX_H
#include "mp4isofullbox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4MetaBox: public Mp4IsoFullBox
{
public:
Mp4MetaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4MetaBox();
//! parse meta contents
void parse();
private:
class Mp4MetaBoxPrivate;
Mp4MetaBoxPrivate* d;
}; // Mp4MetaBox
} // namespace MP4
} // namespace TagLib
#endif // MP4METABOX_H

View File

@ -0,0 +1,83 @@
#include "tlist.h"
#include <iostream>
#include "mp4minfbox.h"
#include "mp4stblbox.h"
#include "boxfactory.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4MinfBox::Mp4MinfBoxPrivate
{
public:
//! container for all boxes in minf box
TagLib::List<Mp4IsoBox*> minfBoxes;
//! a box factory for creating the appropriate boxes
MP4::BoxFactory boxfactory;
//! stores the handler type of the current trak
MP4::Fourcc handler_type;
}; // class Mp4MinfBoxPrivate
MP4::Mp4MinfBox::Mp4MinfBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoBox( file, fourcc, size, offset )
{
d = new MP4::Mp4MinfBox::Mp4MinfBoxPrivate();
}
MP4::Mp4MinfBox::~Mp4MinfBox()
{
TagLib::List<Mp4IsoBox*>::Iterator delIter;
for( delIter = d->minfBoxes.begin();
delIter != d->minfBoxes.end();
delIter++ )
{
delete *delIter;
}
delete d;
}
void MP4::Mp4MinfBox::setHandlerType( MP4::Fourcc fourcc )
{
d->handler_type = fourcc;
}
void MP4::Mp4MinfBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
TagLib::uint totalsize = 8;
// parse all contained boxes
TagLib::uint size;
MP4::Fourcc fourcc;
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
{
totalsize += size;
// check for errors
if( totalsize > MP4::Mp4IsoBox::size() )
{
std::cerr << "Error in mp4 file " << mp4file->name() << " minf box contains bad box with name: " << fourcc.toString() << std::endl;
return;
}
// create the appropriate subclass and parse it
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
if(static_cast<TagLib::uint>( fourcc ) == 0x7374626c /*stbl*/ )
{
// cast to hdlr box
Mp4StblBox* stblbox = static_cast<Mp4StblBox*>( curbox );
if(!stblbox)
return;
// set handler type
stblbox->setHandlerType( d->handler_type );
}
curbox->parsebox();
d->minfBoxes.append( curbox );
// check for end of minf box
if( totalsize == MP4::Mp4IsoBox::size() )
break;
}
}

View File

@ -0,0 +1,30 @@
#ifndef MP4MINFBOX_H
#define MP4MINFBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4MinfBox: public Mp4IsoBox
{
public:
Mp4MinfBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4MinfBox();
//! parse minf contents
void parse();
//! set the handler type - needed for stsd
void setHandlerType( MP4::Fourcc fourcc );
private:
class Mp4MinfBoxPrivate;
Mp4MinfBoxPrivate* d;
}; // Mp4MinfBox
} // namespace MP4
} // namespace TagLib
#endif // MP4MINFBOX_H

View File

@ -0,0 +1,65 @@
#include "tlist.h"
#include <iostream>
#include "mp4moovbox.h"
#include "boxfactory.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4MoovBox::Mp4MoovBoxPrivate
{
public:
//! container for all boxes in moov box
TagLib::List<Mp4IsoBox*> moovBoxes;
//! a box factory for creating the appropriate boxes
MP4::BoxFactory boxfactory;
}; // class Mp4MoovBoxPrivate
MP4::Mp4MoovBox::Mp4MoovBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoBox( file, fourcc, size, offset )
{
d = new MP4::Mp4MoovBox::Mp4MoovBoxPrivate();
}
MP4::Mp4MoovBox::~Mp4MoovBox()
{
TagLib::List<Mp4IsoBox*>::Iterator delIter;
for( delIter = d->moovBoxes.begin();
delIter != d->moovBoxes.end();
delIter++ )
{
delete *delIter;
}
delete d;
}
void MP4::Mp4MoovBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
TagLib::uint totalsize = 8;
// parse all contained boxes
TagLib::uint size;
MP4::Fourcc fourcc;
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
{
totalsize += size;
// check for errors
if( totalsize > MP4::Mp4IsoBox::size() )
{
std::cerr << "Error in mp4 file " << mp4file->name() << " moov box contains bad box with name: " << fourcc.toString() << std::endl;
return;
}
// create the appropriate subclass and parse it
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
curbox->parsebox();
d->moovBoxes.append( curbox );
// check for end of moov box
if( totalsize == MP4::Mp4IsoBox::size() )
break;
}
}

View File

@ -0,0 +1,28 @@
#ifndef MP4MOOVBOX_H
#define MP4MOOVBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4MoovBox: public Mp4IsoBox
{
public:
Mp4MoovBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4MoovBox();
//! parse moov contents
void parse();
private:
class Mp4MoovBoxPrivate;
Mp4MoovBoxPrivate* d;
}; // Mp4MoovBox
} // namespace MP4
} // namespace TagLib
#endif // MP4MOOVBOX_H

View File

@ -0,0 +1,119 @@
#include <deque>
#include <iostream>
#include "mp4mvhdbox.h"
#include "boxfactory.h"
#include "mp4file.h"
#include "mp4propsproxy.h"
using namespace TagLib;
class MP4::Mp4MvhdBox::Mp4MvhdBoxPrivate
{
public:
//! creation time of the file
TagLib::ulonglong creationTime;
//! modification time of the file - since midnight, Jan. 1, 1904, UTC-time
TagLib::ulonglong modificationTime;
//! timescale for the file - referred by all time specifications in this box
TagLib::uint timescale;
//! duration of presentation
TagLib::ulonglong duration;
//! playout speed
TagLib::uint rate;
//! volume for entire presentation
TagLib::uint volume;
//! track ID for an additional track (next new track)
TagLib::uint nextTrackID;
}; // class Mp4MvhdBoxPrivate
MP4::Mp4MvhdBox::Mp4MvhdBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoFullBox( file, fourcc, size, offset )
{
d = new MP4::Mp4MvhdBox::Mp4MvhdBoxPrivate();
}
MP4::Mp4MvhdBox::~Mp4MvhdBox()
{
delete d;
}
TagLib::ulonglong MP4::Mp4MvhdBox::creationTime() const
{
return d->creationTime;
}
TagLib::ulonglong MP4::Mp4MvhdBox::modificationTime() const
{
return d->modificationTime;
}
TagLib::uint MP4::Mp4MvhdBox::timescale() const
{
return d->timescale;
}
TagLib::ulonglong MP4::Mp4MvhdBox::duration() const
{
return d->duration;
}
TagLib::uint MP4::Mp4MvhdBox::rate() const
{
return d->rate;
}
TagLib::uint MP4::Mp4MvhdBox::volume() const
{
return d->volume;
}
TagLib::uint MP4::Mp4MvhdBox::nextTrackID() const
{
return d->nextTrackID;
}
void MP4::Mp4MvhdBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
if( version() == 1 )
{
if( !mp4file->readLongLong( d->creationTime ) )
return;
if( !mp4file->readLongLong( d->modificationTime ) )
return;
if( !mp4file->readInt( d->timescale ) )
return;
if( !mp4file->readLongLong( d->duration ) )
return;
}
else
{
TagLib::uint creationTime_tmp, modificationTime_tmp, duration_tmp;
if( !mp4file->readInt( creationTime_tmp ) )
return;
if( !mp4file->readInt( modificationTime_tmp ) )
return;
if( !mp4file->readInt( d->timescale ) )
return;
if( !mp4file->readInt( duration_tmp ) )
return;
d->creationTime = creationTime_tmp;
d->modificationTime = modificationTime_tmp;
d->duration = duration_tmp;
}
if( !mp4file->readInt( d->rate ) )
return;
if( !mp4file->readInt( d->volume ) )
return;
// jump over unused fields
mp4file->seek( 68, File::Current );
if( !mp4file->readInt( d->nextTrackID ) )
return;
// register at proxy
mp4file->propProxy()->registerMvhd( this );
}

View File

@ -0,0 +1,44 @@
#ifndef MP4MVHDBOX_H
#define MP4MVHDBOX_H
#include "mp4isofullbox.h"
#include "mp4fourcc.h"
#include "mp4file.h" // ulonglong
namespace TagLib
{
namespace MP4
{
class Mp4MvhdBox: public Mp4IsoFullBox
{
public:
Mp4MvhdBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4MvhdBox();
//! function to get the creation time of the mp4 file
ulonglong creationTime() const;
//! function to get the modification time of the mp4 file
ulonglong modificationTime() const;
//! function to get the timescale referenced by the above timestamps
uint timescale() const;
//! function to get the presentation duration in the mp4 file
ulonglong duration() const;
//! function to get the rate (playout speed) - typically 1.0;
uint rate() const;
//! function to get volume level for presentation - typically 1.0;
uint volume() const;
//! function to get the track ID for adding new tracks - useless for this lib
uint nextTrackID() const;
//! parse mvhd contents
void parse();
private:
class Mp4MvhdBoxPrivate;
Mp4MvhdBoxPrivate* d;
}; // Mp4MvhdBox
} // namespace MP4
} // namespace TagLib
#endif // MP4MVHDBOX_H

View File

@ -0,0 +1,68 @@
#include "mp4propsproxy.h"
using namespace TagLib;
class MP4::Mp4PropsProxy::Mp4PropsProxyPrivate
{
public:
//! the movie header box
MP4::Mp4MvhdBox* mvhdbox;
//! the sample table box
MP4::Mp4AudioSampleEntry* audiosampleentry;
};
MP4::Mp4PropsProxy::Mp4PropsProxy()
{
d = new MP4::Mp4PropsProxy::Mp4PropsProxyPrivate();
d->mvhdbox = 0;
d->audiosampleentry = 0;
}
MP4::Mp4PropsProxy::~Mp4PropsProxy()
{
delete d;
}
TagLib::uint MP4::Mp4PropsProxy::seconds() const
{
if( d->mvhdbox )
return static_cast<TagLib::uint>( d->mvhdbox->duration() / d->mvhdbox->timescale() );
else
return 0;
}
TagLib::uint MP4::Mp4PropsProxy::channels() const
{
if( d->audiosampleentry )
return d->audiosampleentry->channels();
else
return 0;
}
TagLib::uint MP4::Mp4PropsProxy::sampleRate() const
{
if( d->audiosampleentry )
return (d->audiosampleentry->samplerate()>>16);
else
return 0;
}
TagLib::uint MP4::Mp4PropsProxy::bitRate() const
{
if( d->audiosampleentry )
return (d->audiosampleentry->bitrate());
else
return 0;
}
void MP4::Mp4PropsProxy::registerMvhd( MP4::Mp4MvhdBox* mvhdbox )
{
d->mvhdbox = mvhdbox;
}
void MP4::Mp4PropsProxy::registerAudioSampleEntry( MP4::Mp4AudioSampleEntry* audioSampleEntry )
{
d->audiosampleentry = audioSampleEntry;
}

View File

@ -0,0 +1,44 @@
#ifndef MP4PROPSPROXY_H
#define MP4PROPSPROXY_H MP4PROPSPROXY_H
#include "mp4mvhdbox.h"
#include "mp4audiosampleentry.h"
namespace TagLib
{
namespace MP4
{
//! Mp4PropsProxy is used to access the stsd box and mvhd box directly
/*! this class works as a shortcut to avoid stepping through all parent boxes
* to access the boxes in question
*/
class Mp4PropsProxy
{
public:
//! constructor for properties proxy
Mp4PropsProxy();
//! destructor
~Mp4PropsProxy();
//! function to get length of media in seconds
TagLib::uint seconds() const;
//! function to get the nunmber of channels
TagLib::uint channels() const;
//! function to get the sample rate
TagLib::uint sampleRate() const;
//! function to get the bitrate rate
TagLib::uint bitRate() const;
//! function to register the movie header box - mvhd
void registerMvhd( MP4::Mp4MvhdBox* mvhdbox );
//! function to register the sample description box
void registerAudioSampleEntry( MP4::Mp4AudioSampleEntry* audiosampleentry );
private:
class Mp4PropsProxyPrivate;
Mp4PropsProxyPrivate* d;
}; // Mp4PropsProxy
} // MP4
} // TagLib
#endif // MP4PROPSPROXY_H

View File

@ -0,0 +1,38 @@
#include "mp4sampleentry.h"
#include "mp4isobox.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4SampleEntry::Mp4SampleEntryPrivate
{
public:
TagLib::uint data_reference_index;
};
MP4::Mp4SampleEntry::Mp4SampleEntry( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::Mp4SampleEntry::Mp4SampleEntryPrivate();
}
MP4::Mp4SampleEntry::~Mp4SampleEntry()
{
delete d;
}
//! parse the content of the box
void MP4::Mp4SampleEntry::parse()
{
TagLib::MP4::File* mp4file = static_cast<TagLib::MP4::File*>(file());
if(!mp4file)
return;
// skip the first 6 bytes
mp4file->seek( 6, TagLib::File::Current );
// read data reference index
if(!mp4file->readShort( d->data_reference_index))
return;
parseEntry();
}

View File

@ -0,0 +1,33 @@
#ifndef MP4SAMPLEENTRY_H
#define MP4SAMPLEENTRY_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4SampleEntry: public Mp4IsoBox
{
public:
Mp4SampleEntry( File* file, MP4::Fourcc fourcc, uint size, long offset );
~Mp4SampleEntry();
public:
//! parse the content of the box
virtual void parse();
private:
//! function to be implemented in subclass
virtual void parseEntry() = 0;
protected:
class Mp4SampleEntryPrivate;
Mp4SampleEntryPrivate* d;
}; // class Mp4SampleEntry
} // namespace MP4
} // namespace TagLib
#endif // MP4SAMPLEENTRY_H

View File

@ -0,0 +1,29 @@
#include "mp4skipbox.h"
#include "mp4isobox.h"
#include "tfile.h"
using namespace TagLib;
class MP4::Mp4SkipBox::Mp4SkipBoxPrivate
{
public:
};
MP4::Mp4SkipBox::Mp4SkipBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
:Mp4IsoBox(file, fourcc, size, offset)
{
d = new MP4::Mp4SkipBox::Mp4SkipBoxPrivate();
}
MP4::Mp4SkipBox::~Mp4SkipBox()
{
delete d;
}
//! parse the content of the box
void MP4::Mp4SkipBox::parse()
{
// skip contents
file()->seek( size() - 8, TagLib::File::Current );
}

View File

@ -0,0 +1,29 @@
#ifndef MP4SKIPBOX_H
#define MP4SKIPBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4SkipBox: public Mp4IsoBox
{
public:
Mp4SkipBox( File* file, MP4::Fourcc fourcc, uint size, long offset );
~Mp4SkipBox();
private:
//! parse the content of the box
virtual void parse();
protected:
class Mp4SkipBoxPrivate;
Mp4SkipBoxPrivate* d;
}; // class Mp4SkipBox
} // namespace MP4
} // namespace TagLib
#endif // MP4SKIPBOX_H

View File

@ -0,0 +1,84 @@
#include "tlist.h"
#include <iostream>
#include "mp4stblbox.h"
#include "mp4stsdbox.h"
#include "boxfactory.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4StblBox::Mp4StblBoxPrivate
{
public:
//! container for all boxes in stbl box
TagLib::List<Mp4IsoBox*> stblBoxes;
//! a box factory for creating the appropriate boxes
MP4::BoxFactory boxfactory;
//! the handler type for the current trak
MP4::Fourcc handler_type;
}; // class Mp4StblBoxPrivate
MP4::Mp4StblBox::Mp4StblBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoBox( file, fourcc, size, offset )
{
d = new MP4::Mp4StblBox::Mp4StblBoxPrivate();
}
MP4::Mp4StblBox::~Mp4StblBox()
{
TagLib::List<Mp4IsoBox*>::Iterator delIter;
for( delIter = d->stblBoxes.begin();
delIter != d->stblBoxes.end();
delIter++ )
{
delete *delIter;
}
delete d;
}
void MP4::Mp4StblBox::setHandlerType( MP4::Fourcc fourcc )
{
d->handler_type = fourcc;
}
void MP4::Mp4StblBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
TagLib::uint totalsize = 8;
// parse all contained boxes
TagLib::uint size;
MP4::Fourcc fourcc;
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
{
totalsize += size;
// check for errors
if( totalsize > MP4::Mp4IsoBox::size() )
{
std::cerr << "Error in mp4 file " << mp4file->name() << " stbl box contains bad box with name: " << fourcc.toString() << std::endl;
return;
}
// create the appropriate subclass and parse it
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
// check for stsd
if( static_cast<TagLib::uint>(fourcc) == 0x73747364 /*'stsd'*/ )
{
// cast to stsd box
MP4::Mp4StsdBox* stsdbox = static_cast<MP4::Mp4StsdBox*>(curbox);
if(!stsdbox)
return;
// set the handler type
stsdbox->setHandlerType( d->handler_type );
}
curbox->parsebox();
d->stblBoxes.append( curbox );
// check for end of stbl box
if( totalsize == MP4::Mp4IsoBox::size() )
break;
}
}

View File

@ -0,0 +1,30 @@
#ifndef MP4STBLBOX_H
#define MP4STBLBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4StblBox: public Mp4IsoBox
{
public:
Mp4StblBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4StblBox();
//! parse stbl contents
void parse();
//! set the handler type - needed for stsd
void setHandlerType( MP4::Fourcc fourcc );
private:
class Mp4StblBoxPrivate;
Mp4StblBoxPrivate* d;
}; // Mp4StblBox
} // namespace MP4
} // namespace TagLib
#endif // MP4STBLBOX_H

View File

@ -0,0 +1,70 @@
#include "tlist.h"
#include <iostream>
#include "mp4stsdbox.h"
#include "mp4audiosampleentry.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4StsdBox::Mp4StsdBoxPrivate
{
public:
//! the handler type for the current trak
MP4::Fourcc handler_type;
//! the audio sample entry
MP4::Mp4AudioSampleEntry* audioSampleEntry;
}; // class Mp4StsdBoxPrivate
MP4::Mp4StsdBox::Mp4StsdBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoFullBox( file, fourcc, size, offset )
{
d = new MP4::Mp4StsdBox::Mp4StsdBoxPrivate();
}
MP4::Mp4StsdBox::~Mp4StsdBox()
{
delete d;
}
void MP4::Mp4StsdBox::setHandlerType( MP4::Fourcc fourcc )
{
d->handler_type = fourcc;
}
void MP4::Mp4StsdBox::parse()
{
MP4::File* mp4file = static_cast<MP4::File*>( file() );
if(!mp4file)
return;
TagLib::uint totalsize = 12; // initial size of box
// check for handler type - only parse if 'soun':
if( static_cast<TagLib::uint>(d->handler_type) == 0x736f756e )
{
// read entry count
TagLib::uint entry_count;
if(!mp4file->readInt( entry_count ))
return;
// simply read first entry and skip all following
// read size and type
TagLib::uint cursize;
MP4::Fourcc fourcc;
if( !mp4file->readSizeAndType( cursize, fourcc ))
return;
totalsize += 12;
// alocate an AudioSampleEntry
d->audioSampleEntry = new MP4::Mp4AudioSampleEntry( mp4file, fourcc, cursize, mp4file->tell() );
// parse the AudioSampleEntry
d->audioSampleEntry->parse();
totalsize += cursize-8;
// skip the remaining box contents
mp4file->seek( size()-totalsize, TagLib::File::Current );
}
else
{
mp4file->seek( size()-totalsize, TagLib::File::Current );
}
}

View File

@ -0,0 +1,30 @@
#ifndef MP4STSDBOX_H
#define MP4STSDBOX_H
#include "mp4isofullbox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4StsdBox: public Mp4IsoFullBox
{
public:
Mp4StsdBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4StsdBox();
//! parse stsd contents
void parse();
//! set the handler type - needed for stsd
void setHandlerType( MP4::Fourcc fourcc );
private:
class Mp4StsdBoxPrivate;
Mp4StsdBoxPrivate* d;
}; // Mp4StsdBox
} // namespace MP4
} // namespace TagLib
#endif // MP4STSDBOX_H

View File

@ -0,0 +1,147 @@
#include "mp4tagsproxy.h"
#include "itunesdatabox.h"
using namespace TagLib;
class MP4::Mp4TagsProxy::Mp4TagsProxyPrivate
{
public:
ITunesDataBox* titleData;
ITunesDataBox* artistData;
ITunesDataBox* albumData;
ITunesDataBox* coverData;
ITunesDataBox* genreData;
ITunesDataBox* yearData;
ITunesDataBox* trknData;
ITunesDataBox* commentData;
ITunesDataBox* groupingData;
ITunesDataBox* composerData;
ITunesDataBox* diskData;
ITunesDataBox* bpmData;
};
MP4::Mp4TagsProxy::Mp4TagsProxy()
{
d = new MP4::Mp4TagsProxy::Mp4TagsProxyPrivate();
d->titleData = 0;
d->artistData = 0;
d->albumData = 0;
d->coverData = 0;
d->genreData = 0;
d->yearData = 0;
d->trknData = 0;
d->commentData = 0;
d->groupingData = 0;
d->composerData = 0;
d->diskData = 0;
d->bpmData = 0;
}
MP4::Mp4TagsProxy::~Mp4TagsProxy()
{
delete d;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::titleData() const
{
return d->titleData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::artistData() const
{
return d->artistData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::albumData() const
{
return d->albumData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::genreData() const
{
return d->genreData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::yearData() const
{
return d->yearData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::trknData() const
{
return d->trknData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::commentData() const
{
return d->commentData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::groupingData() const
{
return d->groupingData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::composerData() const
{
return d->composerData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::diskData() const
{
return d->diskData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::bpmData() const
{
return d->bpmData;
}
MP4::ITunesDataBox* MP4::Mp4TagsProxy::coverData() const
{
return d->coverData;
}
void MP4::Mp4TagsProxy::registerBox( EBoxType boxtype, ITunesDataBox* databox )
{
switch( boxtype )
{
case title:
d->titleData = databox;
break;
case artist:
d->artistData = databox;
break;
case album:
d->albumData = databox;
break;
case cover:
d->coverData = databox;
break;
case genre:
d->genreData = databox;
break;
case year:
d->yearData = databox;
break;
case trackno:
d->trknData = databox;
break;
case comment:
d->commentData = databox;
break;
case grouping:
d->groupingData = databox;
break;
case composer:
d->composerData = databox;
break;
case disk:
d->diskData = databox;
break;
case bpm:
d->bpmData = databox;
break;
}
}

View File

@ -0,0 +1,78 @@
#ifndef MP4TAGSPROXY_H
#define MP4TAGSPROXY_H
namespace TagLib
{
namespace MP4
{
// forward declaration(s)
class ITunesDataBox;
/*! proxy for mp4 itunes tag relevant boxes
*
* this class works as a proxy for the specific tag boxes
* in an mp4 itunes file. the boxes are mired in
* the mp4 file structure and stepping through all box layers
* is avoided by registration at the proxy object.
*/
class Mp4TagsProxy
{
public:
/*! enum for all supported box types */
typedef enum
{
title = 0,
artist,
album,
cover,
genre,
year,
trackno,
comment,
grouping,
composer,
disk,
bpm
} EBoxType;
//! constructor
Mp4TagsProxy();
//! destructor
~Mp4TagsProxy();
//! function to get the data box for the title
ITunesDataBox* titleData() const;
//! function to get the data box for the artist
ITunesDataBox* artistData() const;
//! function to get the data box for the album
ITunesDataBox* albumData() const;
//! function to get the data box for the genre
ITunesDataBox* genreData() const;
//! function to get the data box for the year
ITunesDataBox* yearData() const;
//! function to get the data box for the track number
ITunesDataBox* trknData() const;
//! function to get the data box for the comment
ITunesDataBox* commentData() const;
//! function to get the data box for the grouping
ITunesDataBox* groupingData() const;
//! function to get the data box for the composer
ITunesDataBox* composerData() const;
//! function to get the data box for the disk number
ITunesDataBox* diskData() const;
//! function to get the data box for the bpm
ITunesDataBox* bpmData() const;
//! function to get the data box for the cover
ITunesDataBox* coverData() const;
//! function to register a data box for a certain box type
void registerBox( EBoxType boxtype, ITunesDataBox* databox );
private:
class Mp4TagsProxyPrivate;
//! private data of tags proxy
Mp4TagsProxyPrivate* d;
}; // class Mp4TagsProxy
} // namespace MP4
} // namespace TagLib
#endif // MP4TAGSPROXY_H

View File

@ -0,0 +1,65 @@
#include "tlist.h"
#include <iostream>
#include "mp4trakbox.h"
#include "boxfactory.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4TrakBox::Mp4TrakBoxPrivate
{
public:
//! container for all boxes in trak box
TagLib::List<Mp4IsoBox*> trakBoxes;
//! a box factory for creating the appropriate boxes
MP4::BoxFactory boxfactory;
}; // class Mp4TrakBoxPrivate
MP4::Mp4TrakBox::Mp4TrakBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoBox( file, fourcc, size, offset )
{
d = new MP4::Mp4TrakBox::Mp4TrakBoxPrivate();
}
MP4::Mp4TrakBox::~Mp4TrakBox()
{
TagLib::List<Mp4IsoBox*>::Iterator delIter;
for( delIter = d->trakBoxes.begin();
delIter != d->trakBoxes.end();
delIter++ )
{
delete *delIter;
}
delete d;
}
void MP4::Mp4TrakBox::parse()
{
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
TagLib::uint totalsize = 8;
// parse all contained boxes
TagLib::uint size;
MP4::Fourcc fourcc;
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
{
totalsize += size;
// check for errors
if( totalsize > MP4::Mp4IsoBox::size() )
{
std::cerr << "Error in mp4 file " << mp4file->name() << " trak box contains bad box with name: " << fourcc.toString() << std::endl;
return;
}
// create the appropriate subclass and parse it
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
curbox->parsebox();
d->trakBoxes.append( curbox );
// check for end of trak box
if( totalsize == MP4::Mp4IsoBox::size() )
break;
}
}

View File

@ -0,0 +1,28 @@
#ifndef MP4TRAKBOX_H
#define MP4TRAKBOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4TrakBox: public Mp4IsoBox
{
public:
Mp4TrakBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4TrakBox();
//! parse trak contents
void parse();
private:
class Mp4TrakBoxPrivate;
Mp4TrakBoxPrivate* d;
}; // Mp4TrakBox
} // namespace MP4
} // namespace TagLib
#endif // MP4TRAKBOX_H

View File

@ -0,0 +1,74 @@
#include "tlist.h"
#include <iostream>
#include "mp4udtabox.h"
#include "boxfactory.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::Mp4UdtaBox::Mp4UdtaBoxPrivate
{
public:
//! container for all boxes in udta box
TagLib::List<Mp4IsoBox*> udtaBoxes;
//! a box factory for creating the appropriate boxes
MP4::BoxFactory boxfactory;
}; // class Mp4UdtaBoxPrivate
MP4::Mp4UdtaBox::Mp4UdtaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
: Mp4IsoBox( file, fourcc, size, offset )
{
d = new MP4::Mp4UdtaBox::Mp4UdtaBoxPrivate();
}
MP4::Mp4UdtaBox::~Mp4UdtaBox()
{
TagLib::List<Mp4IsoBox*>::Iterator delIter;
for( delIter = d->udtaBoxes.begin();
delIter != d->udtaBoxes.end();
delIter++ )
{
delete *delIter;
}
delete d;
}
void MP4::Mp4UdtaBox::parse()
{
#if 0
std::cout << " parsing udta box" << std::endl;
#endif
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
TagLib::uint totalsize = 8;
// parse all contained boxes
TagLib::uint size;
MP4::Fourcc fourcc;
#if 0
std::cout << " ";
#endif
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
{
totalsize += size;
// check for errors
if( totalsize > MP4::Mp4IsoBox::size() )
{
std::cerr << "Error in mp4 file " << mp4file->name() << " udta box contains bad box with name: " << fourcc.toString() << std::endl;
return;
}
// create the appropriate subclass and parse it
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
curbox->parsebox();
d->udtaBoxes.append( curbox );
// check for end of udta box
if( totalsize == MP4::Mp4IsoBox::size() )
break;
#if 0
std::cout << " ";
#endif
}
}

View File

@ -0,0 +1,28 @@
#ifndef MP4UDTABOX_H
#define MP4UDTABOX_H
#include "mp4isobox.h"
#include "mp4fourcc.h"
namespace TagLib
{
namespace MP4
{
class Mp4UdtaBox: public Mp4IsoBox
{
public:
Mp4UdtaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
~Mp4UdtaBox();
//! parse moov contents
void parse();
private:
class Mp4UdtaBoxPrivate;
Mp4UdtaBoxPrivate* d;
}; // Mp4UdtaBox
} // namespace MP4
} // namespace TagLib
#endif // MP4UDTABOX_H

View File

@ -89,6 +89,11 @@ public:
// public members
////////////////////////////////////////////////////////////////////////////////
MPC::File::File() : TagLib::File()
{
d = new FilePrivate;
}
MPC::File::File(const char *file, bool readProperties,
Properties::ReadStyle propertiesStyle) : TagLib::File(file)
{
@ -111,6 +116,67 @@ MPC::Properties *MPC::File::audioProperties() const
return d->properties;
}
void MPC::File::read(bool readProperties, Properties::ReadStyle /* propertiesStyle */)
{
// Look for an ID3v1 tag
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
d->hasID3v1 = true;
}
// Look for an APE tag
findAPE();
d->APELocation = findAPE();
if(d->APELocation >= 0) {
d->APETag = new APE::Tag(this, d->APELocation);
d->APESize = d->APETag->footer()->completeTagSize();
d->APELocation = d->APELocation + d->APETag->footer()->size() - d->APESize;
d->hasAPE = true;
}
if(d->hasID3v1 && d->hasAPE)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else {
if(d->hasID3v1)
d->tag = d->ID3v1Tag;
else {
if(d->hasAPE)
d->tag = d->APETag;
else
d->tag = d->APETag = new APE::Tag;
}
}
// Look for and skip an ID3v2 tag
d->ID3v2Location = findID3v2();
if(d->ID3v2Location >= 0) {
seek(d->ID3v2Location);
d->ID3v2Header = new ID3v2::Header(readBlock(ID3v2::Header::size()));
d->ID3v2Size = d->ID3v2Header->completeTagSize();
d->hasID3v2 = true;
}
if(d->hasID3v2)
seek(d->ID3v2Location + d->ID3v2Size);
else
seek(0);
// Look for MPC metadata
if(readProperties) {
d->properties = new Properties(readBlock(MPC::HeaderSize),
length() - d->ID3v2Size - d->APESize);
}
}
bool MPC::File::save()
{
if(readOnly()) {
@ -254,67 +320,6 @@ void MPC::File::remove(int tags)
// private members
////////////////////////////////////////////////////////////////////////////////
void MPC::File::read(bool readProperties, Properties::ReadStyle /* propertiesStyle */)
{
// Look for an ID3v1 tag
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
d->hasID3v1 = true;
}
// Look for an APE tag
findAPE();
d->APELocation = findAPE();
if(d->APELocation >= 0) {
d->APETag = new APE::Tag(this, d->APELocation);
d->APESize = d->APETag->footer()->completeTagSize();
d->APELocation = d->APELocation + d->APETag->footer()->size() - d->APESize;
d->hasAPE = true;
}
if(d->hasID3v1 && d->hasAPE)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else {
if(d->hasID3v1)
d->tag = d->ID3v1Tag;
else {
if(d->hasAPE)
d->tag = d->APETag;
else
d->tag = d->APETag = new APE::Tag;
}
}
// Look for and skip an ID3v2 tag
d->ID3v2Location = findID3v2();
if(d->ID3v2Location >= 0) {
seek(d->ID3v2Location);
d->ID3v2Header = new ID3v2::Header(readBlock(ID3v2::Header::size()));
d->ID3v2Size = d->ID3v2Header->completeTagSize();
d->hasID3v2 = true;
}
if(d->hasID3v2)
seek(d->ID3v2Location + d->ID3v2Size);
else
seek(0);
// Look for MPC metadata
if(readProperties) {
d->properties = new Properties(readBlock(MPC::HeaderSize),
length() - d->ID3v2Size - d->APESize);
}
}
long MPC::File::findAPE()
{
if(!isValid())

View File

@ -22,6 +22,7 @@
#ifndef TAGLIB_MPCFILE_H
#define TAGLIB_MPCFILE_H
#include "taglib_export.h"
#include "tfile.h"
#include "mpcproperties.h"
@ -55,7 +56,7 @@ namespace TagLib {
* The only invalid tag combination supported is an ID3v1 tag after an APE tag.
*/
class File : public TagLib::File
class TAGLIB_EXPORT File : public TagLib::File
{
public:
/*!
@ -75,6 +76,12 @@ namespace TagLib {
AllTags = 0xffff
};
/*!
* Contructs an MPC file object without reading a file. Allows object
* fields to be set up before reading.
*/
File();
/*!
* Contructs an MPC file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
@ -100,6 +107,14 @@ namespace TagLib {
*/
virtual Properties *audioProperties() const;
/*!
* Reads from MPC file. If \a readProperties is true the file's audio
* properties will also be read using \a propertiesStyle. If false,
* \a propertiesStyle is ignored.
*/
void read(bool readProperties = true,
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Saves the file.
*/
@ -147,7 +162,6 @@ namespace TagLib {
File(const File &);
File &operator=(const File &);
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
void scan();
long findAPE();
long findID3v1();

View File

@ -81,13 +81,6 @@ int MPC::Properties::sampleRate() const
return d->sampleRate;
}
/*
int MPC::Properties::sampleWidth() const
{
return d->sampleWidth;
}
*/
int MPC::Properties::channels() const
{
return d->channels;
@ -121,18 +114,21 @@ void MPC::Properties::read()
d->channels = 2;
}
else {
unsigned int headerData = d->data.mid(0, 4).toUInt(false);
uint headerData = d->data.mid(0, 4).toUInt(false);
d->bitrate = (headerData >> 23) & 0x01ff;
d->version = (headerData >> 11) & 0x03ff;
d->sampleRate = 44100;
d->channels = 2;
if(d->version >= 5)
frames = d->data.mid(4, 4).toUInt(false);
else
frames = d->data.mid(4, 2).toUInt(false);
frames = d->data.mid(6, 2).toUInt(false);
}
unsigned int samples = frames * 1152 - 576;
uint samples = frames * 1152 - 576;
d->length = d->sampleRate > 0 ? (samples + (d->sampleRate / 2)) / d->sampleRate : 0;
if(!d->bitrate)

Some files were not shown because too many files have changed in this diff Show More