Let --keep-foreign-metadata on decode pick the right decode format
This commit is contained in:
parent
a12c6f3236
commit
a8c20a6af1
@ -309,26 +309,7 @@ FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, const ch
|
||||
|
||||
is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
|
||||
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(decoder_session->test_only && strcmp(infilename, "-") != 0) {
|
||||
if(decoder_session->test_only && strcmp(infilename, "-") != 0) {
|
||||
/* When testing, we can be a little more pedantic, as long
|
||||
* as we can seek properly */
|
||||
FLAC__byte buffer[3];
|
||||
|
@ -498,8 +498,7 @@ static FLAC__bool read_from_flac_(foreign_metadata_t *fm, FILE *f, FLAC__Metadat
|
||||
{
|
||||
FLAC__byte id[4], buffer[32];
|
||||
FLAC__off_t offset;
|
||||
FLAC__bool foreign_metadata_found = false, type_found = false, ds64_found = false;
|
||||
uint32_t foreign_metadata_found_type = 0;
|
||||
FLAC__bool first_block = true, type_found = false, ds64_found = false;
|
||||
|
||||
FLAC__ASSERT(FLAC__STREAM_METADATA_APPLICATION_ID_LEN == sizeof(id)*8);
|
||||
|
||||
@ -510,18 +509,18 @@ 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))) {
|
||||
/* 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 */
|
||||
if(first_block) {
|
||||
uint32_t i;
|
||||
for(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;
|
||||
fm->type = i;
|
||||
first_block = false;
|
||||
}
|
||||
continue;
|
||||
if(first_block) /* means no first foreign metadata block was found yet */
|
||||
continue;
|
||||
}
|
||||
else if(memcmp(id, FLAC__FOREIGN_METADATA_APPLICATION_ID[fm->type], sizeof(id)))
|
||||
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;
|
||||
@ -671,23 +670,6 @@ static FLAC__bool read_from_flac_(foreign_metadata_t *fm, FILE *f, FLAC__Metadat
|
||||
if(!append_block_(fm, offset, FLAC__metadata_simple_iterator_get_block_length(it)-sizeof(id), error))
|
||||
return false;
|
||||
}
|
||||
if(!type_found) {
|
||||
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)";
|
||||
return false;
|
||||
|
115
src/flac/main.c
115
src/flac/main.c
@ -75,7 +75,7 @@ static int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__b
|
||||
static int decode_file(const char *infilename);
|
||||
|
||||
static const char *get_encoded_outfilename(const char *infilename);
|
||||
static const char *get_decoded_outfilename(const char *infilename);
|
||||
static const char *get_decoded_outfilename(const char *infilename, const FileFormat format);
|
||||
static const char *get_outfilename(const char *infilename, const char *suffix);
|
||||
|
||||
static void die(const char *message);
|
||||
@ -1726,8 +1726,7 @@ void show_explain(void)
|
||||
void format_mistake(const char *infilename, FileFormat wrong, FileFormat right)
|
||||
{
|
||||
/* WATCHOUT: indexed by FileFormat */
|
||||
static const char * const ff[] = { " raw", " WAVE", " Wave64", "n RF64", "n AIFF", "n AIFF-C", " FLAC", "n Ogg FLAC" };
|
||||
flac__utils_printf(stderr, 1, "WARNING: %s is not a%s file; treating as a%s file\n", infilename, ff[wrong], ff[right]);
|
||||
flac__utils_printf(stderr, 1, "WARNING: %s is not a%s file; treating as a%s file\n", infilename, FileFormatString[wrong], FileFormatString[right]);
|
||||
}
|
||||
|
||||
int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_last_file)
|
||||
@ -2108,7 +2107,9 @@ int decode_file(const char *infilename)
|
||||
FLAC__bool treat_as_ogg = false;
|
||||
FileFormat output_format = FORMAT_WAVE;
|
||||
decode_options_t decode_options;
|
||||
const char *outfilename = get_decoded_outfilename(infilename);
|
||||
foreign_metadata_t foreign_metadata_instance = {0}; /* Allocate space */
|
||||
foreign_metadata_t *foreign_metadata = 0;
|
||||
const char *outfilename = get_outfilename(infilename, ". "); /* Placeholder until we know what the actual suffix is */
|
||||
size_t infilename_length;
|
||||
|
||||
if(0 == outfilename) {
|
||||
@ -2116,13 +2117,29 @@ int decode_file(const char *infilename)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Error if output file already exists (and -f not used).
|
||||
* Use grabbag__file_get_filesize() as a cheap way to check.
|
||||
*/
|
||||
if(!option_values.test_only && !option_values.force_file_overwrite && strcmp(outfilename, "-") && grabbag__file_get_filesize(outfilename) != (FLAC__off_t)(-1)) {
|
||||
flac__utils_printf(stderr, 1, "ERROR: output file %s already exists, use -f to override\n", outfilename);
|
||||
return 1;
|
||||
if(!option_values.analyze && !option_values.test_only &&(option_values.keep_foreign_metadata || option_values.keep_foreign_metadata_if_present)) {
|
||||
const char *error;
|
||||
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_RAW)
|
||||
return usage_error("ERROR: --keep-foreign-metadata cannot be used with raw output\n");
|
||||
foreign_metadata = &foreign_metadata_instance;
|
||||
if(!flac__foreign_metadata_read_from_flac(foreign_metadata, infilename, &error)) {
|
||||
if(option_values.keep_foreign_metadata_if_present) {
|
||||
flac__utils_printf(stderr, 1, "%s: WARNING reading foreign metadata: %s\n", infilename, error);
|
||||
if(option_values.treat_warnings_as_errors) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
/* Couldn't find foreign metadata, stop processing */
|
||||
foreign_metadata = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", infilename, error);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(option_values.force_raw_format)
|
||||
@ -2143,21 +2160,53 @@ int decode_file(const char *infilename)
|
||||
(strlen(outfilename) >= 4 && 0 == FLAC__STRCASECMP(outfilename+(strlen(outfilename)-4), ".w64"))
|
||||
)
|
||||
output_format = FORMAT_WAVE64;
|
||||
else if(foreign_metadata != NULL) {
|
||||
/* Pick a format based on what the foreign metadata contains */
|
||||
if(foreign_metadata->type == FOREIGN_BLOCK_TYPE__WAVE64)
|
||||
output_format = FORMAT_WAVE64;
|
||||
else if(foreign_metadata->is_rf64)
|
||||
output_format = FORMAT_RF64;
|
||||
else if(foreign_metadata->type == FOREIGN_BLOCK_TYPE__AIFF) {
|
||||
output_format = FORMAT_AIFF;
|
||||
if(foreign_metadata->is_aifc) {
|
||||
flac__utils_printf(stderr, 1, "ERROR restoring foreign metadata: restoring AIFF-C files is not yet supported\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
output_format = FORMAT_WAVE;
|
||||
/* Further split is determined in decode.c */
|
||||
}
|
||||
else
|
||||
output_format = FORMAT_WAVE;
|
||||
|
||||
/* Check whether output format agrees with foreign metadata */
|
||||
if(foreign_metadata != NULL) {
|
||||
if((output_format != FORMAT_WAVE && output_format != FORMAT_RF64) && foreign_metadata->type == FOREIGN_BLOCK_TYPE__RIFF)
|
||||
return usage_error("ERROR: foreign metadata type RIFF cannot be restored to a%s file, only to WAVE and RF64\n",FileFormatString[output_format]);
|
||||
if((output_format != FORMAT_AIFF && output_format != FORMAT_AIFF_C) && foreign_metadata->type == FOREIGN_BLOCK_TYPE__AIFF)
|
||||
return usage_error("ERROR: foreign metadata type AIFF cannot be restored to a%s file, only to AIFF and AIFF-C\n",FileFormatString[output_format]);
|
||||
if(output_format != FORMAT_WAVE64 && foreign_metadata->type == FOREIGN_BLOCK_TYPE__WAVE64)
|
||||
return usage_error("ERROR: foreign metadata type Wave64 cannot be restored to a%s file, only to Wave64\n",FileFormatString[output_format]);
|
||||
}
|
||||
|
||||
/* Now reassemble outfilename */
|
||||
get_decoded_outfilename(infilename, output_format);
|
||||
|
||||
/*
|
||||
* Error if output file already exists (and -f not used).
|
||||
* Use grabbag__file_get_filesize() as a cheap way to check.
|
||||
*/
|
||||
if(!option_values.test_only && !option_values.force_file_overwrite && strcmp(outfilename, "-") && grabbag__file_get_filesize(outfilename) != (FLAC__off_t)(-1)) {
|
||||
flac__utils_printf(stderr, 1, "ERROR: output file %s already exists, use -f to override\n", outfilename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!option_values.test_only && !option_values.analyze) {
|
||||
if(output_format == FORMAT_RAW && (option_values.format_is_big_endian < 0 || option_values.format_is_unsigned_samples < 0))
|
||||
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 || 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)
|
||||
return usage_error("ERROR: --keep-foreign-metadata can only be used with WAVE, Wave64, RF64, or AIFF output\n");
|
||||
}
|
||||
|
||||
infilename_length = strlen(infilename);
|
||||
if(option_values.use_ogg)
|
||||
treat_as_ogg = true;
|
||||
@ -2212,28 +2261,10 @@ int decode_file(const char *infilename)
|
||||
retval = flac__decode_file(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, decode_options);
|
||||
}
|
||||
else {
|
||||
decode_options.format_options.iff.foreign_metadata = 0;
|
||||
|
||||
/* initialize foreign metadata if requested */
|
||||
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?
|
||||
FOREIGN_BLOCK_TYPE__RIFF :
|
||||
output_format==FORMAT_WAVE64?
|
||||
FOREIGN_BLOCK_TYPE__WAVE64 :
|
||||
FOREIGN_BLOCK_TYPE__AIFF
|
||||
);
|
||||
if(0 == decode_options.format_options.iff.foreign_metadata) {
|
||||
flac__utils_printf(stderr, 1, "ERROR: creating foreign metadata object\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
decode_options.format_options.iff.foreign_metadata = foreign_metadata;
|
||||
|
||||
retval = flac__decode_file(infilename, option_values.test_only? 0 : outfilename, option_values.analyze, option_values.aopts, decode_options);
|
||||
|
||||
if(decode_options.format_options.iff.foreign_metadata)
|
||||
flac__foreign_metadata_delete(decode_options.format_options.iff.foreign_metadata);
|
||||
}
|
||||
|
||||
if(retval == 0 && strcmp(infilename, "-")) {
|
||||
@ -2261,7 +2292,7 @@ const char *get_encoded_outfilename(const char *infilename)
|
||||
return get_outfilename(p, suffix);
|
||||
}
|
||||
|
||||
const char *get_decoded_outfilename(const char *infilename)
|
||||
const char *get_decoded_outfilename(const char *infilename, const FileFormat format)
|
||||
{
|
||||
const char *suffix;
|
||||
const char *p;
|
||||
@ -2276,16 +2307,16 @@ const char *get_decoded_outfilename(const char *infilename)
|
||||
if(option_values.analyze) {
|
||||
suffix = ".ana";
|
||||
}
|
||||
else if(option_values.force_raw_format) {
|
||||
else if(format == FORMAT_RAW) {
|
||||
suffix = ".raw";
|
||||
}
|
||||
else if(option_values.force_aiff_format) {
|
||||
else if(format == FORMAT_AIFF) {
|
||||
suffix = ".aiff";
|
||||
}
|
||||
else if(option_values.force_rf64_format) {
|
||||
else if(format == FORMAT_RF64) {
|
||||
suffix = ".rf64";
|
||||
}
|
||||
else if(option_values.force_wave64_format) {
|
||||
else if(format == FORMAT_WAVE64) {
|
||||
suffix = ".w64";
|
||||
}
|
||||
else {
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <stdio.h> /* for FILE */
|
||||
|
||||
typedef enum { FORMAT_RAW, FORMAT_WAVE, FORMAT_WAVE64, FORMAT_RF64, FORMAT_AIFF, FORMAT_AIFF_C, FORMAT_FLAC, FORMAT_OGGFLAC } FileFormat;
|
||||
static const char * const FileFormatString[] = { " raw", " WAVE", " Wave64", "n RF64", "n AIFF", "n AIFF-C", " FLAC", "n Ogg FLAC" };
|
||||
|
||||
typedef struct {
|
||||
FLAC__bool is_relative; /* i.e. specification string started with + or - */
|
||||
|
@ -182,6 +182,20 @@ rt_test_wav ()
|
||||
rm -f rt.flac rt.wav
|
||||
}
|
||||
|
||||
rt_test_wav_autokf ()
|
||||
{
|
||||
f="$1"
|
||||
extra="$2"
|
||||
echo $ECHO_N "round-trip test ($f) encode... " $ECHO_C
|
||||
run_flac --force --verify --channel-map=none --no-padding --lax -o rt.flac $extra $f || die "ERROR"
|
||||
echo $ECHO_N "decode... " $ECHO_C
|
||||
run_flac --force --decode --channel-map=none $extra rt.flac || die "ERROR"
|
||||
echo $ECHO_N "compare... " $ECHO_C
|
||||
cmp $f rt.wav || die "ERROR: file mismatch"
|
||||
echo "OK"
|
||||
rm -f rt.flac rt.wav
|
||||
}
|
||||
|
||||
rt_test_w64 ()
|
||||
{
|
||||
f="$1"
|
||||
@ -196,6 +210,20 @@ rt_test_w64 ()
|
||||
rm -f rt.flac rt.w64
|
||||
}
|
||||
|
||||
rt_test_w64_autokf ()
|
||||
{
|
||||
f="$1"
|
||||
extra="$2"
|
||||
echo $ECHO_N "round-trip test ($f) encode... " $ECHO_C
|
||||
run_flac --force --verify --channel-map=none --no-padding --lax -o rt.flac $extra $f || die "ERROR"
|
||||
echo $ECHO_N "decode... " $ECHO_C
|
||||
run_flac --force --decode --channel-map=none $extra rt.flac || die "ERROR"
|
||||
echo $ECHO_N "compare... " $ECHO_C
|
||||
cmp $f rt.w64 || die "ERROR: file mismatch"
|
||||
echo "OK"
|
||||
rm -f rt.flac rt.w64
|
||||
}
|
||||
|
||||
rt_test_rf64 ()
|
||||
{
|
||||
f="$1"
|
||||
@ -210,6 +238,20 @@ rt_test_rf64 ()
|
||||
rm -f rt.flac rt.rf64
|
||||
}
|
||||
|
||||
rt_test_rf64_autokf ()
|
||||
{
|
||||
f="$1"
|
||||
extra="$2"
|
||||
echo $ECHO_N "round-trip test ($f) encode... " $ECHO_C
|
||||
run_flac --force --verify --channel-map=none --no-padding --lax -o rt.flac $extra $f || die "ERROR"
|
||||
echo $ECHO_N "decode... " $ECHO_C
|
||||
run_flac --force --decode --channel-map=none $extra rt.flac || die "ERROR"
|
||||
echo $ECHO_N "compare... " $ECHO_C
|
||||
cmp $f rt.rf64 || die "ERROR: file mismatch"
|
||||
echo "OK"
|
||||
rm -f rt.flac rt.rf64
|
||||
}
|
||||
|
||||
rt_test_aiff ()
|
||||
{
|
||||
f="$1"
|
||||
@ -1177,6 +1219,12 @@ rt_test_w64 wacky2.w64 '--keep-foreign-metadata'
|
||||
rt_test_rf64 wacky1.rf64 '--keep-foreign-metadata'
|
||||
rt_test_rf64 wacky2.rf64 '--keep-foreign-metadata'
|
||||
|
||||
rt_test_wav_autokf wacky1.wav '--keep-foreign-metadata'
|
||||
rt_test_wav_autokf wacky2.wav '--keep-foreign-metadata'
|
||||
rt_test_w64_autokf wacky1.w64 '--keep-foreign-metadata'
|
||||
rt_test_w64_autokf wacky2.w64 '--keep-foreign-metadata'
|
||||
rt_test_rf64_autokf wacky1.rf64 '--keep-foreign-metadata'
|
||||
rt_test_rf64_autokf wacky2.rf64 '--keep-foreign-metadata'
|
||||
|
||||
############################################################################
|
||||
# test the metadata-handling properties of flac-to-flac encoding
|
||||
|
Loading…
x
Reference in New Issue
Block a user