aboutsummaryrefslogtreecommitdiff
path: root/src/idop.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/idop.c')
-rw-r--r--src/idop.c132
1 files changed, 106 insertions, 26 deletions
diff --git a/src/idop.c b/src/idop.c
index 0ce4c65..063ff78 100644
--- a/src/idop.c
+++ b/src/idop.c
@@ -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);
}
+

Return to:

Send suggestions and report system problems to the System administrator.