summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn van Beurden <mvanb1@gmail.com>2022-06-24 22:09:09 +0200
committerMartijn van Beurden <mvanb1@gmail.com>2022-06-28 07:11:16 +0200
commitb3c6fc2a04cdd9b912be0ba5c6500931e0961448 (patch)
treec928f7b8dd6c78170d650282c50ef772e3af95fb
parente6ff8b035a0f4e0e7b96adf10ae061dafa900229 (diff)
downloadflac-b3c6fc2a04cdd9b912be0ba5c6500931e0961448.tar.gz
Improve foreign metadata handling
Add options --keep-foreign-metadata-if-present and improve error messages when on decoding the wrong type of foreign metadata is found.
-rw-r--r--man/flac.13
-rw-r--r--man/flac.sgml8
-rw-r--r--man/metaflac.14
-rw-r--r--src/flac/decode.c39
-rw-r--r--src/flac/decode.h1
-rw-r--r--src/flac/encode.c11
-rw-r--r--src/flac/encode.h1
-rw-r--r--src/flac/foreign_metadata.c34
-rw-r--r--src/flac/foreign_metadata.h4
-rw-r--r--src/flac/main.c65
10 files changed, 132 insertions, 38 deletions
diff --git a/man/flac.1 b/man/flac.1
index 0d130526..100274d9 100644
--- a/man/flac.1
+++ b/man/flac.1
@@ -74,6 +74,9 @@ Output files have their timestamps/permissions set to match those of their input
\fB--keep-foreign-metadata \fR
If encoding, save WAVE, RF64, or AIFF non-audio chunks in FLAC metadata. If decoding, restore any saved non-audio chunks from FLAC metadata when writing the decoded file. Foreign metadata cannot be transcoded, e.g. WAVE chunks saved in a FLAC file cannot be restored when decoding to AIFF. Input and output must be regular files (not stdin or stdout).
.TP
+\fB--keep-foreign-metadata-if-present \fR
+Like --keep-foreign-metadata, but without throwing an error if foreign metadata cannot be found or restored, instead printing a warning.
+.TP
\fB--skip={\fI#\fB|\fImm:ss.ss\fB}\fR
Skip over the first number of samples of the input. This works for both encoding and decoding, but not testing. The alternative form mm:ss.ss can be used to specify minutes, seconds, and fractions of a second.
.TP
diff --git a/man/flac.sgml b/man/flac.sgml
index d1edf3a2..4aa0f094 100644
--- a/man/flac.sgml
+++ b/man/flac.sgml
@@ -223,6 +223,14 @@
</varlistentry>
<varlistentry>
+ <term><option>--keep-foreign-metadata-if-present</option>
+ </term>
+ <listitem>
+ <para>Like --keep-foreign-metadata, but without throwing an error if foreign metadata cannot be found or restored, instead printing a warning.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--skip</option>={<replaceable>#</replaceable>|<replaceable>mm:ss.ss</replaceable>}</term>
<listitem>
<para>Skip over the first number of samples of the input. This works for both encoding and decoding, but not testing. The alternative form mm:ss.ss can be used to specify minutes, seconds, and fractions of a second.</para>
diff --git a/man/metaflac.1 b/man/metaflac.1
index 0c1c66bc..1490dffe 100644
--- a/man/metaflac.1
+++ b/man/metaflac.1
@@ -200,8 +200,8 @@ number of channels. The sample rate must be one of 8, 11.025,
96, 112, 128, 144, 176.4, or 192kHz.
.TP
\fB--scan-replay-gain\fR
-Like --add-replay-gain, but only analyzes the files rather than
-writing them to the tags.
+Like --add-replay-gain, but only analyzes the files rather
+than writing them to the tags.
.TP
\fB--remove-replay-gain\fR
Removes the ReplayGain tags.
diff --git a/src/flac/decode.c b/src/flac/decode.c
index a7d07210..aaf2c46a 100644
--- a/src/flac/decode.c
+++ b/src/flac/decode.c
@@ -42,6 +42,7 @@ typedef struct {
FLAC__bool treat_warnings_as_errors;
FLAC__bool continue_through_decode_errors;
FLAC__bool channel_map_none;
+ FLAC__bool relaxed_foreign_metadata_handling;
struct {
replaygain_synthesis_spec_t spec;
@@ -67,6 +68,7 @@ typedef struct {
FLAC__bool aborting_due_to_until; /* true if we intentionally abort decoding prematurely because we hit the --until point */
FLAC__bool aborting_due_to_unparseable; /* true if we abort decoding because we hit an unparseable frame */
FLAC__bool error_callback_suppress_messages; /* turn on to prevent repeating messages from the error callback */
+ FLAC__bool warn_user_about_foreign_metadata; /* to prevent more than one warning message per file */
FLAC__bool iff_headers_need_fixup;
@@ -98,7 +100,7 @@ static FLAC__bool is_big_endian_host_;
/*
* local routines
*/
-static FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool use_first_serial_number, long serial_number, FileFormat format, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FLAC__bool channel_map_none, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, utils__CueSpecification *cue_specification, foreign_metadata_t *foreign_metadata, const char *infilename, const char *outfilename);
+static FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool use_first_serial_number, long serial_number, FileFormat format, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FLAC__bool channel_map_none, FLAC__bool relaxed_foreign_metadata_handling, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, utils__CueSpecification *cue_specification, foreign_metadata_t *foreign_metadata, const char *infilename, const char *outfilename);
static void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred);
static FLAC__bool DecoderSession_init_decoder(DecoderSession *d, const char *infilename);
static FLAC__bool DecoderSession_process(DecoderSession *d);
@@ -160,6 +162,7 @@ int flac__decode_file(const char *infilename, const char *outfilename, FLAC__boo
options.treat_warnings_as_errors,
options.continue_through_decode_errors,
options.channel_map_none,
+ options.relaxed_foreign_metadata_handling,
options.replaygain_synthesis_spec,
analysis_mode,
aopts,
@@ -183,7 +186,7 @@ int flac__decode_file(const char *infilename, const char *outfilename, FLAC__boo
return DecoderSession_finish_ok(&decoder_session);
}
-FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool use_first_serial_number, long serial_number, FileFormat format, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FLAC__bool channel_map_none, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, utils__CueSpecification *cue_specification, foreign_metadata_t *foreign_metadata, const char *infilename, const char *outfilename)
+FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool use_first_serial_number, long serial_number, FileFormat format, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FLAC__bool channel_map_none, FLAC__bool relaxed_foreign_metadata_handling, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, utils__CueSpecification *cue_specification, foreign_metadata_t *foreign_metadata, const char *infilename, const char *outfilename)
{
#if FLAC__HAS_OGG
d->is_ogg = is_ogg;
@@ -199,6 +202,7 @@ FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__
d->treat_warnings_as_errors = treat_warnings_as_errors;
d->continue_through_decode_errors = continue_through_decode_errors;
d->channel_map_none = channel_map_none;
+ d->relaxed_foreign_metadata_handling = relaxed_foreign_metadata_handling;
d->replaygain.spec = replaygain_synthesis_spec;
d->replaygain.apply = false;
d->replaygain.scale = 0.0;
@@ -220,6 +224,10 @@ FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__
d->aborting_due_to_until = false;
d->aborting_due_to_unparseable = false;
d->error_callback_suppress_messages = false;
+ if(relaxed_foreign_metadata_handling)
+ d->warn_user_about_foreign_metadata = false;
+ else
+ d->warn_user_about_foreign_metadata = true;
d->iff_headers_need_fixup = false;
@@ -296,8 +304,20 @@ FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, const ch
if(!decoder_session->analysis_mode && !decoder_session->test_only && decoder_session->foreign_metadata) {
const char *error;
if(!flac__foreign_metadata_read_from_flac(decoder_session->foreign_metadata, infilename, &error)) {
- flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", decoder_session->inbasefilename, error);
- return false;
+ if(decoder_session->relaxed_foreign_metadata_handling) {
+ flac__utils_printf(stderr, 1, "%s: WARNING reading foreign metadata: %s\n", decoder_session->inbasefilename, error);
+ if(decoder_session->treat_warnings_as_errors) {
+ return false;
+ }
+ else {
+ /* Couldn't find foreign metadata, stop processing */
+ decoder_session->foreign_metadata = 0;
+ }
+ }
+ else {
+ flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", decoder_session->inbasefilename, error);
+ return false;
+ }
}
}
@@ -314,6 +334,12 @@ FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, const ch
if (decoder_session->replaygain.spec.apply || !decoder_session->channel_map_none)
FLAC__stream_decoder_set_metadata_respond(decoder_session->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
+ if(!decoder_session->analysis_mode && !decoder_session->test_only && decoder_session->foreign_metadata == NULL)
+ /* Warn user if foreign metadata is found */
+ for(uint32_t i = 0; i < FLAC__FOREIGN_METADATA_NUMBER_OF_RECOGNIZED_APPLICATION_IDS; i++)
+ FLAC__stream_decoder_set_metadata_respond_application(decoder_session->decoder, (FLAC__byte *)FLAC__FOREIGN_METADATA_APPLICATION_ID[i]);
+
+
#if FLAC__HAS_OGG
if(decoder_session->is_ogg) {
if(!decoder_session->use_first_serial_number)
@@ -1449,6 +1475,11 @@ void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMet
}
(void)flac__utils_get_channel_mask_tag(metadata, &decoder_session->channel_mask);
}
+ else if(metadata->type == FLAC__METADATA_TYPE_APPLICATION && decoder_session->warn_user_about_foreign_metadata) {
+ /* Foreign metadata signalling */
+ flac__utils_printf(stderr, 1, "%s: WARNING: found foreign metadata, use --keep-foreign-metadata to restore\n", decoder_session->inbasefilename);
+ decoder_session->warn_user_about_foreign_metadata = false;
+ }
}
void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
diff --git a/src/flac/decode.h b/src/flac/decode.h
index 6a90bfc6..bd93fd6a 100644
--- a/src/flac/decode.h
+++ b/src/flac/decode.h
@@ -52,6 +52,7 @@ typedef struct {
FLAC__bool has_cue_specification;
utils__CueSpecification cue_specification;
FLAC__bool channel_map_none; /* --channel-map=none specified, eventually will expand to take actual channel map */
+ FLAC__bool relaxed_foreign_metadata_handling;
FileFormat format;
union {
diff --git a/src/flac/encode.c b/src/flac/encode.c
index 26812030..7dc226af 100644
--- a/src/flac/encode.c
+++ b/src/flac/encode.c
@@ -978,8 +978,15 @@ int flac__encode_file(FILE *infile, FLAC__off_t infilesize, const char *infilena
flac__foreign_metadata_read_from_wave64(options.format_options.iff.foreign_metadata, infilename, &error) :
flac__foreign_metadata_read_from_aiff(options.format_options.iff.foreign_metadata, infilename, &error)
)) {
- flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", encoder_session.inbasefilename, error);
- return EncoderSession_finish_error(&encoder_session);
+ if(options.relaxed_foreign_metadata_handling) {
+ flac__utils_printf(stderr, 1, "%s: WARNING reading foreign metadata: %s\n", encoder_session.inbasefilename, error);
+ if(encoder_session.treat_warnings_as_errors)
+ return EncoderSession_finish_error(&encoder_session);
+ }
+ else {
+ flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", encoder_session.inbasefilename, error);
+ return EncoderSession_finish_error(&encoder_session);
+ }
}
}
diff --git a/src/flac/encode.h b/src/flac/encode.h
index b0efda8a..1ae19449 100644
--- a/src/flac/encode.h
+++ b/src/flac/encode.h
@@ -86,6 +86,7 @@ typedef struct {
FLAC__bool sector_align;
FLAC__bool error_on_compression_fail;
FLAC__bool limit_min_bitrate;
+ FLAC__bool relaxed_foreign_metadata_handling;
FLAC__StreamMetadata *vorbis_comment;
FLAC__StreamMetadata *vorbis_comment_with_channel_mask_tag;
diff --git a/src/flac/foreign_metadata.c b/src/flac/foreign_metadata.c
index 9ad9c185..72ba3386 100644
--- a/src/flac/foreign_metadata.c
+++ b/src/flac/foreign_metadata.c
@@ -35,8 +35,7 @@
#endif
#define min(x,y) ((x)<(y)?(x):(y))
-
-static const char *FLAC__FOREIGN_METADATA_APPLICATION_ID[3] = { "aiff" , "riff", "w64 " };
+const char *FLAC__FOREIGN_METADATA_APPLICATION_ID[FLAC__FOREIGN_METADATA_NUMBER_OF_RECOGNIZED_APPLICATION_IDS] = { "aiff" , "riff", "w64 " };
static FLAC__uint32 unpack32be_(const FLAC__byte *b)
{
@@ -474,7 +473,8 @@ static FLAC__bool read_from_flac_(foreign_metadata_t *fm, FILE *f, FLAC__Metadat
{
FLAC__byte id[4], buffer[12];
FLAC__off_t offset;
- FLAC__bool type_found = false, ds64_found = false;
+ FLAC__bool foreign_metadata_found = false, type_found = false, ds64_found = false;
+ uint32_t foreign_metadata_found_type = 0;
FLAC__ASSERT(FLAC__STREAM_METADATA_APPLICATION_ID_LEN == sizeof(id)*8);
@@ -485,8 +485,17 @@ static FLAC__bool read_from_flac_(foreign_metadata_t *fm, FILE *f, FLAC__Metadat
if(error) *error = "FLAC__metadata_simple_iterator_get_application_id() error (002)";
return false;
}
- if(memcmp(id, FLAC__FOREIGN_METADATA_APPLICATION_ID[fm->type], sizeof(id)))
+ if(memcmp(id, FLAC__FOREIGN_METADATA_APPLICATION_ID[fm->type], sizeof(id))) {
+ /* The found application metadata block is not of the right type, check
+ * whether it is of another recognized type so we can tell the user it
+ * is decoding to the wrong file format */
+ for(uint32_t i = 0; i < FLAC__FOREIGN_METADATA_NUMBER_OF_RECOGNIZED_APPLICATION_IDS; i++)
+ if(memcmp(id, FLAC__FOREIGN_METADATA_APPLICATION_ID[i], sizeof(id)) == 0) {
+ foreign_metadata_found = true;
+ foreign_metadata_found_type = i;
+ }
continue;
+ }
offset = FLAC__metadata_simple_iterator_get_block_offset(it);
/* skip over header and app ID */
offset += (FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8;
@@ -614,8 +623,21 @@ static FLAC__bool read_from_flac_(foreign_metadata_t *fm, FILE *f, FLAC__Metadat
return false;
}
if(!type_found) {
- if(error) *error = "no foreign metadata found (022)";
- return false;
+ if(foreign_metadata_found) {
+ if(error) {
+ if(foreign_metadata_found_type == 0 /*"aiff"*/)
+ *error = "found foreign metadata of wrong type, try decoding to AIFF instead";
+ else if(foreign_metadata_found_type == 1 /*"riff"*/)
+ *error = "found foreign metadata of wrong type, try decoding to WAV or RF64 instead";
+ else if(foreign_metadata_found_type == 2 /*"w64 "*/)
+ *error = "found foreign metadata of wrong type, try decoding to WAVE64 instead";
+ }
+ return false;
+ }
+ else {
+ if(error) *error = "no foreign metadata found (022)";
+ return false;
+ }
}
if(fm->is_rf64 && !ds64_found) {
if(error) *error = "invalid RF64 file: second chunk is not \"ds64\" (023)";
diff --git a/src/flac/foreign_metadata.h b/src/flac/foreign_metadata.h
index e5a17dd1..cb433d84 100644
--- a/src/flac/foreign_metadata.h
+++ b/src/flac/foreign_metadata.h
@@ -28,6 +28,10 @@
#include "utils.h"
#include "share/compat.h"
+#define FLAC__FOREIGN_METADATA_NUMBER_OF_RECOGNIZED_APPLICATION_IDS 3
+
+extern const char *FLAC__FOREIGN_METADATA_APPLICATION_ID[FLAC__FOREIGN_METADATA_NUMBER_OF_RECOGNIZED_APPLICATION_IDS];
+
/* WATCHOUT: these enums are used to index internal arrays */
typedef enum {
FOREIGN_BLOCK_TYPE__AIFF = 0, /* for AIFF and AIFF-C */
diff --git a/src/flac/main.c b/src/flac/main.c
index 9a972021..906457dc 100644
--- a/src/flac/main.c
+++ b/src/flac/main.c
@@ -90,25 +90,26 @@ static struct share__option long_options_[] = {
/*
* general options
*/
- { "help" , share__no_argument, 0, 'h' },
- { "explain" , share__no_argument, 0, 'H' },
- { "version" , share__no_argument, 0, 'v' },
- { "decode" , share__no_argument, 0, 'd' },
- { "analyze" , share__no_argument, 0, 'a' },
- { "test" , share__no_argument, 0, 't' },
- { "stdout" , share__no_argument, 0, 'c' },
- { "silent" , share__no_argument, 0, 's' },
- { "totally-silent" , share__no_argument, 0, 0 },
- { "warnings-as-errors" , share__no_argument, 0, 'w' },
- { "force" , share__no_argument, 0, 'f' },
- { "delete-input-file" , share__no_argument, 0, 0 },
- { "preserve-modtime" , share__no_argument, 0, 0 },
- { "keep-foreign-metadata" , share__no_argument, 0, 0 },
- { "output-prefix" , share__required_argument, 0, 0 },
- { "output-name" , share__required_argument, 0, 'o' },
- { "skip" , share__required_argument, 0, 0 },
- { "until" , share__required_argument, 0, 0 },
- { "channel-map" , share__required_argument, 0, 0 }, /* undocumented */
+ { "help" , share__no_argument, 0, 'h' },
+ { "explain" , share__no_argument, 0, 'H' },
+ { "version" , share__no_argument, 0, 'v' },
+ { "decode" , share__no_argument, 0, 'd' },
+ { "analyze" , share__no_argument, 0, 'a' },
+ { "test" , share__no_argument, 0, 't' },
+ { "stdout" , share__no_argument, 0, 'c' },
+ { "silent" , share__no_argument, 0, 's' },
+ { "totally-silent" , share__no_argument, 0, 0 },
+ { "warnings-as-errors" , share__no_argument, 0, 'w' },
+ { "force" , share__no_argument, 0, 'f' },
+ { "delete-input-file" , share__no_argument, 0, 0 },
+ { "preserve-modtime" , share__no_argument, 0, 0 },
+ { "keep-foreign-metadata" , share__no_argument, 0, 0 },
+ { "keep-foreign-metadata-if-present" , share__no_argument, 0, 0 },
+ { "output-prefix" , share__required_argument, 0, 0 },
+ { "output-name" , share__required_argument, 0, 'o' },
+ { "skip" , share__required_argument, 0, 0 },
+ { "until" , share__required_argument, 0, 0 },
+ { "channel-map" , share__required_argument, 0, 0 }, /* undocumented */
/*
* decoding options
@@ -244,6 +245,7 @@ static struct {
FLAC__bool delete_input;
FLAC__bool preserve_modtime;
FLAC__bool keep_foreign_metadata;
+ FLAC__bool keep_foreign_metadata_if_present;
FLAC__bool replay_gain;
FLAC__bool ignore_chunk_sizes;
FLAC__bool sector_align;
@@ -468,7 +470,7 @@ int do_it(void)
if(!option_values.mode_decode && 0 != option_values.cuesheet_filename && option_values.num_files > 1) {
return usage_error("ERROR: --cuesheet cannot be used when encoding multiple files\n");
}
- if(option_values.keep_foreign_metadata) {
+ if(option_values.keep_foreign_metadata || option_values.keep_foreign_metadata_if_present) {
/* we're not going to try and support the re-creation of broken WAVE files */
if(option_values.ignore_chunk_sizes)
return usage_error("ERROR: using --keep-foreign-metadata cannot be used with --ignore-chunk-sizes\n");
@@ -572,6 +574,7 @@ FLAC__bool init_options(void)
option_values.delete_input = false;
option_values.preserve_modtime = true;
option_values.keep_foreign_metadata = false;
+ option_values.keep_foreign_metadata_if_present = false;
option_values.replay_gain = false;
option_values.ignore_chunk_sizes = false;
option_values.sector_align = false;
@@ -675,6 +678,9 @@ int parse_option(int short_option, const char *long_option, const char *option_a
else if(0 == strcmp(long_option, "keep-foreign-metadata")) {
option_values.keep_foreign_metadata = true;
}
+ else if(0 == strcmp(long_option, "keep-foreign-metadata-if-present")) {
+ option_values.keep_foreign_metadata_if_present = true;
+ }
else if(0 == strcmp(long_option, "output-prefix")) {
FLAC__ASSERT(0 != option_argument);
option_values.output_prefix = option_argument;
@@ -855,6 +861,7 @@ int parse_option(int short_option, const char *long_option, const char *option_a
}
else if(0 == strcmp(long_option, "no-keep-foreign-metadata")) {
option_values.keep_foreign_metadata = false;
+ option_values.keep_foreign_metadata_if_present = false;
}
else if(0 == strcmp(long_option, "no-replay-gain")) {
option_values.replay_gain = false;
@@ -1257,6 +1264,8 @@ void show_help(void)
printf(" --delete-input-file Deletes after a successful encode/decode\n");
printf(" --preserve-modtime Output files keep timestamp of input (default)\n");
printf(" --keep-foreign-metadata Save/restore WAVE or AIFF non-audio chunks\n");
+ printf(" --keep-foreign-metadata-if-present Save/restore WAVE or AIFF non-audio\n");
+ printf(" but not return an error when no such chunks are found\n");
printf(" --skip={#|mm:ss.ss} Skip the given initial samples for each input\n");
printf(" --until={#|[+|-]mm:ss.ss} Stop at the given sample for each input file\n");
#if FLAC__HAS_OGG
@@ -1410,6 +1419,12 @@ void show_explain(void)
printf(" transcoded, e.g. WAVE chunks saved in a FLAC file\n");
printf(" cannot be restored when decoding to AIFF. Input\n");
printf(" and output must be regular files, not stdin/out.\n");
+ printf(" --keep-foreign-metadata-if-present As previous option, but do not throw\n");
+ printf(" an error in case no foreign metadata is found,\n");
+ printf(" the wrong kind of foreign metadata is found (on\n");
+ printf(" decoding) or if the foreign could not be parsed,\n");
+ printf(" i.e. all foreign metadata related errors are\n");
+ printf(" treated as warnings.\n");
printf(" --skip={#|mm:ss.ss} Skip the first # samples of each input file; can\n");
printf(" be used both for encoding and decoding. The\n");
printf(" alternative form mm:ss.ss can be used to specify\n");
@@ -1803,7 +1818,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
}
}
- if(option_values.keep_foreign_metadata) {
+ if(option_values.keep_foreign_metadata || option_values.keep_foreign_metadata_if_present) {
if(encode_infile == stdin || option_values.force_to_stdout) {
conditional_fclose(encode_infile);
return usage_error("ERROR: --keep-foreign-metadata cannot be used when encoding from stdin or to stdout\n");
@@ -1946,6 +1961,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
encode_options.debug.do_md5 = option_values.debug.do_md5;
encode_options.error_on_compression_fail = option_values.error_on_compression_fail;
encode_options.limit_min_bitrate = option_values.limit_min_bitrate;
+ encode_options.relaxed_foreign_metadata_handling = option_values.keep_foreign_metadata_if_present;
/* if infilename and outfilename point to the same file, we need to write to a temporary file */
if(encode_infile != stdin && grabbag__file_are_same(infilename, outfilename)) {
@@ -1976,7 +1992,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
encode_options.format_options.iff.foreign_metadata = 0;
/* initialize foreign metadata if requested */
- if(option_values.keep_foreign_metadata) {
+ if(option_values.keep_foreign_metadata || option_values.keep_foreign_metadata_if_present) {
encode_options.format_options.iff.foreign_metadata =
flac__foreign_metadata_new(
input_format==FORMAT_WAVE || input_format==FORMAT_RF64?
@@ -2102,7 +2118,7 @@ int decode_file(const char *infilename)
return usage_error("ERROR: for decoding to a raw file you must specify a value for --endian and --sign\n");
}
- if(option_values.keep_foreign_metadata) {
+ if(option_values.keep_foreign_metadata || option_values.keep_foreign_metadata_if_present) {
if(0 == strcmp(infilename, "-") || 0 == strcmp(outfilename, "-"))
return usage_error("ERROR: --keep-foreign-metadata cannot be used when decoding from stdin or to stdout\n");
if(output_format != FORMAT_WAVE && output_format != FORMAT_WAVE64 && output_format != FORMAT_RF64 && output_format != FORMAT_AIFF && output_format != FORMAT_AIFF_C)
@@ -2145,6 +2161,7 @@ int decode_file(const char *infilename)
decode_options.treat_warnings_as_errors = option_values.treat_warnings_as_errors;
decode_options.continue_through_decode_errors = option_values.continue_through_decode_errors;
+ decode_options.relaxed_foreign_metadata_handling = option_values.keep_foreign_metadata_if_present;
decode_options.replaygain_synthesis_spec = option_values.replaygain_synthesis_spec;
#if FLAC__HAS_OGG
decode_options.is_ogg = treat_as_ogg;
@@ -2164,7 +2181,7 @@ int decode_file(const char *infilename)
decode_options.format_options.iff.foreign_metadata = 0;
/* initialize foreign metadata if requested */
- if(option_values.keep_foreign_metadata) {
+ if(option_values.keep_foreign_metadata || option_values.keep_foreign_metadata_if_present) {
decode_options.format_options.iff.foreign_metadata =
flac__foreign_metadata_new(
output_format==FORMAT_WAVE || output_format==FORMAT_RF64?