e2d2baece9
git-svn-id: https://svn.musicpd.org/mpd/trunk@196 09075e82-0dd4-0310-85a5-a0d7c8717e4f
298 lines
8.3 KiB
Plaintext
298 lines
8.3 KiB
Plaintext
%{
|
|
/*
|
|
* libid3tag - ID3 tag manipulation library
|
|
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
|
|
*
|
|
* 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
|
|
*
|
|
* $Id: compat.gperf,v 1.11 2004/01/23 09:41:32 rob Exp $
|
|
*/
|
|
|
|
# ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
# endif
|
|
|
|
# include "global.h"
|
|
|
|
# include <stdlib.h>
|
|
# include <string.h>
|
|
|
|
# ifdef HAVE_ASSERT_H
|
|
# include <assert.h>
|
|
# endif
|
|
|
|
# include "id3tag.h"
|
|
# include "compat.h"
|
|
# include "frame.h"
|
|
# include "field.h"
|
|
# include "parse.h"
|
|
# include "ucs4.h"
|
|
|
|
# define EQ(id) #id, 0
|
|
# define OBSOLETE 0, 0
|
|
# define TX(id) #id, translate_##id
|
|
|
|
static id3_compat_func_t translate_TCON;
|
|
%}
|
|
struct id3_compat;
|
|
%%
|
|
#
|
|
# ID3v2.2 and ID3v2.3 frames
|
|
#
|
|
# Only obsolete frames or frames with an equivalent ID3v2.4 frame ID are
|
|
# listed here. If a frame ID is not listed, it is assumed that the same
|
|
# frame ID is itself the equivalent ID3v2.4 frame ID.
|
|
#
|
|
# This list may also include frames with new content interpretations; the
|
|
# translation function will rewrite the contents to comply with ID3v2.4.
|
|
#
|
|
BUF, EQ(RBUF) /* Recommended buffer size */
|
|
CNT, EQ(PCNT) /* Play counter */
|
|
COM, EQ(COMM) /* Comments */
|
|
CRA, EQ(AENC) /* Audio encryption */
|
|
CRM, OBSOLETE /* Encrypted meta frame [obsolete] */
|
|
EQU, OBSOLETE /* Equalization [obsolete] */
|
|
EQUA, OBSOLETE /* Equalization [obsolete] */
|
|
ETC, EQ(ETCO) /* Event timing codes */
|
|
GEO, EQ(GEOB) /* General encapsulated object */
|
|
IPL, EQ(TIPL) /* Involved people list */
|
|
IPLS, EQ(TIPL) /* Involved people list */
|
|
LNK, EQ(LINK) /* Linked information */
|
|
MCI, EQ(MCDI) /* Music CD identifier */
|
|
MLL, EQ(MLLT) /* MPEG location lookup table */
|
|
PIC, EQ(APIC) /* Attached picture */
|
|
POP, EQ(POPM) /* Popularimeter */
|
|
REV, EQ(RVRB) /* Reverb */
|
|
RVA, OBSOLETE /* Relative volume adjustment [obsolete] */
|
|
RVAD, OBSOLETE /* Relative volume adjustment [obsolete] */
|
|
SLT, EQ(SYLT) /* Synchronised lyric/text */
|
|
STC, EQ(SYTC) /* Synchronised tempo codes */
|
|
TAL, EQ(TALB) /* Album/movie/show title */
|
|
TBP, EQ(TBPM) /* BPM (beats per minute) */
|
|
TCM, EQ(TCOM) /* Composer */
|
|
TCO, TX(TCON) /* Content type */
|
|
TCON, TX(TCON) /* Content type */
|
|
TCR, EQ(TCOP) /* Copyright message */
|
|
TDA, OBSOLETE /* Date [obsolete] */
|
|
TDAT, OBSOLETE /* Date [obsolete] */
|
|
TDY, EQ(TDLY) /* Playlist delay */
|
|
TEN, EQ(TENC) /* Encoded by */
|
|
TFT, EQ(TFLT) /* File type */
|
|
TIM, OBSOLETE /* Time [obsolete] */
|
|
TIME, OBSOLETE /* Time [obsolete] */
|
|
TKE, EQ(TKEY) /* Initial key */
|
|
TLA, EQ(TLAN) /* Language(s) */
|
|
TLE, EQ(TLEN) /* Length */
|
|
TMT, EQ(TMED) /* Media type */
|
|
TOA, EQ(TOPE) /* Original artist(s)/performer(s) */
|
|
TOF, EQ(TOFN) /* Original filename */
|
|
TOL, EQ(TOLY) /* Original lyricist(s)/text writer(s) */
|
|
TOR, EQ(TDOR) /* Original release year [obsolete] */
|
|
TORY, EQ(TDOR) /* Original release year [obsolete] */
|
|
TOT, EQ(TOAL) /* Original album/movie/show title */
|
|
TP1, EQ(TPE1) /* Lead performer(s)/soloist(s) */
|
|
TP2, EQ(TPE2) /* Band/orchestra/accompaniment */
|
|
TP3, EQ(TPE3) /* Conductor/performer refinement */
|
|
TP4, EQ(TPE4) /* Interpreted, remixed, or otherwise modified by */
|
|
TPA, EQ(TPOS) /* Part of a set */
|
|
TPB, EQ(TPUB) /* Publisher */
|
|
TRC, EQ(TSRC) /* ISRC (international standard recording code) */
|
|
TRD, OBSOLETE /* Recording dates [obsolete] */
|
|
TRDA, OBSOLETE /* Recording dates [obsolete] */
|
|
TRK, EQ(TRCK) /* Track number/position in set */
|
|
TSI, OBSOLETE /* Size [obsolete] */
|
|
TSIZ, OBSOLETE /* Size [obsolete] */
|
|
TSS, EQ(TSSE) /* Software/hardware and settings used for encoding */
|
|
TT1, EQ(TIT1) /* Content group description */
|
|
TT2, EQ(TIT2) /* Title/songname/content description */
|
|
TT3, EQ(TIT3) /* Subtitle/description refinement */
|
|
TXT, EQ(TEXT) /* Lyricist/text writer */
|
|
TXX, EQ(TXXX) /* User defined text information frame */
|
|
TYE, OBSOLETE /* Year [obsolete] */
|
|
TYER, OBSOLETE /* Year [obsolete] */
|
|
UFI, EQ(UFID) /* Unique file identifier */
|
|
ULT, EQ(USLT) /* Unsynchronised lyric/text transcription */
|
|
WAF, EQ(WOAF) /* Official audio file webpage */
|
|
WAR, EQ(WOAR) /* Official artist/performer webpage */
|
|
WAS, EQ(WOAS) /* Official audio source webpage */
|
|
WCM, EQ(WCOM) /* Commercial information */
|
|
WCP, EQ(WCOP) /* Copyright/legal information */
|
|
WPB, EQ(WPUB) /* Publishers official webpage */
|
|
WXX, EQ(WXXX) /* User defined URL link frame */
|
|
%%
|
|
|
|
static
|
|
int translate_TCON(struct id3_frame *frame, char const *oldid,
|
|
id3_byte_t const *data, id3_length_t length)
|
|
{
|
|
id3_byte_t const *end;
|
|
enum id3_field_textencoding encoding;
|
|
id3_ucs4_t *string = 0, *ptr, *endptr;
|
|
int result = 0;
|
|
|
|
/* translate old TCON syntax into multiple strings */
|
|
|
|
assert(frame->nfields == 2);
|
|
|
|
encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1;
|
|
|
|
end = data + length;
|
|
|
|
if (id3_field_parse(&frame->fields[0], &data, end - data, &encoding) == -1)
|
|
goto fail;
|
|
|
|
string = id3_parse_string(&data, end - data, encoding, 0);
|
|
if (string == 0)
|
|
goto fail;
|
|
|
|
ptr = string;
|
|
while (*ptr == '(') {
|
|
if (*++ptr == '(')
|
|
break;
|
|
|
|
endptr = ptr;
|
|
while (*endptr && *endptr != ')')
|
|
++endptr;
|
|
|
|
if (*endptr)
|
|
*endptr++ = 0;
|
|
|
|
if (id3_field_addstring(&frame->fields[1], ptr) == -1)
|
|
goto fail;
|
|
|
|
ptr = endptr;
|
|
}
|
|
|
|
if (*ptr && id3_field_addstring(&frame->fields[1], ptr) == -1)
|
|
goto fail;
|
|
|
|
if (0) {
|
|
fail:
|
|
result = -1;
|
|
}
|
|
|
|
if (string)
|
|
free(string);
|
|
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
* NAME: compat->fixup()
|
|
* DESCRIPTION: finish compatibility translations
|
|
*/
|
|
int id3_compat_fixup(struct id3_tag *tag)
|
|
{
|
|
struct id3_frame *frame;
|
|
unsigned int index;
|
|
id3_ucs4_t timestamp[17] = { 0 };
|
|
int result = 0;
|
|
|
|
/* create a TDRC frame from obsolete TYER/TDAT/TIME frames */
|
|
|
|
/*
|
|
* TYE/TYER: YYYY
|
|
* TDA/TDAT: DDMM
|
|
* TIM/TIME: HHMM
|
|
*
|
|
* TDRC: yyyy-MM-ddTHH:mm
|
|
*/
|
|
|
|
index = 0;
|
|
while ((frame = id3_tag_findframe(tag, ID3_FRAME_OBSOLETE, index++))) {
|
|
char const *id;
|
|
id3_byte_t const *data, *end;
|
|
id3_length_t length;
|
|
enum id3_field_textencoding encoding;
|
|
id3_ucs4_t *string;
|
|
|
|
id = id3_field_getframeid(&frame->fields[0]);
|
|
assert(id);
|
|
|
|
if (strcmp(id, "TYER") != 0 && strcmp(id, "YTYE") != 0 &&
|
|
strcmp(id, "TDAT") != 0 && strcmp(id, "YTDA") != 0 &&
|
|
strcmp(id, "TIME") != 0 && strcmp(id, "YTIM") != 0)
|
|
continue;
|
|
|
|
data = id3_field_getbinarydata(&frame->fields[1], &length);
|
|
assert(data);
|
|
|
|
if (length < 1)
|
|
continue;
|
|
|
|
end = data + length;
|
|
|
|
encoding = id3_parse_uint(&data, 1);
|
|
string = id3_parse_string(&data, end - data, encoding, 0);
|
|
|
|
if (id3_ucs4_length(string) < 4) {
|
|
free(string);
|
|
continue;
|
|
}
|
|
|
|
if (strcmp(id, "TYER") == 0 ||
|
|
strcmp(id, "YTYE") == 0) {
|
|
timestamp[0] = string[0];
|
|
timestamp[1] = string[1];
|
|
timestamp[2] = string[2];
|
|
timestamp[3] = string[3];
|
|
}
|
|
else if (strcmp(id, "TDAT") == 0 ||
|
|
strcmp(id, "YTDA") == 0) {
|
|
timestamp[4] = '-';
|
|
timestamp[5] = string[2];
|
|
timestamp[6] = string[3];
|
|
timestamp[7] = '-';
|
|
timestamp[8] = string[0];
|
|
timestamp[9] = string[1];
|
|
}
|
|
else { /* TIME or YTIM */
|
|
timestamp[10] = 'T';
|
|
timestamp[11] = string[0];
|
|
timestamp[12] = string[1];
|
|
timestamp[13] = ':';
|
|
timestamp[14] = string[2];
|
|
timestamp[15] = string[3];
|
|
}
|
|
|
|
free(string);
|
|
}
|
|
|
|
if (timestamp[0]) {
|
|
id3_ucs4_t *strings;
|
|
|
|
frame = id3_frame_new("TDRC");
|
|
if (frame == 0)
|
|
goto fail;
|
|
|
|
strings = timestamp;
|
|
|
|
if (id3_field_settextencoding(&frame->fields[0],
|
|
ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1 ||
|
|
id3_field_setstrings(&frame->fields[1], 1, &strings) == -1 ||
|
|
id3_tag_attachframe(tag, frame) == -1) {
|
|
id3_frame_delete(frame);
|
|
goto fail;
|
|
}
|
|
}
|
|
|
|
if (0) {
|
|
fail:
|
|
result = -1;
|
|
}
|
|
|
|
return result;
|
|
}
|