aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/frametab.gperf5
-rw-r--r--src/idest.h3
-rw-r--r--src/idop.c57
3 files changed, 42 insertions, 23 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);
diff --git a/src/idop.c b/src/idop.c
index 063ff78..c3a3ce2 100644
--- a/src/idop.c
+++ b/src/idop.c
@@ -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)) {
@@ -310,28 +332,28 @@ field_to_string(union id3_field *field, int isgenre)
/* FIXME */
break;
case ID3_FIELD_TYPE_STRING:
ucs4 = id3_field_getstring(field);;
if (ucs4)
- ret = idest_ucs4_cvt(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;

Return to:

Send suggestions and report system problems to the System administrator.