diff options
author | Martijn van Beurden <mvanb1@gmail.com> | 2022-06-24 22:09:09 +0200 |
---|---|---|
committer | Martijn van Beurden <mvanb1@gmail.com> | 2022-06-28 07:11:16 +0200 |
commit | b3c6fc2a04cdd9b912be0ba5c6500931e0961448 (patch) | |
tree | c928f7b8dd6c78170d650282c50ef772e3af95fb /src | |
parent | e6ff8b035a0f4e0e7b96adf10ae061dafa900229 (diff) | |
download | flac-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/flac/decode.c | 39 | ||||
-rw-r--r-- | src/flac/decode.h | 1 | ||||
-rw-r--r-- | src/flac/encode.c | 11 | ||||
-rw-r--r-- | src/flac/encode.h | 1 | ||||
-rw-r--r-- | src/flac/foreign_metadata.c | 34 | ||||
-rw-r--r-- | src/flac/foreign_metadata.h | 4 | ||||
-rw-r--r-- | src/flac/main.c | 65 |
7 files changed, 119 insertions, 36 deletions
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? |