summaryrefslogtreecommitdiffstats
path: root/Src/id3v2
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 14:54:57 +0200
committerJef <jef@targetspot.com>2024-09-24 14:54:57 +0200
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/id3v2
parentAdding .gitignore (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar
winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.bz2
winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.lz
winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.xz
winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.zst
winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.zip
Diffstat (limited to 'Src/id3v2')
-rw-r--r--Src/id3v2/id3_dll.h180
-rw-r--r--Src/id3v2/id3_dll_wrapper.cpp481
-rw-r--r--Src/id3v2/id3_error.cpp67
-rw-r--r--Src/id3v2/id3_error.h61
-rw-r--r--Src/id3v2/id3_externals.h21
-rw-r--r--Src/id3v2/id3_field.cpp520
-rw-r--r--Src/id3v2/id3_field.h282
-rw-r--r--Src/id3v2/id3_field_binary.cpp83
-rw-r--r--Src/id3v2/id3_field_integer.cpp81
-rw-r--r--Src/id3v2/id3_field_string_ascii.cpp239
-rw-r--r--Src/id3v2/id3_field_string_unicode.cpp338
-rw-r--r--Src/id3v2/id3_frame.cpp273
-rw-r--r--Src/id3v2/id3_frame.h55
-rw-r--r--Src/id3v2/id3_frame_parse.cpp40
-rw-r--r--Src/id3v2/id3_frame_render.cpp178
-rw-r--r--Src/id3v2/id3_header.cpp98
-rw-r--r--Src/id3v2/id3_header.h80
-rw-r--r--Src/id3v2/id3_header_frame.cpp181
-rw-r--r--Src/id3v2/id3_header_frame.h81
-rw-r--r--Src/id3v2/id3_header_tag.cpp86
-rw-r--r--Src/id3v2/id3_header_tag.h48
-rw-r--r--Src/id3v2/id3_int28.cpp62
-rw-r--r--Src/id3v2/id3_int28.h41
-rw-r--r--Src/id3v2/id3_misc_support.cpp175
-rw-r--r--Src/id3v2/id3_misc_support.h39
-rw-r--r--Src/id3v2/id3_tag.cpp316
-rw-r--r--Src/id3v2/id3_tag.h111
-rw-r--r--Src/id3v2/id3_tag_file.cpp18
-rw-r--r--Src/id3v2/id3_tag_find.cpp199
-rw-r--r--Src/id3v2/id3_tag_parse.cpp449
-rw-r--r--Src/id3v2/id3_tag_parse_lyrics3.cpp244
-rw-r--r--Src/id3v2/id3_tag_parse_v1.cpp22
-rw-r--r--Src/id3v2/id3_tag_render.cpp151
-rw-r--r--Src/id3v2/id3_tag_sync.cpp123
-rw-r--r--Src/id3v2/id3_types.h58
-rw-r--r--Src/id3v2/id3_version.h28
-rw-r--r--Src/id3v2/id3v2.vcxproj242
-rw-r--r--Src/id3v2/id3v2.vcxproj.filters117
38 files changed, 5868 insertions, 0 deletions
diff --git a/Src/id3v2/id3_dll.h b/Src/id3v2/id3_dll.h
new file mode 100644
index 000000000..be41b8716
--- /dev/null
+++ b/Src/id3v2/id3_dll.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_dll_wrapper.cpp b/Src/id3v2/id3_dll_wrapper.cpp
new file mode 100644
index 000000000..e84344109
--- /dev/null
+++ b/Src/id3v2/id3_dll_wrapper.cpp
@@ -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
+
+
diff --git a/Src/id3v2/id3_error.cpp b/Src/id3v2/id3_error.cpp
new file mode 100644
index 000000000..5eb8d862f
--- /dev/null
+++ b/Src/id3v2/id3_error.cpp
@@ -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
diff --git a/Src/id3v2/id3_error.h b/Src/id3v2/id3_error.h
new file mode 100644
index 000000000..b8948fc6a
--- /dev/null
+++ b/Src/id3v2/id3_error.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_externals.h b/Src/id3v2/id3_externals.h
new file mode 100644
index 000000000..31e253c33
--- /dev/null
+++ b/Src/id3v2/id3_externals.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_field.cpp b/Src/id3v2/id3_field.cpp
new file mode 100644
index 000000000..4b21cb777
--- /dev/null
+++ b/Src/id3v2/id3_field.cpp
@@ -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;
+}
+
+
diff --git a/Src/id3v2/id3_field.h b/Src/id3v2/id3_field.h
new file mode 100644
index 000000000..0c17a761c
--- /dev/null
+++ b/Src/id3v2/id3_field.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_field_binary.cpp b/Src/id3v2/id3_field_binary.cpp
new file mode 100644
index 000000000..47c51be63
--- /dev/null
+++ b/Src/id3v2/id3_field_binary.cpp
@@ -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;
+} \ No newline at end of file
diff --git a/Src/id3v2/id3_field_integer.cpp b/Src/id3v2/id3_field_integer.cpp
new file mode 100644
index 000000000..41f06d978
--- /dev/null
+++ b/Src/id3v2/id3_field_integer.cpp
@@ -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;
+}
diff --git a/Src/id3v2/id3_field_string_ascii.cpp b/Src/id3v2/id3_field_string_ascii.cpp
new file mode 100644
index 000000000..cee763483
--- /dev/null
+++ b/Src/id3v2/id3_field_string_ascii.cpp
@@ -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;
+}
+
+
diff --git a/Src/id3v2/id3_field_string_unicode.cpp b/Src/id3v2/id3_field_string_unicode.cpp
new file mode 100644
index 000000000..4e84943d3
--- /dev/null
+++ b/Src/id3v2/id3_field_string_unicode.cpp
@@ -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;
+}
+
+
diff --git a/Src/id3v2/id3_frame.cpp b/Src/id3v2/id3_frame.cpp
new file mode 100644
index 000000000..dd22f43b7
--- /dev/null
+++ b/Src/id3v2/id3_frame.cpp
@@ -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;
+}
diff --git a/Src/id3v2/id3_frame.h b/Src/id3v2/id3_frame.h
new file mode 100644
index 000000000..ca40caf1d
--- /dev/null
+++ b/Src/id3v2/id3_frame.h
@@ -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
+};
+
+
diff --git a/Src/id3v2/id3_frame_parse.cpp b/Src/id3v2/id3_frame_parse.cpp
new file mode 100644
index 000000000..5d2107e64
--- /dev/null
+++ b/Src/id3v2/id3_frame_parse.cpp
@@ -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;
+}
+
+
diff --git a/Src/id3v2/id3_frame_render.cpp b/Src/id3v2/id3_frame_render.cpp
new file mode 100644
index 000000000..acc2cdbf8
--- /dev/null
+++ b/Src/id3v2/id3_frame_render.cpp
@@ -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;
+}
+
+
diff --git a/Src/id3v2/id3_header.cpp b/Src/id3v2/id3_header.cpp
new file mode 100644
index 000000000..7da3592ec
--- /dev/null
+++ b/Src/id3v2/id3_header.cpp
@@ -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;
+}
+
+
diff --git a/Src/id3v2/id3_header.h b/Src/id3v2/id3_header.h
new file mode 100644
index 000000000..18252c8e3
--- /dev/null
+++ b/Src/id3v2/id3_header.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_header_frame.cpp b/Src/id3v2/id3_header_frame.cpp
new file mode 100644
index 000000000..4f7379bc1
--- /dev/null
+++ b/Src/id3v2/id3_header_frame.cpp
@@ -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;
+} \ No newline at end of file
diff --git a/Src/id3v2/id3_header_frame.h b/Src/id3v2/id3_header_frame.h
new file mode 100644
index 000000000..809c7bcc3
--- /dev/null
+++ b/Src/id3v2/id3_header_frame.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_header_tag.cpp b/Src/id3v2/id3_header_tag.cpp
new file mode 100644
index 000000000..252cf2bee
--- /dev/null
+++ b/Src/id3v2/id3_header_tag.cpp
@@ -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;
+}
+
+
diff --git a/Src/id3v2/id3_header_tag.h b/Src/id3v2/id3_header_tag.h
new file mode 100644
index 000000000..04e876910
--- /dev/null
+++ b/Src/id3v2/id3_header_tag.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_int28.cpp b/Src/id3v2/id3_int28.cpp
new file mode 100644
index 000000000..ed714a721
--- /dev/null
+++ b/Src/id3v2/id3_int28.cpp
@@ -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 ];
+}
+
diff --git a/Src/id3v2/id3_int28.h b/Src/id3v2/id3_int28.h
new file mode 100644
index 000000000..ab1cb51c3
--- /dev/null
+++ b/Src/id3v2/id3_int28.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_misc_support.cpp b/Src/id3v2/id3_misc_support.cpp
new file mode 100644
index 000000000..75be26c8f
--- /dev/null
+++ b/Src/id3v2/id3_misc_support.cpp
@@ -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;
+}
+
+
diff --git a/Src/id3v2/id3_misc_support.h b/Src/id3v2/id3_misc_support.h
new file mode 100644
index 000000000..a17ebfeaa
--- /dev/null
+++ b/Src/id3v2/id3_misc_support.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_tag.cpp b/Src/id3v2/id3_tag.cpp
new file mode 100644
index 000000000..1fa1bcd2b
--- /dev/null
+++ b/Src/id3v2/id3_tag.cpp
@@ -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;
+}
+
+
diff --git a/Src/id3v2/id3_tag.h b/Src/id3v2/id3_tag.h
new file mode 100644
index 000000000..cb2192974
--- /dev/null
+++ b/Src/id3v2/id3_tag.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_tag_file.cpp b/Src/id3v2/id3_tag_file.cpp
new file mode 100644
index 000000000..984be30eb
--- /dev/null
+++ b/Src/id3v2/id3_tag_file.cpp
@@ -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"
+
+
diff --git a/Src/id3v2/id3_tag_find.cpp b/Src/id3v2/id3_tag_find.cpp
new file mode 100644
index 000000000..8b342bf66
--- /dev/null
+++ b/Src/id3v2/id3_tag_find.cpp
@@ -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);
+}
+
+
diff --git a/Src/id3v2/id3_tag_parse.cpp b/Src/id3v2/id3_tag_parse.cpp
new file mode 100644
index 000000000..77734bcf8
--- /dev/null
+++ b/Src/id3v2/id3_tag_parse.cpp
@@ -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 ;
+}
+
diff --git a/Src/id3v2/id3_tag_parse_lyrics3.cpp b/Src/id3v2/id3_tag_parse_lyrics3.cpp
new file mode 100644
index 000000000..0ed3f8397
--- /dev/null
+++ b/Src/id3v2/id3_tag_parse_lyrics3.cpp
@@ -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 ;
+}
+*/
+
diff --git a/Src/id3v2/id3_tag_parse_v1.cpp b/Src/id3v2/id3_tag_parse_v1.cpp
new file mode 100644
index 000000000..09a0f0832
--- /dev/null
+++ b/Src/id3v2/id3_tag_parse_v1.cpp
@@ -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"
+
+
+
+
diff --git a/Src/id3v2/id3_tag_render.cpp b/Src/id3v2/id3_tag_render.cpp
new file mode 100644
index 000000000..3e30167f1
--- /dev/null
+++ b/Src/id3v2/id3_tag_render.cpp
@@ -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;
+}
+
+
diff --git a/Src/id3v2/id3_tag_sync.cpp b/Src/id3v2/id3_tag_sync.cpp
new file mode 100644
index 000000000..75aef393b
--- /dev/null
+++ b/Src/id3v2/id3_tag_sync.cpp
@@ -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 ;
+} \ No newline at end of file
diff --git a/Src/id3v2/id3_types.h b/Src/id3v2/id3_types.h
new file mode 100644
index 000000000..aae486449
--- /dev/null
+++ b/Src/id3v2/id3_types.h
@@ -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
+
+
diff --git a/Src/id3v2/id3_version.h b/Src/id3v2/id3_version.h
new file mode 100644
index 000000000..03d9a7ee5
--- /dev/null
+++ b/Src/id3v2/id3_version.h
@@ -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
+
+
diff --git a/Src/id3v2/id3v2.vcxproj b/Src/id3v2/id3v2.vcxproj
new file mode 100644
index 000000000..1ec49196d
--- /dev/null
+++ b/Src/id3v2/id3v2.vcxproj
@@ -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> \ No newline at end of file
diff --git a/Src/id3v2/id3v2.vcxproj.filters b/Src/id3v2/id3v2.vcxproj.filters
new file mode 100644
index 000000000..460a19421
--- /dev/null
+++ b/Src/id3v2/id3v2.vcxproj.filters
@@ -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> \ No newline at end of file