diff options
-rw-r--r-- | doc/idest.texi | 2 | ||||
-rw-r--r-- | src/idop.c | 68 | ||||
-rw-r--r-- | src/main.c | 5 |
3 files changed, 51 insertions, 24 deletions
diff --git a/doc/idest.texi b/doc/idest.texi index 2b65ab7..f9934c7 100644 --- a/doc/idest.texi +++ b/doc/idest.texi | |||
@@ -486,13 +486,13 @@ $ idest --fixup *.mp3 | |||
486 | @end example | 486 | @end example |
487 | 487 | ||
488 | If the input tags also contain malformed 8-bit encodings | 488 | If the input tags also contain malformed 8-bit encodings |
489 | (@pxref{broken 8bit encoding}), you can fix them as shown below: | 489 | (@pxref{broken 8bit encoding}), you can fix them as shown below: |
490 | 490 | ||
491 | @example | 491 | @example |
492 | $ idest --broken-8bit-encoding=iso-8859-1 --fixup *.mp3 | 492 | $ idest --broken-8bit-charset=iso-8859-1 --fixup *.mp3 |
493 | @end example | 493 | @end example |
494 | 494 | ||
495 | @node Copy | 495 | @node Copy |
496 | @chapter Copying Tags Between Files | 496 | @chapter Copying Tags Between Files |
497 | @xopindex{copy, described} | 497 | @xopindex{copy, described} |
498 | To copy tags from one file to another, use the @option{--copy} | 498 | To copy tags from one file to another, use the @option{--copy} |
@@ -185,23 +185,42 @@ safe_id3_file_update_and_close(struct id3_file *file) | |||
185 | sigprocmask(SIG_BLOCK, &set, &oldset); | 185 | sigprocmask(SIG_BLOCK, &set, &oldset); |
186 | id3_file_update(file); | 186 | id3_file_update(file); |
187 | id3_file_close(file); | 187 | id3_file_close(file); |
188 | sigprocmask(SIG_SETMASK, &oldset, NULL); | 188 | sigprocmask(SIG_SETMASK, &oldset, NULL); |
189 | } | 189 | } |
190 | 190 | ||
191 | static int | 191 | enum frame_recode_option { |
192 | frame_encoding_is_8bit(struct id3_frame const *frame) | 192 | FRAME_RECODE_NONE, /* Nothing to recode */ |
193 | FRAME_RECODE_UTF8, /* Convert all frames to UTF-8 encoding */ | ||
194 | FRAME_RECODE_BROKEN /* Convert broken 8-bit encodings */ | ||
195 | }; | ||
196 | |||
197 | enum frame_recode_option | ||
198 | frame_recode_detect(struct id3_frame const *frame) | ||
193 | { | 199 | { |
194 | union id3_field const *field; | 200 | union id3_field const *field; |
195 | 201 | ||
196 | if (!frame) | 202 | if (!frame) |
197 | return 0; | 203 | return FRAME_RECODE_NONE; |
198 | field = id3_frame_field(frame, 0); | 204 | field = id3_frame_field(frame, 0); |
199 | if (!field) | 205 | if (!field) |
200 | return 0; | 206 | return FRAME_RECODE_NONE; |
201 | return id3_field_gettextencoding(field) == ID3_FIELD_TEXTENCODING_ISO_8859_1; | 207 | switch (id3_field_gettextencoding(field)) { |
208 | case ID3_FIELD_TEXTENCODING_ISO_8859_1: | ||
209 | if (broken_8bit_charset) | ||
210 | return FRAME_RECODE_BROKEN; | ||
211 | /* fall through */ | ||
212 | case ID3_FIELD_TEXTENCODING_UTF_16: | ||
213 | case ID3_FIELD_TEXTENCODING_UTF_16BE: | ||
214 | return FRAME_RECODE_UTF8; | ||
215 | |||
216 | case ID3_FIELD_TEXTENCODING_UTF_8: | ||
217 | default: | ||
218 | break; | ||
219 | } | ||
220 | return FRAME_RECODE_NONE; | ||
202 | } | 221 | } |
203 | 222 | ||
204 | static int | 223 | static int |
205 | frame_is_genre(struct id3_frame const *frame) | 224 | frame_is_genre(struct id3_frame const *frame) |
206 | { | 225 | { |
207 | if (!frame) | 226 | if (!frame) |
@@ -209,13 +228,13 @@ frame_is_genre(struct id3_frame const *frame) | |||
209 | return strcmp(frame->id, ID3_FRAME_GENRE) == 0; | 228 | return strcmp(frame->id, ID3_FRAME_GENRE) == 0; |
210 | } | 229 | } |
211 | 230 | ||
212 | char * | 231 | char * |
213 | idest_ucs4_cvt(id3_ucs4_t const *ucs4, struct id3_frame const *frame) | 232 | idest_ucs4_cvt(id3_ucs4_t const *ucs4, struct id3_frame const *frame) |
214 | { | 233 | { |
215 | if (broken_8bit_charset && frame_encoding_is_8bit(frame)) { | 234 | if (frame_recode_detect(frame) == FRAME_RECODE_BROKEN) { |
216 | char *tempval = (char*)id3_ucs4_latin1duplicate(ucs4); | 235 | char *tempval = (char*)id3_ucs4_latin1duplicate(ucs4); |
217 | char *output; | 236 | char *output; |
218 | int rc = utf8_convert(idest_conv_recode, tempval, &output); | 237 | int rc = utf8_convert(idest_conv_recode, tempval, &output); |
219 | free(tempval); | 238 | free(tempval); |
220 | if (rc == 0) | 239 | if (rc == 0) |
221 | return output; | 240 | return output; |
@@ -552,15 +571,12 @@ update_frames(struct id3_tag *tag) | |||
552 | static void | 571 | static void |
553 | fixup_charset(struct id3_tag *tag) | 572 | fixup_charset(struct id3_tag *tag) |
554 | { | 573 | { |
555 | struct id3_frame *frame; | 574 | struct id3_frame *frame; |
556 | unsigned i; | 575 | unsigned i; |
557 | 576 | ||
558 | if (!broken_8bit_charset) | ||
559 | return; | ||
560 | |||
561 | for (i = 0; (frame = id3_tag_findframe(tag, NULL, i)); i++) { | 577 | for (i = 0; (frame = id3_tag_findframe(tag, NULL, i)); i++) { |
562 | struct ed_item itm; | 578 | struct ed_item itm; |
563 | const struct idest_frametab *ft = | 579 | const struct idest_frametab *ft = |
564 | idest_frame_lookup(frame->id); | 580 | idest_frame_lookup(frame->id); |
565 | 581 | ||
566 | if (!ft) { | 582 | if (!ft) { |
@@ -568,27 +584,33 @@ fixup_charset(struct id3_tag *tag) | |||
568 | error(0, 0, | 584 | error(0, 0, |
569 | "%s: unsupported text frame", | 585 | "%s: unsupported text frame", |
570 | frame->id); | 586 | frame->id); |
571 | continue; | 587 | continue; |
572 | } | 588 | } |
573 | 589 | ||
574 | if (!frame_encoding_is_8bit(frame)) | 590 | switch (frame_recode_detect(frame)) { |
575 | continue; | 591 | case FRAME_RECODE_NONE: |
576 | 592 | break; | |
577 | ed_item_zero(&itm); | 593 | |
578 | itm.name = xstrdup(frame->id); | 594 | case FRAME_RECODE_UTF8: |
579 | memcpy(itm.id, frame->id, 4); | 595 | if (strcasecmp(charset, "UTF-8") != 0) |
580 | if (ft->decode(&itm, frame)) { | 596 | break; |
581 | error(0, 0, "%s: decoding to %s failed", | 597 | case FRAME_RECODE_BROKEN: |
582 | frame->id, charset); | 598 | ed_item_zero(&itm); |
583 | continue; | 599 | itm.name = xstrdup(frame->id); |
600 | memcpy(itm.id, frame->id, 4); | ||
601 | if (ft->decode(&itm, frame)) { | ||
602 | error(0, 0, "%s: decoding to %s failed", | ||
603 | frame->id, charset); | ||
604 | continue; | ||
605 | } | ||
606 | if (!input_list) | ||
607 | input_list = ed_list_create(); | ||
608 | gl_list_add_last(input_list, ed_item_dup(&itm)); | ||
609 | ed_item_free_content(&itm); | ||
584 | } | 610 | } |
585 | if (!input_list) | ||
586 | input_list = ed_list_create(); | ||
587 | gl_list_add_last(input_list, ed_item_dup(&itm)); | ||
588 | ed_item_free_content(&itm); | ||
589 | } | 611 | } |
590 | } | 612 | } |
591 | 613 | ||
592 | void | 614 | void |
593 | set_tags(const char *name) | 615 | set_tags(const char *name) |
594 | { | 616 | { |
@@ -194,12 +194,17 @@ main(int argc, char **argv) | |||
194 | 194 | ||
195 | set_program_name(argv[0]); | 195 | set_program_name(argv[0]); |
196 | 196 | ||
197 | get_options(argc, argv); | 197 | get_options(argc, argv); |
198 | if (!default_version_option) | 198 | if (!default_version_option) |
199 | default_version_option = IDEST_ID3V_1|IDEST_ID3V_2; | 199 | default_version_option = IDEST_ID3V_1|IDEST_ID3V_2; |
200 | if (fixup_option) { | ||
201 | if (charset) | ||
202 | error(1, 0, "--charset cannot be used with --fixup"); | ||
203 | charset = "UTF-8"; | ||
204 | } | ||
200 | 205 | ||
201 | argc -= optind; | 206 | argc -= optind; |
202 | argv += optind; | 207 | argv += optind; |
203 | 208 | ||
204 | if (format_name) { | 209 | if (format_name) { |
205 | if (mode_set) | 210 | if (mode_set) |