Restore compression type name to AIFF-C from foreign metadata
This commit is contained in:
parent
692f2ebe93
commit
92b5292d65
@ -113,7 +113,7 @@ static int DecoderSession_finish_error(DecoderSession *d);
|
||||
static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, uint32_t sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
|
||||
static FLAC__bool write_iff_headers(FILE *f, DecoderSession *decoder_session, FLAC__uint64 samples);
|
||||
static FLAC__bool write_riff_wave_fmt_chunk_body(FILE *f, FLAC__bool is_waveformatextensible, uint32_t bps, uint32_t channels, uint32_t sample_rate, FLAC__uint32 channel_mask);
|
||||
static FLAC__bool write_aiff_form_comm_chunk(FILE *f, FLAC__uint64 samples, uint32_t bps, uint32_t channels, uint32_t sample_rate, FileFormat format, FileSubFormat subformat);
|
||||
static FLAC__bool write_aiff_form_comm_chunk(FILE *f, FLAC__uint64 samples, uint32_t bps, uint32_t channels, uint32_t sample_rate, FileFormat format, FileSubFormat subformat, FLAC__uint32 comm_length);
|
||||
static FLAC__bool write_little_endian_uint16(FILE *f, FLAC__uint16 val);
|
||||
static FLAC__bool write_little_endian_uint32(FILE *f, FLAC__uint32 val);
|
||||
static FLAC__bool write_little_endian_uint64(FILE *f, FLAC__uint64 val);
|
||||
@ -700,7 +700,7 @@ FLAC__bool write_iff_headers(FILE *f, DecoderSession *decoder_session, FLAC__uin
|
||||
else if(format == FORMAT_AIFF)
|
||||
iff_size = 46 + foreign_metadata_size + aligned_data_size;
|
||||
else /* AIFF-C */
|
||||
iff_size = 52 + foreign_metadata_size + aligned_data_size;
|
||||
iff_size = 16 + foreign_metadata_size + aligned_data_size + fm->aifc_comm_length;
|
||||
|
||||
if(format != FORMAT_WAVE64 && format != FORMAT_RF64 && iff_size >= 0xFFFFFFF4) {
|
||||
flac__utils_printf(stderr, 1, "%s: ERROR: stream is too big to fit in a single %s file\n", decoder_session->inbasefilename, fmt_desc);
|
||||
@ -847,7 +847,7 @@ FLAC__bool write_iff_headers(FILE *f, DecoderSession *decoder_session, FLAC__uin
|
||||
}
|
||||
}
|
||||
|
||||
if(!write_aiff_form_comm_chunk(f, samples, decoder_session->bps, decoder_session->channels, decoder_session->sample_rate, format, subformat))
|
||||
if(!write_aiff_form_comm_chunk(f, samples, decoder_session->bps, decoder_session->channels, decoder_session->sample_rate, format, subformat, fm?fm->aifc_comm_length:0))
|
||||
return false;
|
||||
|
||||
decoder_session->fm_offset2 = ftello(f);
|
||||
@ -918,21 +918,23 @@ FLAC__bool write_riff_wave_fmt_chunk_body(FILE *f, FLAC__bool is_waveformatexten
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool write_aiff_form_comm_chunk(FILE *f, FLAC__uint64 samples, uint32_t bps, uint32_t channels, uint32_t sample_rate, FileFormat format, FileSubFormat subformat)
|
||||
FLAC__bool write_aiff_form_comm_chunk(FILE *f, FLAC__uint64 samples, uint32_t bps, uint32_t channels, uint32_t sample_rate, FileFormat format, FileSubFormat subformat, FLAC__uint32 comm_length)
|
||||
{
|
||||
FLAC__uint32 i;
|
||||
FLAC__ASSERT(samples <= 0xffffffff);
|
||||
|
||||
if(comm_length == 0) {
|
||||
if(format == FORMAT_AIFF)
|
||||
comm_length = 30;
|
||||
else
|
||||
comm_length = 36;
|
||||
}
|
||||
|
||||
if(flac__utils_fwrite("COMM", 1, 4, f) != 4)
|
||||
return false;
|
||||
|
||||
if(format == FORMAT_AIFF) {
|
||||
if(!write_big_endian_uint32(f, 18)) /* chunk size = 18 */
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(!write_big_endian_uint32(f, 24)) /* chunk size = 24 */
|
||||
return false;
|
||||
}
|
||||
if(!write_big_endian_uint32(f, comm_length-12)) /* chunk size = 18 */
|
||||
return false;
|
||||
|
||||
if(!write_big_endian_uint16(f, (FLAC__uint16)channels))
|
||||
return false;
|
||||
@ -955,8 +957,10 @@ FLAC__bool write_aiff_form_comm_chunk(FILE *f, FLAC__uint64 samples, uint32_t bp
|
||||
if(flac__utils_fwrite("sowt", 1, 4, f) != 4)
|
||||
return false;
|
||||
}
|
||||
if(flac__utils_fwrite("\x00\x00", 1, 2, f) != 2)
|
||||
return false;
|
||||
for(i = 34; i < comm_length; i++) {
|
||||
if(flac__utils_fwrite("\x00", 1, 1, f) != 1)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -498,6 +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__uint32 length;
|
||||
FLAC__bool first_block = true, type_found = false, ds64_found = false;
|
||||
|
||||
FLAC__ASSERT(FLAC__STREAM_METADATA_APPLICATION_ID_LEN == sizeof(id)*8);
|
||||
@ -522,6 +523,7 @@ static FLAC__bool read_from_flac_(foreign_metadata_t *fm, FILE *f, FLAC__Metadat
|
||||
else if(memcmp(id, FLAC__FOREIGN_METADATA_APPLICATION_ID[fm->type], sizeof(id)))
|
||||
continue;
|
||||
offset = FLAC__metadata_simple_iterator_get_block_offset(it);
|
||||
length = FLAC__metadata_simple_iterator_get_block_length(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;
|
||||
offset += sizeof(id);
|
||||
@ -636,11 +638,12 @@ static FLAC__bool read_from_flac_(foreign_metadata_t *fm, FILE *f, FLAC__Metadat
|
||||
}
|
||||
fm->format_block = fm->num_blocks;
|
||||
if(fm->is_aifc) {
|
||||
if(fread(buffer+4, 1, 28, f) != 28) {
|
||||
if(fread(buffer+4, 1, 26, f) != 26) {
|
||||
if(error) *error = "read error (020)";
|
||||
return false;
|
||||
}
|
||||
fm->is_sowt = 0 == memcmp(buffer+26, "sowt", 2);
|
||||
fm->aifc_comm_length = length;
|
||||
}
|
||||
}
|
||||
else if(!memcmp(buffer, "SSND", 4)) {
|
||||
@ -700,48 +703,68 @@ static FLAC__bool write_to_iff_(foreign_metadata_t *fm, FILE *fin, FILE *fout, F
|
||||
/* don't write first (RIFF/RF64/FORM) chunk, or ds64 chunk in the case of RF64, compare instead */
|
||||
for(i = 0; i < (fm->is_rf64?2:1); i++) {
|
||||
if(fseeko(fin, fm->blocks[i].offset, SEEK_SET) < 0) {
|
||||
if(error) *error = "seek failed in FLAC file (003)";
|
||||
if(error) *error = "seek failed in FLAC file";
|
||||
return false;
|
||||
}
|
||||
if(!compare_data_(fin, fout, fm->blocks[i].size, error, "read failed in WAVE/AIFF file (004)", "write failed in FLAC file (005)", "stored foreign metadata seems invalid"))
|
||||
if(!compare_data_(fin, fout, fm->blocks[i].size, error, "read failed in FLAC file", "read failed in WAVE/AIFF file", "stored main chunk length differs from written length"))
|
||||
return false;
|
||||
}
|
||||
|
||||
for(; i < fm->format_block; i++) {
|
||||
if(fseeko(fin, fm->blocks[i].offset, SEEK_SET) < 0) {
|
||||
if(error) *error = "seek failed in FLAC file (003)";
|
||||
if(error) *error = "seek failed in FLAC file";
|
||||
return false;
|
||||
}
|
||||
if(!copy_data_(fin, fout, fm->blocks[i].size, error, "read failed in WAVE/AIFF file (004)", "write failed in FLAC file (005)"))
|
||||
if(!copy_data_(fin, fout, fm->blocks[i].size, error, "read failed in FLAC file", "read failed in WAVE/AIFF file"))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fm->is_aifc) {
|
||||
/* Need to restore compression type name */
|
||||
if(fseeko(fout, 30, SEEK_CUR) < 0) {
|
||||
if(error) *error = "seek failed in AIFF-C file";
|
||||
return false;
|
||||
}
|
||||
if(fseeko(fin, fm->blocks[i].offset+30, SEEK_SET) < 0) {
|
||||
if(error) *error = "seek failed in FLAC file";
|
||||
return false;
|
||||
}
|
||||
if(!copy_data_(fin, fout, fm->aifc_comm_length-34, error, "read failed in FLAC file", "write failed in WAVE/AIFF file"))
|
||||
return false;
|
||||
/* Now seek back */
|
||||
if(fseeko(fout, ((FLAC__int32)(fm->aifc_comm_length) * -1) + 4, SEEK_CUR) < 0) {
|
||||
if(error) *error = "seek failed in AIFF-C file";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* compare format block */
|
||||
if(fseeko(fin, fm->blocks[i].offset, SEEK_SET) < 0) {
|
||||
if(error) *error = "seek failed in FLAC file (003)";
|
||||
if(error) *error = "seek failed in FLAC file";
|
||||
return false;
|
||||
}
|
||||
if(!compare_data_(fin, fout, fm->blocks[i].size, error, "read failed in WAVE/AIFF file (004)", "write failed in FLAC file (005)", "stored foreign format block differs from written block. Perhaps the file is being restored to a different format than that of the original file"))
|
||||
if(!compare_data_(fin, fout, fm->blocks[i].size, error, "read failed in FLAC file", "read failed in WAVE/AIFF file", "stored foreign format block differs from written block. Perhaps the file is being restored to a different format than that of the original file"))
|
||||
return false;
|
||||
i++;
|
||||
|
||||
for(; i < fm->audio_block; i++) {
|
||||
if(fseeko(fin, fm->blocks[i].offset, SEEK_SET) < 0) {
|
||||
if(error) *error = "seek failed in FLAC file (007)";
|
||||
if(error) *error = "seek failed in FLAC file";
|
||||
return false;
|
||||
}
|
||||
if(!copy_data_(fin, fout, fm->blocks[i].size, error, "read failed in WAVE/AIFF file (008)", "write failed in FLAC file (009)"))
|
||||
if(!copy_data_(fin, fout, fm->blocks[i].size, error, "read failed in FLAC file", "write failed in WAVE/AIFF file"))
|
||||
return false;
|
||||
}
|
||||
if(fseeko(fout, offset3, SEEK_SET) < 0) {
|
||||
if(error) *error = "seek failed in WAVE/AIFF file (010)";
|
||||
if(error) *error = "seek failed in WAVE/AIFF file";
|
||||
return false;
|
||||
}
|
||||
for(i = fm->audio_block+1; i < fm->num_blocks; i++) {
|
||||
if(fseeko(fin, fm->blocks[i].offset, SEEK_SET) < 0) {
|
||||
if(error) *error = "seek failed in FLAC file (011)";
|
||||
if(error) *error = "seek failed in FLAC file";
|
||||
return false;
|
||||
}
|
||||
if(!copy_data_(fin, fout, fm->blocks[i].size, error, "read failed in WAVE/AIFF file (012)", "write failed in FLAC file (013)"))
|
||||
if(!copy_data_(fin, fout, fm->blocks[i].size, error, "read failed in FLAC file", "write failed in WAVE/AIFF file"))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -63,6 +63,7 @@ typedef struct {
|
||||
FLAC__bool is_wavefmtex; /* always false if type!=RIFF */
|
||||
FLAC__bool is_aifc; /* always false if type!=AIFF */
|
||||
FLAC__bool is_sowt; /* always false if type!=AIFF */
|
||||
FLAC__uint32 aifc_comm_length;
|
||||
FLAC__uint32 ssnd_offset_size; /* 0 if type!=AIFF */
|
||||
} foreign_metadata_t;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user