tag: id3v2: Do not convert obsolete TDA/TDAT frames to TDRC frames, otherwise the four-digit number will be interp...

Original commit message from CVS:
* gst-libs/gst/tag/id3v2.c: (id3demux_id3v2_frames_to_tag_list):
* gst-libs/gst/tag/id3v2.h:
* gst-libs/gst/tag/id3v2frames.c: (id3demux_id3v2_parse_frame),
(parse_obsolete_tdat_frame):
Do not convert obsolete TDA/TDAT frames to TDRC frames, otherwise
the four-digit number will be interpreted as a year, whereas it is
month and day in DDMM format. Instead, parse TDAT frames and fix up
the date in the GST_TAG_DATE tag later if we also extracted a year.
Fixes #407349.
This commit is contained in:
Tim-Philipp Müller 2007-03-06 18:16:49 +00:00 committed by Tim-Philipp Müller
parent 763eea481e
commit c76c78670d
3 changed files with 44 additions and 6 deletions

View file

@ -242,7 +242,6 @@ const struct ID3v2FrameIDConvert
} frame_id_conversions[] = { } frame_id_conversions[] = {
/* 2.3.x frames */ /* 2.3.x frames */
{ {
"TDAT", "TDRC"}, {
"TORY", "TDOR"}, { "TORY", "TDOR"}, {
"TYER", "TDRC"}, "TYER", "TDRC"},
/* 2.2.x frames */ /* 2.2.x frames */
@ -266,7 +265,7 @@ const struct ID3v2FrameIDConvert
"TCM", "TCOM"}, { "TCM", "TCOM"}, {
"TCO", "TCON"}, { "TCO", "TCON"}, {
"TCR", "TCOP"}, { "TCR", "TCOP"}, {
"TDA", "TDRC"}, { "TDA", "TDAT"}, { /* obsolete, but we need to parse it anyway */
"TDY", "TDLY"}, { "TDY", "TDLY"}, {
"TEN", "TENC"}, { "TEN", "TENC"}, {
"TFT", "TFLT"}, { "TFT", "TFLT"}, {
@ -500,5 +499,18 @@ id3demux_id3v2_frames_to_tag_list (ID3TagsWorking * work, guint size)
return ID3TAGS_BROKEN_TAG; return ID3TAGS_BROKEN_TAG;
} }
/* Set day/month now if they were in a separate (obsolete) TDAT frame */
if (work->pending_day != 0 && work->pending_month != 0) {
GDate *date = NULL;
if (gst_tag_list_get_date (work->tags, GST_TAG_DATE, &date)) {
g_date_set_day (date, work->pending_day);
g_date_set_month (date, work->pending_month);
gst_tag_list_add (work->tags, GST_TAG_MERGE_REPLACE, GST_TAG_DATE,
date, NULL);
g_date_free (date);
}
}
return ID3TAGS_READ_TAG; return ID3TAGS_READ_TAG;
} }

View file

@ -78,6 +78,10 @@ typedef struct {
/* Previous genre string, for simple duplicate removal */ /* Previous genre string, for simple duplicate removal */
gchar *prev_genre; gchar *prev_genre;
/* To collect day/month from obsolete TDAT frame if it exists */
guint pending_month;
guint pending_day;
} ID3TagsWorking; } ID3TagsWorking;
enum { enum {

View file

@ -44,6 +44,7 @@ static gchar *parse_user_text_identification_frame (ID3TagsWorking * work,
static gchar *parse_unique_file_identifier (ID3TagsWorking * work, static gchar *parse_unique_file_identifier (ID3TagsWorking * work,
const gchar ** tag_name); const gchar ** tag_name);
static gboolean parse_relative_volume_adjustment_two (ID3TagsWorking * work); static gboolean parse_relative_volume_adjustment_two (ID3TagsWorking * work);
static void parse_obsolete_tdat_frame (ID3TagsWorking * work);
static gboolean id3v2_tag_to_taglist (ID3TagsWorking * work, static gboolean id3v2_tag_to_taglist (ID3TagsWorking * work,
const gchar * tag_name, const gchar * tag_str); const gchar * tag_name, const gchar * tag_str);
/* Parse a single string into an array of gchar* */ /* Parse a single string into an array of gchar* */
@ -100,6 +101,7 @@ id3demux_id3v2_parse_frame (ID3TagsWorking * work)
if (tag_name == NULL && if (tag_name == NULL &&
strncmp (work->frame_id, "RVA2", 4) != 0 && strncmp (work->frame_id, "RVA2", 4) != 0 &&
strncmp (work->frame_id, "TXXX", 4) != 0 && strncmp (work->frame_id, "TXXX", 4) != 0 &&
strncmp (work->frame_id, "TDAT", 4) != 0 &&
strncmp (work->frame_id, "UFID", 4) != 0) { strncmp (work->frame_id, "UFID", 4) != 0) {
return FALSE; return FALSE;
} }
@ -152,12 +154,15 @@ id3demux_id3v2_parse_frame (ID3TagsWorking * work)
} }
if (work->frame_id[0] == 'T') { if (work->frame_id[0] == 'T') {
if (strcmp (work->frame_id, "TXXX") != 0) { if (strcmp (work->frame_id, "TDAT") == 0) {
/* Text identification frame */ parse_obsolete_tdat_frame (work);
tag_fields = parse_text_identification_frame (work); result = TRUE;
} else { } else if (strcmp (work->frame_id, "TXXX") == 0) {
/* Handle user text frame */ /* Handle user text frame */
tag_str = parse_user_text_identification_frame (work, &tag_name); tag_str = parse_user_text_identification_frame (work, &tag_name);
} else {
/* Text identification frame */
tag_fields = parse_text_identification_frame (work);
} }
} else if (!strcmp (work->frame_id, "COMM")) { } else if (!strcmp (work->frame_id, "COMM")) {
/* Comment */ /* Comment */
@ -635,6 +640,23 @@ parse_relative_volume_adjustment_two (ID3TagsWorking * work)
return (gain_tag_name != NULL || peak_tag_name != NULL); return (gain_tag_name != NULL || peak_tag_name != NULL);
} }
static void
parse_obsolete_tdat_frame (ID3TagsWorking * work)
{
if (work->parse_size >= 5 &&
work->parse_data[0] == ID3V2_ENCODING_ISO8859 &&
g_ascii_isdigit (work->parse_data[1]) &&
g_ascii_isdigit (work->parse_data[2]) &&
g_ascii_isdigit (work->parse_data[3]) &&
g_ascii_isdigit (work->parse_data[4])) {
work->pending_day = (10 * g_ascii_digit_value (work->parse_data[1])) +
g_ascii_digit_value (work->parse_data[2]);
work->pending_month = (10 * g_ascii_digit_value (work->parse_data[3])) +
g_ascii_digit_value (work->parse_data[4]);
GST_LOG ("date (dd/mm) %02u/%02u", work->pending_day, work->pending_month);
}
}
static gboolean static gboolean
id3v2_tag_to_taglist (ID3TagsWorking * work, const gchar * tag_name, id3v2_tag_to_taglist (ID3TagsWorking * work, const gchar * tag_name,
const gchar * tag_str) const gchar * tag_str)