diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2017-01-30 22:35:35 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2017-01-30 22:35:35 +0200 |
commit | 6494fe85e087bad327859dd3103133569ac2ec5b (patch) | |
tree | 8daa2bef423a0b62e67fdaf3a177647d796acd7e | |
parent | cb959f75e36fbc08105fdc311fddd50516c5f1d8 (diff) | |
download | idest-6494fe85e087bad327859dd3103133569ac2ec5b.tar.gz idest-6494fe85e087bad327859dd3103133569ac2ec5b.tar.bz2 |
Apply --broken-8bit-charset only to frames in 8-bit encoding.
* src/frametab.gperf (decode_qv): Passe frame as the 2nd argument
to field_to_string.
(text_decode): Likewise.
* src/idest.h (idest_ucs4_cvt): Remove.
(field_to_string): Change the type of the 2nd argument.
* src/idop.c (frame_encoding_is_8bit)
(frame_is_genre): New auxiliary functions.
(idest_ucs4_cvt): Take frame as the 2nd argument. Do recoding
only if the frame's encoding in 8-bit.
(add_stringlist): Take frame instead of the isgenre boolean; pass
it to idest_ucs4_cvt. All uses changed.
(field_to_string): Take frame as the 2nd argument. All uses changed.
(fixup_charset): Merge with collect_text_frames.
-rw-r--r-- | src/frametab.gperf | 7 | ||||
-rw-r--r-- | src/idest.h | 3 | ||||
-rw-r--r-- | src/idop.c | 59 |
3 files changed, 44 insertions, 25 deletions
diff --git a/src/frametab.gperf b/src/frametab.gperf index 7863d08..c02b771 100644 --- a/src/frametab.gperf +++ b/src/frametab.gperf @@ -39,13 +39,13 @@ decode_qv(struct ed_item *item, struct id3_frame const *frame, item->qc = count; item->qv = xcalloc(item->qc, sizeof(item->qv[0])); for (i = 0; i < count; i++) { field = id3_frame_field(frame, n + i); if (!field) break; - item->qv[i] = field_to_string(field, 0); + item->qv[i] = field_to_string(field, frame); } return 0; } char *_idest_errstr[] = { "no error", @@ -343,21 +343,20 @@ text_encode(struct id3_frame *frame, struct ed_item const *item) return 0; } static int text_decode(struct ed_item *item, struct id3_frame const *frame) { - int isgenre = strcmp(frame->id, ID3_FRAME_GENRE) == 0; union id3_field *field; char *str; int rc; - + field = id3_frame_field(frame, 1); if (!field) return IDEST_ERR_NOFIELD; - str = field_to_string(field, isgenre); + str = field_to_string(field, frame); rc = utf8_convert(idest_conv_decode, str, &item->value); free(str); if (rc) return IDEST_ERR_BADCONV; return 0; } diff --git a/src/idest.h b/src/idest.h index 2c10077..787cdad 100644 --- a/src/idest.h +++ b/src/idest.h @@ -89,17 +89,16 @@ extern int fixup_option; /* idop.c */ int guess_file_tag_options(struct id3_file *file, int *modified); int set_frame_value(struct id3_frame *frame, const struct ed_item *item); void set_tags(const char *name); void del_tags(const char *name); -char *idest_ucs4_cvt(id3_ucs4_t const *ucs4); void query_tags(const char *name); void info_id3(const char *name); -char *field_to_string(union id3_field *field, int isgenre); +char *field_to_string(union id3_field *field, struct id3_frame const *frame); int field_binary_from_string(union id3_field *field, const char *str); char *field_binary_to_string(union id3_field *field); int frame_field_from_rawdata(struct id3_frame *frame, int n, enum id3_field_type type, const char *value); @@ -185,16 +185,37 @@ safe_id3_file_update_and_close(struct id3_file *file) sigprocmask(SIG_BLOCK, &set, &oldset); id3_file_update(file); id3_file_close(file); sigprocmask(SIG_SETMASK, &oldset, NULL); } +static int +frame_encoding_is_8bit(struct id3_frame const *frame) +{ + union id3_field const *field; + + if (!frame) + return 0; + field = id3_frame_field(frame, 0); + if (!field) + return 0; + return id3_field_gettextencoding(field) == ID3_FIELD_TEXTENCODING_ISO_8859_1; +} + +static int +frame_is_genre(struct id3_frame const *frame) +{ + if (!frame) + return 0; + return strcmp(frame->id, ID3_FRAME_GENRE) == 0; +} + char * -idest_ucs4_cvt(id3_ucs4_t const *ucs4) +idest_ucs4_cvt(id3_ucs4_t const *ucs4, struct id3_frame const *frame) { - if (broken_8bit_charset) { + if (broken_8bit_charset && frame_encoding_is_8bit(frame)) { 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; @@ -202,28 +223,29 @@ idest_ucs4_cvt(id3_ucs4_t const *ucs4) broken_8bit_charset, "utf-8"); } return (char*) id3_ucs4_utf8duplicate(ucs4); } static void -add_stringlist(gl_list_t list, union id3_field *field, int isgenre, +add_stringlist(gl_list_t list, union id3_field *field, + struct id3_frame const *frame, size_t *psize) { unsigned i, nstrings = id3_field_getnstrings(field); size_t size = 0; for (i = 0; i < nstrings; i++) { id3_ucs4_t const *ucs4; char *str; ucs4 = id3_field_getstrings(field, i); if (!ucs4) continue; - if (isgenre) + if (frame_is_genre(frame)) ucs4 = id3_genre_name(ucs4); - str = idest_ucs4_cvt(ucs4); + str = idest_ucs4_cvt(ucs4, frame); size += strlen(str); gl_list_add_last(list, str); } if (psize) *psize = size; } @@ -281,13 +303,13 @@ field_binary_from_string(union id3_field *field, const char *str) field->binary.data[i] = b; } return IDEST_OK; } char * -field_to_string(union id3_field *field, int isgenre) +field_to_string(union id3_field *field, struct id3_frame const *frame) { id3_ucs4_t const *ucs4; char *ret = NULL; char buf[128]; switch (id3_field_type(field)) { @@ -309,29 +331,29 @@ field_to_string(union id3_field *field, int isgenre) case ID3_FIELD_TYPE_LATIN1LIST: /* FIXME */ break; case ID3_FIELD_TYPE_STRING: ucs4 = id3_field_getstring(field);; - if (ucs4) - ret = idest_ucs4_cvt(ucs4); + if (ucs4) + ret = idest_ucs4_cvt(ucs4, frame); break; case ID3_FIELD_TYPE_STRINGFULL: ucs4 = id3_field_getfullstring(field); - ret = idest_ucs4_cvt(ucs4); + ret = idest_ucs4_cvt(ucs4, frame); break; case ID3_FIELD_TYPE_STRINGLIST: { gl_list_t list; size_t sz; gl_list_iterator_t itr; const void *p; list = new_string_list(true); - add_stringlist(list, field, isgenre, &sz); + add_stringlist(list, field, frame, &sz); ret = xmalloc(sz + 1); ret[0] = 0; itr = gl_list_iterator(list); while (gl_list_iterator_next(&itr, &p, NULL)) strcat(ret, p); gl_list_iterator_free(&itr); @@ -525,29 +547,36 @@ update_frames(struct id3_tag *tag) } gl_list_iterator_free(&itr); return modified; } static void -collect_text_frames(struct id3_tag *tag) +fixup_charset(struct id3_tag *tag) { struct id3_frame *frame; unsigned i; + if (!broken_8bit_charset) + return; + 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; } + if (!frame_encoding_is_8bit(frame)) + 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); @@ -557,20 +586,12 @@ collect_text_frames(struct id3_tag *tag) 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) { struct id3_file *file; struct id3_tag *tag; int modified = 0; |