1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef _MSC_VER
#include "win32/zlib.h"
#else
#include <zlib.h>
#endif
#define ID3_BLOCK_SIZE 4096
// ID3v1 field frames
#define ID3_FRAME_TITLE "TIT2"
#define ID3_FRAME_ARTIST "TPE1"
#define ID3_FRAME_ALBUM "TALB"
#define ID3_FRAME_TRACK "TRCK"
#define ID3_FRAME_YEAR "TDRC"
#define ID3_FRAME_GENRE "TCON"
#define ID3_FRAME_COMMENT "COMM"
// Tag flags
enum {
ID3_TAG_FLAG_UNSYNCHRONISATION = 0x80,
ID3_TAG_FLAG_EXTENDEDHEADER = 0x40,
ID3_TAG_FLAG_EXPERIMENTALINDICATOR = 0x20,
ID3_TAG_FLAG_FOOTERPRESENT = 0x10
};
// Frame flags
enum {
// v2.3 flags
ID3_FRAME_FLAG_V23_COMPRESSION = 0x0080,
ID3_FRAME_FLAG_V23_ENCRYPTION = 0x0040,
ID3_FRAME_FLAG_V23_GROUPINGIDENTITY = 0x0020,
// v2.4 flags
ID3_FRAME_FLAG_V24_GROUPINGIDENTITY = 0x0040,
ID3_FRAME_FLAG_V24_COMPRESSION = 0x0008,
ID3_FRAME_FLAG_V24_ENCRYPTION = 0x0004,
ID3_FRAME_FLAG_V24_UNSYNCHRONISATION = 0x0002,
ID3_FRAME_FLAG_V24_DATALENGTHINDICATOR = 0x0001
};
enum id3_field_type {
ID3_FIELD_TYPE_TEXTENCODING,
ID3_FIELD_TYPE_LATIN1,
ID3_FIELD_TYPE_LATIN1LIST,
ID3_FIELD_TYPE_STRING,
ID3_FIELD_TYPE_STRINGFULL,
ID3_FIELD_TYPE_STRINGLIST,
ID3_FIELD_TYPE_LANGUAGE,
ID3_FIELD_TYPE_FRAMEID,
ID3_FIELD_TYPE_DATE,
ID3_FIELD_TYPE_INT8,
ID3_FIELD_TYPE_INT16,
ID3_FIELD_TYPE_INT24,
ID3_FIELD_TYPE_INT32,
ID3_FIELD_TYPE_INT32PLUS,
ID3_FIELD_TYPE_BINARYDATA
};
enum id3_field_textencoding {
ISO_8859_1 = 0x00,
UTF_16 = 0x01,
UTF_16BE = 0x02,
UTF_8 = 0x03
};
typedef struct id3info {
PerlIO *infile;
char *file;
Buffer *buf;
HV *info;
HV *tags;
// scratch buffer used for UTF-8 decoding each frame
Buffer *utf8;
uint8_t version_major;
uint8_t version_minor;
uint8_t flags;
uint8_t tag_data_safe;
uint32_t size;
uint32_t size_remain;
uint32_t offset; // For non-MP3, offset into file where tag begins
} id3info;
typedef struct id3_compat {
char const *id;
char const *equiv;
} id3_compat;
typedef struct id3_frametype {
char const *id;
unsigned int nfields;
enum id3_field_type const *fields;
char const *description;
} id3_frametype;
extern struct id3_frametype const id3_frametype_text;
extern struct id3_frametype const id3_frametype_url;
extern struct id3_frametype const id3_frametype_experimental;
extern struct id3_frametype const id3_frametype_unknown;
extern struct id3_frametype const id3_frametype_obsolete;
int parse_id3(PerlIO *infile, char *file, HV *info, HV *tags, uint32_t seek, off_t file_size);
int _id3_parse_v1(id3info *id3);
int _id3_parse_v2(id3info *id3);
int _id3_parse_v2_frame(id3info *id3);
int _id3_parse_v2_frame_data(id3info *id3, char const *id, uint32_t size, id3_frametype const *frametype);
void _id3_set_array_tag(id3info *id3, char const *id, AV *framedata);
uint32_t _id3_get_v1_utf8_string(id3info *id3, SV **string, uint32_t len);
uint32_t _id3_get_utf8_string(id3info *id3, SV **string, uint32_t len, uint8_t encoding);
uint32_t _id3_parse_rvad(id3info *id3, char const *id, uint32_t size);
uint32_t _id3_parse_rgad(id3info *id3);
uint32_t _id3_parse_rva2(id3info *id3, uint32_t len, AV *framedata);
uint32_t _id3_parse_sylt(id3info *id3, uint8_t encoding, uint32_t len, AV *framedata);
uint32_t _id3_parse_etco(id3info *id3, uint32_t len, AV *framedata);
void _id3_convert_tdrc(id3info *id3);
uint32_t _id3_deunsync(unsigned char *data, uint32_t length);
void _id3_skip(id3info *id3, uint32_t size);
char const * _id3_genre_index(unsigned int index);
char const * _id3_genre_name(char const *string);
id3_compat const * _id3_compat_lookup(register char const *, register unsigned int);
id3_frametype const * _id3_frametype_lookup(register char const *, register unsigned int);
|