diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/idop.c | 68 | ||||
-rw-r--r-- | src/main.c | 5 |
2 files changed, 50 insertions, 23 deletions
@@ -188,17 +188,36 @@ safe_id3_file_update_and_close(struct id3_file *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 |
@@ -212,7 +231,7 @@ frame_is_genre(struct id3_frame const *frame) | |||
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); |
@@ -555,9 +574,6 @@ fixup_charset(struct id3_tag *tag) | |||
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 = |
@@ -571,21 +587,27 @@ fixup_charset(struct id3_tag *tag) | |||
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 | ||
@@ -197,6 +197,11 @@ main(int argc, char **argv) | |||
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; |