Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

180
Src/id3v2/id3_dll.h Normal file
View File

@ -0,0 +1,180 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_DLLHEADERS_H
#define ID3LIB_DLLHEADERS_H
typedef unsigned char uchar;
typedef short signed int ssint;
typedef short unsigned int suint;
typedef long signed int lsint;
typedef long unsigned int luint;
typedef long double ldoub;
typedef long unsigned int * bitset;
struct ID3_VerInfo
{
char name [ 30 ];
luint version,
revision;
};
enum ID3_TextEnc
{
ID3TE_ASCII = 0,
ID3TE_UNICODE
};
enum ID3_FieldID
{
ID3FN_NOFIELD = 0,
ID3FN_TEXTENC,
ID3FN_TEXT,
ID3FN_URL,
ID3FN_DATA,
ID3FN_DESCRIPTION,
ID3FN_OWNER,
ID3FN_EMAIL,
ID3FN_RATING,
ID3FN_FILENAME,
ID3FN_LANGUAGE,
ID3FN_PICTURETYPE,
ID3FN_IMAGEFORMAT,
ID3FN_MIMETYPE,
ID3FN_COUNTER,
ID3FN_SYMBOL,
ID3FN_VOLUMEADJ,
ID3FN_NUMBITS,
ID3FN_VOLCHGRIGHT,
ID3FN_VOLCHGLEFT,
ID3FN_PEAKVOLRIGHT,
ID3FN_PEAKVOLLEFT,
ID3FN_LASTFIELDID
};
enum ID3_FrameID
{
ID3FID_NOFRAME = 0,
ID3FID_ORIGALBUM,
ID3FID_PUBLISHER,
ID3FID_ENCODEDBY,
ID3FID_ENCODERSETTINGS,
ID3FID_ORIGFILENAME,
ID3FID_LANGUAGE,
ID3FID_PARTINSET,
ID3FID_DATE,
ID3FID_TIME,
ID3FID_RECORDINGDATES,
ID3FID_MEDIATYPE,
ID3FID_FILETYPE,
ID3FID_NETRADIOSTATION,
ID3FID_NETRADIOOWNER,
ID3FID_LYRICIST,
ID3FID_ORIGARTIST,
ID3FID_ORIGLYRICIST,
ID3FID_SUBTITLE,
ID3FID_MIXARTIST,
ID3FID_USERTEXT,
ID3FID_CONTENTGROUP,
ID3FID_TITLE,
ID3FID_LEADARTIST,
ID3FID_BAND,
ID3FID_ALBUM,
ID3FID_YEAR,
ID3FID_CONDUCTOR,
ID3FID_COMPOSER,
ID3FID_COPYRIGHT,
ID3FID_CONTENTTYPE,
ID3FID_TRACKNUM,
ID3FID_COMMENT,
ID3FID_WWWAUDIOFILE,
ID3FID_WWWARTIST,
ID3FID_WWWAUDIOSOURCE,
ID3FID_WWWCOMMERCIALINFO,
ID3FID_WWWCOPYRIGHT,
ID3FID_WWWPUBLISHER,
ID3FID_WWWPAYMENT,
ID3FID_WWWRADIOPAGE,
ID3FID_WWWUSER,
ID3FID_INVOLVEDPEOPLE,
ID3FID_UNSYNCEDLYRICS,
ID3FID_PICTURE,
ID3FID_GENERALOBJECT,
ID3FID_UNIQUEFILEID,
ID3FID_PLAYCOUNTER,
ID3FID_POPULARIMETER,
ID3FID_GROUPINGREG,
ID3FID_CRYPTOREG
};
class ID3_Field;
class ID3_Frame;
class ID3_Tag;
void ID3_GetVersion ( ID3_VerInfo *info );
// tag wrappers
ID3_Tag *ID3Tag_New ( void );
void ID3Tag_Delete ( ID3_Tag *tag );
void ID3Tag_Clear ( ID3_Tag *tag );
bool ID3Tag_HasChanged ( ID3_Tag *tag );
void ID3Tag_SetUnsync ( ID3_Tag *tag, bool unsync );
void ID3Tag_SetExtendedHeader ( ID3_Tag *tag, bool ext );
void ID3Tag_SetCompression ( ID3_Tag *tag, bool comp );
void ID3Tag_SetPadding ( ID3_Tag *tag, bool pad );
void ID3Tag_AddFrame ( ID3_Tag *tag, ID3_Frame *frame );
void ID3Tag_AddFrames ( ID3_Tag *tag, ID3_Frame *frames, luint num );
void ID3Tag_RemoveFrame ( ID3_Tag *tag, ID3_Frame *frame );
void ID3Tag_Parse ( ID3_Tag *tag, uchar header[ ID3_TAGHEADERSIZE ], uchar *buffer );
luint ID3Tag_Link ( ID3_Tag *tag, char *fileName );
void ID3Tag_Update ( ID3_Tag *tag );
void ID3Tag_Strip ( ID3_Tag *tag, bool v1Also );
ID3_Frame *ID3Tag_FindFrameWithID ( ID3_Tag *tag, ID3_FrameID id );
ID3_Frame *ID3Tag_FindFrameWithINT ( ID3_Tag *tag, ID3_FrameID id, ID3_FieldID fld, luint data );
ID3_Frame *ID3Tag_FindFrameWithASCII ( ID3_Tag *tag, ID3_FrameID id, ID3_FieldID fld, char *data );
ID3_Frame *ID3Tag_FindFrameWithUNICODE ( ID3_Tag *tag, ID3_FrameID id, ID3_FieldID fld, wchar_t *data );
ID3_Frame *ID3Tag_GetFrameNum ( ID3_Tag *tag, luint num );
luint ID3Tag_NumFrames ( ID3_Tag *tag );
// frame wrappers
void ID3Frame_Clear ( ID3_Frame *frame );
void ID3Frame_SetID ( ID3_Frame *frame, ID3_FrameID id );
ID3_FrameID ID3Frame_GetID ( ID3_Frame *frame );
ID3_Field *ID3Frame_GetField ( ID3_Frame *frame, ID3_FieldID name );
// field wrappers
void ID3Field_Clear ( ID3_Field *field );
luint ID3Field_Size ( ID3_Field *field );
luint ID3Field_GetNumTextItems ( ID3_Field *field );
void ID3Field_SetINT ( ID3_Field *field, luint data );
luint ID3Field_GetINT ( ID3_Field *field );
void ID3Field_SetUNICODE ( ID3_Field *field, wchar_t *string );
luint ID3Field_GetUNICODE ( ID3_Field *field, wchar_t *buffer, luint maxChars, luint itemNum );
void ID3Field_AddUNICODE ( ID3_Field *field, wchar_t *string );
void ID3Field_SetASCII ( ID3_Field *field, char *string );
luint ID3Field_GetASCII ( ID3_Field *field, char *buffer, luint maxChars, luint itemNum );
void ID3Field_AddASCII ( ID3_Field *field, char *string );
void ID3Field_SetBINARY ( ID3_Field *field, uchar *data, luint size );
void ID3Field_GetBINARY ( ID3_Field *field, uchar *buffer, luint buffLength );
void ID3Field_FromFile ( ID3_Field *field, char *fileName );
void ID3Field_ToFile ( ID3_Field *field, char *fileName );
#endif

View File

@ -0,0 +1,481 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include "id3_tag.h"
#ifdef __DLL
#include <string.h>
struct ID3_VerInfo
{
char name [ 30 ];
luint version,
revision;
};
// misc wrappers
CDLLEXPORT
void ID3_GetVersion ( ID3_VerInfo *info )
{
info->version = ID3LIB_VER;
info->revision = ID3LIB_REV;
strcpy ( info->name, ID3LIB_NAME );
return;
}
// tag wrappers
CDLLEXPORT
ID3_Tag *ID3Tag_New ( void )
{
return new ID3_Tag;
}
CDLLEXPORT
void ID3Tag_Delete ( ID3_Tag *tag )
{
if ( tag )
delete tag;
return;
}
CDLLEXPORT
void ID3Tag_Clear ( ID3_Tag *tag )
{
if ( tag )
tag->Clear();
return;
}
CDLLEXPORT
bool ID3Tag_HasChanged ( ID3_Tag *tag )
{
bool changed = false;
if ( tag )
changed = tag->HasChanged();
return changed;
}
CDLLEXPORT
void ID3Tag_SetUnsync ( ID3_Tag *tag, bool unsync )
{
if ( tag )
tag->SetUnsync ( unsync );
return;
}
CDLLEXPORT
void ID3Tag_SetExtendedHeader ( ID3_Tag *tag, bool ext )
{
if ( tag )
tag->SetExtendedHeader ( ext );
return;
}
CDLLEXPORT
void ID3Tag_SetCompression ( ID3_Tag *tag, bool comp )
{
if ( tag )
tag->SetCompression ( comp );
return;
}
CDLLEXPORT
void ID3Tag_SetPadding ( ID3_Tag *tag, bool pad )
{
if ( tag )
tag->SetPadding ( pad );
return;
}
CDLLEXPORT
void ID3Tag_AddFrame ( ID3_Tag *tag, ID3_Frame *frame )
{
if ( tag )
tag->AddFrame ( frame );
return;
}
CDLLEXPORT
void ID3Tag_AddFrames ( ID3_Tag *tag, ID3_Frame *frames, luint num )
{
if ( tag )
tag->AddFrames ( frames, num );
return;
}
CDLLEXPORT
void ID3Tag_RemoveFrame ( ID3_Tag *tag, ID3_Frame *frame )
{
if ( tag )
tag->RemoveFrame ( frame );
return;
}
CDLLEXPORT
void ID3Tag_Parse ( ID3_Tag *tag, uchar header[ ID3_TAGHEADERSIZE ], uchar *buffer )
{
if ( tag )
tag->Parse ( header, buffer );
return;
}
CDLLEXPORT
luint ID3Tag_Link ( ID3_Tag *tag, char *fileName )
{
luint offset = 0;
if ( tag )
offset = tag->Link ( fileName );
return offset;
}
CDLLEXPORT
void ID3Tag_Update ( ID3_Tag *tag )
{
if ( tag )
tag->Update();
return;
}
CDLLEXPORT
void ID3Tag_Strip ( ID3_Tag *tag, bool v1Also )
{
if ( tag )
tag->Strip ( v1Also );
return;
}
CDLLEXPORT
ID3_Frame *ID3Tag_FindFrameWithID ( ID3_Tag *tag, ID3_FrameID id )
{
ID3_Frame *frame = NULL;
if ( tag )
frame = tag->Find ( id );
return frame;
}
CDLLEXPORT
ID3_Frame *ID3Tag_FindFrameWithINT ( ID3_Tag *tag, ID3_FrameID id, ID3_FieldID fld, luint data )
{
ID3_Frame *frame = NULL;
if ( tag )
frame = tag->Find ( id, fld, data );
return frame;
}
CDLLEXPORT
ID3_Frame *ID3Tag_FindFrameWithASCII ( ID3_Tag *tag, ID3_FrameID id, ID3_FieldID fld, char *data )
{
ID3_Frame *frame = NULL;
if ( tag )
frame = tag->Find ( id, fld, data );
return frame;
}
CDLLEXPORT
ID3_Frame *ID3Tag_FindFrameWithUNICODE ( ID3_Tag *tag, ID3_FrameID id, ID3_FieldID fld, wchar_t *data )
{
ID3_Frame *frame = NULL;
if ( tag )
frame = tag->Find ( id, fld, data );
return frame;
}
CDLLEXPORT
luint ID3Tag_NumFrames ( ID3_Tag *tag )
{
luint num = 0;
if ( tag )
num = tag->NumFrames();
return num;
}
CDLLEXPORT
ID3_Frame *ID3Tag_GetFrameNum ( ID3_Tag *tag, luint num )
{
ID3_Frame *frame = NULL;
if ( tag )
frame = tag->GetFrameNum ( num );
return frame;
}
// frame wrappers
CDLLEXPORT
void ID3Frame_Clear ( ID3_Frame *frame )
{
if ( frame )
frame->Clear();
return;
}
CDLLEXPORT
void ID3Frame_SetID ( ID3_Frame *frame, ID3_FrameID id )
{
if ( frame )
frame->SetID ( id );
return;
}
CDLLEXPORT
ID3_FrameID ID3Frame_GetID ( ID3_Frame *frame )
{
ID3_FrameID id = ID3FID_NOFRAME;
if ( frame )
id = frame->GetID();
return id;
}
CDLLEXPORT
ID3_Field *ID3Frame_GetField ( ID3_Frame *frame, ID3_FieldID name )
{
ID3_Field *field = NULL;
if ( frame )
field = &( frame->Field ( name ) );
return field;
}
// field wrappers
CDLLEXPORT
void ID3Field_Clear ( ID3_Field *field )
{
if ( field )
field->Clear();
return;
}
CDLLEXPORT
luint ID3Field_Size ( ID3_Field *field )
{
luint size = 0;
if ( field )
size = field->Size();
return size;
}
CDLLEXPORT
luint ID3Field_GetNumTextItems ( ID3_Field *field )
{
luint items = 0;
if ( field )
items = field->GetNumTextItems();
return items;
}
CDLLEXPORT
void ID3Field_SetINT ( ID3_Field *field, luint data )
{
if ( field )
field->Set ( data );
return;
}
CDLLEXPORT
luint ID3Field_GetINT ( ID3_Field *field )
{
luint value = 0;
if ( field )
value = field->Get();
return value;
}
CDLLEXPORT
void ID3Field_SetUNICODE ( ID3_Field *field, wchar_t *string )
{
if ( field )
field->Set ( string );
return;
}
CDLLEXPORT
luint ID3Field_GetUNICODE ( ID3_Field *field, wchar_t *buffer, luint maxChars, luint itemNum )
{
luint numChars = 0;
if ( field )
numChars = field->Get ( buffer, maxChars, itemNum );
return numChars;
}
CDLLEXPORT
void ID3Field_AddUNICODE ( ID3_Field *field, wchar_t *string )
{
if ( field )
field->Add ( string );
return;
}
CDLLEXPORT
void ID3Field_SetASCII ( ID3_Field *field, char *string )
{
if ( field )
field->Set ( string );
return;
}
CDLLEXPORT
luint ID3Field_GetASCII ( ID3_Field *field, char *buffer, luint maxChars, luint itemNum )
{
luint numChars = 0;
if ( field )
numChars = field->Get ( buffer, maxChars, itemNum );
return numChars;
}
CDLLEXPORT
void ID3Field_AddASCII ( ID3_Field *field, char *string )
{
if ( field )
field->Add ( string );
return;
}
CDLLEXPORT
void ID3Field_SetBINARY ( ID3_Field *field, uchar *data, luint size )
{
if ( field )
field->Set ( data, size );
return;
}
CDLLEXPORT
void ID3Field_GetBINARY ( ID3_Field *field, uchar *buffer, luint buffLength )
{
if ( field )
field->Get ( buffer, buffLength );
return;
}
CDLLEXPORT
void ID3Field_FromFile ( ID3_Field *field, char *fileName )
{
if ( field )
field->FromFile ( fileName );
return;
}
CDLLEXPORT
void ID3Field_ToFile ( ID3_Field *field, char *fileName )
{
if ( field )
field->ToFile ( fileName );
return;
}
#endif

67
Src/id3v2/id3_error.cpp Normal file
View File

@ -0,0 +1,67 @@
#if 0 //JF 10.30.00
// The authors have released ID3Lib as Public Domain(PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney(dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include <string.h>
#include "id3_error.h"
/*static char *ID3_ErrorDescs[] =
{
"out of memory",
"no source/dest data specified",
"no buffer specified",
"invalid frame id",
"field not found",
"unknown field type",
"tag is already attached to a file",
"invalid tag version",
"file not found",
"error in zlib compression library"
};*/
ID3_Error::ID3_Error(ID3_Err code, char *file, luint line)
{
error = code;
errLine = line;
lstrcpyn(errFile, file, 256);
}
ID3_Err ID3_Error::GetErrorID(void)
{
return error;
}
/*char *ID3_Error::GetErrorDesc(void)
{
return ID3_ErrorDescs[error];
}*/
char *ID3_Error::GetErrorFile(void)
{
return errFile;
}
luint ID3_Error::GetErrorLine(void)
{
return errLine;
}
#endif

61
Src/id3v2/id3_error.h Normal file
View File

@ -0,0 +1,61 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_ERROR_H
#define ID3LIB_ERROR_H
#include "id3_types.h"
enum ID3_Err
{
ID3E_NoMemory = 0,
ID3E_NoData,
ID3E_NoBuffer,
ID3E_InvalidFrameID,
ID3E_FieldNotFound,
ID3E_UnknownFieldType,
ID3E_TagAlreadyAttached,
ID3E_InvalidTagVersion,
ID3E_NoFile,
ID3E_zlibError
};
class ID3_Error
{
public:
ID3_Err GetErrorID(void);
//char *GetErrorDesc(void);
char *GetErrorFile(void);
luint GetErrorLine(void);
// *** PRIVATE INTERNAL DATA - DO NOT USE *** PRIVATE INTERNAL DATA - DO NOT USE ***
ID3_Error(ID3_Err id, char *file, luint lineNum);
protected:
ID3_Err error;
luint errLine;
char errFile[256];
};
#ifdef _DEBUG
//#define ID3_THROW(x) throw ID3_Error (x, __FILE__, __LINE__)
#define ID3_THROW(x) void()
#else
#define ID3_THROW(x) void()
#endif
#endif

21
Src/id3v2/id3_externals.h Normal file
View File

@ -0,0 +1,21 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_EXTERNALS_H
#define ID3LIB_EXTERNALS_H
#endif

520
Src/id3v2/id3_field.cpp Normal file
View File

@ -0,0 +1,520 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
// improved/optimized/whatever 10/30/00 JF
#include <windows.h>
#include <string.h>
#include "id3_field.h"
static ID3_FieldDef ID3FD_URL[] =
{
{ID3FN_URL, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD},
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_UserURL[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_TEXTENC, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_DESCRIPTION, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL | ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_URL, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_Text[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_TEXTENC, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_TEXT, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_UserText[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_TEXTENC, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_DESCRIPTION, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL | ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_TEXT, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_GeneralText[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_TEXTENC, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_LANGUAGE, ID3FTY_ASCIISTRING, 3, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_DESCRIPTION, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL | ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_TEXT, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_Picture[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_TEXTENC, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_IMAGEFORMAT, ID3FTY_ASCIISTRING, 3, 2, 0, ID3VC_LOWER, NULL, ID3FN_NOFIELD },
{ID3FN_MIMETYPE, ID3FTY_ASCIISTRING, -1, 3, 0, ID3VC_HIGHER, ID3FF_NULL, ID3FN_NOFIELD },
{ID3FN_PICTURETYPE, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_DESCRIPTION, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL | ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_DATA, ID3FTY_BINARY, -1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_GEO[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_TEXTENC, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_MIMETYPE, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL, ID3FN_NOFIELD },
{ID3FN_FILENAME, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL | ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_DESCRIPTION, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL | ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_DATA, ID3FTY_BINARY, -1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_UFI[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_OWNER, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL, ID3FN_NOFIELD },
{ID3FN_DATA, ID3FTY_BINARY, -1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_PRIVATE[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_OWNER, ID3FTY_ASCIISTRING, -1, 3, 0, ID3VC_HIGHER, ID3FF_NULL, ID3FN_NOFIELD },
{ID3FN_DATA, ID3FTY_BINARY, -1, 3, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_PlayCounter[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_COUNTER, ID3FTY_INTEGER, 4, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_Popularimeter[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_EMAIL, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL, ID3FN_NOFIELD },
{ID3FN_RATING, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_COUNTER, ID3FTY_INTEGER, 4, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_Registration[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_OWNER, ID3FTY_ASCIISTRING, -1, 3, 0, ID3VC_HIGHER, ID3FF_NULL, ID3FN_NOFIELD },
{ID3FN_SYMBOL, ID3FTY_INTEGER, 1, 3, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_DATA, ID3FTY_BINARY, -1, 3, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_InvolvedPeople[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_TEXTENC, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_TEXT, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL | ID3FF_NULLDIVIDE | ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_Volume[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_VOLUMEADJ, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_NUMBITS, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_VOLCHGRIGHT, ID3FTY_BITFIELD, -1, 2, 0, ID3VC_HIGHER, ID3FF_ADJUSTEDBY, ID3FN_NUMBITS },
{ID3FN_VOLCHGLEFT, ID3FTY_BITFIELD, -1, 2, 0, ID3VC_HIGHER, ID3FF_ADJUSTEDBY, ID3FN_NUMBITS },
{ID3FN_PEAKVOLRIGHT, ID3FTY_BITFIELD, -1, 2, 0, ID3VC_HIGHER, ID3FF_ADJUSTEDBY, ID3FN_NUMBITS },
{ID3FN_PEAKVOLLEFT, ID3FTY_BITFIELD, -1, 2, 0, ID3VC_HIGHER, ID3FF_ADJUSTEDBY, ID3FN_NUMBITS },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_MCDI[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_CD_TOC, ID3FTY_BINARY, -1, 3, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD},
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_Text_v2_4[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_TEXTENC, ID3FTY_INTEGER, 1, 4, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_TEXT, ID3FTY_ASCIISTRING, -1, 4, 0, ID3VC_HIGHER, ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_Timestamp1[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_TIMESTAMP, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_DATA, ID3FTY_BINARY, -1, 3, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FieldDef ID3FD_Timestamp2[] =
{
// FIELD FIELD FIXED RENDER IF OR
// NAME TYPE LEN VER REV WHAT? FLAGS LINKED FIELD
{ID3FN_TEXTENC, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_LANGUAGE, ID3FTY_ASCIISTRING, 3, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_TIMESTAMP, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_CONTENTTYPE, ID3FTY_INTEGER, 1, 2, 0, ID3VC_HIGHER, NULL, ID3FN_NOFIELD },
{ID3FN_DESCRIPTION, ID3FTY_ASCIISTRING, -1, 2, 0, ID3VC_HIGHER, ID3FF_NULL | ID3FF_ADJUSTENC, ID3FN_NOFIELD },
{ID3FN_NOFIELD }
};
static ID3_FrameDef ID3_FrameDefs[] =
{
//FRAME ID SHORTID LONGID PRI TAGDISCARD FILEDISCARD HANDLER FIELDDEFS
{ID3FID_ENCODEDBY, "TEN", "TENC", false, true, NULL, ID3FD_Text },
{ID3FID_ORIGALBUM, "TOT", "TOAL", false, false, NULL, ID3FD_Text },
{ID3FID_PUBLISHER, "TPB", "TPUB", false, false, NULL, ID3FD_Text },
{ID3FID_ENCODERSETTINGS, "TSS", "TSSE", false, false, NULL, ID3FD_Text },
{ID3FID_ORIGFILENAME, "TOF", "TOFN", false, false, NULL, ID3FD_Text },
{ID3FID_LANGUAGE, "TLA", "TLAN", false, false, NULL, ID3FD_Text },
{ID3FID_PARTINSET, "TPA", "TPOS", false, false, NULL, ID3FD_Text },
{ID3FID_DATE, "TDA", "TDAT", false, false, NULL, ID3FD_Text },
{ID3FID_TIME, "TIM", "TIME", false, false, NULL, ID3FD_Text },
{ID3FID_RECORDINGDATES, "TRD", "TRDA", false, false, NULL, ID3FD_Text },
{ID3FID_MEDIATYPE, "TMT", "TMED", false, false, NULL, ID3FD_Text },
{ID3FID_FILETYPE, "TFT", "TFLT", false, false, NULL, ID3FD_Text },
{ID3FID_NETRADIOSTATION, "TRN", "TRSN", false, false, NULL, ID3FD_Text },
{ID3FID_NETRADIOOWNER, "TRO", "TRSO", false, false, NULL, ID3FD_Text },
{ID3FID_LYRICIST, "TXT", "TEXT", false, false, NULL, ID3FD_Text },
{ID3FID_ORIGARTIST, "TOA", "TOPE", false, false, NULL, ID3FD_Text },
{ID3FID_ORIGLYRICIST, "TOL", "TOLY", false, false, NULL, ID3FD_Text },
{ID3FID_CONTENTGROUP, "TT1", "TIT1", false, false, NULL, ID3FD_Text },
{ID3FID_TITLE, "TT2", "TIT2", false, false, NULL, ID3FD_Text },
{ID3FID_SUBTITLE, "TT3", "TIT3", false, false, NULL, ID3FD_Text },
{ID3FID_LEADARTIST, "TP1", "TPE1", false, false, NULL, ID3FD_Text },
{ID3FID_BAND, "TP2", "TPE2", false, false, NULL, ID3FD_Text },
{ID3FID_CONDUCTOR, "TP3", "TPE3", false, false, NULL, ID3FD_Text },
{ID3FID_MIXARTIST, "TP4", "TPE4", false, false, NULL, ID3FD_Text },
{ID3FID_ALBUM, "TAL", "TALB", false, false, NULL, ID3FD_Text },
{ID3FID_YEAR, "TYE", "TYER", false, false, NULL, ID3FD_Text },
{ID3FID_COMPOSER, "TCM", "TCOM", false, false, NULL, ID3FD_Text },
{ID3FID_COPYRIGHT, "TCR", "TCOP", false, false, NULL, ID3FD_Text },
{ID3FID_PRODUCEDNOTICE, " ", "TPRO", false, false, NULL, ID3FD_Text },
{ID3FID_CONTENTTYPE, "TCO", "TCON", false, false, NULL, ID3FD_Text },
{ID3FID_TRACKNUM, "TRK", "TRCK", false, false, NULL, ID3FD_Text },
{ID3FID_USERTEXT, "TXX", "TXXX", false, false, NULL, ID3FD_UserText },
{ID3FID_COMMENT, "COM", "COMM", false, false, NULL, ID3FD_GeneralText },
{ID3FID_TERMSOFUSE, " ", "USER", false, false, NULL, ID3FD_GeneralText },
{ID3FID_UNSYNCEDLYRICS, "ULT", "USLT", false, false, NULL, ID3FD_GeneralText },
{ID3FID_SYNCEDLYRICS, "SLT", "SYLT", false, false, NULL, ID3FD_Timestamp2 },
{ID3FID_SYNCEDTEMPOCODE, "STC", "SYTC", false, false, NULL, ID3FD_Timestamp1 },
// URL Frames
{ID3FID_WWWAUDIOFILE, "WAF", "WOAF", false, false, NULL, ID3FD_URL },
{ID3FID_WWWARTIST, "WAR", "WOAR", false, false, NULL, ID3FD_URL },
{ID3FID_WWWAUDIOSOURCE, "WAS", "WOAS", false, false, NULL, ID3FD_URL },
{ID3FID_WWWCOMMERCIALINFO, "WCM", "WCOM", false, false, NULL, ID3FD_URL },
{ID3FID_WWWCOPYRIGHT, "WCP", "WCOP", false, false, NULL, ID3FD_URL },
{ID3FID_WWWPUBLISHER, "WPB", "WPUB", false, false, NULL, ID3FD_URL },
{ID3FID_WWWPAYMENT, "WPY", "WPAY", false, false, NULL, ID3FD_URL },
{ID3FID_WWWRADIOPAGE, "WRA", "WORS", false, false, NULL, ID3FD_URL },
{ID3FID_WWWUSER, "WXX", "WXXX", false, false, NULL, ID3FD_UserURL },
// misc frames
{ID3FID_INVOLVEDPEOPLE, "IPL", "IPLS", false, false, NULL, ID3FD_InvolvedPeople },
{ID3FID_PICTURE, "PIC", "APIC", false, false, NULL, ID3FD_Picture },
{ID3FID_GENERALOBJECT, "GEO", "GEOB", false, false, NULL, ID3FD_GEO },
{ID3FID_UNIQUEFILEID, "UFI", "UFID", false, false, NULL, ID3FD_UFI },
{ID3FID_PRIVATE, " ", "PRIV", false, false, NULL, ID3FD_PRIVATE },
{ID3FID_PLAYCOUNTER, "CNT", "PCNT", false, false, NULL, ID3FD_PlayCounter },
{ID3FID_POPULARIMETER, "POP", "POPM", false, false, NULL, ID3FD_Popularimeter },
{ID3FID_CRYPTOREG, " ", "ENCR", false, false, NULL, ID3FD_Registration },
{ID3FID_GROUPINGREG, " ", "GRID", false, false, NULL, ID3FD_Registration },
{ID3FID_SIGNATURE, " ", "SIGN", false, false, NULL, ID3FD_Registration },
{ID3FID_MCDI, "MCI", "MCDI", false, false, NULL, ID3FD_MCDI},
{ID3FID_BPM, "TBP", "TBPM", false, false, NULL, ID3FD_Text},
{ID3FID_KEY, "TKE", "TKEY", false, false, NULL, ID3FD_Text},
{ID3FID_MOOD, " ", "TMOO", false, false, NULL, ID3FD_Text},
{ID3FID_ISRC, "TRC", "TSRC", false, false, NULL, ID3FD_Text},
{ID3FID_RECORDINGTIME, " ", "TDRC", false, false, NULL, ID3FD_Text},
{ID3FID_COMPILATION, "TCP", "TCMP", false, false, NULL, ID3FD_Text},
{ID3FID_ALBUMSORT, "TSA", "TSOA", false, false, NULL, ID3FD_Text},
{ID3FID_ALBUMARTISTSORT, "TS2", "TSO2", false, false, NULL, ID3FD_Text},
{ID3FID_PERFORMERSORT, "TSP", "TSOP", false, false, NULL, ID3FD_Text},
{ID3FID_COMPOSERSORT, "TSC", "TSOC", false, false, NULL, ID3FD_Text},
{ID3FID_TITLESORT, "TST", "TSOT", false, false, NULL, ID3FD_Text},
{ID3FID_REPLAYGAIN, " ", "RGAD", false, false, NULL, ID3FD_UserText },
{ID3FID_VOLUMEADJ, "RVA", "RVAD", false, false, NULL, ID3FD_Volume },
{ID3FID_INVOLVEDPEOPLE2, " ", "TIPL", false, false, NULL, ID3FD_InvolvedPeople },
{ID3FID_CREDITS, " ", "TMCL", false, false, NULL, ID3FD_InvolvedPeople },
{ID3FID_ENCODINGTIME, " ", "TDEN", false, false, NULL, ID3FD_Text },
{ID3FID_FILEOWNER, " ", "TOWN", false, false, NULL, ID3FD_Text },
{ID3FID_LENGTH, "TLE", "TLEN", false, false, NULL, ID3FD_Text },
{ID3FID_ORIGYEAR, "TOR", "TORY", false, false, NULL, ID3FD_Text },
{ID3FID_ORIGRELEASETIME, " ", "TDOR", false, false, NULL, ID3FD_Text },
{ID3FID_RELEASETIME, " ", "TDRL", false, false, NULL, ID3FD_Text },
{ID3FID_SETSUBTITLE, " ", "TSST", false, false, NULL, ID3FD_Text },
{ID3FID_TAGGINGTIME, " ", "TDTG", false, false, NULL, ID3FD_Text },
{ID3FID_PLAYLISTDELAY, "TDY", "TDLY", false, false, NULL, ID3FD_Text },
{ID3FID_PODCAST, " ", "PCST", false, false, NULL, ID3FD_Text },
{ID3FID_PODCASTCATEGORY, " ", "TCAT", false, false, NULL, ID3FD_Text },
{ID3FID_PODCASTDESC, " ", "TDES", false, false, NULL, ID3FD_Text },
{ID3FID_PODCASTID, " ", "TGID", false, false, NULL, ID3FD_Text },
{ID3FID_PODCASTURL, " ", "WFED", false, false, NULL, ID3FD_URL },
{ID3FID_NOFRAME }
};
ID3_Field::ID3_Field(void)
{
name = ID3FN_NOFIELD;
type = ID3FTY_INTEGER;
data = 0;
size = 0;
flags = 0;
//SetVersion(3,0);
version = 3;
revision = 0;
fixedLength = -1;
ioVersion = 3;
ioRevision = 0;
control = ID3VC_HIGHER;
Clear();
}
ID3_Field::~ID3_Field(void)
{
Clear();
}
void ID3_Field::Clear(void)
{
if (data && type != ID3FTY_INTEGER) free(data);
type = ID3FTY_INTEGER;
data = 0;
size = sizeof (luint);
hasChanged = true;
return;
}
void ID3_Field::SetVersion (uchar ver, uchar rev)
{
if (version != ver || revision != rev) hasChanged = true;
version = ver;
revision = rev;
return;
}
bool ID3_Field::HasChanged (void)
{
return hasChanged;
}
luint ID3_Field::Size(void)
{
return BinSize (false);
}
luint ID3_Field::BinSize(bool withExtras)
{
luint bytes = 0;
if (control == ID3VC_HIGHER)
{
if (version < ioVersion || revision < ioRevision)
return 0;
}
else
{
if (version > ioVersion || revision > ioRevision)
return 0;
}
bytes = size;
if (withExtras)
{
if (!data && size)
{
if (flags & ID3FF_NULL)
bytes = 2;
else
bytes = 0;
}
// if we are a Unicode string, add 2 bytes for the BOM (but
// only if there is a string to render - regardless of NULL)
if (type == ID3FTY_UNICODESTRING && data && size) bytes += 2;
// if we are an ASCII string, divide by sizeof (wchar_t)
// because internally we store the string as Unicode, so
// the ASCII version will only be half as long
if (type == ID3FTY_UTF8STRING)
{
if (data && size)
bytes = WideCharToMultiByte(CP_UTF8, 0, (const wchar_t *)data, (int)(size/sizeof(wchar_t)), 0, 0, 0, 0);
else
bytes /= sizeof(wchar_t);
}
if (type == ID3FTY_ASCIISTRING)
{
// TODO: this statement isn't correct (especially for double byte)
// we could use WideCharToMultiByte to determine an exact byte count
bytes /= sizeof (wchar_t);
}
}
else
{
// because it seems that the application called us via ID3_Field::Size()
// we are going to return the number of characters, not bytes, so if
// the string is Unicode, we will half the 'bytes' variable because
// Unicode strings have twice as many bytes as they do characters
if (type == ID3FTY_UNICODESTRING)
bytes /= sizeof(wchar_t);
}
// check to see if we are within the legal limit for this field
// -1 means arbitrary length field
if (fixedLength != -1)
bytes = fixedLength;
return bytes;
}
luint ID3_Field::Parse(uchar *buffer, luint posn, luint buffSize)
{
if (control == ID3VC_HIGHER)
{
if (version < ioVersion || revision < ioRevision)
return 0;
}
else
{
if (version > ioVersion || revision > ioRevision)
return 0;
}
switch(type)
{
case ID3FTY_INTEGER:
return ParseInteger(buffer, posn, buffSize);
case ID3FTY_BINARY:
return ParseBinary(buffer, posn, buffSize);
case ID3FTY_ASCIISTRING:
return ParseASCIIString(buffer, posn, buffSize);
case ID3FTY_UNICODESTRING:
return ParseUnicodeString(buffer, posn, buffSize);
case ID3FTY_UTF8STRING:
return ParseUTF8String(buffer, posn, buffSize);
default:
//ID3_THROW (ID3E_UnknownFieldType);
break;
}
return 0;
}
ID3_FrameDef *ID3_FindFrameDef(ID3_FrameID id)
{
luint cur = 0;
while (1)
{
if (ID3_FrameDefs[cur].id == id)
return &ID3_FrameDefs[cur];
if (ID3_FrameDefs[cur].id == ID3FID_NOFRAME)
return NULL;
cur++;
}
}
ID3_FrameID ID3_FindFrameID(const char *id)
{
luint cur = 0;
while (1)
{
if (ID3_FrameDefs[cur].id == ID3FID_NOFRAME)
return ID3FID_NOFRAME;
if (((strncmp(ID3_FrameDefs[cur].shortTextID, id, 3) == 0) && strlen (id) == 3)
|| ((strncmp(ID3_FrameDefs[cur].longTextID, id, 4) == 0) && strlen (id) == 4))
return ID3_FrameDefs[cur].id;
cur++;
}
}
luint ID3_Field::Render(uchar *buffer)
{
if (control == ID3VC_HIGHER)
{
if (version < ioVersion || revision < ioRevision)
return 0;
}
else
{
if (version > ioVersion || revision > ioRevision)
return 0;
}
switch(type)
{
case ID3FTY_INTEGER:
return RenderInteger(buffer);
case ID3FTY_BINARY:
return RenderBinary(buffer);
case ID3FTY_ASCIISTRING:
return RenderLatinString(buffer);
case ID3FTY_UNICODESTRING:
return RenderUnicodeString(buffer);
case ID3FTY_UTF8STRING:
return RenderUTF8String(buffer);
default:
// ID3_THROW (ID3E_UnknownFieldType);
break;
}
return 0;
}

282
Src/id3v2/id3_field.h Normal file
View File

@ -0,0 +1,282 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
// improved/optimized/whatEVER jan-08-2006 benski
#ifndef ID3LIB_FIELD_H
#define ID3LIB_FIELD_H
#include <wchar.h>
#include "id3_types.h"
#include "id3_error.h"
// field flags
#define ID3FF_NULL (1 << 0)
#define ID3FF_NULLDIVIDE (1 << 1)
#define ID3FF_ADJUSTENC (1 << 2)
#define ID3FF_ADJUSTEDBY (1 << 3)
enum ID3_TextEnc
{
ID3TE_ASCII = 0,
ID3TE_UNICODE = 1, // UTF-16
ID3TE_UTF16_BE = 2, // UTF-16 big endian, no BOM
ID3TE_UTF8 = 3, // UTF-8
};
enum ID3_FieldType
{
ID3FTY_INTEGER = 0,
ID3FTY_BITFIELD,
ID3FTY_BINARY,
ID3FTY_ASCIISTRING,
ID3FTY_UNICODESTRING,
ID3FTY_UTF8STRING,
};
enum ID3_FieldID
{
ID3FN_NOFIELD = 0,
ID3FN_TEXTENC,
ID3FN_TEXT,
ID3FN_URL,
ID3FN_DATA,
ID3FN_DESCRIPTION,
ID3FN_OWNER,
ID3FN_EMAIL,
ID3FN_RATING,
ID3FN_FILENAME,
ID3FN_LANGUAGE,
ID3FN_PICTURETYPE,
ID3FN_IMAGEFORMAT,
ID3FN_MIMETYPE,
ID3FN_TIMESTAMP,
ID3FN_CONTENTTYPE,
ID3FN_COUNTER,
ID3FN_SYMBOL,
ID3FN_VOLUMEADJ,
ID3FN_NUMBITS,
ID3FN_VOLCHGRIGHT,
ID3FN_VOLCHGLEFT,
ID3FN_PEAKVOLRIGHT,
ID3FN_PEAKVOLLEFT,
ID3FN_CD_TOC,
ID3FN_LASTFIELDID
};
enum ID3_FrameID
{
ID3FID_NOFRAME = 0,
ID3FID_ENCODEDBY,
ID3FID_ORIGALBUM,
ID3FID_PUBLISHER,
ID3FID_ENCODERSETTINGS,
ID3FID_ORIGFILENAME,
ID3FID_LANGUAGE,
ID3FID_PARTINSET,
ID3FID_DATE,
ID3FID_TIME,
ID3FID_RECORDINGDATES,
ID3FID_MEDIATYPE,
ID3FID_FILETYPE,
ID3FID_NETRADIOSTATION,
ID3FID_NETRADIOOWNER,
ID3FID_LYRICIST,
ID3FID_ORIGARTIST,
ID3FID_ORIGLYRICIST,
ID3FID_CONTENTGROUP,
ID3FID_TITLE,
ID3FID_SUBTITLE,
ID3FID_LEADARTIST,
ID3FID_BAND,
ID3FID_CONDUCTOR,
ID3FID_MIXARTIST,
ID3FID_ALBUM,
ID3FID_YEAR,
ID3FID_COMPOSER,
ID3FID_COPYRIGHT,
ID3FID_PRODUCEDNOTICE,
ID3FID_CONTENTTYPE,
ID3FID_TRACKNUM,
ID3FID_USERTEXT,
ID3FID_COMMENT,
ID3FID_TERMSOFUSE,
ID3FID_UNSYNCEDLYRICS,
ID3FID_SYNCEDLYRICS,
ID3FID_SYNCEDTEMPOCODE,
ID3FID_WWWAUDIOFILE,
ID3FID_WWWARTIST,
ID3FID_WWWAUDIOSOURCE,
ID3FID_WWWCOMMERCIALINFO,
ID3FID_WWWCOPYRIGHT,
ID3FID_WWWPUBLISHER,
ID3FID_WWWPAYMENT,
ID3FID_WWWRADIOPAGE,
ID3FID_WWWUSER,
ID3FID_INVOLVEDPEOPLE,
ID3FID_PICTURE,
ID3FID_GENERALOBJECT,
ID3FID_UNIQUEFILEID,
ID3FID_PRIVATE,
ID3FID_PLAYCOUNTER,
ID3FID_POPULARIMETER,
ID3FID_CRYPTOREG,
ID3FID_GROUPINGREG,
ID3FID_SIGNATURE,
ID3FID_MCDI,
ID3FID_BPM,
ID3FID_KEY,
ID3FID_MOOD,
ID3FID_ISRC,
ID3FID_RECORDINGTIME,
ID3FID_COMPILATION,
ID3FID_ALBUMSORT,
ID3FID_ALBUMARTISTSORT,
ID3FID_PERFORMERSORT,
ID3FID_COMPOSERSORT,
ID3FID_TITLESORT,
ID3FID_REPLAYGAIN,
ID3FID_VOLUMEADJ,
ID3FID_INVOLVEDPEOPLE2,
ID3FID_CREDITS,
ID3FID_ENCODINGTIME,
ID3FID_FILEOWNER,
ID3FID_LENGTH,
ID3FID_ORIGYEAR,
ID3FID_ORIGRELEASETIME,
ID3FID_RELEASETIME,
ID3FID_SETSUBTITLE,
ID3FID_TAGGINGTIME,
ID3FID_PLAYLISTDELAY,
ID3FID_PODCAST,
ID3FID_PODCASTCATEGORY,
ID3FID_PODCASTDESC,
ID3FID_PODCASTID,
ID3FID_PODCASTURL,
};
enum ID3_VerCtl
{
ID3VC_HIGHER = 0,
ID3VC_LOWER
};
struct ID3_FieldDef
{
ID3_FieldID id;
ID3_FieldType type;
lsint fixedLength;
uchar version;
uchar revision;
ID3_VerCtl control;
luint flags;
ID3_FieldID linkedField;
};
class ID3_Frame;
// TODO: add minimum/maximum version & revision
struct ID3_FrameDef
{
ID3_FrameID id;
char *shortTextID;
char *longTextID;
bool tagDiscard;
bool fileDiscard;
bool (*parseHandler)(ID3_Frame *frame);
ID3_FieldDef *fieldDefs;
};
class ID3_Field
{
public:
ID3_Field(void);
~ID3_Field(void);
void Clear(void);
luint Size(void);
luint GetNumTextItems(void);
// integer field functions
//ID3_Field& operator= (luint newData);
void Set(luint newData);
luint Get(void);
// Unicode string field functions
//ID3_Field& operator= (wchar_t *string);
void SetUnicode(const wchar_t *string);
luint GetUnicode(wchar_t *buffer, luint maxChars, luint itemNum = 1);
void AddUnicode(const wchar_t *string);
// ASCII string field functions
//ID3_Field& operator= (char *string);
void SetLatin(const char *string);
void SetLocal(const char *string);
void SetUTF8(const char *string);
luint GetLocal(char *buffer, luint maxChars, luint itemNum = 1);
luint GetLatin(char *buffer, luint maxChars, luint itemNum = 1);
void AddLocal(const char *string);
void AddLatin(const char *string);
// binary field functions
void Set(uchar *newData, luint newSize);
void Get(uchar *buffer, luint buffLength);
// *** PRIVATE INTERNAL DATA - DO NOT USE *** PRIVATE INTERNAL DATA - DO NOT USE ***
luint BinSize(bool withExtras = true);
bool HasChanged(void);
void SetVersion(uchar ver, uchar rev);
luint Render(uchar *buffer);
luint Parse(uchar *buffer, luint posn, luint buffSize);
ID3_FieldID name; // the ID of this field
ID3_FieldType type; // what type is this field or should be
lsint fixedLength; // if this is positive, the length of the field is fixed
uchar ioVersion; // specific version
uchar ioRevision; // specific revision
ID3_VerCtl control; // render if ver/rev is higher, or lower than frame::version, frame::revision?
luint flags; // special field flags
uchar version; // the version being rendered/parsed
uchar revision; // the revision being rendered/parsed
bool hasChanged; // has the field changed since the last parse/render?
protected:
luint RenderInteger (uchar *buffer);
luint RenderLatinString(uchar *buffer);
luint RenderUnicodeString (uchar *buffer);
luint RenderUTF8String(uchar *buffer);
luint RenderBinary (uchar *buffer);
luint ParseInteger (uchar *buffer, luint posn, luint buffSize);
luint ParseASCIIString (uchar *buffer, luint posn, luint buffSize);
luint ParseUnicodeString (uchar *buffer, luint posn, luint buffSize);
luint ParseUTF8String(uchar *buffer, luint posn, luint buffSize);
luint ParseBinary (uchar *buffer, luint posn, luint buffSize);
uchar *data;
luint size;
};
ID3_FrameDef *ID3_FindFrameDef (ID3_FrameID id);
ID3_FrameID ID3_FindFrameID(const char *id);
#endif

View File

@ -0,0 +1,83 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
// improved/optimized/whatever 10/30/00 JF
#include <windows.h>
#include <stdio.h>
#include <memory.h>
#include "id3_field.h"
void ID3_Field::Set(uchar *newData, luint newSize)
{
Clear();
if (newSize)
{
if (newSize == 4294967295/*-1*/)
{
ID3_THROW(ID3E_NoMemory);
return;
}
if (!(data = (unsigned char *)calloc(newSize, sizeof(unsigned char))))
{
ID3_THROW(ID3E_NoMemory);
}
else
{
memcpy (data, newData, newSize);
size = newSize;
type = ID3FTY_BINARY;
hasChanged = true;
}
}
return;
}
void ID3_Field::Get(uchar *buffer, luint buffLength)
{
if (data && size && buffLength && buffer)
{
luint actualBytes = MIN(buffLength, size);
memcpy(buffer, data, actualBytes);
}
}
luint ID3_Field::ParseBinary (uchar *buffer, luint posn, luint buffSize)
{
luint bytesUsed = 0;
bytesUsed = buffSize - posn;
if (fixedLength != -1)
bytesUsed = MIN (fixedLength, bytesUsed);
Set(&buffer[ posn ], bytesUsed);
hasChanged = false;
return bytesUsed;
}
luint ID3_Field::RenderBinary (uchar *buffer)
{
luint bytesUsed = 0;
bytesUsed = BinSize();
memcpy(buffer, data, bytesUsed);
hasChanged = false;
return bytesUsed;
}

View File

@ -0,0 +1,81 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
// improved/optimized/whatever 10/30/00 JF
// improved/optimized/whatEVER jan-08-2006 benski
#include "id3_field.h"
#if 0 // taking out operators
ID3_Field& ID3_Field::operator=(luint newData)
{
Set(newData);
return *this;
}
#endif
void ID3_Field::Set(luint newData)
{
Clear();
data = reinterpret_cast<uchar *>(newData);
size = sizeof(luint);
type = ID3FTY_INTEGER;
hasChanged = true;
}
luint ID3_Field::Get(void)
{
return (luint) data;
}
luint ID3_Field::ParseInteger(uchar *buffer, luint posn, luint buffSize)
{
luint bytesUsed = 0;
if(buffer && buffSize)
{
luint i;
luint temp = 0;
bytesUsed = 4;
if(fixedLength != -1)
bytesUsed = MIN(fixedLength, bytesUsed);
for(i = 0; i < bytesUsed; i++)
temp |=(buffer[ posn + i ] <<(((bytesUsed - i) - 1) * 8));
Set(temp);
hasChanged = false;
}
return bytesUsed;
}
luint ID3_Field::RenderInteger(uchar *buffer)
{
luint bytesUsed = 0;
luint length = BinSize();
for(luint i = 0; i < length; i++)
buffer[ i ] = (uchar)((((luint) data) >>(((length - i) - 1) * 8)) & 0xFF);
bytesUsed = length;
hasChanged = false;
return bytesUsed;
}

View File

@ -0,0 +1,239 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
// improved/optimized/whatever 10/30/00 JF
// improved/optimized/whatEVER jan-08-2006 benski
#include <stdlib.h>
#include "id3_field.h"
#include "id3_misc_support.h"
#include "../nu/AutoWide.h"
#include "../Plugins/Input/in_mp3/config.h" // TODO: cut
// the ::Set() function for ASCII
void ID3_Field::SetLocal(const char *newString)
{
if (newString)
{
Clear();
AutoWide temp(newString);
SetUnicode(temp);
if (!(flags & ID3FF_ADJUSTENC))
type = ID3FTY_ASCIISTRING;
}
}
void ID3_Field::SetLatin(const char *newString)
{
if (newString)
{
Clear();
AutoWide temp(newString, 28591); // ISO-8859-1 code page
SetUnicode(temp);
type = ID3FTY_ASCIISTRING;
}
return;
}
void ID3_Field::SetUTF8(const char *newString)
{
if (newString)
{
Clear();
AutoWide temp(newString, CP_UTF8);
SetUnicode(temp);
}
return;
}
// the ::Get() function for ASCII
luint ID3_Field::GetLocal(char *buffer, luint maxLength, luint itemNum)
{
luint bytesUsed = 0;
wchar_t *temp;
if (temp = (wchar_t*)calloc(maxLength, sizeof(wchar_t)))
{
if (GetUnicode(temp, maxLength, itemNum))
{
bytesUsed = ID3_UnicodeToLocal(buffer, temp, maxLength);
}
free(temp);
}
else
ID3_THROW (ID3E_NoMemory);
return bytesUsed;
}
void ID3_Field::AddLocal(const char *newString)
{
if (newString)
{
AutoWide temp(newString);
AddUnicode(temp);
}
}
void ID3_Field::AddLatin(const char *newString)
{
if (newString)
{
AutoWide temp(newString, 28591);
AddUnicode(temp);
type = ID3FTY_ASCIISTRING;
}
}
luint ID3_Field::ParseASCIIString(uchar *buffer, luint posn, luint buffSize)
{
luint bytesUsed = 0;
if (fixedLength != -1)
bytesUsed = fixedLength;
else
{
if (flags & ID3FF_NULL)
while ((posn + bytesUsed) < buffSize && buffer[posn + bytesUsed] != 0)
bytesUsed++;
else
bytesUsed = buffSize - posn;
}
if (bytesUsed > 0xffff) // keep it sane, yo (64kb string max should be good)
{
hasChanged=false;
return 0;
}
if (bytesUsed)
{
char *temp = NULL;
if (temp = (char*)calloc(bytesUsed + 1, sizeof(char)))
{
memcpy(temp, &buffer[posn], bytesUsed);
temp[bytesUsed] = 0;
if (config_read_mode == READ_LOCAL) // benski> I added a config option to deal with old tags
SetLocal(temp);
else
SetLatin(temp);
if (!(flags & ID3FF_ADJUSTENC))
type = ID3FTY_ASCIISTRING;
free(temp);
}
else
ID3_THROW (ID3E_NoMemory);
}
if (flags & ID3FF_NULL)
bytesUsed++;
hasChanged = false;
return bytesUsed;
}
luint ID3_Field::ParseUTF8String(uchar *buffer, luint posn, luint buffSize)
{
luint bytesUsed = 0;
if (fixedLength != -1)
bytesUsed = fixedLength;
else
{
if (flags & ID3FF_NULL)
while ((posn + bytesUsed) < buffSize && buffer[posn + bytesUsed] != 0)
bytesUsed++;
else
bytesUsed = buffSize - posn;
}
if (bytesUsed > 0xffff) // keep it sane, yo (64kb string max should be good)
{
hasChanged=false;
return 0;
}
if (bytesUsed)
{
char *temp = NULL;
if (temp = (char*)calloc(bytesUsed + 1, sizeof(char)))
{
memcpy (temp, &buffer[posn], bytesUsed);
temp[bytesUsed] = 0;
SetUTF8(temp);
free(temp);
}
else
ID3_THROW (ID3E_NoMemory);
}
if (flags & ID3FF_NULL)
bytesUsed++;
hasChanged = false;
return bytesUsed;
}
luint ID3_Field::RenderLatinString(uchar *buffer)
{
luint bytesUsed = 0;
buffer[0] = 0;
bytesUsed = BinSize();
if (data && size)
{
luint i;
// benski> I added a config option for whether to use "broken" local system encoding mode
if (config_write_mode == WRITE_LATIN)
ID3_UnicodeToLatin( (char*)buffer, (const wchar_t *) data, bytesUsed, (int)bytesUsed);
else
ID3_UnicodeToLocal( (char*)buffer, (const wchar_t *) data, bytesUsed, bytesUsed);
for (i = 0;i < bytesUsed; i++)
{
if (buffer[i] == 1)
{
char sub = '/';
if (flags & ID3FF_NULLDIVIDE)
sub = '\0';
buffer[i] = sub;
}
}
}
if (bytesUsed == 1 && flags & ID3FF_NULL)
buffer[0] = 0;
hasChanged = false;
return bytesUsed;
}

View File

@ -0,0 +1,338 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
// improved/optimized/whatever 10/30/00 JF
// improved/optimized/whatEVER jan-08-2006 benski
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include "id3_field.h"
#include <windows.h>
#include "../Plugins/Input/in_mp3/config.h" // TODO: cut
#include "id3_misc_support.h"
// this function is another way of using Set()
#if 0
ID3_Field &ID3_Field::operator=(wchar_t *string)
{
Set(string);
return *this;
}
#endif
// this is Set()
void ID3_Field::SetUnicode(const wchar_t *string)
{
luint bytesUsed = lstrlenW(string);
// we can simply increment the
// bytesUsed count here because
// we just pilfer the NULL which is
// present in the string which was
// passed to us
if (flags & ID3FF_NULL)
bytesUsed++;
// doubling the bytesUsed because
// Unicode is twice the size of ASCII
bytesUsed *= sizeof (wchar_t);
Set ((uchar *) string, bytesUsed);
type = ID3FTY_UNICODESTRING;
hasChanged = true;
}
void ID3_Field::AddUnicode(const wchar_t *string)
{
if (!data)
SetUnicode(string);
else
{
wchar_t *temp;
luint newLen;
lsint nullOffset = 0;
// if there is a NULL in this string, set this offset
// so that we ignore it in string size calculations
if (flags & ID3FF_NULL)
nullOffset = -1;
// +1 is for the NULL at the end and the
// other +1 is for the list divider
newLen = 1 + (size / sizeof (wchar_t)) + lstrlenW(string) + 1 + nullOffset;
// I use the value 1 as a divider because then I
// can change it to either a '/' or a NULL at render
// time. This allows easy use of these functions
// for text lists or in the IPLS frame
if (temp = (wchar_t*)calloc(newLen, sizeof(wchar_t)))
{
lstrcpyW(temp, (wchar_t *) data);
temp[(size / sizeof (wchar_t)) + nullOffset] = L'\001';
lstrcpyW (&temp[(size / sizeof (wchar_t)) + 1 + nullOffset], string);
SetUnicode(temp);
free(temp);
}
else
ID3_THROW (ID3E_NoMemory);
}
return;
}
// this is Get()
luint ID3_Field::GetUnicode(wchar_t *buffer, luint maxChars, luint itemNum)
{
luint charsUsed = 0;
// check to see if there is a string in the frame
// to copy before we even try
if (data)
{
lsint nullOffset = 0;
if (flags & ID3FF_NULL)
nullOffset = -1;
// first we must find which element
// is being sought to make sure it
// exists before we try to get it
if (itemNum <= GetNumTextItems() && itemNum > 0)
{
wchar_t *source = (wchar_t *) data;
luint posn = 0;
luint sourceLen = 0;
luint curItemNum = 1;
luint mx= (size / sizeof (wchar_t)) + nullOffset;
// now we find that element and set the souvre pointer
while (posn<mx && curItemNum < itemNum)
{
while (posn<mx && *source != L'\001' && *source != L'\0')
{
source++;
posn++;
}
source++;
posn++;
curItemNum++;
}
if(posn>=mx) return 0;
// now that we are positioned at the first character
// of the string we want, find the end of it
while (posn<mx && source[sourceLen] != L'\001' && source[sourceLen] != L'\0')
{
sourceLen++;
posn++;
}
if (maxChars) // JF
{
// we subtract 1 here so we have
// room for the NULL terminator
//maxChars--; // CT
if (buffer)
{
luint actualChars = MIN (maxChars-1, sourceLen);
wcsncpy (buffer, source, actualChars);
buffer[actualChars] = L'\0';
charsUsed = actualChars;
}
else
ID3_THROW (ID3E_NoBuffer);
}
}
}
return charsUsed;
}
luint ID3_Field::GetNumTextItems (void)
{
luint numItems = 0;
if (data)
{
luint posn = 0;
numItems++;
while (posn < size)
if (data[posn++] == L'\001')
numItems++;
}
return numItems;
}
luint ID3_Field::ParseUnicodeString (uchar *buffer, luint posn, luint buffSize)
{
luint bytesUsed = 0;
wchar_t *temp = NULL;
if (fixedLength != -1)
bytesUsed = fixedLength;
else
{
if (flags & ID3FF_NULL)
while ((posn + bytesUsed) < buffSize &&
! (buffer[posn + bytesUsed] == 0 && buffer[posn + bytesUsed + 1] == 0))
bytesUsed += 2;
else
bytesUsed = buffSize - posn;
}
if (bytesUsed > 0x8ffff)
{
hasChanged = false;
return 0;
}
if (bytesUsed)
{
if (temp = (wchar_t*)calloc(((bytesUsed / sizeof (wchar_t)) + 1), sizeof(wchar_t)))
{
luint loc = 0;
memcpy (temp, &buffer[posn], bytesUsed);
temp[bytesUsed / sizeof (wchar_t)] = 0;
// if there is a BOM, skip past it and check to see if we
// need to swap the byte order around
if (temp[0] == 0xFEFF || temp[0] == 0xFFFE)
{
loc++;
// if we need to swap the byte order
if (temp[0] != 0xFEFF)
{
int mylen=(int) lstrlenW(temp);
for (int i = loc; i < mylen; i++)
temp[i] = ((temp[i] >> 8) & 0xFF) | (((temp[i]) & 0xFF) << 8);
}
}
SetUnicode(&temp[loc]);
free(temp);
}
else
ID3_THROW (ID3E_NoMemory);
}
if (flags & ID3FF_NULL)
bytesUsed += 2;
hasChanged = false;
return bytesUsed;
}
luint ID3_Field::RenderUnicodeString(uchar *buffer)
{
luint bytesUsed = 0;
bytesUsed = BinSize();
if (data && size && bytesUsed >= sizeof (wchar_t))
{
wchar_t *ourString = (wchar_t *) &buffer[sizeof(wchar_t)];
// we render at sizeof (wchar_t) bytes into the buffer
// because we make room for the Unicode BOM
memcpy (&buffer[sizeof (wchar_t)], (uchar *) data, bytesUsed - sizeof (wchar_t));
// now we convert the internal dividers to what they
// are supposed to be
size_t numChars = bytesUsed / sizeof (wchar_t);
for (size_t i = 0; i != numChars-1; i++)
if (ourString[i] == 1)
{
wchar_t sub = L'/';
if (flags & ID3FF_NULLDIVIDE)
sub = L'\0';
ourString[i] = sub;
}
}
if (bytesUsed)
{
// render the BOM
wchar_t *BOM = (wchar_t *) buffer;
BOM[0] = 0xFEFF;
}
if (bytesUsed == 2 && (flags & ID3FF_NULL))
buffer[0] = buffer[1] = 0;
hasChanged = false;
return bytesUsed;
}
luint ID3_Field::RenderUTF8String(uchar *buffer)
{
luint bytesUsed = 0;
buffer[0] = 0;
bytesUsed = BinSize();
if (data && size)
{
luint i;
ID3_UnicodeToUTF8( (char*)buffer, (const wchar_t *) data, bytesUsed, bytesUsed);
for (i = 0;i < bytesUsed; i++)
{
if (buffer[i] == 1)
{
char sub = '/';
if (flags & ID3FF_NULLDIVIDE)
sub = '\0';
buffer[i] = sub;
}
}
}
if (bytesUsed == 1 && flags & ID3FF_NULL)
buffer[0] = 0;
hasChanged = false;
return bytesUsed;
}

273
Src/id3v2/id3_frame.cpp Normal file
View File

@ -0,0 +1,273 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
// improved/optimized/whatever 10/30/00 JF
#include <string.h>
#include "id3_tag.h"
ID3_Frame::ID3_Frame(ID3_FrameID id)
{
luint lwordsForFields = 0;
version = ID3_TAGVERSION;
revision = ID3_TAGREVISION;
numFields = 0;
fields = NULL;
groupingID[0] = 0;
encryptionID[0] = 0;
compression = false;
lwordsForFields = (((luint) ID3FN_LASTFIELDID) - 1) / (sizeof (luint) * 8);
if ((((luint) ID3FN_LASTFIELDID) - 1) % (sizeof (luint) * 8) != 0)
lwordsForFields++;
if (fieldBits = (bitset)calloc(lwordsForFields, sizeof(*fieldBits)))
{
for (luint i = 0; i < lwordsForFields; i++)
fieldBits[i] = 0;
}
else
ID3_THROW (ID3E_NoMemory);
SetID (id);
}
ID3_Frame::~ID3_Frame (void)
{
Clear();
if (fieldBits)
free(fieldBits);
}
void ID3_Frame::Clear (void)
{
if (numFields && fields)
{
for (luint i = 0; i < numFields; i++)
delete fields[i];
free(fields);
fields = NULL;
numFields = 0;
hasChanged = true;
}
return ;
}
void ID3_Frame::SetID (ID3_FrameID id)
{
ID3_FrameDef *info;
Clear();
if (id != ID3FID_NOFRAME)
{
if (info = ID3_FindFrameDef (id))
{
frameID = id;
numFields = 0;
while (info->fieldDefs[numFields].id != ID3FN_NOFIELD)
numFields++;
if ((fields = (ID3_Field **)calloc(numFields, sizeof(ID3_Field*))) == NULL)
ID3_THROW (ID3E_NoMemory);
else
{
for (luint i = 0; i < numFields; i++)
{
if ((fields[i] = new ID3_Field) == NULL)
ID3_THROW (ID3E_NoMemory);
else
{
fields[i]->name = info->fieldDefs[i].id;
fields[i]->type = info->fieldDefs[i].type;
fields[i]->fixedLength = info->fieldDefs[i].fixedLength;
fields[i]->ioVersion = info->fieldDefs[i].version;
fields[i]->ioRevision = info->fieldDefs[i].revision;
fields[i]->control = info->fieldDefs[i].control;
fields[i]->flags = info->fieldDefs[i].flags;
// tell the frame that this field is present
BS_SET (fieldBits, fields[i]->name);
}
}
hasChanged = true;
}
}
else
ID3_THROW (ID3E_InvalidFrameID);
}
return ;
}
ID3_FrameID ID3_Frame::GetID (void)
{
return frameID;
}
void ID3_Frame::SetVersion (uchar ver, uchar rev)
{
if (version != ver || revision != rev)
hasChanged = true;
version = ver;
revision = rev;
return ;
}
lsint ID3_Frame::FindField (ID3_FieldID fieldName)
{
if (BS_ISSET (fieldBits, fieldName))
{
lsint num = 0;
while (num < (lsint) numFields)
{
if (fields[num]->name == fieldName) return num;
num++;
}
return -1;
}
return 0;
}
ID3_Field& ID3_Frame::Field (ID3_FieldID fieldName)
{
luint fieldNum = FindField (fieldName);
if (fieldNum == -1)
ID3_THROW (ID3E_FieldNotFound);
return *fields[fieldNum];
}
void ID3_Frame::UpdateFieldDeps (void)
{
for (luint i = 0; i < numFields; i++)
{
if (fields[i]->flags & ID3FF_ADJUSTEDBY)
{
switch (fields[i]->type)
{
case ID3FTY_BITFIELD:
{
//luint value = 0;
// now find the field on which this
// field is dependent and get a copy
// of the value of that field.
// then adjust the fixedLength of this
// field to that value / 8.
}
break;
}
}
}
return ;
}
void ID3_Frame::UpdateStringTypes(void)
{
for (luint i = 0; i < numFields; i++)
{
if (fields[i]->flags & ID3FF_ADJUSTENC)
{
ID3_TextEnc enc;
ID3_FieldType newType;
enc = (ID3_TextEnc) Field(ID3FN_TEXTENC).Get();
switch (enc)
{
case ID3TE_ASCII:
newType = ID3FTY_ASCIISTRING;
break;
case ID3TE_UNICODE:
newType = ID3FTY_UNICODESTRING;
break;
case ID3TE_UTF8:
newType = ID3FTY_UTF8STRING;
break;
default:
newType = ID3FTY_ASCIISTRING;
break;
}
fields[i]->type = newType;
}
}
}
luint ID3_Frame::Size(void)
{
luint bytesUsed = 0;
ID3_FrameHeader header;
header.SetVersion (version, revision);
bytesUsed = header.Size();
if (strlen (encryptionID))
bytesUsed++;
if (strlen (groupingID))
bytesUsed++;
// this call is to tell the string fields
// what they should be rendered/parsed as
// (ASCII or Unicode)
UpdateStringTypes();
for (luint i = 0; i < numFields; i++)
{
fields[i]->SetVersion (version, revision);
bytesUsed += fields[i]->BinSize();
}
return bytesUsed;
}
bool ID3_Frame::HasChanged (void)
{
if (hasChanged) return hasChanged;
for (luint i = 0; i < numFields; i++)
{
bool changed = fields[i]->HasChanged();
if (changed) return changed;
}
return 0;
}

55
Src/id3v2/id3_frame.h Normal file
View File

@ -0,0 +1,55 @@
// The authors have released ID3Lib as Public Domain(PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney(dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#pragma once
#include "id3_types.h"
#include "id3_field.h"
#include "id3_header_frame.h"
class ID3_Frame
{
public:
ID3_Frame(ID3_FrameID id = ID3FID_NOFRAME);
~ID3_Frame(void);
void Clear(void);
void SetID(ID3_FrameID id);
ID3_FrameID GetID(void);
ID3_Field& Field(ID3_FieldID name);
// *** PRIVATE INTERNAL DATA - DO NOT USE *** PRIVATE INTERNAL DATA - DO NOT USE ***
bool HasChanged(void);
void SetVersion(uchar ver, uchar rev);
void Parse(uchar *buffer, luint size);
luint Size(void);
luint Render(uchar *buffer);
char encryptionID[256]; // the encryption method with which this frame is encrypted
char groupingID[256]; // the group to which this frame belongs
bool compression; // should we try to compress?
bool hasChanged; // has the frame changed since the last parse/render?
bitset fieldBits; // which fields are present?
ID3_FrameID frameID; // what frame are we?
protected:
void UpdateStringTypes(void);
void UpdateFieldDeps(void);
lsint FindField(ID3_FieldID name);
uchar version; // what version tag?
uchar revision; // what revision tag?
luint numFields; // how many fields are in this frame?
ID3_Field **fields; // an array of field object pointers
};

View File

@ -0,0 +1,40 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include "id3_frame.h"
void ID3_Frame::Parse(uchar *buffer, luint size)
{
luint i;
luint posn = 0;
for (i = 0; i < numFields; i++)
{
fields[i]->SetVersion (version, revision);
posn += fields[i]->Parse (buffer, posn, size);
// if we just parsed a TEXTENC field, we'd
// better tell the rest of the concerned string
// fields in the frame what they are expected to
// parse (ASCII or Unicode)
if (fields[i]->name == ID3FN_TEXTENC)
UpdateStringTypes();
}
hasChanged = false;
return;
}

View File

@ -0,0 +1,178 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
// improved/optimized/whatever 10/30/00 JF
#include <string.h>
#include <memory.h>
#include "id3_tag.h"
#include "id3_misc_support.h"
luint ID3_Frame::Render (uchar *buffer)
{
luint bytesUsed = 0;
ID3_FrameHeader header;
ID3_FrameDef *info;
luint flags;
luint extras = 0;
header.SetVersion (version, revision);
bytesUsed += header.Size();
// here is where we include things like
// grouping IDs and crypto IDs
if (strlen (encryptionID))
{
buffer[bytesUsed] = encryptionID[0];
bytesUsed++, extras++;
}
if (strlen (groupingID))
{
buffer[bytesUsed] = groupingID[0];
bytesUsed++, extras++;
}
/*
if (version < 4)
{
// benski> set any UTF8 strings read from id3v2.4 to UTF-16,
// so we can write with id3v2.3
for (luint i = 0; i < numFields; i++)
{
if (fields[i]->flags & ID3FF_ADJUSTENC)
{
ID3_TextEnc enc= (ID3_TextEnc) Field(ID3FN_TEXTENC).Get();
if (enc == ID3TE_UTF8 || enc == ID3TE_UTF16_BE)
Field(ID3FN_TEXTENC).Set(ID3TE_UNICODE);
}
}
}
*/
// this call is to tell the string fields
// what they should be rendered/parsed as
// (ASCII or Unicode)
UpdateStringTypes();
for (luint i = 0; i < numFields; i++)
{
fields[i]->SetVersion (version, revision);
bytesUsed += fields[i]->Render (&buffer[bytesUsed]);
}
// if we can compress frames individually and we
// have been asked to compress the frames
/*
if (compression && version >= 3)
{
luint newFrameSize;
uchar *newTemp;
bytesUsed -= header.Size();
newFrameSize = bytesUsed + (bytesUsed / 10) + 12;
if (newTemp = new uchar[newFrameSize])
{
if (compress (newTemp, &newFrameSize, &buffer[header.Size() + extras], bytesUsed - extras) == Z_OK)
{
// if the compression actually saves space
if ((newFrameSize + sizeof (luint)) < bytesUsed)
{
luint posn;
int i;
posn = header.Size();
extras += sizeof (luint);
memcpy (&buffer[posn + sizeof (luint)], newTemp, newFrameSize);
for (i = 0; i < sizeof (luint); i++)
buffer[posn + i] = (uchar) ((bytesUsed >> ((sizeof (luint) - i - 1) * 8)) & 0xFF);
bytesUsed = newFrameSize + sizeof (luint);
didCompress = true;
}
}
else
ID3_THROW (ID3E_zlibError);
bytesUsed += header.Size();
delete[] newTemp;
}
else
ID3_THROW (ID3E_NoMemory);
}
*/
// perform any encryption here
/* if (strlen (encryptionID))
{
}*/
// determine which flags need to be set
if (info = ID3_FindFrameDef (frameID))
{
bool didCompress = false;
flags = 0;
if (version == 4)
{
if (info->tagDiscard)
flags |= ID3FL_TAGALTER_2_4;
if (info->fileDiscard)
flags |= ID3FL_FILEALTER_2_4;
if (didCompress)
flags |= ID3FL_COMPRESSION_2_4;
if (strlen (encryptionID))
flags |= ID3FL_ENCRYPTION_2_4;
if (strlen (groupingID))
flags |= ID3FL_GROUPING_2_4;
}
else
{
if (info->tagDiscard)
flags |= ID3FL_TAGALTER_2_3;
if (info->fileDiscard)
flags |= ID3FL_FILEALTER_2_3;
if (didCompress)
flags |= ID3FL_COMPRESSION_2_3;
if (strlen (encryptionID))
flags |= ID3FL_ENCRYPTION_2_3;
if (strlen (groupingID))
flags |= ID3FL_GROUPING_2_3;
}
}
else
ID3_THROW (ID3E_InvalidFrameID);
header.SetFrameID(frameID);
header.SetFlags(flags);
header.SetDataSize(bytesUsed - header.Size());
header.Render(buffer);
hasChanged = false;
return bytesUsed;
}

98
Src/id3v2/id3_header.cpp Normal file
View File

@ -0,0 +1,98 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include <string.h>
#include <memory.h>
#include "id3_header.h"
#include "id3_error.h"
static ID3_HeaderInfo ID3_VersionInfo[4][3] =
{
// SIZEOF SIZEOF SIZEOF EXT EXT EXPERIM
// VER REV FRID FRSZ FRFL HEADER SIZE BIT
{
{ 2, 0, 3, 3, 0, false, 0, false },
{ 2, 1, 3, 3, 0, true, 8, true },
{0,},
},
{
{ 3, 0, 4, 4, 2, false, 10, false },
{0,},
},
{
{ 4, 0, 4, 4, 2, false, 10, false },
{0,},
},
{ 0 }
};
ID3_HeaderInfo *ID3_LookupHeaderInfo(uchar ver, uchar rev)
{
ID3_HeaderInfo *info = NULL;
size_t v=0,r=0;
while (ID3_VersionInfo[v][0].version != 0)
{
r=0;
if (ID3_VersionInfo[v][0].version == ver)
{
while (ID3_VersionInfo[v][r].version != 0)
{
if (ID3_VersionInfo[v][r].revision == rev)
{
goto found;
}
else
r++;
}
// later revision. still backwards compat so we'll stick with it.
r--;
goto found;
}
else
v++;
}
found:
if (ID3_VersionInfo[v][r].version != 0)
info = &ID3_VersionInfo[v][r];
return info;
}
ID3_Header::ID3_Header(void)
{
SetVersion(ID3_TAGVERSION, ID3_TAGREVISION);
dataSize = 0;
flags = 0;
}
void ID3_Header::SetVersion(uchar ver, uchar rev)
{
version = ver;
revision = rev;
info = ID3_LookupHeaderInfo(version, revision);
}
void ID3_Header::SetDataSize(luint newSize)
{
dataSize = newSize;
}
void ID3_Header::SetFlags(luint newFlags)
{
flags = newFlags;
}

80
Src/id3v2/id3_header.h Normal file
View File

@ -0,0 +1,80 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_HEADER_H
#define ID3LIB_HEADER_H
#include "id3_types.h"
#define MIN_ID3_TAGVERSION 2
#define MAX_ID3_TAGVERSION 4
#define ID3_TAGVERSION (3)
#define ID3_TAGREVISION (0)
struct ID3_HeaderInfo
{
unsigned __int8 version;
unsigned __int8 revision;
unsigned __int8 frameIDBytes;
unsigned __int8 frameSizeBytes;
unsigned __int8 frameFlagsBytes;
bool hasExtHeader;
luint extHeaderBytes;
bool setExpBit;
};
struct ID3_Quirks
{
ID3_Quirks() : id3v2_4_itunes_bug(false) {}
bool id3v2_4_itunes_bug; // itunes doesn't write syncsafe values for 2.4
};
class ID3_Header
{
public:
ID3_Header (void);
void SetVersion(uchar ver, uchar rev);
void SetDataSize(luint newSize);
void SetFlags(luint newFlags);
void SetQuirks(ID3_Quirks &_quirks)
{
quirks=_quirks;
}
ID3_Quirks &GetQuirks()
{
return quirks;
}
virtual luint Size(void) = 0;
virtual luint Render(unsigned __int8 *buffer) = 0;
// *** PRIVATE INTERNAL DATA - DO NOT USE *** PRIVATE INTERNAL DATA - DO NOT USE ***
protected:
unsigned __int8 version; // which version?
unsigned __int8 revision; // which revision?
luint dataSize; // how big is the data?
luint flags; // tag flags
ID3_HeaderInfo *info; // the info about this version of the headers
ID3_Quirks quirks;
};
ID3_HeaderInfo *ID3_LookupHeaderInfo (uchar ver, uchar rev);
#endif

View File

@ -0,0 +1,181 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include <string.h>
#include <memory.h>
#include "id3_header_frame.h"
#include "id3_error.h"
bool ID3_FrameAttr::HasDataLength(int version)
{
if (version == 4)
return !!(flags & ID3FL_DATA_LENGTH_2_4);
else
return 0;
}
bool ID3_FrameAttr::HasCompression(int version)
{
if (version == 4)
return !!(flags & ID3FL_COMPRESSION_2_4);
else
return !!(flags & ID3FL_COMPRESSION_2_3);
}
bool ID3_FrameAttr::HasEncryption(int version)
{
if (version == 4)
return !!(flags & ID3FL_ENCRYPTION_2_4);
else
return !!(flags & ID3FL_ENCRYPTION_2_3);
}
bool ID3_FrameAttr::HasGrouping(int version)
{
if (version == 4)
return !!(flags & ID3FL_GROUPING_2_4);
else
return !!(flags & ID3FL_GROUPING_2_3);
}
bool ID3_FrameAttr::HasUnsync(int version)
{
if (version == 4)
return !!(flags & ID3FL_UNSYNC_2_4);
else
return false;
}
void ID3_FrameAttr::ClearUnSync(int version)
{
if (version == 4)
flags&= ~ID3FL_UNSYNC_2_4;
}
void ID3_FrameAttr::SetFlags(luint _flags)
{
flags = _flags;
}
void ID3_FrameHeader::SetFrameID (ID3_FrameID id)
{
frameID = id;
}
luint ID3_FrameHeader::Size(void)
{
if (!info)
return 0;
return info->frameIDBytes + info->frameSizeBytes + info->frameFlagsBytes;
}
// TODO: benski> we should make a return value of 0 mean 'error'
luint ID3_FrameHeader::GetFrameInfo(ID3_FrameAttr &attr, const uchar *buffer, size_t remSize)
{
luint posn = 0;
luint i = 0, bpos = 4;
// verify that the text is all between A-Z and 0-9 (for TALB and TIT2, etc)
for (i = 0; i < 4; i++)
{
if (!((buffer[i] >= '0' && buffer[i] <= '9') || (buffer[i] >= 'A' && buffer[i] <= 'Z')))
{
// TODO: benski> return an error here
// this helps us to get ID3v2.2 PIC frames without
// breaking others since it's not null-terminated!
bpos = i;
}
}
memcpy(attr.textID, (char *) buffer, (bpos > 0 && bpos <= 4 ? bpos : 4));
if (bpos == 3) attr.textID[3] = 0;
attr.textID[4] = 0;
posn += info->frameIDBytes;
attr.size = 0;
for (i = 0; i < info->frameSizeBytes; i++)
attr.size |= buffer[posn + i] << ((info->frameSizeBytes - 1 - i) * 8);
if (version == 4) // 2.4 uses syncsafe sizes
{
// many programs write non-syncsafe sizes anyway (iTunes is the biggest culprit)
// so we'll try to detect it. unfortunately this isn't foolproof
int mask = attr.size & 0x80808080;
if (!quirks.id3v2_4_itunes_bug // make sure we've havn't previously identified that this tag has a problem
&& mask == 0) // if none of the 'reserved' bits are set
{
attr.size = int28().setFromFile(attr.size).get(); // convert to syncsafe value
}
else
{
// benski> cut for now. this can't be trusted because it applies on subsequent re-parses but not anything before this
// quirks.id3v2_4_itunes_bug = true; // mark that the tag has a problem
}
// TODO: it'd be nice to look ahead into the buffer and make sure that our calculated size
// lets us land on the start of a new frame
// although that isn't foolproof either (non-standard fields, etc)
}
posn += info->frameSizeBytes;
luint flags=0;
flags = 0;
for (i = 0; i < info->frameFlagsBytes; i++)
flags |= buffer[ posn + i ] << ((info->frameFlagsBytes - 1 - i) * 8);
attr.SetFlags(flags);
posn += info->frameFlagsBytes;
return posn;
}
luint ID3_FrameHeader::Render(uchar *buffer)
{
luint bytesUsed = 0;
ID3_FrameDef *frameDef = NULL;
char *textID = NULL;
luint i;
if (frameDef = ID3_FindFrameDef(frameID))
{
if (info->frameIDBytes < strlen (frameDef->longTextID))
textID = frameDef->shortTextID;
else
textID = frameDef->longTextID;
}
else
ID3_THROW (ID3E_InvalidFrameID);
memcpy (&buffer[ bytesUsed ], (uchar *) textID, info->frameIDBytes);
bytesUsed += info->frameIDBytes;
for (i = 0; i < info->frameSizeBytes; i++)
{
if (version==4) // 2.4 uses syncsafe sizes
buffer[ bytesUsed + i ] = (uchar) ((dataSize >> ((info->frameSizeBytes - i - 1) * 7)) & 0x7F);
else
buffer[ bytesUsed + i ] = (uchar) ((dataSize >> ((info->frameSizeBytes - i - 1) * 8)) & 0xFF);
}
bytesUsed += info->frameSizeBytes;
for (i = 0; i < info->frameFlagsBytes; i++)
buffer[ bytesUsed + i ] = (uchar) ((flags >> ((info->frameFlagsBytes - i - 1) * 8)) & 0xFF);
bytesUsed += info->frameFlagsBytes;
return bytesUsed;
}

View File

@ -0,0 +1,81 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_HEADER_FRAME_H
#define ID3LIB_HEADER_FRAME_H
#include "id3_types.h"
#include "id3_header.h"
#include "id3_header_tag.h"
#include "id3_field.h"
#define ID3FL_TAGALTER_2_3 (1 << 15)
#define ID3FL_FILEALTER_2_3 (1 << 14)
#define ID3FL_SIGNED_2_3 (1 << 13)
#define ID3FL_COMPRESSION_2_3 (1 << 7)
#define ID3FL_ENCRYPTION_2_3 (1 << 6)
#define ID3FL_GROUPING_2_3 (1 << 5)
#define ID3FL_TAGALTER_2_4 (1 << 14)
#define ID3FL_FILEALTER_2_4 (1 << 13)
#define ID3FL_SIGNED_2_4 (1 << 12)
#define ID3FL_COMPRESSION_2_4 (1 << 3)
#define ID3FL_ENCRYPTION_2_4 (1 << 2)
#define ID3FL_GROUPING_2_4 (1 << 6)
#define ID3FL_UNSYNC_2_4 (1 << 1)
#define ID3FL_DATA_LENGTH_2_4 (1 << 0)
struct ID3_FrameAttr
{
ID3_FrameAttr(void) : size(0), flags(0) { memset(&textID, 0, sizeof(textID)); }
~ID3_FrameAttr(void) {}
char textID[5];
luint size;
public:
void ClearUnSync(int version);
void SetFlags(luint _flags);
bool HasCompression(int version);
bool HasDataLength(int version);
bool HasEncryption(int version);
bool HasGrouping(int version);
bool HasUnsync(int version);
private:
luint flags;
};
class ID3_FrameHeader : public ID3_Header
{
public:
virtual luint Size(void);
void SetFrameID(ID3_FrameID id);
luint GetFrameInfo(ID3_FrameAttr &attr, const uchar *buffer, size_t remSize);
virtual luint Render(uchar *buffer);
// *** PRIVATE INTERNAL DATA - DO NOT USE *** PRIVATE INTERNAL DATA - DO NOT USE ***
protected:
ID3_FrameID frameID; // which frame are we the header for?
};
#endif

View File

@ -0,0 +1,86 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include <string.h>
#include <memory.h>
#include "id3_header_tag.h"
#include "id3_error.h"
// Analyses a buffer to determine if we have a valid ID3v2 tag header.
// If so, return the number of bytes (starting _after_ the header) to
// read so we get all of the tag
lsint ID3_IsTagHeader(uchar header[ID3_TAGHEADERSIZE])
{
if (!memcmp ("ID3", header, 3) && header[3] <= MAX_ID3_TAGVERSION)
{
int28 temp(&header[6]);
return (int)temp.get();
}
return -1;
}
luint ID3_TagHeader::Size(void)
{
luint bytesUsed = ID3_TAGHEADERSIZE;
if (info && info->hasExtHeader)
bytesUsed += info->extHeaderBytes + sizeof (luint);
return bytesUsed;
}
luint ID3_TagHeader::Render(uchar *buffer)
{
luint bytesUsed = 0;
memcpy (&buffer[bytesUsed], (uchar *) ID3_TAGID, strlen (ID3_TAGID));
bytesUsed += strlen (ID3_TAGID);
buffer[bytesUsed++] = version;
buffer[bytesUsed++] = revision;
// do the automatic flags
if (info->setExpBit)
flags |= ID3HF_EXPERIMENTAL;
if (info->hasExtHeader)
flags |= ID3HF_EXTENDEDHEADER;
// set the flags byte in the header
buffer[bytesUsed++] = (uchar) (flags & 0xFF);
int28 temp = (uint32_t)dataSize;
for (luint i = 0; i < sizeof (luint); i++)
buffer[bytesUsed++] = temp[i];
// now we render the extended header
if (info->hasExtHeader)
{
luint i;
for (i = 0; i < sizeof (luint); i++)
buffer[bytesUsed + i] = (uchar) ((info->extHeaderBytes >> ((sizeof (luint) - i - 1) * 8)) & 0xFF);
bytesUsed += i;
}
bytesUsed = Size();
return bytesUsed;
}

View File

@ -0,0 +1,48 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_HEADER_TAG_H
#define ID3LIB_HEADER_TAG_H
#include "id3_types.h"
#include "id3_header.h"
#define ID3_TAGID "ID3"
#define ID3_TAGHEADERSIZE (10)
#define ID3HF_UNSYNC (1 << 7)
#define ID3HF_EXTENDEDHEADER (1 << 6)
#define ID3HF_EXPERIMENTAL (1 << 5)
#define ID3HF_FOOTER (1 << 4) // id3v2.4
#define ID3HF_2_3_MASK (ID3HF_UNSYNC | ID3HF_EXTENDEDHEADER | ID3HF_EXPERIMENTAL)
#define ID3HF_2_4_MASK (ID3HF_UNSYNC | ID3HF_EXTENDEDHEADER | ID3HF_EXPERIMENTAL | ID3HF_FOOTER)
class ID3_TagHeader : public ID3_Header
{
public:
virtual luint Size(void);
virtual luint Render(uchar *buffer);
};
lsint ID3_IsTagHeader(uchar header[ID3_TAGHEADERSIZE]);
#endif

62
Src/id3v2/id3_int28.cpp Normal file
View File

@ -0,0 +1,62 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
// Mon Nov 23 18:34:01 1998
#include "id3_int28.h"
#include <bfc/platform/types.h>
int28::int28(uint32_t val)
{
set ( val );
}
int28::int28(const uchar *val)
{
for ( int i = 0; i < sizeof ( uint32_t ); i++ )
value[ i ] = val[ i ];
}
void int28::set(uint32_t val)
{
for ( int i = 0; i < sizeof ( uint32_t ); i++ )
value[ sizeof ( uint32_t ) - 1 - i ] = (uint8_t) ( ( val >> ( i * 7 ) ) & 127 ) & 0xFF;
return;
}
int28 &int28::setFromFile(uint32_t val)
{
for ( int i = 0; i < sizeof ( uint32_t ); i++ )
value[sizeof(uint32_t) - 1 - i] = (uint8_t) (val >>(i*8)) & 0xFF;
return *this;
}
luint int28::get ( void )
{
luint newSize = 0L;
uchar bytes [ 4 ];
bytes[ 3 ] = value[ 3 ] | ( ( value[ 2 ] & 1 ) << 7 );
bytes[ 2 ] = ( ( value[ 2 ] >> 1 ) & 63 ) | ( ( value[ 1 ] & 3 ) << 6 );
bytes[ 1 ] = ( ( value[ 1 ] >> 2 ) & 31 ) | ( ( value[ 0 ] & 7 ) << 5 );
bytes[ 0 ] = ( ( value[ 0 ] >> 3 ) & 15 );
newSize = bytes[ 3 ] | ( (luint) bytes[ 2 ] << 8 ) | ( (luint) bytes[ 1 ] << 16 ) | ( (luint) bytes[ 0 ] << 24 );
return newSize;
}
uchar int28::operator[] ( luint posn )
{
return value[ posn ];
}

41
Src/id3v2/id3_int28.h Normal file
View File

@ -0,0 +1,41 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_TYPES_28BITINT_H
#define ID3LIB_TYPES_28BITINT_H
#include "id3_types.h"
class int28
{
public:
int28( uint32_t val = 0 ); // used for int32 -> int28 conversion
int28( const uchar *val ); // used for int28 -> int32 conversion
int28 &setFromFile(uint32_t val); // used for int28 -> int32 conversion
uchar operator[] ( size_t posn );
luint get ( void );
// *** PRIVATE INTERNAL DATA - DO NOT USE *** PRIVATE INTERNAL DATA - DO NOT USE ***
protected:
void set ( uint32_t val );
uchar value[ sizeof ( luint ) ]; // the integer stored as a uchar array
};
#endif

View File

@ -0,0 +1,175 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include "id3_misc_support.h"
int ID3_UnicodeToLatin(char *latin, const wchar_t *unicode, luint len, int inLen)
{
if (unicode && latin && len)
return WideCharToMultiByte(28591, 0, unicode, inLen/*-1*/, latin, len, NULL, NULL) - 1;
else if (latin && len)
latin[0]=0;
return 0;
}
int ID3_UnicodeToLocal(char *local, const wchar_t *unicode, luint len, int inLen)
{
if (unicode && local && len)
return WideCharToMultiByte(CP_ACP, 0, unicode, inLen/*-1*/, local, len, NULL, NULL)-1;
else if (local && len)
local[0]=0;
return 0;
}
int ID3_UnicodeToUTF8(char *local, const wchar_t *unicode, luint len, int inLen)
{
if (unicode && local && len)
return WideCharToMultiByte(CP_UTF8, 0, unicode, inLen/*-1*/, local, len, NULL, NULL)-1;
else if (local && len)
local[0]=0;
return 0;
}
void ID3_AddArtist(ID3_Tag *tag, char *text)
{
if (tag->Find(ID3FID_LEADARTIST ) == NULL &&
tag->Find (ID3FID_BAND ) == NULL &&
tag->Find (ID3FID_CONDUCTOR ) == NULL &&
tag->Find (ID3FID_COMPOSER ) == NULL &&
text && text[0])
{
ID3_Frame *artistFrame=new ID3_Frame;
artistFrame->SetID(ID3FID_LEADARTIST);
artistFrame->Field(ID3FN_TEXT).SetLocal(text);
tag->AddFrame(artistFrame, true);
}
return;
}
void ID3_AddArtist_Latin(ID3_Tag *tag, char *text)
{
if (tag->Find (ID3FID_LEADARTIST ) == NULL &&
tag->Find (ID3FID_BAND ) == NULL &&
tag->Find (ID3FID_CONDUCTOR ) == NULL &&
tag->Find (ID3FID_COMPOSER ) == NULL &&
text && text[0])
{
ID3_Frame *artistFrame= new ID3_Frame;
artistFrame->SetID (ID3FID_LEADARTIST);
artistFrame->Field(ID3FN_TEXT).SetLatin(text);
tag->AddFrame (artistFrame, true );
}
return;
}
void ID3_AddAlbum(ID3_Tag *tag, char *text)
{
if (tag->Find (ID3FID_ALBUM ) == NULL && strlen (text ) > 0 )
{
ID3_Frame *albumFrame;
if (albumFrame = new ID3_Frame )
{
albumFrame->SetID (ID3FID_ALBUM );
albumFrame->Field(ID3FN_TEXT).SetLocal(text);
tag->AddFrame (albumFrame, true );
}
else
ID3_THROW (ID3E_NoMemory );
}
return;
}
void ID3_AddAlbum_Latin(ID3_Tag *tag, char *text)
{
if (tag->Find(ID3FID_ALBUM) == NULL
&& text && text[0])
{
ID3_Frame *albumFrame = new ID3_Frame;
albumFrame->SetID (ID3FID_ALBUM );
albumFrame->Field(ID3FN_TEXT).SetLocal(text);
tag->AddFrame (albumFrame, true );
}
return;
}
void ID3_AddTitle(ID3_Tag *tag, char *text)
{
if (tag->Find(ID3FID_TITLE) == NULL
&& text && text[0])
{
ID3_Frame *titleFrame;
if (titleFrame = new ID3_Frame)
{
titleFrame->SetID(ID3FID_TITLE);
titleFrame->Field(ID3FN_TEXT).SetLocal(text);
tag->AddFrame (titleFrame, true );
}
else
ID3_THROW(ID3E_NoMemory);
}
return;
}
void ID3_AddTitle_Latin(ID3_Tag *tag, char *text)
{
if (tag->Find(ID3FID_TITLE) == NULL
&& text && text[0])
{
ID3_Frame *titleFrame= new ID3_Frame;
titleFrame->SetID(ID3FID_TITLE);
titleFrame->Field(ID3FN_TEXT).SetLatin(text);
tag->AddFrame(titleFrame, true);
}
return;
}
void ID3_AddLyrics(ID3_Tag *tag, char *text)
{
if (tag->Find (ID3FID_UNSYNCEDLYRICS ) == NULL && strlen (text ) > 0 )
{
ID3_Frame *lyricsFrame;
if (lyricsFrame = new ID3_Frame )
{
lyricsFrame->SetID (ID3FID_UNSYNCEDLYRICS );
lyricsFrame->Field(ID3FN_LANGUAGE).SetLatin("eng");
lyricsFrame->Field(ID3FN_TEXT ).SetLocal(text);
tag->AddFrame (lyricsFrame, true );
}
else
ID3_THROW (ID3E_NoMemory );
}
return;
}

View File

@ -0,0 +1,39 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_MISC_SUPPORT_H
#define ID3LIB_MISC_SUPPORT_H
#include <wchar.h>
#include <string.h>
#include "id3_types.h"
#include "id3_tag.h"
// in 'id3_misc_support.cpp'
void ID3_AddTitle(ID3_Tag *tag, char *text);
void ID3_AddTitle_Latin(ID3_Tag *tag, char *text);
void ID3_AddArtist(ID3_Tag *tag, char *text);
void ID3_AddArtist_Latin(ID3_Tag *tag, char *text);
void ID3_AddAlbum(ID3_Tag *tag, char *text);
void ID3_AddAlbum_Latin(ID3_Tag *tag, char *text);
void ID3_AddLyrics(ID3_Tag *tag, char *text);
int ID3_UnicodeToLocal(char *local, const wchar_t *unicode, luint len, int inLen=-1);
int ID3_UnicodeToLatin(char *latin, const wchar_t *unicode, luint len, int inLen=-1);
int ID3_UnicodeToUTF8(char *latin, const wchar_t *unicode, luint len, int inLen=-1);
#endif

316
Src/id3v2/id3_tag.cpp Normal file
View File

@ -0,0 +1,316 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include "id3_tag.h"
luint ID3_Tag::instances = 0;
ID3_Tag &operator << (ID3_Tag& tag, ID3_Frame& frame)
{
tag.AddFrame (&frame);
return tag;
}
ID3_Tag &operator << (ID3_Tag& tag, ID3_Frame *frame)
{
tag.AddFrame (frame);
return tag;
}
ID3_Tag::ID3_Tag()
{
syncBuffer=0;
forcedPadding=0;
SetupTag();
instances++;
}
void ID3_Tag::ForcePading(luint _padding)
{
forcedPadding=_padding;
}
void ID3_Tag::SetupTag()
{
version = ID3_TAGVERSION;
revision = ID3_TAGREVISION;
frameList = NULL;
binaryList = NULL;
findCursor = NULL;
syncOn = false;
compression = false;
padding = true;
extendedHeader = false;
globalUnsync = false;
Clear();
return ;
}
ID3_Tag::~ID3_Tag(void)
{
Clear();
instances--;
if (instances == 0)
{}}
void ID3_Tag::Clear(void)
{
if (frameList)
{
ClearList (frameList);
frameList = NULL;
}
if (binaryList)
{
ClearList (binaryList);
binaryList = NULL;
}
findCursor = NULL;
hasChanged = true;
free(syncBuffer);
syncBuffer=0;
return ;
}
void ID3_Tag::DeleteElem(ID3_Elem *cur)
{
if (cur)
{
if (cur->tagOwns)
{
if (cur->frame)
{
delete cur->frame;
cur->frame = NULL;
}
if (cur->binary)
{
free(cur->binary);
cur->binary = NULL;
cur->binarySize=0;
}
}
findCursor = NULL;
hasChanged = true;
free(cur);
}
return ;
}
void ID3_Tag::ClearList(ID3_Elem *list)
{
ID3_Elem *cur = list;
while (cur)
{
ID3_Elem *next;
next = cur->next;
DeleteElem (cur);
cur = next;
}
return ;
}
void ID3_Tag::AddFrame(ID3_Frame *newFrame, bool freeWhenDone)
{
ID3_Elem *elem;
if (newFrame)
{
if (elem = (ID3_Elem *)calloc(1, sizeof(ID3_Elem)))
{
elem->next = frameList;
elem->frame = newFrame;
elem->binary = NULL;
elem->binarySize = 0;
elem->tagOwns = freeWhenDone;
frameList = elem;
findCursor = NULL;
hasChanged = true;
}
else
ID3_THROW (ID3E_NoMemory);
}
else
ID3_THROW (ID3E_NoData);
return ;
}
void ID3_Tag::RemoveFrame(ID3_Frame *frame)
{
ID3_Elem *elem = NULL;
if (elem = Find (frame))
RemoveFromList (elem, &frameList);
return ;
}
void ID3_Tag::RemoveFromList (ID3_Elem *which, ID3_Elem **list)
{
ID3_Elem *cur = *list;
if (cur == which)
{
*list = which->next;
DeleteElem (which);
}
else
{
while (cur)
{
if (cur->next == which)
{
cur->next = which->next;
DeleteElem (which);
break;
}
else
cur = cur->next;
}
}
return ;
}
bool ID3_Tag::HasChanged (void)
{
bool changed = hasChanged;
if (! changed)
{
ID3_Elem *cur = frameList;
while (cur)
{
if (cur->frame)
changed = cur->frame->HasChanged();
if (changed)
break;
else
cur = cur->next;
}
}
return changed;
}
void ID3_Tag::SetVersion(uchar ver, uchar rev)
{
if (version != ver || revision != rev)
hasChanged = true;
version = ver;
revision = rev;
return ;
}
void ID3_Tag::SetUnsync(bool newSync)
{
if (syncOn != newSync)
hasChanged = true;
syncOn = newSync;
return ;
}
void ID3_Tag::SetExtendedHeader(bool ext)
{
if (extendedHeader != ext)
hasChanged = true;
extendedHeader = ext;
return ;
}
void ID3_Tag::SetCompression (bool comp)
{
if (compression != comp)
hasChanged = true;
compression = comp;
return ;
}
void ID3_Tag::SetPadding (bool pad)
{
if (padding != pad)
hasChanged = true;
padding = pad;
return ;
}
luint ID3_Tag::NumFrames (void)
{
luint numFrames = 0;
ID3_Elem *cur = frameList;
while (cur)
{
numFrames++;
cur = cur->next;
}
return numFrames;
}

111
Src/id3v2/id3_tag.h Normal file
View File

@ -0,0 +1,111 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_TAG_H
#define ID3LIB_TAG_H
#include <windows.h>
#include <wchar.h>
#include <stdio.h>
#include "id3_types.h"
#include "id3_frame.h"
#include "id3_header_frame.h"
#include "id3_header_tag.h"
#include "id3_version.h"
// for file buffers etc
#define BUFF_SIZE (65536)
struct ID3_Elem
{
ID3_Elem *next;
ID3_Frame *frame;
uchar *binary;
size_t binarySize;
bool tagOwns;
};
class ID3_Tag
{
public:
ID3_Tag();
~ID3_Tag(void);
void Clear(void);
bool HasChanged(void);
void SetUnsync(bool newSync);
void SetExtendedHeader(bool ext);
void SetCompression(bool comp);
void SetPadding(bool pad);
void ForcePading(luint _padding);
void AddFrame(ID3_Frame *newFrame, bool freeWhenDone = false);
void RemoveFrame(ID3_Frame *oldFrame);
luint Render(uchar *buffer);
luint Size(void);
void Parse(const uchar header[ID3_TAGHEADERSIZE], const uchar *buffer);
ID3_Frame *Find(ID3_FrameID id);
ID3_Frame *Find(ID3_FrameID id, ID3_FieldID fld, luint data);
ID3_Frame *Find(ID3_FrameID id, ID3_FieldID fld, const wchar_t *data);
ID3_Frame *Find(ID3_FrameID id, ID3_FieldID fld, const char *data);
luint NumFrames(void);
ID3_Frame *GetFrameNum(luint num);
ID3_Frame *operator[] (luint num);
// *** PRIVATE INTERNAL DATA - DO NOT USE *** PRIVATE INTERNAL DATA - DO NOT USE ***
void SetupTag();
void SetVersion(uchar ver, uchar rev);
void ClearList(ID3_Elem *list);
void DeleteElem(ID3_Elem *cur);
void AddBinary(const uchar *buffer, luint size);
void ExpandBinaries(const uchar *buffer, luint size);
void ProcessBinaries(ID3_FrameID whichFrame = ID3FID_NOFRAME, bool attach = true); // this default means all frames
void RemoveFromList(ID3_Elem *which, ID3_Elem **list);
ID3_Elem *GetLastElem(ID3_Elem *list);
ID3_Elem *Find(ID3_Frame *frame);
luint PaddingSize(luint curSize);
void RenderExtHeader(uchar *buffer);
luint GetUnSyncSize (uchar *buffer, luint size);
void UnSync (uchar *destData, luint destSize, uchar *sourceData, luint sourceSize);
luint ReSync (uchar *binarySourceData, luint sourceSize);
uchar version; // what version tag?
uchar revision; // what revision tag?
ID3_Elem *frameList; // the list of known frames currently attached to this tag
ID3_Elem *binaryList; // the list of yet-to-be-parsed frames currently attached to this tag
ID3_Elem *findCursor; // on which element in the frameList are we currently positioned?
bool syncOn; // should we unsync this tag when rendering?
bool compression; // should we compress frames when rendering?
bool padding; // add padding to tags?
bool extendedHeader; // create an extended header when rendering?
bool hasChanged; // has the tag changed since the last parse or render?
//FILE *fileHandle; // a handle to the file we are linked to
luint forcedPadding;
bool globalUnsync; // did the header indicate that all frames are unsync'd?
static luint instances; // how many ID3_Tag objects are floating around in this app?
ID3_Quirks quirks;
uchar *syncBuffer; // so we don't destroy someone else's data when we unsynchronize
};
ID3_Tag& operator<< (ID3_Tag& tag, ID3_Frame& frame);
ID3_Tag& operator<< (ID3_Tag& tag, ID3_Frame *frame);
#endif

View File

@ -0,0 +1,18 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include <windows.h>
#include <string.h>
#include "id3_tag.h"

199
Src/id3v2/id3_tag_find.cpp Normal file
View File

@ -0,0 +1,199 @@
// The authors have released ID3Lib as Public Domain(PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney(dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
// improved/optimized/whatEVER jan-08-2006 benski
#include "id3_tag.h"
#include "id3_misc_support.h"
#include "../nu/AutoWide.h"
ID3_Elem *ID3_Tag::Find(ID3_Frame *frame)
{
ID3_Elem *cur = frameList;
while(cur)
{
if (cur->frame == frame)
return cur;
cur = cur->next;
}
return NULL;
}
ID3_Frame *ID3_Tag::Find(ID3_FrameID id)
{
ID3_Elem *cur = findCursor;
if (cur == NULL)
findCursor = cur = frameList;
while(cur)
{
if (cur->frame && cur->frame->GetID() == id)
{
findCursor = cur->next;
return cur->frame;
}
cur = cur->next;
if (cur == NULL) cur = frameList;
if (cur == findCursor) break;
}
return NULL;
}
ID3_Frame *ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const wchar_t *data)
{
ID3_Elem *cur = findCursor;
if (cur == NULL)
findCursor = cur = frameList;
while(cur)
{
if (cur->frame && cur->frame->GetID() == id)
{
if (data && /*lstrlenW(data) &&*/ BS_ISSET(cur->frame->fieldBits, fld))
{
wchar_t *buffer;
luint size;
size = cur->frame->Field(fld).BinSize();
if (buffer =(wchar_t*)calloc(size, sizeof(wchar_t)))
{
buffer[0]=0;
cur->frame->Field(fld).GetUnicode(buffer, size);
if (wcscmp(buffer, data) == 0)
{
free(buffer);
findCursor = cur->next;
return cur->frame;
}
free(buffer);
}
}
}
cur = cur->next;
if (cur == NULL) cur = frameList;
if (cur == findCursor) break;
}
return NULL;
}
ID3_Frame *ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const char *data)
{
ID3_Elem *cur = findCursor;
if (cur == NULL)
findCursor = cur = frameList;
while(cur)
{
if (cur->frame && cur->frame->GetID() == id)
{
if (data && /*lstrlenW(data) &&*/ BS_ISSET(cur->frame->fieldBits, fld))
{
char *buffer;
luint size;
size = cur->frame->Field(fld).BinSize();
if (buffer =(char*)calloc(size, sizeof(char)))
{
buffer[0]=0;
cur->frame->Field(fld).GetLocal(buffer, size);
if (strcmp(buffer, data) == 0)
{
free(buffer);
findCursor = cur->next;
return cur->frame;
}
free(buffer);
}
}
}
cur = cur->next;
if (cur == NULL) cur = frameList;
if (cur == findCursor) break;
}
return NULL;
}
ID3_Frame *ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, luint data)
{
ID3_Elem *cur = findCursor;
if (cur == NULL)
findCursor = cur = frameList;
while(cur)
{
if (cur->frame &&(cur->frame->GetID() == id))
{
if (cur->frame->Field(fld).Get() == data)
{
findCursor=cur->next;
return cur->frame;
}
}
cur = cur->next;
if (cur == NULL) cur = frameList;
if (cur == findCursor) break;
}
return NULL;
}
ID3_Frame *ID3_Tag::GetFrameNum(luint num)
{
luint curNum=0;
ID3_Elem *cur = frameList;
while(cur)
{
if (num == curNum)
{
return cur->frame;
}
curNum++;
cur = cur->next;
}
return 0;
}
ID3_Frame *ID3_Tag::operator[](luint num)
{
return GetFrameNum(num);
}

449
Src/id3v2/id3_tag_parse.cpp Normal file
View File

@ -0,0 +1,449 @@
// The authors have released ID3Lib as Public Domain(PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney(dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include "id3_tag.h"
#include "../Plugins/Input/in_mp3/LAMEinfo.h"
#include <assert.h>
#include "zlib.h"
ID3_Elem *ID3_Tag::GetLastElem(ID3_Elem *list)
{
ID3_Elem *last = list;
while (last && last->next)
last = last->next;
return last;
}
void ID3_Tag::AddBinary(const uchar *buffer, luint size)
{
uchar *newBin;
if (size > 0)
{
if (newBin = (uchar*)calloc(size, sizeof(uchar)))
{
ID3_Elem * elem;
memcpy(newBin, buffer, size);
if (elem = (ID3_Elem*)calloc(1, sizeof(ID3_Elem)))
{
elem->next = NULL;
elem->frame = NULL;
elem->binary = newBin;
elem->binarySize = size;
elem->tagOwns = true;
ID3_Elem * lastElem = GetLastElem(binaryList);
if (lastElem)
lastElem->next = elem;
else
binaryList = elem;
}
else
{
free(newBin);
ID3_THROW(ID3E_NoMemory);
}
}
else
ID3_THROW(ID3E_NoMemory);
}
else
ID3_THROW(ID3E_NoData);
return ;
}
void ID3_Tag::ExpandBinaries(const uchar *buffer, luint size)
{
ID3_FrameAttr attr;
ID3_FrameHeader frHeader;
luint posn = 0;
while (posn < (size - 6) && buffer[posn] != 0)
{
//luint newBinSize;
frHeader.SetVersion(version, revision);
frHeader.SetQuirks(quirks);
posn += frHeader.GetFrameInfo(attr, &buffer[posn], size);
//newBinSize = frHeader.Size() + attr.size;
if ((posn + attr.size) > (size))
{
ID3_THROW(ID3E_NoMemory);
return ;
}
quirks=frHeader.GetQuirks();
// firstly, let's check to see if we are parsing a CDM. If so,
// let's expanded it out now.
if (strcmp(attr.textID, "CDM") == 0)
{
// if the method was zlib
if (buffer[posn] == 'z')
{
unsigned long expandedSize = 0;
uchar *expBin;
expandedSize |= buffer[posn + 1] << 24;
expandedSize |= buffer[posn + 2] << 16;
expandedSize |= buffer[posn + 3] << 8;
expandedSize |= buffer[posn + 4];
if (expBin = (uchar*)calloc(expandedSize, sizeof(uchar)))
{
uncompress(expBin, &expandedSize, &buffer[posn + 1 + sizeof(luint)], (uLong)(attr.size - sizeof(luint) - 1));
ExpandBinaries(expBin, expandedSize);
posn += attr.size;
free(expBin);
}
}
}
else
{
AddBinary(&buffer[posn - frHeader.Size()], attr.size + frHeader.Size());
posn += attr.size;
}
}
return ;
}
void ID3_Tag::ProcessBinaries(ID3_FrameID whichFrame, bool attach)
{
ID3_FrameAttr attr;
ID3_FrameHeader frHeader;
ID3_Elem *cur = binaryList;
frHeader.SetVersion(version, revision);
frHeader.SetQuirks(quirks);
while (cur && cur->binary)
{
ID3_FrameID id;
ID3_Frame *frame;
luint posn;
luint extras = 0;
unsigned long expandedSize = 0;
//uchar groupingID = 0;
//uchar encryptionID = 0;
posn = frHeader.GetFrameInfo(attr, cur->binary, cur->binarySize);
assert(attr.size + frHeader.Size() == cur->binarySize);
uint32_t data_length = 0;
if (attr.HasDataLength(version))
{
data_length = 0;
for (int i = 0; i < 4; i++)
data_length |= cur->binary[posn + i] << ((data_length - 1 - i) * 8);
// size of Re-sync'd data. we'll just ignore for now
data_length = int28().setFromFile(data_length).get();
//attr.size = data_length;
posn+=4;
extras+=4;
}
if (attr.HasCompression(version))
{
if (attr.HasDataLength(version))
expandedSize = data_length;
else
{
expandedSize |= cur->binary[posn + 0] << 24;
expandedSize |= cur->binary[posn + 1] << 16;
expandedSize |= cur->binary[posn + 2] << 8;
expandedSize |= cur->binary[posn + 3];
extras += sizeof(luint);
posn+=4;
}
}
if (attr.HasEncryption(version))
{
//encryptionID = cur->binary[posn];
posn++, extras++;
}
if (attr.HasGrouping(version))
{
//groupingID = cur->binary[posn];
posn++, extras++;
}
id = ID3_FindFrameID(attr.textID);
if ((id == whichFrame || whichFrame == ID3FID_NOFRAME) && id != ID3FID_NOFRAME)
{
uchar *expBin;
bool useExpBin = false;
luint frameSize= attr.size - extras;
if (attr.HasUnsync(version) // if the per-frame unsync flag is set
&& !globalUnsync) // but make sure we didn't already unsync the whole file
{
frameSize=ReSync(&cur->binary[posn], attr.size - 10) + extras;
}
if (attr.HasCompression(version))
{
if (!(expBin = (uchar*)calloc(expandedSize, sizeof(uchar))))
ID3_THROW(ID3E_NoMemory);
if (expBin)
{
int x = uncompress(expBin, &expandedSize, &cur->binary[posn], frameSize);
if (x == 0/*Z_OK*/)
{
useExpBin = true;
}
else
{
free(expBin);
expBin=0;
}
}
}
if (!(frame = new ID3_Frame))
ID3_THROW(ID3E_NoMemory);
ID3_Elem *elem;
frame->SetVersion(version, revision);
frame->SetID(id);
if (useExpBin)
{
frame->Parse(expBin, expandedSize);
free(expBin);
}
else
frame->Parse(&cur->binary[posn], frameSize);
// here is where we call a special handler
// for this frame type if one is specified
// in the frame definition
{
ID3_FrameDef *frameInfo;
frameInfo = ID3_FindFrameDef(id);
if (frameInfo && frameInfo->parseHandler)
attach = frameInfo->parseHandler(frame);
}
// if, after all is said and done, we
// are still supposed to attach our
// newly parsed frame to the tag, do so
if (attach)
{
if (!(elem = (ID3_Elem *)calloc(1, sizeof(ID3_Elem))))
ID3_THROW(ID3E_NoMemory);
elem->next = NULL;
elem->frame = frame;
elem->binary = NULL;
elem->binarySize=0;
elem->tagOwns = true;
ID3_Elem * lastElem = GetLastElem(frameList);
if (lastElem)
lastElem->next = elem;
else
frameList = elem;
}
else
{
// if not, delete it
delete frame;
}
ID3_Elem *temp = cur;
cur = cur->next;
RemoveFromList(temp, &binaryList);
}
else
{
cur = cur->next;
}
}
return ;
}
void ID3_Tag::Parse(const uchar header[ID3_TAGHEADERSIZE], const uchar *buffer)
{
luint tagSize = 0;
int28 temp = &header[6];
luint posn = 0;
uchar prevVer = version;
uchar prevRev = revision;
Clear();
tagSize = temp.get();
SetVersion(header[3], header[4]);
// make sure we understand this version
if (version > MAX_ID3_TAGVERSION || version < MIN_ID3_TAGVERSION)
return;
globalUnsync = !!(header[5] & ID3HF_UNSYNC);
if (globalUnsync)
{
assert(syncBuffer==0);
syncBuffer = (uchar *)calloc(tagSize, sizeof(uchar));
memcpy(syncBuffer, buffer, tagSize);
buffer=syncBuffer;
tagSize = ReSync(syncBuffer, tagSize);
}
// okay, if we are 2.01, then let's skip over the
// extended header for now because I am lazy
if (version == 2 && revision == 1)
if (header[5] & ID3HF_EXTENDEDHEADER)
{
luint extSize = 0;
extSize |= buffer[0] << 24;
extSize |= buffer[1] << 16;
extSize |= buffer[2] << 8;
extSize |= buffer[3] << 0;
posn = extSize + sizeof(luint);
}
// okay, if we are 3.00, then let's actually
// parse the extended header(for now, we skip
// it because we are lazy)
if (version == 3 && revision == 0)
{
// according to id3v2.3 specs section 3.1
// "All the other flags should be cleared. If one of these undefined flags are set that might mean that the tag is not readable for a parser that does not know the flags function."
if (header[5] & ~ID3HF_2_3_MASK)
{
// TODO: benski> is this the best way to show an error?
Clear();
return;
}
if (header[5] & ID3HF_EXTENDEDHEADER)
{
luint extSize = 0;
extSize |= buffer[0] << 24;
extSize |= buffer[1] << 16;
extSize |= buffer[2] << 8;
extSize |= buffer[3] << 0;
posn = extSize + sizeof(luint);
}
}
// id3v2.4
if (version == 4 && revision == 0)
{
// according to id3v2.4 specs section 3.1
// "All the other flags MUST be cleared. If one of these undefined flags
// are set, the tag might not be readable for a parser that does not
// know the flags function."
if (header[5] & ~ID3HF_2_4_MASK)
{
// TODO: benski> is this the best way to show an error?
Clear();
return;
}
if (header[5] & ID3HF_EXTENDEDHEADER)
{
luint extSize = 0;
extSize |= buffer[0] << 24;
extSize |= buffer[1] << 16;
extSize |= buffer[2] << 8;
extSize |= buffer[3] << 0;
posn = extSize + sizeof(luint);
}
}
if (posn >= tagSize)
{
// TODO: benski> is this the best way to show an error?
Clear();
return;
}
// this call will convert the binary data block(tag)
// into a linked list of binary frames
ExpandBinaries(&buffer[posn], tagSize-posn);
// let's parse the CRYPTO frames
// the 'false' parameter means "don't
// attach the frame to the tag when
// processed". This is because we have
// installed a parsing handler for the
// crypto reg frame. This is a default
// parameter - if the frame type has a
// custom parsing handler, that handler
// will tell ID3Lib whether to attach
// or not.
ProcessBinaries(ID3FID_CRYPTOREG, false);
// let's parse the GROUPING frames
// the 'false' parameter means "don't
// attach the frame to the tag when
// processed". This is because we have
// installed a parsing handler for the
// crypto reg frame. This is a default
// parameter - if the frame type has a
// custom parsing handler, that handler
// will tell ID3Lib whether to attach
// or not.
ProcessBinaries(ID3FID_GROUPINGREG, false);
// let's parse the rest of the binaries
ProcessBinaries();
// upgrade older tags to our preferred revision
if (prevVer > version || (prevVer == version && prevRev > revision))
SetVersion(prevVer, prevRev);
// set the flag which says that the tag hasn't changed
hasChanged = false;
return ;
}

View File

@ -0,0 +1,244 @@
// The authors have released ID3Lib as Public Domain(PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney(dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "id3_tag.h"
#include "id3_misc_support.h"
/*
luint ID3_CRLFtoLF( char *buffer, luint size)
{
luint newSize = 0;
char *dest = buffer;
char *source = buffer;
if ( buffer && size)
{
while ( source < ( buffer + size))
{
if ( *source == 0x0D)
source++;
else
*dest++ = *source++;
}
newSize = dest - buffer;
}
else
ID3_THROW( ID3E_NoData);
return newSize;
}
*/
/*
luint ID3_StripTimeStamps( char *buffer, luint size)
{
luint newSize = 0;
char *dest = buffer;
char *source = buffer;
if ( buffer && size)
{
while ( source < ( buffer + size))
{
if ( *source == '[')
source += 7;
else
*dest++ = *source++;
}
newSize = dest - buffer;
}
else
ID3_THROW( ID3E_NoData);
return newSize;
}
*/
/*
void ID3_Tag::ParseLyrics3( void)
{
if (file_handle != INVALID_HANDLE_VALUE)
{
uchar buffer[ 18 ];
DWORD dw;
SetFilePointer(file_handle, -143, NULL, FILE_END);
ReadFile(file_handle, buffer, 18, &dw, NULL);
// first check for an ID3v1 tag
if ( memcmp( &buffer[ 15 ], "TAG", 3) == 0)
{
if ( memcmp( &buffer[ 6 ], "LYRICSEND", 9) == 0)
{
// we have a Lyrics3 v1.00 tag
}
else if ( memcmp( &buffer[ 6 ], "LYRICS200", 9) == 0)
{
// we have a Lyrics3 v2.00 tag
luint lyricsSize;
buffer[ 6 ] = 0;
int intSize = atoi((char *) buffer);
if (intSize > 0)
lyricsSize = intSize;
else
return;
SetFilePointer(file_handle, -143 - lyricsSize, NULL, FILE_END);
ReadFile(file_handle, buffer, 11, &dw, NULL);
if ( memcmp( buffer, "LYRICSBEGIN", 11) == 0)
{
hasL3Tag = true;
luint bytesToRead = lyricsSize - 11;
uchar *buff2;
extraBytes += lyricsSize + 9 + 6;
if ( buff2 = (uchar*)malloc(bytesToRead))
{
luint posn = 0;
bool stampsUsed = false;
ReadFile(file_handle, buff2, bytesToRead, &dw, NULL);
while ( posn < bytesToRead)
{
uchar fid[ 4 ];
uchar sizeT[ 6 ];
luint size;
fid[ 3 ] = 0;
sizeT[ 5 ] = 0;
memcpy( fid, &buff2[ posn ], 3);
memcpy( sizeT, &buff2[ posn + 3 ], 5);
int intSize = atoi((char *)sizeT);
if (intSize>0)
{
size = intSize;
}
else
{
free(buff2);
return;
}
// the IND field
if ( strcmp((char *) fid, "IND") == 0)
{
if ( buff2[ posn + 8 + 1 ] == '1')
stampsUsed = true;
}
// the TITLE field
if ( strcmp((char *) fid, "ETT") == 0)
{
char *text;
if ( text = (char*)malloc(size + 1))
{
text[ size ] = 0;
memcpy( text, &buff2[ posn + 8 ], size);
ID3_AddTitle( this, text);
free(text);
}
else
ID3_THROW( ID3E_NoMemory);
}
// the ARTIST field
if ( strcmp((char *) fid, "EAR") == 0)
{
char *text;
if ( text = (char*)malloc(size + 1))
{
text[ size ] = 0;
memcpy( text, &buff2[ posn + 8 ], size);
ID3_AddArtist( this, text);
free(text);
}
else
ID3_THROW( ID3E_NoMemory);
}
// the ALBUM field
if ( strcmp((char *) fid, "EAL") == 0)
{
char *text;
if ( text = (char*)malloc(size + 1))
{
text[ size ] = 0;
memcpy( text, &buff2[ posn + 8 ], size);
ID3_AddAlbum( this, text);
free(text);
}
else
ID3_THROW( ID3E_NoMemory);
}
// the LYRICS field
if ( strcmp((char *) fid, "LYR") == 0)
{
char *text;
luint newSize;
newSize = ID3_CRLFtoLF((char *) & buff2[ posn + 8 ], size);
if ( stampsUsed)
newSize = ID3_StripTimeStamps((char *) & buff2[ posn + 8 ], newSize);
if ( text = (char*)malloc(newSize + 1))
{
text[ newSize ] = 0;
memcpy( text, &buff2[ posn + 8 ], newSize);
ID3_AddLyrics( this, text);
free(text);
}
else
ID3_THROW( ID3E_NoMemory);
}
posn += size + 8;
}
free(buff2);
}
}
}
}
}
else
ID3_THROW( ID3E_NoData);
return ;
}
*/

View File

@ -0,0 +1,22 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include "id3_tag.h"
#include "id3_misc_support.h"

View File

@ -0,0 +1,151 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include <string.h>
#include <memory.h>
#include "id3_tag.h"
#include "id3_misc_support.h"
#include <windows.h>
luint ID3_Tag::Render( uchar *buffer )
{
luint bytesUsed = 0;
ID3_Elem *cur = frameList;
ID3_TagHeader header;
if (version > ID3_TAGVERSION || (version == ID3_TAGVERSION && revision > ID3_TAGREVISION))
SetVersion(version, revision);
else
SetVersion ( ID3_TAGVERSION, ID3_TAGREVISION );
header.SetVersion ( version, revision );
bytesUsed += header.Size();
// set up the encryption and grouping IDs
while (cur)
{
if (cur->frame)
{
cur->frame->compression = compression;
cur->frame->SetVersion ( version, revision );
bytesUsed += cur->frame->Render(&buffer[bytesUsed]);
}
cur = cur->next;
}
if (syncOn)
{
luint newTagSize;
newTagSize = GetUnSyncSize ( &buffer[ header.Size() ], bytesUsed - header.Size() );
if ( newTagSize > 0 && ( newTagSize + header.Size() ) > bytesUsed )
{
uchar *tempz;
if ( tempz = (uchar*)calloc(newTagSize, sizeof(uchar)) )
{
UnSync ( tempz, newTagSize, &buffer[ header.Size() ], bytesUsed - header.Size() );
header.SetFlags ( ID3HF_UNSYNC );
memcpy ( &buffer[ header.Size() ], tempz, newTagSize );
bytesUsed = newTagSize + header.Size();
free(tempz);
}
else
ID3_THROW ( ID3E_NoMemory );
}
}
// zero the remainder of the buffer so that our
// padding bytes are zero
luint paddingSize = PaddingSize(bytesUsed);
for ( luint i = 0; i < paddingSize; i++ )
buffer[ bytesUsed + i ] = 0;
bytesUsed += paddingSize;
header.SetDataSize ( bytesUsed - header.Size() );
header.Render ( buffer );
// set the flag which says that the tag hasn't changed
hasChanged = false;
return bytesUsed;
}
luint ID3_Tag::Size( void )
{
luint bytesUsed = 0;
ID3_Elem *cur = frameList;
ID3_TagHeader header;
header.SetVersion(version, revision);
bytesUsed += header.Size();
while (cur)
{
if (cur->frame)
{
cur->frame->SetVersion ( version, revision );
bytesUsed += cur->frame->Size();
}
cur = cur->next;
}
// add 30% for sync
if (syncOn)
bytesUsed += bytesUsed / 3;
bytesUsed += PaddingSize(bytesUsed);
return bytesUsed;
}
void ID3_Tag::RenderExtHeader ( uchar *buffer )
{
if ( version == 3 && revision == 0 )
{
}
return;
}
#define ID3_PADMULTIPLE ( 2048 )
#define ID3_PADMAX ( 4096 )
luint ID3_Tag::PaddingSize(luint curSize)
{
luint newSize = 0;
// if padding is switched off
if (!padding)
return 0;
if (forcedPadding)
return forcedPadding;
else
newSize = ( ( curSize / ID3_PADMULTIPLE ) + 1 ) * ID3_PADMULTIPLE;
return newSize - curSize;
}

123
Src/id3v2/id3_tag_sync.cpp Normal file
View File

@ -0,0 +1,123 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#include "id3_tag.h"
// To be used when reading an ID3v2-tag
// Transforms all FF 00 sequences into FF
luint ID3_Tag::ReSync(uchar *binarySourceData, luint sourceSize)
{
uchar *source, *dest;
uchar temp;
luint destinationSize;
source = binarySourceData;
destinationSize = sourceSize;
while (source < binarySourceData + sourceSize)
{
temp = *source++;
if (temp == 0xFF && source < binarySourceData + sourceSize)
{
if ((temp = *source++) == 0x00)
destinationSize--;
}
}
dest = source = binarySourceData;
while ((source < binarySourceData + sourceSize) && (dest < binarySourceData + sourceSize))
{
*dest++ = temp = *source++;
if (temp == 0xFF && source < binarySourceData + sourceSize)
{
if ((temp = *source++) != 0x00 && dest < binarySourceData + sourceSize)
* dest++ = temp;
}
}
for (luint cl=destinationSize;cl<sourceSize;cl++)
binarySourceData[cl]=0;
return destinationSize;
}
// How big will the tag be after we unsync?
luint ID3_Tag::GetUnSyncSize(uchar *buffer, luint size)
{
luint extraSize = 0;
uchar *source = buffer;
// Determine the size needed for the destination data
while (source < buffer + size)
{
uchar temp = *source++;
if (temp == 0xFF)
{
// last byte?
if (source == (buffer + size))
extraSize++;
else
{
temp = *source;
if (((temp & 0xE0) == 0xE0) || (temp == 0))
extraSize++;
}
}
}
return extraSize + size;
}
// To be used when writing an ID3v2-tag
// Transforms:
// 11111111 111xxxxx -> 11111111 00000000 111xxxxx
// 11111111 00000000 -> 11111111 00000000 00000000
// 11111111 <EOF> -> 11111111 00000000 <EOF>
void ID3_Tag::UnSync(uchar *destData, luint destSize, uchar *sourceData, luint sourceSize)
{
uchar *source = sourceData;
uchar *dest = destData;
// Now do the real transformation
while (source < sourceData + sourceSize)
{
uchar temp = *dest++ = *source++;
if (temp == 0xFF)
{
// last byte?
if (source == (sourceData + sourceSize))
*dest++ = 0;
else
{
temp = *source;
if (((temp & 0xE0) == 0xE0) || (temp == 0))
*dest++ = 0;
}
}
}
return ;
}

58
Src/id3v2/id3_types.h Normal file
View File

@ -0,0 +1,58 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_TYPES_H
#define ID3LIB_TYPES_H
#include <wchar.h>
#include <bfc/platform/types.h>
typedef unsigned char uchar;
typedef short signed int ssint;
typedef short unsigned int suint;
typedef long signed int lsint;
typedef size_t luint;
typedef long double ldoub;
typedef long unsigned int * bitset;
#define BS_SET(v,x) ( (v)[ (x) / ( sizeof ( luint ) * 8 ) ] |= ( 1 << ( (x) % ( sizeof ( luint ) * 8 ) ) ) )
#define BS_CLEAR(v,x) ( (v)[ (x) / ( sizeof ( luint ) * 8 ) ] &= ~( 1 << ( (x) % ( sizeof ( luint ) * 8 ) ) ) )
#define BS_ISSET(v,x) ( (v)[ (x) / ( sizeof ( luint ) * 8 ) ] & ( 1 << ( (x) % ( sizeof ( luint ) * 8 ) ) ) )
#ifndef NULL
#define NULL (0L)
#endif
#ifndef MIN
inline lsint MIN ( lsint x, lsint y )
{
return x < y ? x : y;
}
#endif
#ifndef MAX
inline lsint MAX ( lsint x, lsint y )
{
return x > y ? x : y;
}
#endif
// include other abstract types here because they
// may depend on the types defined above
#include "id3_int28.h"
#endif

28
Src/id3v2/id3_version.h Normal file
View File

@ -0,0 +1,28 @@
// The authors have released ID3Lib as Public Domain (PD) and claim no copyright,
// patent or other intellectual property protection in this work. This means that
// it may be modified, redistributed and used in commercial and non-commercial
// software and hardware without restrictions. ID3Lib is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
//
// The ID3Lib authors encourage improvements and optimisations to be sent to the
// ID3Lib coordinator, currently Dirk Mahoney (dirk@id3.org). Approved
// submissions may be altered, and will be included and released under these terms.
//
// Mon Nov 23 18:34:01 1998
#ifndef ID3LIB_VERSION_H
#define ID3LIB_VERSION_H
#define ID3LIB_NAME "ID3Lib"
#define ID3LIB_VERSION "v3.05a"
#define ID3LIB_VER ( 3 )
#define ID3LIB_REV ( 5 )
#define ID3LIB_DATE "Mon Nov 23 18:34:01 1998"
#define ID3LIB_VERSTRING ID3LIB_NAME " " ID3LIB_VERSION " " ID3LIB_DATE
#endif

242
Src/id3v2/id3v2.vcxproj Normal file
View File

@ -0,0 +1,242 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0C7AAFA2-2A78-4B91-99A3-3E866B484ADB}</ProjectGuid>
<RootNamespace>id3v2</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<DisableSpecificWarnings>4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<DisableSpecificWarnings>4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="id3_error.cpp" />
<ClCompile Include="id3_field.cpp" />
<ClCompile Include="id3_field_binary.cpp" />
<ClCompile Include="id3_field_integer.cpp" />
<ClCompile Include="id3_field_string_ascii.cpp" />
<ClCompile Include="id3_field_string_unicode.cpp" />
<ClCompile Include="id3_frame.cpp" />
<ClCompile Include="id3_frame_parse.cpp" />
<ClCompile Include="id3_frame_render.cpp" />
<ClCompile Include="id3_header.cpp" />
<ClCompile Include="id3_header_frame.cpp" />
<ClCompile Include="id3_header_tag.cpp" />
<ClCompile Include="id3_int28.cpp" />
<ClCompile Include="id3_misc_support.cpp" />
<ClCompile Include="id3_tag.cpp" />
<ClCompile Include="id3_tag_file.cpp" />
<ClCompile Include="id3_tag_find.cpp" />
<ClCompile Include="id3_tag_parse.cpp" />
<ClCompile Include="id3_tag_render.cpp" />
<ClCompile Include="id3_tag_sync.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="id3_dll.h" />
<ClInclude Include="id3_error.h" />
<ClInclude Include="id3_externals.h" />
<ClInclude Include="id3_field.h" />
<ClInclude Include="id3_frame.h" />
<ClInclude Include="id3_header.h" />
<ClInclude Include="id3_header_frame.h" />
<ClInclude Include="id3_header_tag.h" />
<ClInclude Include="id3_int28.h" />
<ClInclude Include="id3_misc_support.h" />
<ClInclude Include="id3_tag.h" />
<ClInclude Include="id3_types.h" />
<ClInclude Include="id3_version.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="id3_tag_sync.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_tag_render.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_tag_parse.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_tag_find.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_tag_file.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_tag.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_misc_support.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_int28.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_header_tag.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_header_frame.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_header.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_frame_render.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_frame_parse.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_frame.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_field_string_ascii.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_field_string_unicode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_field_integer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_field_binary.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_field.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="id3_error.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="id3_dll.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_error.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_externals.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_field.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_frame.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_header.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_header_frame.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_header_tag.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_int28.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_misc_support.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_tag.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="id3_version.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{46ade71f-4fd9-4b0f-892b-56a821313b48}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{eba6dadd-5cbf-4fe4-873d-c7937c58f6fc}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{5bc6abde-bd55-40fa-88a7-043a118989c6}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>