From 3e010c19412a53b86f251126d427a272224795bd Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Tue, 12 Jul 2011 19:55:28 +0300 Subject: Change ID3 version handling. * src/cmdline.opt: New option --default-id-version. The --convert and --id-version take version list as their argument. * src/idest.h (IDEST_ID3V_1) (IDEST_ID3V_2): New constants. (default_version_option): New extern. * src/idop.c (set_tags): Don't alter version_option. Unless none of version_option, default_version_option or convert_version is set, preserve existing file structure. Create new tags according to the settings of default_version_option. * src/main.c (main): Set default value for default_version_option. * NEWS: Document changes. * doc/idest.texi: Update. --- src/idop.c | 64 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 21 deletions(-) (limited to 'src/idop.c') diff --git a/src/idop.c b/src/idop.c index f124986..a906a8c 100644 --- a/src/idop.c +++ b/src/idop.c @@ -130,13 +130,27 @@ update_frame(struct id3_tag *tag, const struct ed_item *item) set_frame_value(frame, item); } +static int +build_tag_options(struct id3_tag *tag, unsigned long location, + id3_length_t length, void *data) +{ + unsigned int ver = id3_tag_version(tag); + + if (ID3_TAG_VERSION_MAJOR(ver) == 1) + *(unsigned int*)data |= IDEST_ID3V_1; + else + *(unsigned int*)data |= IDEST_ID3V_2; + return 0; +} + void set_tags(const char *name) { struct id3_file *file; struct id3_tag *tag; int modified = 0; - + int vopt = version_option; + file = id3_file_open(name, ID3_FILE_MODE_READWRITE); if (!file) error(1, errno, "cannot open file %s", name); @@ -159,27 +173,34 @@ set_tags(const char *name) /* FIXME */ modified |= guile_transform(name, tag); + + if (convert_version == 0) { + if (modified && !vopt) { + if (id3_file_struct_ntags(file)) { + id3_file_struct_iterate(file, + build_tag_options, + &vopt); + } else + vopt = default_version_option; + } + } else if (id3_file_struct_ntags(file)) { + id3_file_struct_iterate(file, build_tag_options, &vopt); + if (vopt != convert_version) { + vopt = convert_version; + modified |= 1; + } + } - switch (convert_version) { - case 1: - id3_tag_options(tag, - ID3_TAG_OPTION_NO_ID3V2, - ID3_TAG_OPTION_NO_ID3V2); - version_option = 1; - modified |= 1; - break; + if (modified && vopt) { + int opts = 0; - case 2: - id3_tag_options(tag, ID3_TAG_OPTION_ID3V1, 0); - version_option = 0; - modified |= 1; - break; - } - - if (version_option == 1) { - id3_tag_options(tag, ID3_TAG_OPTION_ID3V1, - ID3_TAG_OPTION_ID3V1); - modified |= 1; + if (vopt & IDEST_ID3V_1) + opts |= ID3_TAG_OPTION_ID3V1; + if (!(vopt & IDEST_ID3V_2)) + opts |= ID3_TAG_OPTION_NO_ID3V2; + id3_tag_options(tag, + ID3_TAG_OPTION_ID3V1|ID3_TAG_OPTION_NO_ID3V2, + opts); } if (modified) safe_id3_file_update_and_close(file); @@ -435,8 +456,9 @@ prinfo(struct id3_tag *tag, unsigned long location, id3_length_t length, void *data) { unsigned int ver = id3_tag_version(tag); + unsigned int major = ID3_TAG_VERSION_MAJOR(ver); printf("version: %u.%u\n", - ID3_TAG_VERSION_MAJOR(ver), + major > 1 ? 20 + major : major, ID3_TAG_VERSION_MINOR(ver)); printf("offset: %lu\n", location); printf("length: %lu\n", length); -- cgit v1.2.1