static char *get_tag (struct id3_tag *tag, const char *what) { struct id3_frame *frame; union id3_field *field; const id3_ucs4_t *ucs4; char *comm = NULL; frame = id3_tag_findframe (tag, what, 0); if (frame && (field = &frame->fields[1])) { ucs4 = id3_field_getstrings (field, 0); if (ucs4) { /* Workaround for ID3 tags v1/v1.1 where the encoding * is latin1. */ union id3_field *encoding_field = &frame->fields[0]; if ((id3_tag_options(tag, 0, 0) & ID3_TAG_OPTION_ID3V1) || ((options_get_int ("EnforceTagsEncoding") && (id3_field_gettextencoding((encoding_field)) == ID3_FIELD_TEXTENCODING_ISO_8859_1)))) { char *t; comm = (char *)id3_ucs4_latin1duplicate (ucs4); #ifdef HAVE_RCC if (options_get_int("UseRCC")) comm = do_rcc (comm); else { #endif /* HAVE_RCC */ t = comm; comm = id3v1_fix (comm); free (t); #ifdef HAVE_RCC } #endif /* HAVE_RCC */ } else comm = (char *)id3_ucs4_utf8duplicate (ucs4); } } return comm; }
static inline bool tag_is_id3v1(struct id3_tag *tag) { return (id3_tag_options(tag, 0, 0) & ID3_TAG_OPTION_ID3V1) != 0; }
static int _BarFlyTagID3Write(BarFly_t const* fly, uint8_t const* cover_art, size_t cover_size, BarSettings_t const* settings) { int const BUFFER_SIZE = 5; int const TAG_PADDED_SIZE = 1024; char const BAR_FLY_ID3_FRAME_DISC[] = "TPOS"; int exit_status = 0; int status; struct id3_tag* tag; char buffer[BUFFER_SIZE]; assert(fly != NULL); assert(fly->audio_file_path != NULL); assert(settings != NULL); /* * Set the minimum size for the tag. The tag will use CRC and compression. * FIXME - figure out if the padded size is really needed. */ tag = id3_tag_new(); if (tag == NULL) { BarUiMsg(settings, MSG_ERR, "Failed to create new tag.\n"); goto error; } id3_tag_setlength(tag, TAG_PADDED_SIZE); id3_tag_options(tag, ID3_TAG_OPTION_UNSYNCHRONISATION | ID3_TAG_OPTION_APPENDEDTAG | ID3_TAG_OPTION_CRC | ID3_TAG_OPTION_COMPRESSION, 0); /* * Add the data to the tag. */ status = BarFlyID3AddFrame(tag, ID3_FRAME_ARTIST, fly->artist, settings); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Failed to write artist to tag.\n"); goto error; } status = BarFlyID3AddFrame(tag, ID3_FRAME_ALBUM, fly->album, settings); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Failed to write album to tag.\n"); goto error; } status = BarFlyID3AddFrame(tag, ID3_FRAME_TITLE, fly->title, settings); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Failed to write title to tag.\n"); goto error; } if (fly->year != 0) { snprintf(buffer, BUFFER_SIZE, "%hu", fly->year); buffer[BUFFER_SIZE - 1] = '\0'; status = BarFlyID3AddFrame(tag, ID3_FRAME_YEAR, buffer, settings); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Failed to write year to tag.\n"); goto error; } } if (fly->track != 0) { snprintf(buffer, BUFFER_SIZE, "%hu", fly->track); buffer[BUFFER_SIZE - 1] = '\0'; status = BarFlyID3AddFrame(tag, ID3_FRAME_TRACK, buffer, settings); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Failed to write track number to tag.\n"); goto error; } } if (fly->disc != 0) { snprintf(buffer, BUFFER_SIZE, "%hu", fly->disc); buffer[BUFFER_SIZE - 1] = '\0'; status = BarFlyID3AddFrame(tag, BAR_FLY_ID3_FRAME_DISC, buffer, settings); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Failed to write disc number to tag.\n"); goto error; } } if (cover_art != NULL) { status = BarFlyID3AddCover(tag, cover_art, cover_size, settings); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Failed to write cover to tag.\n"); goto error; } } /* * Write the tag to the file. */ status = BarFlyID3WriteFile(fly->audio_file_path, tag, settings); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Failed to write the tag.\n"); goto error; } goto end; error: exit_status = -1; end: if (tag != NULL) { id3_tag_delete(tag); } return exit_status; }