diff options
Diffstat (limited to 'src/idop.c')
-rw-r--r-- | src/idop.c | 132 |
1 files changed, 106 insertions, 26 deletions
@@ -191,10 +191,17 @@ safe_id3_file_update_and_close(struct id3_file *file) char * idest_ucs4_cvt(id3_ucs4_t const *ucs4) { - if (latin1_option) - return (char*)id3_ucs4_latin1duplicate(ucs4); - else - return (char*)id3_ucs4_utf8duplicate(ucs4); + if (broken_8bit_charset) { + char *tempval = (char*)id3_ucs4_latin1duplicate(ucs4); + char *output; + int rc = utf8_convert(idest_conv_recode, tempval, &output); + free(tempval); + if (rc == 0) + return output; + error(0, 0, "can't recode value from %s to %s", + broken_8bit_charset, "utf-8"); + } + return (char*) id3_ucs4_utf8duplicate(ucs4); } static void @@ -419,7 +426,7 @@ find_matching_frame(struct id3_tag *tag, const struct ed_item *item, frame = id3_tag_findframe(tag, item->id, 0); else { int i; - for (i = 0; frame = id3_tag_findframe(tag, item->id, i); i++) { + for (i = 0; (frame = id3_tag_findframe(tag, item->id, i)); i++) { if (cmp(frame, item) == 0) break; } @@ -473,12 +480,13 @@ copy_source_tags(struct id3_tag *tag) itm.name = xstrdup(frame->id); memcpy(itm.id, frame->id, 4); if (ft->decode(&itm, frame)) { - error(0, 0, "%s: decoding failed", frame->id); + error(0, 0, "%s: decoding to %s failed", + frame->id, charset); continue; } rc = update_frame(tag, &itm); if (rc) - error(1, 0, + error(0, 0, "cannot set frame %s: %s", frame->id, idest_strerror(rc)); ed_item_free_content(&itm); @@ -487,6 +495,79 @@ copy_source_tags(struct id3_tag *tag) return 1; } +static int +update_frames(struct id3_tag *tag) +{ + gl_list_iterator_t itr; + const void *p; + int modified = 0; + + itr = gl_list_iterator(input_list); + while (gl_list_iterator_next(&itr, &p, NULL)) { + struct ed_item *item = (struct ed_item *) p; + + /* Recode value */ + if (item->value) { + char *newval; + if (utf8_convert(idest_conv_encode, + item->value, &newval) == 0) { + free(item->value); + item->value = newval; + } + } + + int rc = update_frame(tag, item); + if (rc) + error(1, 0, + "cannot set frame %s: %s", + item->id, idest_strerror(rc)); + modified = 1; + } + gl_list_iterator_free(&itr); + return modified; +} + +static void +collect_text_frames(struct id3_tag *tag) +{ + struct id3_frame *frame; + unsigned i; + + for (i = 0; (frame = id3_tag_findframe(tag, NULL, i)); i++) { + struct ed_item itm; + const struct idest_frametab *ft = + idest_frame_lookup(frame->id); + if (!ft) { + if (verbose_option) + error(0, 0, + "%s: unsupported text frame", + frame->id); + continue; + } + + ed_item_zero(&itm); + itm.name = xstrdup(frame->id); + memcpy(itm.id, frame->id, 4); + if (ft->decode(&itm, frame)) { + error(0, 0, "%s: decoding to %s failed", + frame->id, charset); + continue; + } + if (!input_list) + input_list = ed_list_create(); + gl_list_add_last(input_list, ed_item_dup(&itm)); + ed_item_free_content(&itm); + } +} + +static void +fixup_charset(struct id3_tag *tag) +{ + if (!broken_8bit_charset) + return; + collect_text_frames(tag); +} + void set_tags(const char *name) { @@ -504,25 +585,20 @@ set_tags(const char *name) if (!tag) abort(); /* FIXME */ - if (input_list) { - gl_list_iterator_t itr; - const void *p; - - itr = gl_list_iterator(input_list); - while (gl_list_iterator_next(&itr, &p, NULL)) { - const struct ed_item *item = p; - int rc = update_frame(tag, item); - if (rc) - error(1, 0, - "cannot set frame %s: %s", - item->id, idest_strerror(rc)); - modified |= 1; - } - gl_list_iterator_free(&itr); - } - modified |= copy_source_tags(tag); + if (fixup_option) { + fixup_charset(tag); + id3_tag_options(tag, + ID3_TAG_OPTION_UNSYNCHRONISATION + | ID3_TAG_OPTION_COMPRESSION + | ID3_TAG_OPTION_CRC, 0); + modified |= 1; + } + + if (input_list) + modified |= update_frames(tag); + /* FIXME */ modified |= guile_transform(name, tag); @@ -601,7 +677,8 @@ show_tags(struct id3_tag *tag) outitm.name = xstrdup(frame->id); memcpy(outitm.id, frame->id, 4); if (ft->decode(&outitm, frame)) { - error(0, 0, "%s: decoding failed", frame->id); + error(0, 0, "%s: decoding to %s failed", + frame->id, charset); continue; } output_list_append(&outitm, NULL); @@ -617,7 +694,9 @@ show_tags(struct id3_tag *tag) memcpy(outitm.id, ref->id, 4); if (ft->decode(&outitm, frame)) { error(0, 0, - "%s: decoding failed", frame->id); + "%s: decoding to %s failed", + frame->id, + charset); continue; } output_list_append(&outitm, ref); @@ -682,3 +761,4 @@ info_id3(const char *name) id3_file_struct_iterate(file, prinfo, NULL); id3_file_close(file); } + |