diff options
Diffstat (limited to 'libid3tag')
-rw-r--r-- | libid3tag/compat.gperf | 97 |
1 files changed, 95 insertions, 2 deletions
diff --git a/libid3tag/compat.gperf b/libid3tag/compat.gperf index 6fa1d4e..71e28d0 100644 --- a/libid3tag/compat.gperf +++ b/libid3tag/compat.gperf @@ -28,6 +28,7 @@ # include <stdlib.h> # include <string.h> +# include <ctype.h> # ifdef HAVE_ASSERT_H # include <assert.h> @@ -44,7 +45,7 @@ # define OBSOLETE 0, 0 # define TX(id) #id, translate_##id -static id3_compat_func_t translate_TCON; +static id3_compat_func_t translate_TCON, translate_APIC; %} struct id3_compat; %% @@ -72,7 +73,7 @@ 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 */ +PIC, TX(APIC) /* Attached picture */ POP, EQ(POPM) /* Popularimeter */ REV, EQ(RVRB) /* Reverb */ RVA, OBSOLETE /* Relative volume adjustment [obsolete] */ @@ -190,6 +191,98 @@ translate_TCON(struct id3_frame *frame, char const *oldid, return result; } +static const char * +translate_subtype(const id3_byte_t *in) +{ + static char lcin[4]; + static struct inout { + char *in; + char *out; + } subtype_trans[] = { + { "jpg", "jpeg" }, + { NULL } + }; + struct inout *p; + + lcin[0] = tolower(in[0]); + lcin[1] = tolower(in[1]); + lcin[2] = tolower(in[2]); + lcin[3] = 0; + for (p = subtype_trans; p->in; p++) + if (memcmp(p->in, in, 3) == 0) + return p->out; + return lcin; +} + +static id3_latin1_t * +str_to_mime_type(const id3_byte_t *str) +{ + const char *subtype = translate_subtype(str); + static const char prefix[] = "image/"; + char *ret; + + ret = malloc(sizeof(prefix) + strlen(subtype)); + if (ret) + strcat(strcpy(ret, prefix), subtype); + return (id3_latin1_t *) ret; +} + +static int +translate_APIC(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_FIELD_TEXTENCODING_ISO_8859_1; + int rc = 0; + + /* translate old PIC into APIC */ + + assert(frame->nfields == 5); + + end = data + length; + + do { + /* Encoding */ + if ((rc = id3_field_parse(&frame->fields[0], &data, + end - data, &encoding)) == -1) + break; + + /* MIME type: a 3-byte string in v2.2, as pointed out + in https://bugs.kde.org/show_bug.cgi?id=167786#c2 */ + if ((end - data) < 3) { + rc = -1; + break; + } + id3_field_finish(&frame->fields[1]); + frame->fields[1].latin1.ptr = str_to_mime_type(data); + if (!frame->fields[1].latin1.ptr) { + rc = -1; + break; + } + data += 3; + + /* Picture type */ + if ((rc = id3_field_parse(&frame->fields[2], &data, + end - data, &encoding)) == -1) + break; + /* Description */ + if ((rc = id3_field_parse(&frame->fields[3], &data, + end - data, &encoding)) == -1) + break; + /* Picture date */ + if ((rc = id3_field_parse(&frame->fields[4], &data, + end - data, &encoding)) == -1) + break; + } while (0); + + if (rc) { + /* FIXME: cleanup */ + ; + } + return rc; +} + /* * NAME: compat->fixup() * DESCRIPTION: finish compatibility translations |