+#ifdef HAVE_LIBID3TAG
+
+#include <id3tag.h>
+
+static char *get_latin1(id3_ucs4_t const *string)
+{
+ if (!string)
+ return NULL;
+ return (char *)id3_ucs4_latin1duplicate(string);
+}
+
+static char *get_stringlist(union id3_field *field)
+{
+ unsigned int k, nstrings = id3_field_getnstrings(field);
+ char *result = NULL;
+
+ for (k = 0; k < nstrings; k++) {
+ char *tmp = (char *)get_latin1(id3_field_getstrings(field, k));
+ if (result) {
+ char *tmp2 = result;
+ result = make_message("%s %s", tmp2, tmp);
+ free(tmp);
+ free(tmp2);
+ } else
+ result = tmp;
+ }
+ return result;
+}
+
+static char *get_string(union id3_field *field)
+{
+ id3_ucs4_t const *string = id3_field_getfullstring(field);
+
+ return get_latin1(string);
+}
+
+#define FOR_EACH_FIELD(f, j, fr) for (j = 0; j < (fr)->nfields && \
+ (f = id3_frame_field((fr), j)); j++)
+
+static char *get_strings(struct id3_frame *fr)
+{
+ int j;
+ union id3_field *field;
+
+ FOR_EACH_FIELD(field, j, fr) {
+ enum id3_field_type type = id3_field_type(field);
+
+ if (type == ID3_FIELD_TYPE_STRINGLIST)
+ return get_stringlist(field);
+ if (type == ID3_FIELD_TYPE_STRINGFULL)
+ return get_string(field);
+ }
+ return NULL;
+}
+
+static void mp3_get_id3(__a_unused unsigned char *map,
+ __a_unused size_t numbytes, int fd, struct taginfo *tags)
+{
+ int i;
+ struct id3_tag *id3_t;
+ struct id3_file *id3_f = id3_file_fdopen(fd, ID3_FILE_MODE_READONLY);
+
+ if (!id3_f)
+ return;
+ id3_t = id3_file_tag(id3_f);
+ if (!id3_t) {
+ id3_file_close(id3_f);
+ return;
+ }
+ for (i = 0; i < id3_t->nframes; i++) {
+ struct id3_frame *fr = id3_t->frames[i];
+ if (!strcmp(fr->id, "TIT2")) {
+ if (!tags->title)
+ tags->title = get_strings(fr);
+ continue;
+ }
+ if (!strcmp(fr->id, "TPE1")) {
+ if (!tags->artist)
+ tags->artist = get_strings(fr);
+ continue;
+ }
+ if (!strcmp(fr->id, "TALB")) {
+ if (!tags->album)
+ tags->album = get_strings(fr);
+ continue;
+ }
+ if (!strcmp(fr->id, "TDRC")) {
+ if (!tags->year)
+ tags->year = get_strings(fr);
+ continue;
+ }
+ if (!strcmp(fr->id, "COMM")) {
+ if (!tags->comment)
+ tags->comment = get_strings(fr);
+ continue;
+ }
+ }
+ id3_file_close(id3_f);
+}
+
+#else /* HAVE_LIBID3TAG */
+