38
38
#include <math.h> /* for floor() */
39
39
#include <stdio.h> /* for FILE etc. */
40
40
#include <stdlib.h> /* for malloc */
41
#include <string.h> /* for strcmp(), strerror( */
41
#include <string.h> /* for strcmp(), strerror() */
42
42
#include "FLAC/all.h"
43
#include "share/alloc.h"
43
44
#include "share/grabbag.h"
44
45
#include "encode.h"
116
118
extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
117
119
extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
118
120
extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
121
extern FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value);
123
126
static FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FILE *infile, const char *infilename, const char *outfilename);
124
127
static void EncoderSession_destroy(EncoderSession *e);
125
static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero);
128
static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero, foreign_metadata_t *foreign_metadata);
126
129
static int EncoderSession_finish_error(EncoderSession *e);
127
static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, FLAC__uint32 channel_mask, unsigned channels, unsigned bps, unsigned sample_rate, FLACDecoderData *flac_decoder_data);
130
static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, FLAC__uint32 channel_mask, unsigned channels, unsigned bps, unsigned sample_rate, const foreign_metadata_t *foreign_metadata, FLACDecoderData *flac_decoder_data);
128
131
static FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples);
129
132
static FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e);
130
133
static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
151
154
static FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
152
155
static FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset);
153
156
static unsigned count_channel_mask_bits(FLAC__uint32 mask);
154
158
static FLAC__uint32 limit_channel_mask(FLAC__uint32 mask, unsigned channels);
157
162
* public routines
196
201
channel_map[i] = i;
204
if(options.foreign_metadata) {
206
if(!flac__foreign_metadata_read_from_aiff(options.foreign_metadata, infilename, &error)) {
207
flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", encoder_session.inbasefilename, error);
208
return EncoderSession_finish_error(&encoder_session);
199
212
/* lookahead[] already has "FORMxxxxAIFF", do sub-chunks */
324
337
/* skip any extra data in the COMM chunk */
325
338
if(!fskip_ahead(infile, skip)) {
326
flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra COMM data\n", encoder_session.inbasefilename);
339
flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over extra COMM data\n", encoder_session.inbasefilename);
327
340
return EncoderSession_finish_error(&encoder_session);
341
354
else if(got_ssnd_chunk==false && !memcmp(chunk_id, "SSND", 4)) { /* sound data chunk */
342
355
unsigned int offset= 0U, block_size= 0U, align_remainder= 0U, data_bytes;
343
size_t bytes_per_frame= channels*(bps>>3);
356
const size_t bytes_per_frame= channels*(bps>>3);
344
357
FLAC__uint64 total_samples_in_input, trim = 0;
345
358
FLAC__bool pad= false;
352
365
/* SSND chunk size */
353
366
if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
354
367
return EncoderSession_finish_error(&encoder_session);
368
if(options.common.ignore_chunk_sizes) {
369
FLAC__ASSERT(!options.common.sector_align);
370
data_bytes = (unsigned)(-(int)bytes_per_frame); /* max out data_bytes; we'll use EOF as signal to stop reading */
374
data_bytes-= 8U; /* discount the offset and block size fields */
356
376
pad= (data_bytes & 1U) ? true : false;
357
data_bytes-= 8U; /* discount the offset and block size fields */
360
379
if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
405
424
data_bytes-= (unsigned int)encoder_session.skip*bytes_per_frame; /*@@@ WATCHOUT: 4GB limit */
406
encoder_session.total_samples_to_encode= total_samples_in_input - encoder_session.skip;
425
if(options.common.ignore_chunk_sizes) {
426
encoder_session.total_samples_to_encode= 0;
427
flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
428
FLAC__ASSERT(0 == encoder_session.until);
431
encoder_session.total_samples_to_encode= total_samples_in_input - encoder_session.skip;
407
433
if(encoder_session.until > 0) {
408
434
trim = total_samples_in_input - encoder_session.until;
409
435
FLAC__ASSERT(total_samples_in_input > 0);
422
448
/* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */
423
449
encoder_session.unencoded_size= encoder_session.total_samples_to_encode*bytes_per_frame+54;
425
if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, channels, bps-shift, sample_rate, /*flac_decoder_data=*/0))
451
if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, channels, bps-shift, sample_rate, options.foreign_metadata, /*flac_decoder_data=*/0))
426
452
return EncoderSession_finish_error(&encoder_session);
428
454
/* first do any samples in the reservoir */
454
480
return EncoderSession_finish_error(&encoder_session);
456
482
else if(feof(infile)) {
457
flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written);
458
if(encoder_session.treat_warnings_as_errors)
459
return EncoderSession_finish_error(&encoder_session);
483
if(options.common.ignore_chunk_sizes) {
484
flac__utils_printf(stderr, 1, "%s: INFO: hit EOF with --ignore-chunk-sizes, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.samples_written);
487
flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
488
if(encoder_session.treat_warnings_as_errors)
489
return EncoderSession_finish_error(&encoder_session);
541
572
got_ssnd_chunk= true;
543
574
else { /* other chunk */
544
if(!memcmp(chunk_id, "COMM", 4)) {
545
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_session.inbasefilename);
546
if(encoder_session.treat_warnings_as_errors)
547
return EncoderSession_finish_error(&encoder_session);
549
else if(!memcmp(chunk_id, "SSND", 4)) {
550
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename);
551
if(encoder_session.treat_warnings_as_errors)
552
return EncoderSession_finish_error(&encoder_session);
555
flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_session.inbasefilename, chunk_id);
575
if(!options.foreign_metadata) {
576
if(!memcmp(chunk_id, "COMM", 4))
577
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
578
else if(!memcmp(chunk_id, "SSND", 4))
579
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
580
else if(!options.foreign_metadata)
581
flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s' (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename, chunk_id);
556
582
if(encoder_session.treat_warnings_as_errors)
557
583
return EncoderSession_finish_error(&encoder_session);
566
592
FLAC__ASSERT(skip<=LONG_MAX);
567
593
if(!fskip_ahead(infile, skip)) {
568
fprintf(stderr, "%s: ERROR during read while skipping unknown chunk\n", encoder_session.inbasefilename);
594
fprintf(stderr, "%s: ERROR during read while skipping over unknown chunk\n", encoder_session.inbasefilename);
569
595
return EncoderSession_finish_error(&encoder_session);
577
603
return EncoderSession_finish_error(&encoder_session);
580
return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
606
return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero, options.foreign_metadata);
583
609
int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
585
611
EncoderSession encoder_session;
586
612
FLAC__bool is_unsigned_samples = false;
587
613
unsigned channels = 0, bps = 0, sample_rate = 0, shift = 0;
588
size_t bytes_per_wide_sample, bytes_read;
589
615
size_t channel_map[FLAC__MAX_CHANNELS];
590
616
FLAC__uint16 x, format; /* format is the wFormatTag word from the 'fmt ' chunk */
591
617
FLAC__uint32 xx, channel_mask = 0;
622
648
channel_map[i] = i;
651
if(options.foreign_metadata) {
653
if(!flac__foreign_metadata_read_from_wave(options.foreign_metadata, infilename, &error)) {
654
flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", encoder_session.inbasefilename, error);
655
return EncoderSession_finish_error(&encoder_session);
626
660
* lookahead[] already has "RIFFxxxxWAVE", do sub-chunks
882
916
/* skip any extra data in the fmt sub-chunk */
883
917
if(!fskip_ahead(infile, data_bytes)) {
884
flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra 'fmt' data\n", encoder_session.inbasefilename);
918
flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over extra 'fmt' data\n", encoder_session.inbasefilename);
885
919
return EncoderSession_finish_error(&encoder_session);
899
933
else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
900
934
FLAC__uint64 total_samples_in_input, trim = 0;
901
935
FLAC__bool pad = false;
936
const size_t bytes_per_wide_sample = channels * (bps >> 3);
902
937
unsigned data_bytes;
905
940
if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
906
941
return EncoderSession_finish_error(&encoder_session);
908
if(0 == data_bytes) {
909
flac__utils_printf(stderr, 1, "%s: ERROR: 'data' subchunk has size of 0\n", encoder_session.inbasefilename);
910
return EncoderSession_finish_error(&encoder_session);
942
if(options.common.ignore_chunk_sizes) {
943
FLAC__ASSERT(!options.common.sector_align);
944
data_bytes = (unsigned)(-(int)bytes_per_wide_sample); /* max out data_bytes; we'll use EOF as signal to stop reading */
948
if(0 == data_bytes) {
949
flac__utils_printf(stderr, 1, "%s: ERROR: 'data' subchunk has size of 0\n", encoder_session.inbasefilename);
950
return EncoderSession_finish_error(&encoder_session);
912
953
pad = (data_bytes & 1U) ? true : false;
914
bytes_per_wide_sample = channels * (bps >> 3);
916
955
/* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
917
956
FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
918
957
total_samples_in_input = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;
936
975
data_bytes -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
937
encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
976
if(options.common.ignore_chunk_sizes) {
977
encoder_session.total_samples_to_encode = 0;
978
flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
979
FLAC__ASSERT(0 == encoder_session.until);
982
encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
938
984
if(encoder_session.until > 0) {
939
985
trim = total_samples_in_input - encoder_session.until;
940
986
FLAC__ASSERT(total_samples_in_input > 0);
953
999
/* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
954
1000
encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample + 44;
956
if(!EncoderSession_init_encoder(&encoder_session, options.common, channel_mask, channels, bps-shift, sample_rate, /*flac_decoder_data=*/0))
1002
if(!EncoderSession_init_encoder(&encoder_session, options.common, channel_mask, channels, bps-shift, sample_rate, options.foreign_metadata, /*flac_decoder_data=*/0))
957
1003
return EncoderSession_finish_error(&encoder_session);
990
1036
return EncoderSession_finish_error(&encoder_session);
992
1038
else if(feof(infile)) {
993
flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
994
if(encoder_session.treat_warnings_as_errors)
995
return EncoderSession_finish_error(&encoder_session);
1039
if(options.common.ignore_chunk_sizes) {
1040
flac__utils_printf(stderr, 1, "%s: INFO: hit EOF with --ignore-chunk-sizes, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.samples_written);
1043
flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
1044
if(encoder_session.treat_warnings_as_errors)
1045
return EncoderSession_finish_error(&encoder_session);
1076
1127
got_data_chunk = true;
1079
if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
1080
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename);
1081
if(encoder_session.treat_warnings_as_errors)
1082
return EncoderSession_finish_error(&encoder_session);
1084
else if(xx == 0x61746164) { /* "data" */
1085
if(got_data_chunk) {
1086
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename);
1087
if(encoder_session.treat_warnings_as_errors)
1088
return EncoderSession_finish_error(&encoder_session);
1090
else if(!got_fmt_chunk) {
1091
flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
1092
return EncoderSession_finish_error(&encoder_session);
1099
flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c'\n", encoder_session.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
1100
if(encoder_session.treat_warnings_as_errors)
1101
return EncoderSession_finish_error(&encoder_session);
1130
if(xx == 0x61746164 && !got_fmt_chunk) { /* "data" */
1131
flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
1132
return EncoderSession_finish_error(&encoder_session);
1135
if(!options.foreign_metadata) {
1136
if(xx == 0x20746d66 && got_fmt_chunk) /* "fmt " */
1137
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
1138
else if(xx == 0x61746164) /* "data" */
1139
flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
1141
flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c' (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
1142
if(encoder_session.treat_warnings_as_errors)
1143
return EncoderSession_finish_error(&encoder_session);
1103
1146
/* sub-chunk size */
1104
1147
if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
1105
1148
return EncoderSession_finish_error(&encoder_session);
1109
1152
FLAC__ASSERT(skip<=LONG_MAX);
1110
1153
if(!fskip_ahead(infile, skip)) {
1111
flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_session.inbasefilename);
1154
flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over unsupported sub-chunk\n", encoder_session.inbasefilename);
1112
1155
return EncoderSession_finish_error(&encoder_session);
1118
return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
1161
return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero, options.foreign_metadata);
1121
1164
int flac__encode_raw(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options)
1219
if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, options.channels, options.bps, options.sample_rate, /*flac_decoder_data=*/0))
1262
if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, options.channels, options.bps, options.sample_rate, /*foreign_metadata=*/0, /*flac_decoder_data=*/0))
1220
1263
return EncoderSession_finish_error(&encoder_session);
1386
return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
1429
return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero, /*foreign_metadata=*/0);
1389
1432
int flac__encode_flac(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, flac_encode_options_t options, FLAC__bool input_is_ogg)
1499
1542
encoder_session.unencoded_size = decoder_data.filesize;
1501
1544
/* (channel mask will get copied over from the source VORBIS_COMMENT if it exists) */
1502
if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, decoder_data.metadata_blocks[0]->data.stream_info.channels, decoder_data.metadata_blocks[0]->data.stream_info.bits_per_sample, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate, &decoder_data))
1545
if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, decoder_data.metadata_blocks[0]->data.stream_info.channels, decoder_data.metadata_blocks[0]->data.stream_info.bits_per_sample, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate, /*foreign_metadata=*/0, &decoder_data))
1503
1546
goto fubar2; /*@@@ yuck */
1541
1584
FLAC__stream_decoder_delete(decoder);
1542
retval = EncoderSession_finish_ok(&encoder_session, -1, -1);
1585
retval = EncoderSession_finish_ok(&encoder_session, -1, -1, /*foreign_metadata=*/0);
1543
1586
/* have to wail until encoder is completely finished before deleting because of the final step of writing the seekpoint offsets */
1544
1587
for(i = 0; i < decoder_data.num_metadata_blocks; i++)
1545
1588
FLAC__metadata_object_delete(decoder_data.metadata_blocks[i]);
1712
/*@@@@@@ should this go here or somewhere else? */
1713
if(ret == 0 && foreign_metadata) {
1715
if(!flac__foreign_metadata_write_to_flac(foreign_metadata, e->infilename, e->outfilename, &error)) {
1716
flac__utils_printf(stderr, 1, "%s: ERROR: updating foreign metadata in FLAC file: %s\n", e->inbasefilename, error);
1668
1721
EncoderSession_destroy(e);
1691
FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, FLAC__uint32 channel_mask, unsigned channels, unsigned bps, unsigned sample_rate, FLACDecoderData *flac_decoder_data)
1693
unsigned num_metadata, i;
1694
FLAC__StreamMetadata padding, *cuesheet = 0;
1695
FLAC__StreamMetadata *static_metadata[4+64]; /* MAGIC +64 is for pictures metadata in options.pictures */
1696
FLAC__StreamMetadata **metadata = static_metadata;
1745
unsigned num_metadata;
1746
FLAC__bool *needs_delete;
1747
FLAC__StreamMetadata **metadata;
1748
FLAC__StreamMetadata *cuesheet; /* always needs to be deleted */
1749
} static_metadata_t;
1751
static void static_metadata_init(static_metadata_t *m)
1753
m->num_metadata = 0;
1754
m->needs_delete = 0;
1759
static void static_metadata_clear(static_metadata_t *m)
1762
for(i = 0; i < m->num_metadata; i++)
1763
if(m->needs_delete[i])
1764
FLAC__metadata_object_delete(m->metadata[i]);
1768
free(m->needs_delete);
1770
FLAC__metadata_object_delete(m->cuesheet);
1771
static_metadata_init(m);
1774
static FLAC__bool static_metadata_append(static_metadata_t *m, FLAC__StreamMetadata *d, FLAC__bool needs_delete)
1777
if(0 == (x = safe_realloc_muladd2_(m->metadata, sizeof(*m->metadata), /*times (*/m->num_metadata, /*+*/1/*)*/)))
1779
m->metadata = (FLAC__StreamMetadata**)x;
1780
if(0 == (x = safe_realloc_muladd2_(m->needs_delete, sizeof(*m->needs_delete), /*times (*/m->num_metadata, /*+*/1/*)*/)))
1782
m->needs_delete = (FLAC__bool*)x;
1783
m->metadata[m->num_metadata] = d;
1784
m->needs_delete[m->num_metadata] = needs_delete;
1789
FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, FLAC__uint32 channel_mask, unsigned channels, unsigned bps, unsigned sample_rate, const foreign_metadata_t *foreign_metadata, FLACDecoderData *flac_decoder_data)
1791
FLAC__StreamMetadata padding;
1792
FLAC__StreamMetadata **metadata = 0;
1793
static_metadata_t static_metadata;
1794
unsigned num_metadata = 0, i;
1697
1795
FLAC__StreamEncoderInitStatus init_status;
1698
1796
const FLAC__bool is_cdda = (channels == 1 || channels == 2) && (bps == 16) && (sample_rate == 44100);
1699
1797
char apodizations[2000];
1701
1799
FLAC__ASSERT(sizeof(options.pictures)/sizeof(options.pictures[0]) <= 64);
1801
static_metadata_init(&static_metadata);
1703
1803
e->replay_gain = options.replay_gain;
1704
1804
e->channels = channels;
1705
1805
e->bits_per_sample = bps;
1727
if(!parse_cuesheet(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode, e->treat_warnings_as_errors))
1827
if(!parse_cuesheet(&static_metadata.cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode, e->treat_warnings_as_errors))
1730
if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? cuesheet : 0, e)) {
1830
if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? static_metadata.cuesheet : 0, e)) {
1731
1831
flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1733
FLAC__metadata_object_delete(cuesheet);
1832
static_metadata_clear(&static_metadata);
1836
/* build metadata */
1737
1837
if(flac_decoder_data) {
1739
1839
* we're encoding from FLAC so we will use the FLAC file's
1748
1848
FLAC__StreamMetadata *pic = FLAC__metadata_object_clone(options.pictures[i]);
1750
1850
flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PICTURE block\n", e->inbasefilename);
1752
FLAC__metadata_object_delete(cuesheet);
1851
static_metadata_clear(&static_metadata);
1755
1854
flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks++] = pic;
1773
1872
(void) flac__utils_get_channel_mask_tag(flac_decoder_data->metadata_blocks[i], &channel_mask);
1774
1873
flac__utils_printf(stderr, 1, "%s: WARNING, replacing tags from input FLAC file with those given on the command-line\n", e->inbasefilename);
1775
1874
if(e->treat_warnings_as_errors) {
1777
FLAC__metadata_object_delete(cuesheet);
1875
static_metadata_clear(&static_metadata);
1780
1878
FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1789
1887
FLAC__StreamMetadata *vc = FLAC__metadata_object_clone(options.vorbis_comment);
1790
1888
if(0 == vc || (channel_mask && !flac__utils_set_channel_mask_tag(vc, channel_mask))) {
1791
1889
flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for VORBIS_COMMENT block\n", e->inbasefilename);
1793
FLAC__metadata_object_delete(cuesheet);
1890
static_metadata_clear(&static_metadata);
1796
1893
for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1809
1906
for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1810
1907
FLAC__bool existing_cuesheet_is_bad = false;
1811
1908
/* check if existing cuesheet matches the input audio */
1812
if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && 0 == cuesheet) {
1909
if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && 0 == static_metadata.cuesheet) {
1813
1910
const FLAC__StreamMetadata_CueSheet *cs = &flac_decoder_data->metadata_blocks[i]->data.cue_sheet;
1814
1911
if(e->total_samples_to_encode == 0) {
1815
1912
flac__utils_printf(stderr, 1, "%s: WARNING, cuesheet in input FLAC file cannot be kept if input size is not known, dropping it...\n", e->inbasefilename);
1816
1913
if(e->treat_warnings_as_errors) {
1818
FLAC__metadata_object_delete(cuesheet);
1914
static_metadata_clear(&static_metadata);
1821
1917
existing_cuesheet_is_bad = true;
1823
1919
else if(e->total_samples_to_encode != cs->tracks[cs->num_tracks-1].offset) {
1824
1920
flac__utils_printf(stderr, 1, "%s: WARNING, lead-out offset of cuesheet in input FLAC file does not match input length, dropping existing cuesheet...\n", e->inbasefilename);
1825
1921
if(e->treat_warnings_as_errors) {
1827
FLAC__metadata_object_delete(cuesheet);
1922
static_metadata_clear(&static_metadata);
1830
1925
existing_cuesheet_is_bad = true;
1833
if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != cuesheet)) {
1928
if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != static_metadata.cuesheet)) {
1929
if(0 != static_metadata.cuesheet) {
1835
1930
flac__utils_printf(stderr, 1, "%s: WARNING, replacing cuesheet in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1836
1931
if(e->treat_warnings_as_errors) {
1837
FLAC__metadata_object_delete(cuesheet);
1932
static_metadata_clear(&static_metadata);
1845
1940
flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1847
1942
flac_decoder_data->num_metadata_blocks = j;
1848
if(0 != cuesheet && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1943
if(0 != static_metadata.cuesheet && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1849
1944
/* prepend ours */
1850
FLAC__StreamMetadata *cs = FLAC__metadata_object_clone(cuesheet);
1945
FLAC__StreamMetadata *cs = FLAC__metadata_object_clone(static_metadata.cuesheet);
1852
1947
flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for CUESHEET block\n", e->inbasefilename);
1854
FLAC__metadata_object_delete(cuesheet);
1948
static_metadata_clear(&static_metadata);
1857
1951
for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1882
1976
if(options.num_requested_seek_points > 0) {
1883
1977
flac__utils_printf(stderr, 1, "%s: WARNING, replacing seektable in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1884
1978
if(e->treat_warnings_as_errors) {
1886
FLAC__metadata_object_delete(cuesheet);
1979
static_metadata_clear(&static_metadata);
1893
1986
flac__utils_printf(stderr, 1, "%s: WARNING, can't use existing seektable in input FLAC since the input size is changing or unknown, dropping existing SEEKTABLE block...\n", e->inbasefilename);
1894
1987
if(e->treat_warnings_as_errors) {
1896
FLAC__metadata_object_delete(cuesheet);
1988
static_metadata_clear(&static_metadata);
1910
2002
FLAC__StreamMetadata *st = FLAC__metadata_object_clone(e->seek_table_template);
1912
2004
flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for SEEKTABLE block\n", e->inbasefilename);
1914
FLAC__metadata_object_delete(cuesheet);
2005
static_metadata_clear(&static_metadata);
1917
2008
for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1952
2043
flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
1953
2044
if(0 == flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]) {
1954
2045
flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PADDING block\n", e->inbasefilename);
1956
FLAC__metadata_object_delete(cuesheet);
2046
static_metadata_clear(&static_metadata);
1959
2049
flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->is_last = false; /* the encoder will set this for us */
1970
2060
* we're not encoding from FLAC so we will build the metadata
1974
2063
if(e->seek_table_template->data.seek_table.num_points > 0) {
1975
2064
e->seek_table_template->is_last = false; /* the encoder will set this for us */
1976
metadata[num_metadata++] = e->seek_table_template;
2065
static_metadata_append(&static_metadata, e->seek_table_template, /*needs_delete=*/false);
1979
metadata[num_metadata++] = cuesheet;
2067
if(0 != static_metadata.cuesheet)
2068
static_metadata_append(&static_metadata, static_metadata.cuesheet, /*needs_delete=*/false);
1980
2069
if(channel_mask) {
1981
2070
if(!flac__utils_set_channel_mask_tag(options.vorbis_comment, channel_mask)) {
1982
2071
flac__utils_printf(stderr, 1, "%s: ERROR adding channel mask tag\n", e->inbasefilename);
1984
FLAC__metadata_object_delete(cuesheet);
2072
static_metadata_clear(&static_metadata);
1988
metadata[num_metadata++] = options.vorbis_comment;
2076
static_metadata_append(&static_metadata, options.vorbis_comment, /*needs_delete=*/false);
1989
2077
for(i = 0; i < options.num_pictures; i++)
1990
metadata[num_metadata++] = options.pictures[i];
2078
static_metadata_append(&static_metadata, options.pictures[i], /*needs_delete=*/false);
2079
if(foreign_metadata) {
2080
for(i = 0; i < foreign_metadata->num_blocks; i++) {
2081
FLAC__StreamMetadata *p = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
2083
flac__utils_printf(stderr, 1, "%s: ERROR: out of memory\n", e->inbasefilename);
2084
static_metadata_clear(&static_metadata);
2087
static_metadata_append(&static_metadata, p, /*needs_delete=*/true);
2088
static_metadata.metadata[static_metadata.num_metadata-1]->length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8 + foreign_metadata->blocks[i].size;
2089
/*fprintf(stderr,"@@@@@@ add PADDING=%u\n",static_metadata.metadata[static_metadata.num_metadata-1]->length);*/
1991
2092
if(options.padding != 0) {
1992
2093
padding.is_last = false; /* the encoder will set this for us */
1993
2094
padding.type = FLAC__METADATA_TYPE_PADDING;
1994
2095
padding.length = (unsigned)(options.padding>0? options.padding : (e->total_samples_to_encode / e->sample_rate < 20*60? FLAC_ENCODE__DEFAULT_PADDING : FLAC_ENCODE__DEFAULT_PADDING*8));
1995
metadata[num_metadata++] = &padding;
2096
static_metadata_append(&static_metadata, &padding, /*needs_delete=*/false);
2098
metadata = static_metadata.metadata;
2099
num_metadata = static_metadata.num_metadata;
1999
2102
/* check for a few things that have not already been checked. the
2073
2174
FLAC__stream_encoder_disable_constant_subframes(e->encoder, options.debug.disable_constant_subframes);
2074
2175
FLAC__stream_encoder_disable_fixed_subframes(e->encoder, options.debug.disable_fixed_subframes);
2075
2176
FLAC__stream_encoder_disable_verbatim_subframes(e->encoder, options.debug.disable_verbatim_subframes);
2177
if(!options.debug.do_md5) {
2178
flac__utils_printf(stderr, 1, "%s: WARNING, MD5 computation disabled, resulting file will not have MD5 sum\n", e->inbasefilename);
2179
if(e->treat_warnings_as_errors) {
2180
static_metadata_clear(&static_metadata);
2183
FLAC__stream_encoder_set_do_md5(e->encoder, false);
2077
2186
#if FLAC__HAS_OGG
2078
2187
if(e->use_ogg) {
2090
2199
print_error_with_init_status(e, "ERROR initializing encoder", init_status);
2091
2200
if(FLAC__stream_encoder_get_state(e->encoder) != FLAC__STREAM_ENCODER_IO_ERROR)
2092
2201
e->outputfile_opened = true;
2094
FLAC__metadata_object_delete(cuesheet);
2202
static_metadata_clear(&static_metadata);
2132
2239
if(num_requested_seek_points < 0) {
2133
requested_seek_points = "10s;";
2241
/*@@@@@@ workaround ogg bug: too many seekpoints makes table not fit in one page */
2242
if(e->use_ogg && e->total_samples_to_encode > 0 && e->total_samples_to_encode / e->sample_rate / 10 > 230)
2243
requested_seek_points = "230x;";
2246
requested_seek_points = "10s;";
2134
2247
num_requested_seek_points = 1;
2540
2653
const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * min(1.0, progress));
2656
FLAC__ASSERT(encoder_session->total_samples_to_encode > 0);
2543
2658
if(samples_written == encoder_session->total_samples_to_encode) {
2544
2659
flac__utils_printf(stderr, 2, "\r%s:%s wrote %u bytes, ratio=%0.3f",
2545
2660
encoder_session->inbasefilename,
2767
2882
static unsigned char dump[8192];
2770
long need = (long)min(offset, LONG_MAX);
2771
if(fseeko(f, need, SEEK_CUR) < 0) {
2772
need = (long)min(offset, sizeof(dump));
2886
/* MS' stdio impl can't even seek forward on stdin, have to use pure non-fseek() version: */
2888
const long need = (long)min(offset, sizeof(dump));
2773
2889
if((long)fread(dump, 1, need, f) < need)
2778
#if 0 /* pure non-fseek() version */
2780
const long need = (long)min(offset, sizeof(dump));
2781
if(fread(dump, 1, need, f) < need)
2898
long need = (long)min(offset, LONG_MAX);
2899
if(fseeko(f, need, SEEK_CUR) < 0) {
2900
need = (long)min(offset, sizeof(dump));
2901
if((long)fread(dump, 1, need, f) < need)