comparison src/libid3tag/compat.gperf @ 2503:10692383c103 trunk

[svn] first try for libid3tag integration. this improved libid3tag supports vfs operations and is capable of adding id3v2 tag to files which doesn't have id3v2 tag ever.
author yaz
date Sun, 11 Feb 2007 05:19:07 -0800
parents
children
comparison
equal deleted inserted replaced
2502:b7be0af74307 2503:10692383c103
1 %{
2 /*
3 * libid3tag - ID3 tag manipulation library
4 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * $Id: compat.gperf,v 1.11 2004/01/23 09:41:32 rob Exp $
21 */
22
23 # ifdef HAVE_CONFIG_H
24 # include "config.h"
25 # endif
26
27 # include "global.h"
28
29 # include <stdlib.h>
30 # include <string.h>
31
32 # ifdef HAVE_ASSERT_H
33 # include <assert.h>
34 # endif
35
36 # include "id3tag.h"
37 # include "compat.h"
38 # include "frame.h"
39 # include "field.h"
40 # include "parse.h"
41 # include "ucs4.h"
42
43 # define EQ(id) #id, 0
44 # define OBSOLETE 0, 0
45 # define TX(id) #id, translate_##id
46
47 static id3_compat_func_t translate_TCON;
48 %}
49 struct id3_compat;
50 %%
51 #
52 # ID3v2.2 and ID3v2.3 frames
53 #
54 # Only obsolete frames or frames with an equivalent ID3v2.4 frame ID are
55 # listed here. If a frame ID is not listed, it is assumed that the same
56 # frame ID is itself the equivalent ID3v2.4 frame ID.
57 #
58 # This list may also include frames with new content interpretations; the
59 # translation function will rewrite the contents to comply with ID3v2.4.
60 #
61 BUF, EQ(RBUF) /* Recommended buffer size */
62 CNT, EQ(PCNT) /* Play counter */
63 COM, EQ(COMM) /* Comments */
64 CRA, EQ(AENC) /* Audio encryption */
65 CRM, OBSOLETE /* Encrypted meta frame [obsolete] */
66 EQU, OBSOLETE /* Equalization [obsolete] */
67 EQUA, OBSOLETE /* Equalization [obsolete] */
68 ETC, EQ(ETCO) /* Event timing codes */
69 GEO, EQ(GEOB) /* General encapsulated object */
70 IPL, EQ(TIPL) /* Involved people list */
71 IPLS, EQ(TIPL) /* Involved people list */
72 LNK, EQ(LINK) /* Linked information */
73 MCI, EQ(MCDI) /* Music CD identifier */
74 MLL, EQ(MLLT) /* MPEG location lookup table */
75 PIC, EQ(APIC) /* Attached picture */
76 POP, EQ(POPM) /* Popularimeter */
77 REV, EQ(RVRB) /* Reverb */
78 RVA, OBSOLETE /* Relative volume adjustment [obsolete] */
79 RVAD, OBSOLETE /* Relative volume adjustment [obsolete] */
80 SLT, EQ(SYLT) /* Synchronised lyric/text */
81 STC, EQ(SYTC) /* Synchronised tempo codes */
82 TAL, EQ(TALB) /* Album/movie/show title */
83 TBP, EQ(TBPM) /* BPM (beats per minute) */
84 TCM, EQ(TCOM) /* Composer */
85 TCO, TX(TCON) /* Content type */
86 TCON, TX(TCON) /* Content type */
87 TCR, EQ(TCOP) /* Copyright message */
88 TDA, OBSOLETE /* Date [obsolete] */
89 TDAT, OBSOLETE /* Date [obsolete] */
90 TDY, EQ(TDLY) /* Playlist delay */
91 TEN, EQ(TENC) /* Encoded by */
92 TFT, EQ(TFLT) /* File type */
93 TIM, OBSOLETE /* Time [obsolete] */
94 TIME, OBSOLETE /* Time [obsolete] */
95 TKE, EQ(TKEY) /* Initial key */
96 TLA, EQ(TLAN) /* Language(s) */
97 TLE, EQ(TLEN) /* Length */
98 TMT, EQ(TMED) /* Media type */
99 TOA, EQ(TOPE) /* Original artist(s)/performer(s) */
100 TOF, EQ(TOFN) /* Original filename */
101 TOL, EQ(TOLY) /* Original lyricist(s)/text writer(s) */
102 TOR, EQ(TDOR) /* Original release year [obsolete] */
103 TORY, EQ(TDOR) /* Original release year [obsolete] */
104 TOT, EQ(TOAL) /* Original album/movie/show title */
105 TP1, EQ(TPE1) /* Lead performer(s)/soloist(s) */
106 TP2, EQ(TPE2) /* Band/orchestra/accompaniment */
107 TP3, EQ(TPE3) /* Conductor/performer refinement */
108 TP4, EQ(TPE4) /* Interpreted, remixed, or otherwise modified by */
109 TPA, EQ(TPOS) /* Part of a set */
110 TPB, EQ(TPUB) /* Publisher */
111 TRC, EQ(TSRC) /* ISRC (international standard recording code) */
112 TRD, OBSOLETE /* Recording dates [obsolete] */
113 TRDA, OBSOLETE /* Recording dates [obsolete] */
114 TRK, EQ(TRCK) /* Track number/position in set */
115 TSI, OBSOLETE /* Size [obsolete] */
116 TSIZ, OBSOLETE /* Size [obsolete] */
117 TSS, EQ(TSSE) /* Software/hardware and settings used for encoding */
118 TT1, EQ(TIT1) /* Content group description */
119 TT2, EQ(TIT2) /* Title/songname/content description */
120 TT3, EQ(TIT3) /* Subtitle/description refinement */
121 TXT, EQ(TEXT) /* Lyricist/text writer */
122 TXX, EQ(TXXX) /* User defined text information frame */
123 TYE, OBSOLETE /* Year [obsolete] */
124 TYER, OBSOLETE /* Year [obsolete] */
125 UFI, EQ(UFID) /* Unique file identifier */
126 ULT, EQ(USLT) /* Unsynchronised lyric/text transcription */
127 WAF, EQ(WOAF) /* Official audio file webpage */
128 WAR, EQ(WOAR) /* Official artist/performer webpage */
129 WAS, EQ(WOAS) /* Official audio source webpage */
130 WCM, EQ(WCOM) /* Commercial information */
131 WCP, EQ(WCOP) /* Copyright/legal information */
132 WPB, EQ(WPUB) /* Publishers official webpage */
133 WXX, EQ(WXXX) /* User defined URL link frame */
134 %%
135
136 static
137 int translate_TCON(struct id3_frame *frame, char const *oldid,
138 id3_byte_t const *data, id3_length_t length)
139 {
140 id3_byte_t const *end;
141 enum id3_field_textencoding encoding;
142 id3_ucs4_t *string = 0, *ptr, *endptr;
143 int result = 0;
144
145 /* translate old TCON syntax into multiple strings */
146
147 assert(frame->nfields == 2);
148
149 encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1;
150
151 end = data + length;
152
153 if (id3_field_parse(&frame->fields[0], &data, end - data, &encoding) == -1)
154 goto fail;
155
156 string = id3_parse_string(&data, end - data, encoding, 0);
157 if (string == 0)
158 goto fail;
159
160 ptr = string;
161 while (*ptr == '(') {
162 if (*++ptr == '(')
163 break;
164
165 endptr = ptr;
166 while (*endptr && *endptr != ')')
167 ++endptr;
168
169 if (*endptr)
170 *endptr++ = 0;
171
172 if (id3_field_addstring(&frame->fields[1], ptr) == -1)
173 goto fail;
174
175 ptr = endptr;
176 }
177
178 if (*ptr && id3_field_addstring(&frame->fields[1], ptr) == -1)
179 goto fail;
180
181 if (0) {
182 fail:
183 result = -1;
184 }
185
186 if (string)
187 free(string);
188
189 return result;
190 }
191
192 /*
193 * NAME: compat->fixup()
194 * DESCRIPTION: finish compatibility translations
195 */
196 int id3_compat_fixup(struct id3_tag *tag)
197 {
198 struct id3_frame *frame;
199 unsigned int index;
200 id3_ucs4_t timestamp[17] = { 0 };
201 int result = 0;
202
203 /* create a TDRC frame from obsolete TYER/TDAT/TIME frames */
204
205 /*
206 * TYE/TYER: YYYY
207 * TDA/TDAT: DDMM
208 * TIM/TIME: HHMM
209 *
210 * TDRC: yyyy-MM-ddTHH:mm
211 */
212
213 index = 0;
214 while ((frame = id3_tag_findframe(tag, ID3_FRAME_OBSOLETE, index++))) {
215 char const *id;
216 id3_byte_t const *data, *end;
217 id3_length_t length;
218 enum id3_field_textencoding encoding;
219 id3_ucs4_t *string;
220
221 id = id3_field_getframeid(&frame->fields[0]);
222 assert(id);
223
224 if (strcmp(id, "TYER") != 0 && strcmp(id, "YTYE") != 0 &&
225 strcmp(id, "TDAT") != 0 && strcmp(id, "YTDA") != 0 &&
226 strcmp(id, "TIME") != 0 && strcmp(id, "YTIM") != 0)
227 continue;
228
229 data = id3_field_getbinarydata(&frame->fields[1], &length);
230 assert(data);
231
232 if (length < 1)
233 continue;
234
235 end = data + length;
236
237 encoding = id3_parse_uint(&data, 1);
238 string = id3_parse_string(&data, end - data, encoding, 0);
239
240 if (string == 0)
241 continue;
242
243 if (id3_ucs4_length(string) < 4) {
244 free(string);
245 continue;
246 }
247
248 if (strcmp(id, "TYER") == 0 ||
249 strcmp(id, "YTYE") == 0) {
250 timestamp[0] = string[0];
251 timestamp[1] = string[1];
252 timestamp[2] = string[2];
253 timestamp[3] = string[3];
254 }
255 else if (strcmp(id, "TDAT") == 0 ||
256 strcmp(id, "YTDA") == 0) {
257 timestamp[4] = '-';
258 timestamp[5] = string[2];
259 timestamp[6] = string[3];
260 timestamp[7] = '-';
261 timestamp[8] = string[0];
262 timestamp[9] = string[1];
263 }
264 else { /* TIME or YTIM */
265 timestamp[10] = 'T';
266 timestamp[11] = string[0];
267 timestamp[12] = string[1];
268 timestamp[13] = ':';
269 timestamp[14] = string[2];
270 timestamp[15] = string[3];
271 }
272
273 free(string);
274 }
275
276 if (timestamp[0]) {
277 id3_ucs4_t *strings;
278
279 frame = id3_frame_new("TDRC");
280 if (frame == 0)
281 goto fail;
282
283 strings = timestamp;
284
285 if (id3_field_settextencoding(&frame->fields[0],
286 ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1 ||
287 id3_field_setstrings(&frame->fields[1], 1, &strings) == -1 ||
288 id3_tag_attachframe(tag, frame) == -1) {
289 id3_frame_delete(frame);
290 goto fail;
291 }
292 }
293
294 if (0) {
295 fail:
296 result = -1;
297 }
298
299 return result;
300 }