aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2022-06-22 11:02:42 +0300
committerSergey Poznyakoff <gray@gnu.org>2022-06-22 11:02:42 +0300
commit34486393a5ac768064094b45dabeb45f7d47d3df (patch)
tree42f8473bd61f20d42d60ba08fa73bee17aa3985c
parent25e58312538b34f674e31a6ff70fa7a452ab6b0e (diff)
downloadidest-master.tar.gz
idest-master.tar.bz2
In fixup mode, convert all frames to UTF-8HEADmaster
* src/idop.c (frame_encoding_is_8bit): Remove. (frame_recode_detect): New function. (idest_ucs4_cvt,fixup_charset): Use frame_recode_detect to decide whether to change frame's encoding and/or charset. * src/main.c: Bail out if --fixup is used together with --charset. * doc/idest.texi: Fix typo.
-rw-r--r--doc/idest.texi2
-rw-r--r--src/idop.c68
-rw-r--r--src/main.c5
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
@end example
If the input tags also contain malformed 8-bit encodings
(@pxref{broken 8bit encoding}), you can fix them as shown below:
@example
-$ idest --broken-8bit-encoding=iso-8859-1 --fixup *.mp3
+$ idest --broken-8bit-charset=iso-8859-1 --fixup *.mp3
@end example
@node Copy
@chapter Copying Tags Between Files
@xopindex{copy, described}
To copy tags from one file to another, use the @option{--copy}
diff --git a/src/idop.c b/src/idop.c
index bb9f1c3..01c6574 100644
--- a/src/idop.c
+++ b/src/idop.c
@@ -185,23 +185,42 @@ 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)
+enum frame_recode_option {
+ FRAME_RECODE_NONE, /* Nothing to recode */
+ FRAME_RECODE_UTF8, /* Convert all frames to UTF-8 encoding */
+ FRAME_RECODE_BROKEN /* Convert broken 8-bit encodings */
+};
+
+enum frame_recode_option
+frame_recode_detect(struct id3_frame const *frame)
{
union id3_field const *field;
if (!frame)
- return 0;
+ return FRAME_RECODE_NONE;
field = id3_frame_field(frame, 0);
if (!field)
- return 0;
- return id3_field_gettextencoding(field) == ID3_FIELD_TEXTENCODING_ISO_8859_1;
+ return FRAME_RECODE_NONE;
+ switch (id3_field_gettextencoding(field)) {
+ case ID3_FIELD_TEXTENCODING_ISO_8859_1:
+ if (broken_8bit_charset)
+ return FRAME_RECODE_BROKEN;
+ /* fall through */
+ case ID3_FIELD_TEXTENCODING_UTF_16:
+ case ID3_FIELD_TEXTENCODING_UTF_16BE:
+ return FRAME_RECODE_UTF8;
+
+ case ID3_FIELD_TEXTENCODING_UTF_8:
+ default:
+ break;
+ }
+ return FRAME_RECODE_NONE;
}
static int
frame_is_genre(struct id3_frame const *frame)
{
if (!frame)
@@ -209,13 +228,13 @@ frame_is_genre(struct id3_frame const *frame)
return strcmp(frame->id, ID3_FRAME_GENRE) == 0;
}
char *
idest_ucs4_cvt(id3_ucs4_t const *ucs4, struct id3_frame const *frame)
{
- if (broken_8bit_charset && frame_encoding_is_8bit(frame)) {
+ if (frame_recode_detect(frame) == FRAME_RECODE_BROKEN) {
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;
@@ -552,15 +571,12 @@ update_frames(struct id3_tag *tag)
static void
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) {
@@ -568,27 +584,33 @@ fixup_charset(struct id3_tag *tag)
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);
- continue;
+ switch (frame_recode_detect(frame)) {
+ case FRAME_RECODE_NONE:
+ break;
+
+ case FRAME_RECODE_UTF8:
+ if (strcasecmp(charset, "UTF-8") != 0)
+ break;
+ case FRAME_RECODE_BROKEN:
+ 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);
}
- if (!input_list)
- input_list = ed_list_create();
- gl_list_add_last(input_list, ed_item_dup(&itm));
- ed_item_free_content(&itm);
}
}
void
set_tags(const char *name)
{
diff --git a/src/main.c b/src/main.c
index d084c5a..c83e182 100644
--- a/src/main.c
+++ b/src/main.c
@@ -194,12 +194,17 @@ main(int argc, char **argv)
set_program_name(argv[0]);
get_options(argc, argv);
if (!default_version_option)
default_version_option = IDEST_ID3V_1|IDEST_ID3V_2;
+ if (fixup_option) {
+ if (charset)
+ error(1, 0, "--charset cannot be used with --fixup");
+ charset = "UTF-8";
+ }
argc -= optind;
argv += optind;
if (format_name) {
if (mode_set)

Return to:

Send suggestions and report system problems to the System administrator.