summaryrefslogtreecommitdiff
path: root/src/flac/decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/flac/decode.c')
-rw-r--r--src/flac/decode.c39
1 files changed, 35 insertions, 4 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)