1 /* flac - Command-line FLAC encoder/decoder
2 * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Josh Coalson
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <limits.h> /* for LONG_MAX */
25 #include <math.h> /* for floor() */
26 #include <stdio.h> /* for FILE etc. */
27 #include <stdlib.h> /* for malloc */
28 #include <string.h> /* for strcmp(), strerror() */
31 #include "share/alloc.h"
32 #include "share/grabbag.h"
33 #include "share/compat.h"
39 #define min(x,y) ((x)<(y)?(x):(y))
43 #define max(x,y) ((x)>(y)?(x):(y))
45 /* this MUST be >= 588 so that sector aligning can take place with one read */
46 /* this MUST be < 2^sizeof(size_t) / ( FLAC__MAX_CHANNELS * (FLAC__MAX_BITS_PER_SAMPLE/8) ) */
47 #define CHUNK_OF_SAMPLES 2048
52 unsigned bits_per_sample; /* width of sample point, including 'shift' bits, valid bps is bits_per_sample-shift */
53 unsigned shift; /* # of LSBs samples have been shifted left by */
54 unsigned bytes_per_wide_sample; /* for convenience, always == channels*((bps+7)/8), or 0 if N/A to input format (like FLAC) */
55 FLAC__bool is_unsigned_samples;
56 FLAC__bool is_big_endian;
57 FLAC__uint32 channel_mask;
60 /* this is the client_data attached to the FLAC decoder when encoding from a FLAC file */
63 const FLAC__byte *lookahead;
64 unsigned lookahead_length;
65 size_t num_metadata_blocks;
66 FLAC__StreamMetadata *metadata_blocks[1024]; /*@@@ BAD MAGIC number */
67 FLAC__uint64 samples_left_to_process;
68 FLAC__bool fatal_error;
77 FLAC__bool outputfile_opened; /* true if we successfully opened the output file and we want it to be deleted if there is an error */
78 const char *inbasefilename;
79 const char *infilename;
80 const char *outfilename;
82 FLAC__bool treat_warnings_as_errors;
83 FLAC__bool continue_through_decode_errors;
84 FLAC__bool replay_gain;
85 FLAC__uint64 total_samples_to_encode; /* (i.e. "wide samples" aka "sample frames") WATCHOUT: may be 0 to mean 'unknown' */
86 FLAC__uint64 unencoded_size; /* an estimate of the input size, only used in the progress indicator */
87 FLAC__uint64 bytes_written;
88 FLAC__uint64 samples_written;
96 FLAC__uint64 data_bytes;
99 FLAC__StreamDecoder *decoder;
100 FLACDecoderData client_data;
104 FLAC__StreamEncoder *encoder;
107 FLAC__StreamMetadata *seek_table_template;
110 const int FLAC_ENCODE__DEFAULT_PADDING = 8192;
112 static FLAC__bool is_big_endian_host_;
114 static unsigned char ucbuffer_[CHUNK_OF_SAMPLES*FLAC__MAX_CHANNELS*((FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE+7)/8)];
115 static signed char *scbuffer_ = (signed char *)ucbuffer_;
116 static FLAC__uint16 *usbuffer_ = (FLAC__uint16 *)ucbuffer_;
117 static FLAC__int16 *ssbuffer_ = (FLAC__int16 *)ucbuffer_;
119 static FLAC__int32 in_[FLAC__MAX_CHANNELS][CHUNK_OF_SAMPLES];
120 static FLAC__int32 *input_[FLAC__MAX_CHANNELS];
124 * unpublished debug routines from the FLAC libs
126 extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
127 extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
128 extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
129 extern FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value);
134 static FLAC__bool EncoderSession_construct(EncoderSession *e, encode_options_t options, off_t infilesize, FILE *infile, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length);
135 static void EncoderSession_destroy(EncoderSession *e);
136 static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero, foreign_metadata_t *foreign_metadata);
137 static int EncoderSession_finish_error(EncoderSession *e);
138 static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options);
139 static FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples);
140 static FLAC__bool EncoderSession_format_is_iff(const EncoderSession *e);
141 static FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e);
142 static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
143 static FLAC__bool verify_metadata(const EncoderSession *e, FLAC__StreamMetadata **metadata, unsigned num_metadata);
144 static FLAC__bool format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps, unsigned shift, size_t *channel_map);
145 static void encoder_progress_callback(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data);
146 static FLAC__StreamDecoderReadStatus flac_decoder_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
147 static FLAC__StreamDecoderSeekStatus flac_decoder_seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
148 static FLAC__StreamDecoderTellStatus flac_decoder_tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
149 static FLAC__StreamDecoderLengthStatus flac_decoder_length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
150 static FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder, void *client_data);
151 static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
152 static void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
153 static void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
154 static FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset, FLAC__bool treat_warnings_as_errors);
155 static void print_stats(const EncoderSession *encoder_session);
156 static void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status);
157 static void print_error_with_state(const EncoderSession *e, const char *message);
158 static void print_verify_error(EncoderSession *e);
159 static FLAC__bool read_bytes(FILE *f, FLAC__byte *buf, size_t n, FLAC__bool eof_ok, const char *fn);
160 static FLAC__bool read_uint16(FILE *f, FLAC__bool big_endian, FLAC__uint16 *val, const char *fn);
161 static FLAC__bool read_uint32(FILE *f, FLAC__bool big_endian, FLAC__uint32 *val, const char *fn);
162 static FLAC__bool read_uint64(FILE *f, FLAC__bool big_endian, FLAC__uint64 *val, const char *fn);
163 static FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, const char *fn);
164 static FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset);
165 static unsigned count_channel_mask_bits(FLAC__uint32 mask);
167 static FLAC__uint32 limit_channel_mask(FLAC__uint32 mask, unsigned channels);
170 static FLAC__bool get_sample_info_raw(EncoderSession *e, encode_options_t options)
172 e->info.sample_rate = options.format_options.raw.sample_rate;
173 e->info.channels = options.format_options.raw.channels;
174 e->info.bits_per_sample = options.format_options.raw.bps;
176 e->info.bytes_per_wide_sample = options.format_options.raw.channels * ((options.format_options.raw.bps+7)/8);
177 e->info.is_unsigned_samples = options.format_options.raw.is_unsigned_samples;
178 e->info.is_big_endian = options.format_options.raw.is_big_endian;
179 e->info.channel_mask = 0;
184 static FLAC__bool get_sample_info_wave(EncoderSession *e, encode_options_t options)
186 FLAC__bool got_fmt_chunk = false, got_data_chunk = false, got_ds64_chunk = false;
187 unsigned sample_rate = 0, channels = 0, bps = 0, shift = 0;
188 FLAC__uint32 channel_mask = 0;
189 FLAC__uint64 ds64_data_size = 0;
191 e->info.is_unsigned_samples = false;
192 e->info.is_big_endian = false;
194 if(e->format == FORMAT_WAVE64) {
196 * lookahead[] already has "riff\x2E\x91\xCF\x11\xD6\xA5\x28\xDB", skip over remaining header
198 if(!fskip_ahead(e->fin, 16+8+16-12)) { /* riff GUID + riff size + WAVE GUID - lookahead */
199 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over remaining \"riff\" header\n", e->inbasefilename);
203 /* else lookahead[] already has "RIFFxxxxWAVE" or "RF64xxxxWAVE" */
205 while(!feof(e->fin) && !got_data_chunk) {
206 /* chunk IDs are 4 bytes for WAVE/RF64, 16 for Wave64 */
207 /* for WAVE/RF64 we want the 5th char zeroed so we can treat it like a C string */
208 char chunk_id[16] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' };
210 if(!read_bytes(e->fin, (FLAC__byte*)chunk_id, e->format==FORMAT_WAVE64?16:4, /*eof_ok=*/true, e->inbasefilename)) {
211 flac__utils_printf(stderr, 1, "%s: ERROR: incomplete chunk identifier\n", e->inbasefilename);
217 if(e->format == FORMAT_RF64 && !memcmp(chunk_id, "ds64", 4)) { /* RF64 64-bit sizes chunk */
218 FLAC__uint32 xx, data_bytes;
221 flac__utils_printf(stderr, 1, "%s: ERROR: file has multiple 'ds64' chunks\n", e->inbasefilename);
224 if(got_fmt_chunk || got_data_chunk) {
225 flac__utils_printf(stderr, 1, "%s: ERROR: 'ds64' chunk appears after 'fmt ' or 'data' chunk\n", e->inbasefilename);
229 /* ds64 chunk size */
230 if(!read_uint32(e->fin, /*big_endian=*/false, &xx, e->inbasefilename))
233 if(data_bytes < 28) {
234 flac__utils_printf(stderr, 1, "%s: ERROR: non-standard 'ds64' chunk has length = %u\n", e->inbasefilename, (unsigned)data_bytes);
237 if(data_bytes & 1) /* should never happen, but enforce WAVE alignment rules */
240 /* RIFF 64-bit size, lo/hi */
241 if(!read_uint32(e->fin, /*big_endian=*/false, &xx, e->inbasefilename))
243 if(!read_uint32(e->fin, /*big_endian=*/false, &xx, e->inbasefilename))
246 /* 'data' 64-bit size */
247 if(!read_uint64(e->fin, /*big_endian=*/false, &ds64_data_size, e->inbasefilename))
252 /* skip any extra data in the ds64 chunk */
253 if(!fskip_ahead(e->fin, data_bytes)) {
254 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over extra 'ds64' data\n", e->inbasefilename);
258 got_ds64_chunk = true;
261 !memcmp(chunk_id, "fmt ", 4) &&
262 (e->format!=FORMAT_WAVE64 || !memcmp(chunk_id, "fmt \xF3\xAC\xD3\x11\xD1\x8C\x00\xC0\x4F\x8E\xDB\x8A", 16))
263 ) { /* format chunk */
265 FLAC__uint32 xx, data_bytes;
266 FLAC__uint16 wFormatTag; /* wFormatTag word from the 'fmt ' chunk */
269 flac__utils_printf(stderr, 1, "%s: ERROR: file has multiple 'fmt ' chunks\n", e->inbasefilename);
274 * http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
275 * http://windowssdk.msdn.microsoft.com/en-us/library/ms713497.aspx
276 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/audio_r/hh/Audio_r/aud-prop_d40f094e-44f9-4baa-8a15-03e4fb369501.xml.asp
280 * 2 byte: format type: 1 for WAVE_FORMAT_PCM, 65534 for WAVE_FORMAT_EXTENSIBLE
282 * 4 byte: sample rate (Hz)
283 * 4 byte: avg bytes per sec
284 * 2 byte: block align
285 * 2 byte: bits per sample (not necessarily all significant)
287 * 2 byte: extension size in bytes (usually 0 for WAVEFORMATEX and 22 for WAVEFORMATEXTENSIBLE with PCM)
288 * WAVEFORMATEXTENSIBLE adds
289 * 2 byte: valid bits per sample
290 * 4 byte: channel mask
291 * 16 byte: subformat GUID, first 2 bytes have format type, 1 being PCM
293 * Current spec says WAVEFORMATEX with PCM must have bps == 8 or 16, or any multiple of 8 for WAVEFORMATEXTENSIBLE.
294 * Lots of old broken WAVEs/apps have don't follow it, e.g. 20 bps but a block align of 3/6 for mono/stereo.
296 * Block align for WAVE_FORMAT_PCM or WAVE_FORMAT_EXTENSIBLE is also supposed to be channels*bps/8
298 * If the channel mask has more set bits than # of channels, the extra MSBs are ignored.
299 * If the channel mask has less set bits than # of channels, the extra channels are unassigned to any speaker.
301 * Data is supposed to be unsigned for bps <= 8 else signed.
305 if(!read_uint32(e->fin, /*big_endian=*/false, &xx, e->inbasefilename))
308 if(e->format == FORMAT_WAVE64) {
309 /* other half of the size field should be 0 */
310 if(!read_uint32(e->fin, /*big_endian=*/false, &xx, e->inbasefilename))
313 flac__utils_printf(stderr, 1, "%s: ERROR: freakishly large Wave64 'fmt ' chunk has length = 0x%08X%08X\n", e->inbasefilename, (unsigned)xx, (unsigned)data_bytes);
316 /* subtract size of header */
317 if (data_bytes < 16+8) {
318 flac__utils_printf(stderr, 1, "%s: ERROR: freakishly small Wave64 'fmt ' chunk has length = 0x%08X%08X\n", e->inbasefilename, (unsigned)xx, (unsigned)data_bytes);
321 data_bytes -= (16+8);
323 if(data_bytes < 16) {
324 flac__utils_printf(stderr, 1, "%s: ERROR: non-standard 'fmt ' chunk has length = %u\n", e->inbasefilename, (unsigned)data_bytes);
327 if(e->format != FORMAT_WAVE64) {
328 if(data_bytes & 1) /* should never happen, but enforce WAVE alignment rules */
332 data_bytes = (data_bytes+7) & (~7u); /* should never happen, but enforce Wave64 alignment rules */
336 if(!read_uint16(e->fin, /*big_endian=*/false, &wFormatTag, e->inbasefilename))
338 if(wFormatTag != 1 /*WAVE_FORMAT_PCM*/ && wFormatTag != 65534 /*WAVE_FORMAT_EXTENSIBLE*/) {
339 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported format type %u\n", e->inbasefilename, (unsigned)wFormatTag);
343 /* number of channels */
344 if(!read_uint16(e->fin, /*big_endian=*/false, &x, e->inbasefilename))
346 channels = (unsigned)x;
349 if(!read_uint32(e->fin, /*big_endian=*/false, &xx, e->inbasefilename))
353 /* avg bytes per second (ignored) */
354 if(!read_uint32(e->fin, /*big_endian=*/false, &xx, e->inbasefilename))
357 if(!read_uint16(e->fin, /*big_endian=*/false, &x, e->inbasefilename))
360 /* bits per sample */
361 if(!read_uint16(e->fin, /*big_endian=*/false, &x, e->inbasefilename))
365 e->info.is_unsigned_samples = (bps <= 8);
367 if(wFormatTag == 1) {
368 if(bps != 8 && bps != 16) {
369 if(bps == 24 || bps == 32) {
370 /* let these slide with a warning since they're unambiguous */
371 flac__utils_printf(stderr, 1, "%s: WARNING: legacy WAVE file has format type %u but bits-per-sample=%u\n", e->inbasefilename, (unsigned)wFormatTag, bps);
372 if(e->treat_warnings_as_errors)
376 /* @@@ we could add an option to specify left- or right-justified blocks so we knew how to set 'shift' */
377 flac__utils_printf(stderr, 1, "%s: ERROR: legacy WAVE file has format type %u but bits-per-sample=%u\n", e->inbasefilename, (unsigned)wFormatTag, bps);
381 #if 0 /* @@@ reinstate once we can get an answer about whether the samples are left- or right-justified */
382 if((bps+7)/8 * channels == block_align) {
384 /* assume legacy file is byte aligned with some LSBs zero; this is double-checked in format_input() */
385 flac__utils_printf(stderr, 1, "%s: WARNING: legacy WAVE file (format type %d) has block alignment=%u, bits-per-sample=%u, channels=%u\n", e->inbasefilename, (unsigned)wFormatTag, block_align, bps, channels);
386 if(e->treat_warnings_as_errors)
388 shift = 8 - (bps % 8);
395 flac__utils_printf(stderr, 1, "%s: ERROR: illegal WAVE file (format type %d) has block alignment=%u, bits-per-sample=%u, channels=%u\n", e->inbasefilename, (unsigned)wFormatTag, block_align, bps, channels);
401 if(channels > 2 && !options.channel_map_none) {
402 flac__utils_printf(stderr, 1, "%s: ERROR: WAVE has >2 channels but is not WAVE_FORMAT_EXTENSIBLE; cannot assign channels\n", e->inbasefilename);
405 FLAC__ASSERT(data_bytes >= 16);
409 if(data_bytes < 40) {
410 flac__utils_printf(stderr, 1, "%s: ERROR: invalid WAVEFORMATEXTENSIBLE chunk with size %u\n", e->inbasefilename, (unsigned)data_bytes);
414 if(!read_uint16(e->fin, /*big_endian=*/false, &x, e->inbasefilename))
417 flac__utils_printf(stderr, 1, "%s: ERROR: invalid WAVEFORMATEXTENSIBLE chunk with cbSize %u\n", e->inbasefilename, (unsigned)x);
421 if(!read_uint16(e->fin, /*big_endian=*/false, &x, e->inbasefilename))
423 if((unsigned)x > bps) {
424 flac__utils_printf(stderr, 1, "%s: ERROR: invalid WAVEFORMATEXTENSIBLE chunk with wValidBitsPerSample (%u) > wBitsPerSample (%u)\n", e->inbasefilename, (unsigned)x, bps);
427 shift = bps - (unsigned)x;
429 if(!read_uint32(e->fin, /*big_endian=*/false, &channel_mask, e->inbasefilename))
431 /* for mono/stereo and unassigned channels, we fake the mask */
432 if(channel_mask == 0) {
434 channel_mask = 0x0001;
435 else if(channels == 2)
436 channel_mask = 0x0003;
438 /* set channel mapping */
439 /* FLAC order follows SMPTE and WAVEFORMATEXTENSIBLE but with fewer channels, which are: */
440 /* front left, front right, center, LFE, back left, back right, surround left, surround right */
441 /* the default mapping is sufficient for 1-6 channels and 7-8 are currently unspecified anyway */
443 /* @@@ example for dolby/vorbis order, for reference later in case it becomes important */
445 options.channel_map_none ||
446 channel_mask == 0x0001 || /* 1 channel: (mono) */
447 channel_mask == 0x0003 || /* 2 channels: front left, front right */
448 channel_mask == 0x0033 || /* 4 channels: front left, front right, back left, back right */
449 channel_mask == 0x0603 /* 4 channels: front left, front right, side left, side right */
451 /* keep default channel order */
454 channel_mask == 0x0007 || /* 3 channels: front left, front right, front center */
455 channel_mask == 0x0037 || /* 5 channels: front left, front right, front center, back left, back right */
456 channel_mask == 0x0607 /* 5 channels: front left, front right, front center, side left, side right */
458 /* to dolby order: front left, center, front right [, surround left, surround right ] */
463 channel_mask == 0x003f || /* 6 channels: front left, front right, front center, LFE, back left, back right */
464 channel_mask == 0x060f || /* 6 channels: front left, front right, front center, LFE, side left, side right */
465 channel_mask == 0x070f || /* 7 channels: front left, front right, front center, LFE, back center, side left, side right */
466 channel_mask == 0x063f /* 8 channels: front left, front right, front center, LFE, back left, back right, side left, side right */
468 /* to dolby order: front left, center, front right, surround left, surround right, LFE */
477 options.channel_map_none ||
478 channel_mask == 0x0001 || /* 1 channel: (mono) */
479 channel_mask == 0x0003 || /* 2 channels: front left, front right */
480 channel_mask == 0x0007 || /* 3 channels: front left, front right, front center */
481 channel_mask == 0x0033 || /* 4 channels: front left, front right, back left, back right */
482 channel_mask == 0x0603 || /* 4 channels: front left, front right, side left, side right */
483 channel_mask == 0x0037 || /* 5 channels: front left, front right, front center, back left, back right */
484 channel_mask == 0x0607 || /* 5 channels: front left, front right, front center, side left, side right */
485 channel_mask == 0x003f || /* 6 channels: front left, front right, front center, LFE, back left, back right */
486 channel_mask == 0x060f || /* 6 channels: front left, front right, front center, LFE, side left, side right */
487 channel_mask == 0x070f || /* 7 channels: front left, front right, front center, LFE, back center, side left, side right */
488 channel_mask == 0x063f /* 8 channels: front left, front right, front center, LFE, back left, back right, side left, side right */
490 /* keep default channel order */
494 flac__utils_printf(stderr, 1, "%s: ERROR: WAVEFORMATEXTENSIBLE chunk with unsupported channel mask=0x%04X\n\nUse --channel-map=none option to store channels in current order; FLAC files\nmust also be decoded with --channel-map=none to restore correct order.\n", e->inbasefilename, (unsigned)channel_mask);
497 if(!options.channel_map_none) {
498 if(count_channel_mask_bits(channel_mask) < channels) {
499 flac__utils_printf(stderr, 1, "%s: ERROR: WAVEFORMATEXTENSIBLE chunk: channel mask 0x%04X has unassigned channels (#channels=%u)\n", e->inbasefilename, (unsigned)channel_mask, channels);
503 /* supporting this is too difficult with channel mapping; e.g. what if mask is 0x003f but #channels=4?
504 * there would be holes in the order that would have to be filled in, or the mask would have to be
505 * limited and the logic above rerun to see if it still fits into the FLAC mapping.
507 else if(count_channel_mask_bits(channel_mask) > channels)
508 channel_mask = limit_channel_mask(channel_mask, channels);
510 else if(count_channel_mask_bits(channel_mask) > channels) {
511 flac__utils_printf(stderr, 1, "%s: ERROR: WAVEFORMATEXTENSIBLE chunk: channel mask 0x%04X has extra bits for non-existant channels (#channels=%u)\n", e->inbasefilename, (unsigned)channel_mask, channels);
516 /* first part of GUID */
517 if(!read_uint16(e->fin, /*big_endian=*/false, &x, e->inbasefilename))
520 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported WAVEFORMATEXTENSIBLE chunk with non-PCM format %u\n", e->inbasefilename, (unsigned)x);
526 e->info.bytes_per_wide_sample = channels * (bps / 8);
528 /* skip any extra data in the fmt chunk */
529 if(!fskip_ahead(e->fin, data_bytes)) {
530 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over extra 'fmt' data\n", e->inbasefilename);
534 got_fmt_chunk = true;
537 !memcmp(chunk_id, "data", 4) &&
538 (e->format!=FORMAT_WAVE64 || !memcmp(chunk_id, "data\xF3\xAC\xD3\x11\xD1\x8C\x00\xC0\x4F\x8E\xDB\x8A", 16))
541 FLAC__uint64 data_bytes;
544 flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' chunk before 'fmt' chunk\n", e->inbasefilename);
549 if(e->format != FORMAT_WAVE64) {
550 if(!read_uint32(e->fin, /*big_endian=*/false, &xx, e->inbasefilename))
555 if(!read_uint64(e->fin, /*big_endian=*/false, &data_bytes, e->inbasefilename))
557 /* subtract size of header */
558 if (data_bytes < 16+8) {
559 flac__utils_printf(stderr, 1, "%s: ERROR: freakishly small Wave64 'data' chunk has length = 0x00000000%08X\n", e->inbasefilename, (unsigned)data_bytes);
562 data_bytes -= (16+8);
564 if(e->format == FORMAT_RF64) {
565 if(!got_ds64_chunk) {
566 flac__utils_printf(stderr, 1, "%s: ERROR: RF64 file has no 'ds64' chunk before 'data' chunk\n", e->inbasefilename);
569 if(data_bytes == 0xffffffff)
570 data_bytes = ds64_data_size;
572 if(options.ignore_chunk_sizes) {
573 FLAC__ASSERT(!options.sector_align);
575 flac__utils_printf(stderr, 1, "%s: WARNING: 'data' chunk has non-zero size, using --ignore-chunk-sizes is probably a bad idea\n", e->inbasefilename, chunk_id);
576 if(e->treat_warnings_as_errors)
579 data_bytes = (FLAC__uint64)0 - (FLAC__uint64)e->info.bytes_per_wide_sample; /* max out data_bytes; we'll use EOF as signal to stop reading */
581 else if(0 == data_bytes) {
582 flac__utils_printf(stderr, 1, "%s: ERROR: 'data' chunk has size of 0\n", e->inbasefilename);
586 e->fmt.iff.data_bytes = data_bytes;
588 got_data_chunk = true;
594 if(!options.format_options.iff.foreign_metadata) {
595 if(e->format != FORMAT_WAVE64)
596 flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s' (use --keep-foreign-metadata to keep)\n", e->inbasefilename, chunk_id);
598 flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X (use --keep-foreign-metadata to keep)\n",
600 (unsigned)((const unsigned char *)chunk_id)[3],
601 (unsigned)((const unsigned char *)chunk_id)[2],
602 (unsigned)((const unsigned char *)chunk_id)[1],
603 (unsigned)((const unsigned char *)chunk_id)[0],
604 (unsigned)((const unsigned char *)chunk_id)[5],
605 (unsigned)((const unsigned char *)chunk_id)[4],
606 (unsigned)((const unsigned char *)chunk_id)[7],
607 (unsigned)((const unsigned char *)chunk_id)[6],
608 (unsigned)((const unsigned char *)chunk_id)[9],
609 (unsigned)((const unsigned char *)chunk_id)[8],
610 (unsigned)((const unsigned char *)chunk_id)[10],
611 (unsigned)((const unsigned char *)chunk_id)[11],
612 (unsigned)((const unsigned char *)chunk_id)[12],
613 (unsigned)((const unsigned char *)chunk_id)[13],
614 (unsigned)((const unsigned char *)chunk_id)[14],
615 (unsigned)((const unsigned char *)chunk_id)[15]
617 if(e->treat_warnings_as_errors)
622 if(e->format != FORMAT_WAVE64) {
623 if(!read_uint32(e->fin, /*big_endian=*/false, &xx, e->inbasefilename))
629 if(!read_uint64(e->fin, /*big_endian=*/false, &skip, e->inbasefilename))
631 skip = (skip+7) & (~(FLAC__uint64)7);
632 /* subtract size of header */
634 flac__utils_printf(stderr, 1, "%s: ERROR: freakishly small Wave64 chunk has length = 0x00000000%08X\n", e->inbasefilename, (unsigned)skip);
640 if(!fskip_ahead(e->fin, skip)) {
641 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over chunk\n", e->inbasefilename);
649 flac__utils_printf(stderr, 1, "%s: ERROR: didn't find fmt chunk\n", e->inbasefilename);
652 if(!got_data_chunk) {
653 flac__utils_printf(stderr, 1, "%s: ERROR: didn't find data chunk\n", e->inbasefilename);
657 e->info.sample_rate = sample_rate;
658 e->info.channels = channels;
659 e->info.bits_per_sample = bps;
660 e->info.shift = shift;
661 e->info.channel_mask = channel_mask;
666 static FLAC__bool get_sample_info_aiff(EncoderSession *e, encode_options_t options)
668 FLAC__bool got_comm_chunk = false, got_ssnd_chunk = false;
669 unsigned sample_rate = 0, channels = 0, bps = 0, shift = 0;
670 FLAC__uint64 sample_frames = 0;
671 FLAC__uint32 channel_mask = 0;
673 e->info.is_unsigned_samples = false;
674 e->info.is_big_endian = true;
677 * lookahead[] already has "FORMxxxxAIFF", do chunks
679 while(!feof(e->fin) && !got_ssnd_chunk) {
680 char chunk_id[5] = { '\0', '\0', '\0', '\0', '\0' }; /* one extra byte for terminating NUL so we can also treat it like a C string */
681 if(!read_bytes(e->fin, (FLAC__byte*)chunk_id, 4, /*eof_ok=*/true, e->inbasefilename)) {
682 flac__utils_printf(stderr, 1, "%s: ERROR: incomplete chunk identifier\n", e->inbasefilename);
688 if(!memcmp(chunk_id, "COMM", 4)) { /* common chunk */
692 const FLAC__bool is_aifc = e->format == FORMAT_AIFF_C;
693 const FLAC__uint32 minimum_comm_size = (is_aifc? 22 : 18);
696 flac__utils_printf(stderr, 1, "%s: ERROR: file has multiple 'COMM' chunks\n", e->inbasefilename);
700 /* COMM chunk size */
701 if(!read_uint32(e->fin, /*big_endian=*/true, &xx, e->inbasefilename))
703 else if(xx < minimum_comm_size) {
704 flac__utils_printf(stderr, 1, "%s: ERROR: non-standard %s 'COMM' chunk has length = %u\n", e->inbasefilename, is_aifc? "AIFF-C" : "AIFF", (unsigned int)xx);
707 else if(!is_aifc && xx != minimum_comm_size) {
708 flac__utils_printf(stderr, 1, "%s: WARNING: non-standard %s 'COMM' chunk has length = %u, expected %u\n", e->inbasefilename, is_aifc? "AIFF-C" : "AIFF", (unsigned int)xx, minimum_comm_size);
709 if(e->treat_warnings_as_errors)
712 skip = (xx-minimum_comm_size)+(xx & 1);
714 /* number of channels */
715 if(!read_uint16(e->fin, /*big_endian=*/true, &x, e->inbasefilename))
717 channels = (unsigned)x;
718 if(channels > 2 && !options.channel_map_none) {
719 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number of channels %u for AIFF\n", e->inbasefilename, channels);
723 /* number of sample frames */
724 if(!read_uint32(e->fin, /*big_endian=*/true, &xx, e->inbasefilename))
728 /* bits per sample */
729 if(!read_uint16(e->fin, /*big_endian=*/true, &x, e->inbasefilename))
732 shift = (bps%8)? 8-(bps%8) : 0; /* SSND data is always byte-aligned, left-justified but format_input() will double-check */
736 if(!read_sane_extended(e->fin, &xx, e->inbasefilename))
740 /* check compression type for AIFF-C */
742 if(!read_uint32(e->fin, /*big_endian=*/true, &xx, e->inbasefilename))
744 if(xx == 0x736F7774) /* "sowt" */
745 e->info.is_big_endian = false;
746 else if(xx == 0x4E4F4E45) /* "NONE" */
747 ; /* nothing to do, we already default to big-endian */
749 flac__utils_printf(stderr, 1, "%s: ERROR: can't handle AIFF-C compression type \"%c%c%c%c\"\n", e->inbasefilename, (char)(xx>>24), (char)((xx>>16)&8), (char)((xx>>8)&8), (char)(xx&8));
754 /* set channel mapping */
755 /* FLAC order follows SMPTE and WAVEFORMATEXTENSIBLE but with fewer channels, which are: */
756 /* front left, front right, center, LFE, back left, back right, surround left, surround right */
757 /* specs say the channel ordering is:
759 * ___________________________________________________
763 * quad (ambiguous with 4ch) Fl Fr Bl Br
766 * l:left r:right c:center Fl:front-left Fr:front-right Bl:back-left Br:back-right Lc:left-center Rc:right-center S:surround
767 * so we only have unambiguous mappings for 2, 3, and 5 channels
770 options.channel_map_none ||
771 channels == 1 || /* 1 channel: (mono) */
772 channels == 2 || /* 2 channels: left, right */
773 channels == 3 || /* 3 channels: left, right, center */
774 channels == 5 /* 5 channels: front left, front right, center, surround left, surround right */
776 /* keep default channel order */
779 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number of channels %u for AIFF\n", e->inbasefilename, channels);
783 e->info.bytes_per_wide_sample = channels * (bps / 8);
785 /* skip any extra data in the COMM chunk */
786 if(!fskip_ahead(e->fin, skip)) {
787 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over extra COMM data\n", e->inbasefilename);
791 got_comm_chunk = true;
793 else if(!memcmp(chunk_id, "SSND", 4) && !got_ssnd_chunk) { /* sound data chunk */
795 FLAC__uint64 data_bytes;
798 if(!got_comm_chunk) {
799 flac__utils_printf(stderr, 1, "%s: ERROR: got 'SSND' chunk before 'COMM' chunk\n", e->inbasefilename);
803 /* SSND chunk size */
804 if(!read_uint32(e->fin, /*big_endian=*/true, &xx, e->inbasefilename))
807 if(options.ignore_chunk_sizes) {
808 FLAC__ASSERT(!options.sector_align);
810 flac__utils_printf(stderr, 1, "%s: WARNING: 'SSND' chunk has non-zero size, using --ignore-chunk-sizes is probably a bad idea\n", e->inbasefilename, chunk_id);
811 if(e->treat_warnings_as_errors)
814 data_bytes = (FLAC__uint64)0 - (FLAC__uint64)e->info.bytes_per_wide_sample; /* max out data_bytes; we'll use EOF as signal to stop reading */
816 else if(data_bytes <= 8) {
817 flac__utils_printf(stderr, 1, "%s: ERROR: 'SSND' chunk has size <= 8\n", e->inbasefilename);
821 data_bytes -= 8; /* discount the offset and block size fields */
825 if(!read_uint32(e->fin, /*big_endian=*/true, &xx, e->inbasefilename))
828 data_bytes -= offset;
831 if(!read_uint32(e->fin, /*big_endian=*/true, &xx, e->inbasefilename))
833 if(xx && !options.ignore_chunk_sizes)
834 data_bytes -= (xx - (data_bytes % xx));
835 if(options.ignore_chunk_sizes) {
837 flac__utils_printf(stderr, 1, "%s: WARNING: 'SSND' chunk has non-zero blocksize, using --ignore-chunk-sizes is probably a bad idea\n", e->inbasefilename, chunk_id);
838 if(e->treat_warnings_as_errors)
843 /* skip any SSND offset bytes */
844 if(!fskip_ahead(e->fin, offset)) {
845 flac__utils_printf(stderr, 1, "%s: ERROR: skipping offset in SSND chunk\n", e->inbasefilename);
849 e->fmt.iff.data_bytes = data_bytes;
851 got_ssnd_chunk = true;
855 if(!options.format_options.iff.foreign_metadata) {
856 flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s' (use --keep-foreign-metadata to keep)\n", e->inbasefilename, chunk_id);
857 if(e->treat_warnings_as_errors)
862 if(!read_uint32(e->fin, /*big_endian=*/true, &xx, e->inbasefilename))
865 unsigned long skip = xx + (xx & 1);
867 FLAC__ASSERT(skip <= LONG_MAX);
868 if(!fskip_ahead(e->fin, skip)) {
869 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over chunk\n", e->inbasefilename);
876 if(!got_comm_chunk) {
877 flac__utils_printf(stderr, 1, "%s: ERROR: didn't find COMM chunk\n", e->inbasefilename);
880 if(!got_ssnd_chunk && sample_frames) {
881 flac__utils_printf(stderr, 1, "%s: ERROR: didn't find SSND chunk\n", e->inbasefilename);
885 e->info.sample_rate = sample_rate;
886 e->info.channels = channels;
887 e->info.bits_per_sample = bps;
888 e->info.shift = shift;
889 e->info.channel_mask = channel_mask;
894 static FLAC__bool get_sample_info_flac(EncoderSession *e)
897 FLAC__stream_decoder_set_md5_checking(e->fmt.flac.decoder, false) &&
898 FLAC__stream_decoder_set_metadata_respond_all(e->fmt.flac.decoder)
900 flac__utils_printf(stderr, 1, "%s: ERROR: setting up decoder for FLAC input\n", e->inbasefilename);
904 if (e->format == FORMAT_OGGFLAC) {
905 if (FLAC__stream_decoder_init_ogg_stream(e->fmt.flac.decoder, flac_decoder_read_callback, flac_decoder_seek_callback, flac_decoder_tell_callback, flac_decoder_length_callback, flac_decoder_eof_callback, flac_decoder_write_callback, flac_decoder_metadata_callback, flac_decoder_error_callback, /*client_data=*/e) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
906 flac__utils_printf(stderr, 1, "%s: ERROR: initializing decoder for Ogg FLAC input, state = %s\n", e->inbasefilename, FLAC__stream_decoder_get_resolved_state_string(e->fmt.flac.decoder));
910 else if (FLAC__stream_decoder_init_stream(e->fmt.flac.decoder, flac_decoder_read_callback, flac_decoder_seek_callback, flac_decoder_tell_callback, flac_decoder_length_callback, flac_decoder_eof_callback, flac_decoder_write_callback, flac_decoder_metadata_callback, flac_decoder_error_callback, /*client_data=*/e) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
911 flac__utils_printf(stderr, 1, "%s: ERROR: initializing decoder for FLAC input, state = %s\n", e->inbasefilename, FLAC__stream_decoder_get_resolved_state_string(e->fmt.flac.decoder));
915 if (!FLAC__stream_decoder_process_until_end_of_metadata(e->fmt.flac.decoder) || e->fmt.flac.client_data.fatal_error) {
916 if (e->fmt.flac.client_data.fatal_error)
917 flac__utils_printf(stderr, 1, "%s: ERROR: out of memory or too many metadata blocks while reading metadata in FLAC input\n", e->inbasefilename);
919 flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, state = %s\n", e->inbasefilename, FLAC__stream_decoder_get_resolved_state_string(e->fmt.flac.decoder));
923 if (e->fmt.flac.client_data.num_metadata_blocks == 0) {
924 flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, got no metadata blocks\n", e->inbasefilename);
927 else if (e->fmt.flac.client_data.metadata_blocks[0]->type != FLAC__METADATA_TYPE_STREAMINFO) {
928 flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, first metadata block is not STREAMINFO\n", e->inbasefilename);
931 else if (e->fmt.flac.client_data.metadata_blocks[0]->data.stream_info.total_samples == 0) {
932 flac__utils_printf(stderr, 1, "%s: ERROR: FLAC input has STREAMINFO with unknown total samples which is not supported\n", e->inbasefilename);
936 e->info.sample_rate = e->fmt.flac.client_data.metadata_blocks[0]->data.stream_info.sample_rate;
937 e->info.channels = e->fmt.flac.client_data.metadata_blocks[0]->data.stream_info.channels;
938 e->info.bits_per_sample = e->fmt.flac.client_data.metadata_blocks[0]->data.stream_info.bits_per_sample;
940 e->info.bytes_per_wide_sample = 0;
941 e->info.is_unsigned_samples = false; /* not applicable for FLAC input */
942 e->info.is_big_endian = false; /* not applicable for FLAC input */
943 e->info.channel_mask = 0;
951 int flac__encode_file(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, encode_options_t options)
953 EncoderSession encoder_session;
954 size_t channel_map[FLAC__MAX_CHANNELS];
955 int info_align_carry = -1, info_align_zero = -1;
957 if(!EncoderSession_construct(&encoder_session, options, infilesize, infile, infilename, outfilename, lookahead, lookahead_length))
960 /* initialize default channel map that preserves channel order */
963 for(i = 0; i < sizeof(channel_map)/sizeof(channel_map[0]); i++)
967 /* read foreign metadata if requested */
968 if(EncoderSession_format_is_iff(&encoder_session) && options.format_options.iff.foreign_metadata) {
971 options.format == FORMAT_WAVE || options.format == FORMAT_RF64?
972 flac__foreign_metadata_read_from_wave(options.format_options.iff.foreign_metadata, infilename, &error) :
973 options.format == FORMAT_WAVE64?
974 flac__foreign_metadata_read_from_wave64(options.format_options.iff.foreign_metadata, infilename, &error) :
975 flac__foreign_metadata_read_from_aiff(options.format_options.iff.foreign_metadata, infilename, &error)
977 flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", encoder_session.inbasefilename, error);
978 return EncoderSession_finish_error(&encoder_session);
982 /* initialize encoder session with info about the audio (channels/bps/resolution/endianness/etc) */
983 switch(options.format) {
985 if(!get_sample_info_raw(&encoder_session, options))
986 return EncoderSession_finish_error(&encoder_session);
991 if(!get_sample_info_wave(&encoder_session, options))
992 return EncoderSession_finish_error(&encoder_session);
996 if(!get_sample_info_aiff(&encoder_session, options))
997 return EncoderSession_finish_error(&encoder_session);
1000 case FORMAT_OGGFLAC:
1002 * set up FLAC decoder for the input
1004 if (0 == (encoder_session.fmt.flac.decoder = FLAC__stream_decoder_new())) {
1005 flac__utils_printf(stderr, 1, "%s: ERROR: creating decoder for FLAC input\n", encoder_session.inbasefilename);
1006 return EncoderSession_finish_error(&encoder_session);
1008 if(!get_sample_info_flac(&encoder_session))
1009 return EncoderSession_finish_error(&encoder_session);
1013 /* double protection */
1014 return EncoderSession_finish_error(&encoder_session);
1017 /* some more checks */
1018 if(encoder_session.info.channels == 0 || encoder_session.info.channels > FLAC__MAX_CHANNELS) {
1019 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number of channels %u\n", encoder_session.inbasefilename, encoder_session.info.channels);
1020 return EncoderSession_finish_error(&encoder_session);
1022 if(!FLAC__format_sample_rate_is_valid(encoder_session.info.sample_rate)) {
1023 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, encoder_session.info.sample_rate);
1024 return EncoderSession_finish_error(&encoder_session);
1026 if(encoder_session.info.bits_per_sample-encoder_session.info.shift < 4 || encoder_session.info.bits_per_sample-encoder_session.info.shift > 24) {
1027 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, encoder_session.info.bits_per_sample-encoder_session.info.shift);
1028 return EncoderSession_finish_error(&encoder_session);
1030 if(options.sector_align) {
1031 if(encoder_session.info.channels != 2) {
1032 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, encoder_session.info.channels);
1033 return EncoderSession_finish_error(&encoder_session);
1035 if(encoder_session.info.sample_rate != 44100) {
1036 flac__utils_printf(stderr, 1, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_session.inbasefilename, encoder_session.info.sample_rate);
1037 return EncoderSession_finish_error(&encoder_session);
1039 if(encoder_session.info.bits_per_sample-encoder_session.info.shift != 16) {
1040 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u bits-per-sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, encoder_session.info.bits_per_sample-encoder_session.info.shift);
1041 return EncoderSession_finish_error(&encoder_session);
1046 FLAC__uint64 total_samples_in_input; /* WATCHOUT: may be 0 to mean "unknown" */
1048 FLAC__uint64 until; /* a value of 0 mean end-of-stream (i.e. --until=-0) */
1049 unsigned align_remainder = 0;
1051 switch(options.format) {
1054 total_samples_in_input = 0;
1056 total_samples_in_input = (FLAC__uint64)infilesize / encoder_session.info.bytes_per_wide_sample + *options.align_reservoir_samples;
1063 /* truncation in the division removes any padding byte that was counted in encoder_session.fmt.iff.data_bytes */
1064 total_samples_in_input = encoder_session.fmt.iff.data_bytes / encoder_session.info.bytes_per_wide_sample + *options.align_reservoir_samples;
1067 case FORMAT_OGGFLAC:
1068 total_samples_in_input = encoder_session.fmt.flac.client_data.metadata_blocks[0]->data.stream_info.total_samples + *options.align_reservoir_samples;
1072 /* double protection */
1073 return EncoderSession_finish_error(&encoder_session);
1077 * now that we know the sample rate, canonicalize the
1078 * --skip string to an absolute sample number:
1080 flac__utils_canonicalize_skip_until_specification(&options.skip_specification, encoder_session.info.sample_rate);
1081 FLAC__ASSERT(options.skip_specification.value.samples >= 0);
1082 skip = (FLAC__uint64)options.skip_specification.value.samples;
1083 FLAC__ASSERT(!options.sector_align || (options.format != FORMAT_FLAC && options.format != FORMAT_OGGFLAC && skip == 0));
1084 /* *options.align_reservoir_samples will be 0 unless --sector-align is used */
1085 FLAC__ASSERT(options.sector_align || *options.align_reservoir_samples == 0);
1088 * now that we possibly know the input size, canonicalize the
1089 * --until string to an absolute sample number:
1091 if(!canonicalize_until_specification(&options.until_specification, encoder_session.inbasefilename, encoder_session.info.sample_rate, skip, total_samples_in_input))
1092 return EncoderSession_finish_error(&encoder_session);
1093 until = (FLAC__uint64)options.until_specification.value.samples;
1094 FLAC__ASSERT(!options.sector_align || until == 0);
1096 /* adjust encoding parameters based on skip and until values */
1097 switch(options.format) {
1099 infilesize -= (off_t)skip * encoder_session.info.bytes_per_wide_sample;
1100 encoder_session.total_samples_to_encode = total_samples_in_input - skip;
1107 encoder_session.fmt.iff.data_bytes -= skip * encoder_session.info.bytes_per_wide_sample;
1108 if(options.ignore_chunk_sizes) {
1109 encoder_session.total_samples_to_encode = 0;
1110 flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
1111 FLAC__ASSERT(0 == until);
1114 encoder_session.total_samples_to_encode = total_samples_in_input - skip;
1118 case FORMAT_OGGFLAC:
1119 encoder_session.total_samples_to_encode = total_samples_in_input - skip;
1123 /* double protection */
1124 return EncoderSession_finish_error(&encoder_session);
1127 const FLAC__uint64 trim = total_samples_in_input - until;
1128 FLAC__ASSERT(total_samples_in_input > 0);
1129 FLAC__ASSERT(!options.sector_align);
1130 if(options.format == FORMAT_RAW)
1131 infilesize -= (off_t)trim * encoder_session.info.bytes_per_wide_sample;
1132 else if(EncoderSession_format_is_iff(&encoder_session))
1133 encoder_session.fmt.iff.data_bytes -= trim * encoder_session.info.bytes_per_wide_sample;
1134 encoder_session.total_samples_to_encode -= trim;
1136 if(options.sector_align && (options.format != FORMAT_RAW || infilesize >=0)) { /* for RAW, need to know the filesize */
1137 FLAC__ASSERT(skip == 0); /* asserted above too, but lest we forget */
1138 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
1139 if(options.is_last_file)
1140 encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
1142 encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
1144 switch(options.format) {
1146 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * encoder_session.info.bytes_per_wide_sample;
1149 /* +44 for the size of the WAVE headers; this is just an estimate for the progress indicator and doesn't need to be exact */
1150 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * encoder_session.info.bytes_per_wide_sample + 44;
1153 /* +44 for the size of the WAVE headers; this is just an estimate for the progress indicator and doesn't need to be exact */
1154 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * encoder_session.info.bytes_per_wide_sample + 104;
1157 /* +72 for the size of the RF64 headers; this is just an estimate for the progress indicator and doesn't need to be exact */
1158 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * encoder_session.info.bytes_per_wide_sample + 80;
1162 /* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */
1163 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * encoder_session.info.bytes_per_wide_sample + 54;
1166 case FORMAT_OGGFLAC:
1168 /* if we don't know, use 0 as hint to progress indicator (which is the only place this is used): */
1169 encoder_session.unencoded_size = 0;
1170 else if(skip == 0 && until == 0)
1171 encoder_session.unencoded_size = (FLAC__uint64)infilesize;
1172 else if(total_samples_in_input)
1173 encoder_session.unencoded_size = (FLAC__uint64)infilesize * encoder_session.total_samples_to_encode / total_samples_in_input;
1175 encoder_session.unencoded_size = (FLAC__uint64)infilesize;
1179 /* double protection */
1180 return EncoderSession_finish_error(&encoder_session);
1183 if(encoder_session.total_samples_to_encode == 0)
1184 flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
1186 if(options.format == FORMAT_FLAC || options.format == FORMAT_OGGFLAC)
1187 encoder_session.fmt.flac.client_data.samples_left_to_process = encoder_session.total_samples_to_encode;
1189 /* init the encoder */
1190 if(!EncoderSession_init_encoder(&encoder_session, options))
1191 return EncoderSession_finish_error(&encoder_session);
1193 /* skip over any samples as requested */
1195 switch(options.format) {
1198 unsigned skip_bytes = encoder_session.info.bytes_per_wide_sample * (unsigned)skip;
1199 if(skip_bytes > lookahead_length) {
1200 skip_bytes -= lookahead_length;
1201 lookahead_length = 0;
1202 if(!fskip_ahead(encoder_session.fin, skip_bytes)) {
1203 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
1204 return EncoderSession_finish_error(&encoder_session);
1208 lookahead += skip_bytes;
1209 lookahead_length -= skip_bytes;
1218 if(!fskip_ahead(encoder_session.fin, skip * encoder_session.info.bytes_per_wide_sample)) {
1219 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
1220 return EncoderSession_finish_error(&encoder_session);
1224 case FORMAT_OGGFLAC:
1226 * have to wait until the FLAC encoder is set up for writing
1227 * before any seeking in the input FLAC file, because the seek
1228 * itself will usually call the decoder's write callback, and
1229 * our decoder's write callback passes samples to our FLAC
1232 if(!FLAC__stream_decoder_seek_absolute(encoder_session.fmt.flac.decoder, skip)) {
1233 flac__utils_printf(stderr, 1, "%s: ERROR while skipping samples, FLAC decoder state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(encoder_session.fmt.flac.decoder));
1234 return EncoderSession_finish_error(&encoder_session);
1239 /* double protection */
1240 return EncoderSession_finish_error(&encoder_session);
1245 * first do any samples in the reservoir
1247 if(options.sector_align && *options.align_reservoir_samples > 0) {
1248 FLAC__ASSERT(options.format != FORMAT_FLAC && options.format != FORMAT_OGGFLAC); /* check again */
1249 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.align_reservoir, *options.align_reservoir_samples)) {
1250 print_error_with_state(&encoder_session, "ERROR during encoding");
1251 return EncoderSession_finish_error(&encoder_session);
1256 * decrement infilesize or the data_bytes counter if we need to align the file
1258 if(options.sector_align) {
1259 if(options.is_last_file) {
1260 *options.align_reservoir_samples = 0;
1263 *options.align_reservoir_samples = align_remainder;
1264 if(options.format == FORMAT_RAW) {
1265 FLAC__ASSERT(infilesize >= 0);
1266 infilesize -= (off_t)((*options.align_reservoir_samples) * encoder_session.info.bytes_per_wide_sample);
1267 FLAC__ASSERT(infilesize >= 0);
1269 else if(EncoderSession_format_is_iff(&encoder_session))
1270 encoder_session.fmt.iff.data_bytes -= (*options.align_reservoir_samples) * encoder_session.info.bytes_per_wide_sample;
1275 * now do samples from the file
1277 switch(options.format) {
1279 if(infilesize < 0) {
1281 while(!feof(infile)) {
1282 if(lookahead_length > 0) {
1283 FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * encoder_session.info.bytes_per_wide_sample);
1284 memcpy(ucbuffer_, lookahead, lookahead_length);
1285 bytes_read = fread(ucbuffer_+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * encoder_session.info.bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
1286 if(ferror(infile)) {
1287 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1288 return EncoderSession_finish_error(&encoder_session);
1290 lookahead_length = 0;
1293 bytes_read = fread(ucbuffer_, sizeof(unsigned char), CHUNK_OF_SAMPLES * encoder_session.info.bytes_per_wide_sample, infile);
1295 if(bytes_read == 0) {
1296 if(ferror(infile)) {
1297 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1298 return EncoderSession_finish_error(&encoder_session);
1301 else if(bytes_read % encoder_session.info.bytes_per_wide_sample != 0) {
1302 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1303 return EncoderSession_finish_error(&encoder_session);
1306 unsigned wide_samples = bytes_read / encoder_session.info.bytes_per_wide_sample;
1307 if(!format_input(input_, wide_samples, encoder_session.info.is_big_endian, encoder_session.info.is_unsigned_samples, encoder_session.info.channels, encoder_session.info.bits_per_sample, encoder_session.info.shift, channel_map))
1308 return EncoderSession_finish_error(&encoder_session);
1310 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1311 print_error_with_state(&encoder_session, "ERROR during encoding");
1312 return EncoderSession_finish_error(&encoder_session);
1319 const FLAC__uint64 max_input_bytes = infilesize;
1320 FLAC__uint64 total_input_bytes_read = 0;
1321 while(total_input_bytes_read < max_input_bytes) {
1323 size_t wanted = (CHUNK_OF_SAMPLES * encoder_session.info.bytes_per_wide_sample);
1324 wanted = (size_t) min((FLAC__uint64)wanted, max_input_bytes - total_input_bytes_read);
1326 if(lookahead_length > 0) {
1327 FLAC__ASSERT(lookahead_length <= wanted);
1328 memcpy(ucbuffer_, lookahead, lookahead_length);
1329 wanted -= lookahead_length;
1330 bytes_read = lookahead_length;
1332 bytes_read += fread(ucbuffer_+lookahead_length, sizeof(unsigned char), wanted, infile);
1333 if(ferror(infile)) {
1334 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1335 return EncoderSession_finish_error(&encoder_session);
1338 lookahead_length = 0;
1341 bytes_read = fread(ucbuffer_, sizeof(unsigned char), wanted, infile);
1344 if(bytes_read == 0) {
1345 if(ferror(infile)) {
1346 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1347 return EncoderSession_finish_error(&encoder_session);
1349 else if(feof(infile)) {
1350 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);
1351 if(encoder_session.treat_warnings_as_errors)
1352 return EncoderSession_finish_error(&encoder_session);
1353 total_input_bytes_read = max_input_bytes;
1357 if(bytes_read % encoder_session.info.bytes_per_wide_sample != 0) {
1358 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1359 return EncoderSession_finish_error(&encoder_session);
1362 unsigned wide_samples = bytes_read / encoder_session.info.bytes_per_wide_sample;
1363 if(!format_input(input_, wide_samples, encoder_session.info.is_big_endian, encoder_session.info.is_unsigned_samples, encoder_session.info.channels, encoder_session.info.bits_per_sample, encoder_session.info.shift, channel_map))
1364 return EncoderSession_finish_error(&encoder_session);
1366 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1367 print_error_with_state(&encoder_session, "ERROR during encoding");
1368 return EncoderSession_finish_error(&encoder_session);
1370 total_input_bytes_read += bytes_read;
1381 while(encoder_session.fmt.iff.data_bytes > 0) {
1382 const size_t bytes_to_read = (size_t)min(
1383 encoder_session.fmt.iff.data_bytes,
1384 (FLAC__uint64)CHUNK_OF_SAMPLES * (FLAC__uint64)encoder_session.info.bytes_per_wide_sample
1386 size_t bytes_read = fread(ucbuffer_, sizeof(unsigned char), bytes_to_read, infile);
1387 if(bytes_read == 0) {
1388 if(ferror(infile)) {
1389 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1390 return EncoderSession_finish_error(&encoder_session);
1392 else if(feof(infile)) {
1393 if(options.ignore_chunk_sizes) {
1394 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);
1397 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);
1398 if(encoder_session.treat_warnings_as_errors)
1399 return EncoderSession_finish_error(&encoder_session);
1401 encoder_session.fmt.iff.data_bytes = 0;
1405 if(bytes_read % encoder_session.info.bytes_per_wide_sample != 0) {
1406 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1407 return EncoderSession_finish_error(&encoder_session);
1410 unsigned wide_samples = bytes_read / encoder_session.info.bytes_per_wide_sample;
1411 if(!format_input(input_, wide_samples, encoder_session.info.is_big_endian, encoder_session.info.is_unsigned_samples, encoder_session.info.channels, encoder_session.info.bits_per_sample, encoder_session.info.shift, channel_map))
1412 return EncoderSession_finish_error(&encoder_session);
1414 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1415 print_error_with_state(&encoder_session, "ERROR during encoding");
1416 return EncoderSession_finish_error(&encoder_session);
1418 encoder_session.fmt.iff.data_bytes -= bytes_read;
1424 case FORMAT_OGGFLAC:
1425 while(!encoder_session.fmt.flac.client_data.fatal_error && encoder_session.fmt.flac.client_data.samples_left_to_process > 0) {
1426 /* We can also hit the end of stream without samples_left_to_process
1427 * going to 0 if there are errors and continue_through_decode_errors
1428 * is on, so we want to break in that case too:
1430 if(encoder_session.continue_through_decode_errors && FLAC__stream_decoder_get_state(encoder_session.fmt.flac.decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
1432 if(!FLAC__stream_decoder_process_single(encoder_session.fmt.flac.decoder)) {
1433 flac__utils_printf(stderr, 1, "%s: ERROR: while decoding FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(encoder_session.fmt.flac.decoder));
1434 return EncoderSession_finish_error(&encoder_session);
1437 if(encoder_session.fmt.flac.client_data.fatal_error) {
1438 flac__utils_printf(stderr, 1, "%s: ERROR: while decoding FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(encoder_session.fmt.flac.decoder));
1439 return EncoderSession_finish_error(&encoder_session);
1444 /* double protection */
1445 return EncoderSession_finish_error(&encoder_session);
1449 * now read unaligned samples into reservoir or pad with zeroes if necessary
1451 if(options.sector_align) {
1452 if(options.is_last_file) {
1453 unsigned wide_samples = 588 - align_remainder;
1454 if(wide_samples < 588) {
1457 info_align_zero = wide_samples;
1458 for(channel = 0; channel < encoder_session.info.channels; channel++)
1459 memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
1461 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1462 print_error_with_state(&encoder_session, "ERROR during encoding");
1463 return EncoderSession_finish_error(&encoder_session);
1468 if(*options.align_reservoir_samples > 0) {
1470 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
1471 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.align_reservoir_samples) * encoder_session.info.bytes_per_wide_sample, infile);
1472 if(bytes_read == 0 && ferror(infile)) {
1473 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1474 return EncoderSession_finish_error(&encoder_session);
1476 else if(bytes_read != (*options.align_reservoir_samples) * encoder_session.info.bytes_per_wide_sample) {
1477 flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
1478 if(encoder_session.treat_warnings_as_errors)
1479 return EncoderSession_finish_error(&encoder_session);
1482 info_align_carry = *options.align_reservoir_samples;
1483 if(!format_input(options.align_reservoir, *options.align_reservoir_samples, encoder_session.info.is_big_endian, encoder_session.info.is_unsigned_samples, encoder_session.info.channels, encoder_session.info.bits_per_sample, encoder_session.info.shift, channel_map))
1484 return EncoderSession_finish_error(&encoder_session);
1491 return EncoderSession_finish_ok(
1495 EncoderSession_format_is_iff(&encoder_session)? options.format_options.iff.foreign_metadata : 0
1499 FLAC__bool EncoderSession_construct(EncoderSession *e, encode_options_t options, off_t infilesize, FILE *infile, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length)
1502 FLAC__uint32 test = 1;
1505 * initialize globals
1508 is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
1510 for(i = 0; i < FLAC__MAX_CHANNELS; i++)
1511 input_[i] = &(in_[i][0]);
1515 * initialize instance
1519 e->use_ogg = options.use_ogg;
1521 e->verify = options.verify;
1522 e->treat_warnings_as_errors = options.treat_warnings_as_errors;
1523 e->continue_through_decode_errors = options.continue_through_decode_errors;
1525 e->is_stdout = (0 == strcmp(outfilename, "-"));
1526 e->outputfile_opened = false;
1528 e->inbasefilename = grabbag__file_get_basename(infilename);
1529 e->infilename = infilename;
1530 e->outfilename = outfilename;
1532 e->total_samples_to_encode = 0;
1533 e->unencoded_size = 0;
1534 e->bytes_written = 0;
1535 e->samples_written = 0;
1538 memset(&e->info, 0, sizeof(e->info));
1540 e->format = options.format;
1542 switch(options.format) {
1550 e->fmt.iff.data_bytes = 0;
1553 case FORMAT_OGGFLAC:
1554 e->fmt.flac.decoder = 0;
1555 e->fmt.flac.client_data.filesize = infilesize;
1556 e->fmt.flac.client_data.lookahead = lookahead;
1557 e->fmt.flac.client_data.lookahead_length = lookahead_length;
1558 e->fmt.flac.client_data.num_metadata_blocks = 0;
1559 e->fmt.flac.client_data.samples_left_to_process = 0;
1560 e->fmt.flac.client_data.fatal_error = false;
1564 /* double protection */
1571 e->seek_table_template = 0;
1573 if(0 == (e->seek_table_template = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE))) {
1574 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1578 e->encoder = FLAC__stream_encoder_new();
1579 if(0 == e->encoder) {
1580 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1581 EncoderSession_destroy(e);
1588 void EncoderSession_destroy(EncoderSession *e)
1590 if(e->format == FORMAT_FLAC || e->format == FORMAT_OGGFLAC) {
1592 if(e->fmt.flac.decoder)
1593 FLAC__stream_decoder_delete(e->fmt.flac.decoder);
1594 e->fmt.flac.decoder = 0;
1595 for(i = 0; i < e->fmt.flac.client_data.num_metadata_blocks; i++)
1596 FLAC__metadata_object_delete(e->fmt.flac.client_data.metadata_blocks[i]);
1597 e->fmt.flac.client_data.num_metadata_blocks = 0;
1603 if(0 != e->encoder) {
1604 FLAC__stream_encoder_delete(e->encoder);
1608 if(0 != e->seek_table_template) {
1609 FLAC__metadata_object_delete(e->seek_table_template);
1610 e->seek_table_template = 0;
1614 int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero, foreign_metadata_t *foreign_metadata)
1616 FLAC__StreamEncoderState fse_state = FLAC__STREAM_ENCODER_OK;
1618 FLAC__bool verify_error = false;
1621 fse_state = FLAC__stream_encoder_get_state(e->encoder);
1622 ret = FLAC__stream_encoder_finish(e->encoder)? 0 : 1;
1624 fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA ||
1625 FLAC__stream_encoder_get_state(e->encoder) == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA
1628 /* all errors except verify errors should interrupt the stats */
1629 if(ret && !verify_error)
1630 print_error_with_state(e, "ERROR during encoding");
1631 else if(e->total_samples_to_encode > 0) {
1633 flac__utils_printf(stderr, 2, "\n");
1637 print_verify_error(e);
1641 if(info_align_carry >= 0) {
1642 flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d samples to be carried over\n", e->inbasefilename, info_align_carry);
1644 if(info_align_zero >= 0) {
1645 flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d zero samples to be appended\n", e->inbasefilename, info_align_zero);
1649 /*@@@@@@ should this go here or somewhere else? */
1650 if(ret == 0 && foreign_metadata) {
1652 if(!flac__foreign_metadata_write_to_flac(foreign_metadata, e->infilename, e->outfilename, &error)) {
1653 flac__utils_printf(stderr, 1, "%s: ERROR: updating foreign metadata in FLAC file: %s\n", e->inbasefilename, error);
1658 EncoderSession_destroy(e);
1663 int EncoderSession_finish_error(EncoderSession *e)
1665 FLAC__ASSERT(e->encoder);
1667 if(e->total_samples_to_encode > 0)
1668 flac__utils_printf(stderr, 2, "\n");
1670 if(FLAC__stream_encoder_get_state(e->encoder) == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
1671 print_verify_error(e);
1672 else if(e->outputfile_opened)
1673 /* only want to delete the file if we opened it; otherwise it could be an existing file and our overwrite failed */
1674 unlink(e->outfilename);
1676 EncoderSession_destroy(e);
1682 unsigned num_metadata;
1683 FLAC__bool *needs_delete;
1684 FLAC__StreamMetadata **metadata;
1685 FLAC__StreamMetadata *cuesheet; /* always needs to be deleted */
1686 } static_metadata_t;
1688 static void static_metadata_init(static_metadata_t *m)
1690 m->num_metadata = 0;
1691 m->needs_delete = 0;
1696 static void static_metadata_clear(static_metadata_t *m)
1699 for(i = 0; i < m->num_metadata; i++)
1700 if(m->needs_delete[i])
1701 FLAC__metadata_object_delete(m->metadata[i]);
1705 free(m->needs_delete);
1707 FLAC__metadata_object_delete(m->cuesheet);
1708 static_metadata_init(m);
1711 static FLAC__bool static_metadata_append(static_metadata_t *m, FLAC__StreamMetadata *d, FLAC__bool needs_delete)
1714 if(0 == (x = safe_realloc_muladd2_(m->metadata, sizeof(*m->metadata), /*times (*/m->num_metadata, /*+*/1/*)*/)))
1716 m->metadata = (FLAC__StreamMetadata**)x;
1717 if(0 == (x = safe_realloc_muladd2_(m->needs_delete, sizeof(*m->needs_delete), /*times (*/m->num_metadata, /*+*/1/*)*/)))
1719 m->needs_delete = (FLAC__bool*)x;
1720 m->metadata[m->num_metadata] = d;
1721 m->needs_delete[m->num_metadata] = needs_delete;
1726 FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options)
1728 const unsigned channels = e->info.channels;
1729 const unsigned bps = e->info.bits_per_sample - e->info.shift;
1730 const unsigned sample_rate = e->info.sample_rate;
1731 FLACDecoderData *flac_decoder_data = (e->format == FORMAT_FLAC || e->format == FORMAT_OGGFLAC)? &e->fmt.flac.client_data : 0;
1732 FLAC__StreamMetadata padding;
1733 FLAC__StreamMetadata **metadata = 0;
1734 static_metadata_t static_metadata;
1735 unsigned num_metadata = 0, i;
1736 FLAC__StreamEncoderInitStatus init_status;
1737 const FLAC__bool is_cdda = (channels == 1 || channels == 2) && (bps == 16) && (sample_rate == 44100);
1738 char apodizations[2000];
1740 FLAC__ASSERT(sizeof(options.pictures)/sizeof(options.pictures[0]) <= 64);
1742 static_metadata_init(&static_metadata);
1744 e->replay_gain = options.replay_gain;
1746 apodizations[0] = '\0';
1748 if(e->replay_gain) {
1749 if(channels != 1 && channels != 2) {
1750 flac__utils_printf(stderr, 1, "%s: ERROR, number of channels (%u) must be 1 or 2 for --replay-gain\n", e->inbasefilename, channels);
1753 if(!grabbag__replaygain_is_valid_sample_frequency(sample_rate)) {
1754 flac__utils_printf(stderr, 1, "%s: ERROR, invalid sample rate (%u) for --replay-gain\n", e->inbasefilename, sample_rate);
1757 if(options.is_first_file) {
1758 if(!grabbag__replaygain_init(sample_rate)) {
1759 flac__utils_printf(stderr, 1, "%s: ERROR initializing ReplayGain stage\n", e->inbasefilename);
1765 if(!parse_cuesheet(&static_metadata.cuesheet, options.cuesheet_filename, e->inbasefilename, sample_rate, is_cdda, e->total_samples_to_encode, e->treat_warnings_as_errors))
1768 if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? static_metadata.cuesheet : 0, e)) {
1769 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1770 static_metadata_clear(&static_metadata);
1774 /* build metadata */
1775 if(flac_decoder_data) {
1777 * we're encoding from FLAC so we will use the FLAC file's
1778 * metadata as the basis for the encoded file
1782 * first handle pictures: simple append any --pictures
1785 for(i = 0; i < options.num_pictures; i++) {
1786 FLAC__StreamMetadata *pic = FLAC__metadata_object_clone(options.pictures[i]);
1788 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PICTURE block\n", e->inbasefilename);
1789 static_metadata_clear(&static_metadata);
1792 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks++] = pic;
1797 * next handle vorbis comment: if any tags were specified
1798 * or there is no existing vorbis comment, we create a
1799 * new vorbis comment (discarding any existing one); else
1800 * we keep the existing one. also need to make sure to
1801 * propagate any channel mask tag.
1803 /* @@@ change to append -T values from options.vorbis_comment if input has VC already? */
1805 FLAC__bool vc_found = false;
1806 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1807 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
1809 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT && options.vorbis_comment->data.vorbis_comment.num_comments > 0) {
1810 (void) flac__utils_get_channel_mask_tag(flac_decoder_data->metadata_blocks[i], &e->info.channel_mask);
1811 flac__utils_printf(stderr, 1, "%s: WARNING, replacing tags from input FLAC file with those given on the command-line\n", e->inbasefilename);
1812 if(e->treat_warnings_as_errors) {
1813 static_metadata_clear(&static_metadata);
1816 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1817 flac_decoder_data->metadata_blocks[i] = 0;
1820 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1822 flac_decoder_data->num_metadata_blocks = j;
1823 if((!vc_found || options.vorbis_comment->data.vorbis_comment.num_comments > 0) && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1825 FLAC__StreamMetadata *vc = FLAC__metadata_object_clone(options.vorbis_comment);
1826 if(0 == vc || (e->info.channel_mask && !flac__utils_set_channel_mask_tag(vc, e->info.channel_mask))) {
1827 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for VORBIS_COMMENT block\n", e->inbasefilename);
1828 static_metadata_clear(&static_metadata);
1831 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1832 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1833 flac_decoder_data->metadata_blocks[1] = vc;
1834 flac_decoder_data->num_metadata_blocks++;
1839 * next handle cuesheet: if --cuesheet was specified, use
1840 * it; else if file has existing CUESHEET and cuesheet's
1841 * lead-out offset is correct, keep it; else no CUESHEET
1844 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1845 FLAC__bool existing_cuesheet_is_bad = false;
1846 /* check if existing cuesheet matches the input audio */
1847 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && 0 == static_metadata.cuesheet) {
1848 const FLAC__StreamMetadata_CueSheet *cs = &flac_decoder_data->metadata_blocks[i]->data.cue_sheet;
1849 if(e->total_samples_to_encode == 0) {
1850 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);
1851 if(e->treat_warnings_as_errors) {
1852 static_metadata_clear(&static_metadata);
1855 existing_cuesheet_is_bad = true;
1857 else if(e->total_samples_to_encode != cs->tracks[cs->num_tracks-1].offset) {
1858 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);
1859 if(e->treat_warnings_as_errors) {
1860 static_metadata_clear(&static_metadata);
1863 existing_cuesheet_is_bad = true;
1866 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != static_metadata.cuesheet)) {
1867 if(0 != static_metadata.cuesheet) {
1868 flac__utils_printf(stderr, 1, "%s: WARNING, replacing cuesheet in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1869 if(e->treat_warnings_as_errors) {
1870 static_metadata_clear(&static_metadata);
1874 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1875 flac_decoder_data->metadata_blocks[i] = 0;
1878 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1880 flac_decoder_data->num_metadata_blocks = j;
1881 if(0 != static_metadata.cuesheet && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1883 FLAC__StreamMetadata *cs = FLAC__metadata_object_clone(static_metadata.cuesheet);
1885 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for CUESHEET block\n", e->inbasefilename);
1886 static_metadata_clear(&static_metadata);
1889 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1890 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1891 flac_decoder_data->metadata_blocks[1] = cs;
1892 flac_decoder_data->num_metadata_blocks++;
1897 * next handle seektable: if -S- was specified, no
1898 * SEEKTABLE; else if -S was specified, use it/them;
1899 * else if file has existing SEEKTABLE and input size is
1900 * preserved (no --skip/--until/etc specified), keep it;
1901 * else use default seektable options
1903 * note: meanings of num_requested_seek_points:
1904 * -1 : no -S option given, default to some value
1905 * 0 : -S- given (no seektable)
1906 * >0 : one or more -S options given
1909 FLAC__bool existing_seektable = false;
1910 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1911 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE)
1912 existing_seektable = true;
1913 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE && (e->total_samples_to_encode != flac_decoder_data->metadata_blocks[0]->data.stream_info.total_samples || options.num_requested_seek_points >= 0)) {
1914 if(options.num_requested_seek_points > 0) {
1915 flac__utils_printf(stderr, 1, "%s: WARNING, replacing seektable in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1916 if(e->treat_warnings_as_errors) {
1917 static_metadata_clear(&static_metadata);
1921 else if(options.num_requested_seek_points == 0)
1922 ; /* no warning, silently delete existing SEEKTABLE since user specified --no-seektable (-S-) */
1924 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);
1925 if(e->treat_warnings_as_errors) {
1926 static_metadata_clear(&static_metadata);
1930 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1931 flac_decoder_data->metadata_blocks[i] = 0;
1932 existing_seektable = false;
1935 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1937 flac_decoder_data->num_metadata_blocks = j;
1938 if((options.num_requested_seek_points > 0 || (options.num_requested_seek_points < 0 && !existing_seektable)) && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1940 FLAC__StreamMetadata *st = FLAC__metadata_object_clone(e->seek_table_template);
1942 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for SEEKTABLE block\n", e->inbasefilename);
1943 static_metadata_clear(&static_metadata);
1946 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1947 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1948 flac_decoder_data->metadata_blocks[1] = st;
1949 flac_decoder_data->num_metadata_blocks++;
1954 * finally handle padding: if --no-padding was specified,
1955 * then delete all padding; else if -P was specified,
1956 * use that instead of existing padding (if any); else
1957 * if existing file has padding, move all existing
1958 * padding blocks to one padding block at the end; else
1959 * use default padding.
1963 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1964 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_PADDING) {
1967 p += flac_decoder_data->metadata_blocks[i]->length;
1968 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1969 flac_decoder_data->metadata_blocks[i] = 0;
1972 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1974 flac_decoder_data->num_metadata_blocks = j;
1975 if(options.padding > 0)
1976 p = options.padding;
1978 p = e->total_samples_to_encode / sample_rate < 20*60? FLAC_ENCODE__DEFAULT_PADDING : FLAC_ENCODE__DEFAULT_PADDING*8;
1979 if(options.padding != 0) {
1980 if(p > 0 && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1981 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
1982 if(0 == flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]) {
1983 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PADDING block\n", e->inbasefilename);
1984 static_metadata_clear(&static_metadata);
1987 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->is_last = false; /* the encoder will set this for us */
1988 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->length = p;
1989 flac_decoder_data->num_metadata_blocks++;
1993 metadata = &flac_decoder_data->metadata_blocks[1]; /* don't include STREAMINFO */
1994 num_metadata = flac_decoder_data->num_metadata_blocks - 1;
1998 * we're not encoding from FLAC so we will build the metadata
2001 const foreign_metadata_t *foreign_metadata = EncoderSession_format_is_iff(e)? options.format_options.iff.foreign_metadata : 0;
2003 if(e->seek_table_template->data.seek_table.num_points > 0) {
2004 e->seek_table_template->is_last = false; /* the encoder will set this for us */
2005 static_metadata_append(&static_metadata, e->seek_table_template, /*needs_delete=*/false);
2007 if(0 != static_metadata.cuesheet)
2008 static_metadata_append(&static_metadata, static_metadata.cuesheet, /*needs_delete=*/false);
2009 if(e->info.channel_mask) {
2010 if(!flac__utils_set_channel_mask_tag(options.vorbis_comment, e->info.channel_mask)) {
2011 flac__utils_printf(stderr, 1, "%s: ERROR adding channel mask tag\n", e->inbasefilename);
2012 static_metadata_clear(&static_metadata);
2016 static_metadata_append(&static_metadata, options.vorbis_comment, /*needs_delete=*/false);
2017 for(i = 0; i < options.num_pictures; i++)
2018 static_metadata_append(&static_metadata, options.pictures[i], /*needs_delete=*/false);
2019 if(foreign_metadata) {
2020 for(i = 0; i < foreign_metadata->num_blocks; i++) {
2021 FLAC__StreamMetadata *p = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
2023 flac__utils_printf(stderr, 1, "%s: ERROR: out of memory\n", e->inbasefilename);
2024 static_metadata_clear(&static_metadata);
2027 static_metadata_append(&static_metadata, p, /*needs_delete=*/true);
2028 static_metadata.metadata[static_metadata.num_metadata-1]->length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8 + foreign_metadata->blocks[i].size;
2031 if(options.padding != 0) {
2032 padding.is_last = false; /* the encoder will set this for us */
2033 padding.type = FLAC__METADATA_TYPE_PADDING;
2034 padding.length = (unsigned)(options.padding>0? options.padding : (e->total_samples_to_encode / sample_rate < 20*60? FLAC_ENCODE__DEFAULT_PADDING : FLAC_ENCODE__DEFAULT_PADDING*8));
2035 static_metadata_append(&static_metadata, &padding, /*needs_delete=*/false);
2037 metadata = static_metadata.metadata;
2038 num_metadata = static_metadata.num_metadata;
2041 /* check for a few things that have not already been checked. the
2042 * FLAC__stream_encoder_init*() will check it but only return
2043 * FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA so we check some
2044 * up front to give a better error message.
2046 if(!verify_metadata(e, metadata, num_metadata)) {
2047 static_metadata_clear(&static_metadata);
2051 FLAC__stream_encoder_set_verify(e->encoder, options.verify);
2052 FLAC__stream_encoder_set_streamable_subset(e->encoder, !options.lax);
2053 FLAC__stream_encoder_set_channels(e->encoder, channels);
2054 FLAC__stream_encoder_set_bits_per_sample(e->encoder, bps);
2055 FLAC__stream_encoder_set_sample_rate(e->encoder, sample_rate);
2056 for(i = 0; i < options.num_compression_settings; i++) {
2057 switch(options.compression_settings[i].type) {
2059 FLAC__stream_encoder_set_blocksize(e->encoder, options.compression_settings[i].value.t_unsigned);
2061 case CST_COMPRESSION_LEVEL:
2062 FLAC__stream_encoder_set_compression_level(e->encoder, options.compression_settings[i].value.t_unsigned);
2063 apodizations[0] = '\0';
2065 case CST_DO_MID_SIDE:
2066 FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder, options.compression_settings[i].value.t_bool);
2068 case CST_LOOSE_MID_SIDE:
2069 FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder, options.compression_settings[i].value.t_bool);
2071 case CST_APODIZATION:
2072 if(strlen(apodizations)+strlen(options.compression_settings[i].value.t_string)+2 >= sizeof(apodizations)) {
2073 flac__utils_printf(stderr, 1, "%s: ERROR: too many apodization functions requested\n", e->inbasefilename);
2074 static_metadata_clear(&static_metadata);
2078 strcat(apodizations, options.compression_settings[i].value.t_string);
2079 strcat(apodizations, ";");
2082 case CST_MAX_LPC_ORDER:
2083 FLAC__stream_encoder_set_max_lpc_order(e->encoder, options.compression_settings[i].value.t_unsigned);
2085 case CST_QLP_COEFF_PRECISION:
2086 FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder, options.compression_settings[i].value.t_unsigned);
2088 case CST_DO_QLP_COEFF_PREC_SEARCH:
2089 FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder, options.compression_settings[i].value.t_bool);
2091 case CST_DO_ESCAPE_CODING:
2092 FLAC__stream_encoder_set_do_escape_coding(e->encoder, options.compression_settings[i].value.t_bool);
2094 case CST_DO_EXHAUSTIVE_MODEL_SEARCH:
2095 FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder, options.compression_settings[i].value.t_bool);
2097 case CST_MIN_RESIDUAL_PARTITION_ORDER:
2098 FLAC__stream_encoder_set_min_residual_partition_order(e->encoder, options.compression_settings[i].value.t_unsigned);
2100 case CST_MAX_RESIDUAL_PARTITION_ORDER:
2101 FLAC__stream_encoder_set_max_residual_partition_order(e->encoder, options.compression_settings[i].value.t_unsigned);
2103 case CST_RICE_PARAMETER_SEARCH_DIST:
2104 FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder, options.compression_settings[i].value.t_unsigned);
2109 FLAC__stream_encoder_set_apodization(e->encoder, apodizations);
2110 FLAC__stream_encoder_set_total_samples_estimate(e->encoder, e->total_samples_to_encode);
2111 FLAC__stream_encoder_set_metadata(e->encoder, (num_metadata > 0)? metadata : 0, num_metadata);
2113 FLAC__stream_encoder_disable_constant_subframes(e->encoder, options.debug.disable_constant_subframes);
2114 FLAC__stream_encoder_disable_fixed_subframes(e->encoder, options.debug.disable_fixed_subframes);
2115 FLAC__stream_encoder_disable_verbatim_subframes(e->encoder, options.debug.disable_verbatim_subframes);
2116 if(!options.debug.do_md5) {
2117 flac__utils_printf(stderr, 1, "%s: WARNING, MD5 computation disabled, resulting file will not have MD5 sum\n", e->inbasefilename);
2118 if(e->treat_warnings_as_errors) {
2119 static_metadata_clear(&static_metadata);
2122 FLAC__stream_encoder_set_do_md5(e->encoder, false);
2127 FLAC__stream_encoder_set_ogg_serial_number(e->encoder, options.serial_number);
2129 init_status = FLAC__stream_encoder_init_ogg_file(e->encoder, e->is_stdout? 0 : e->outfilename, encoder_progress_callback, /*client_data=*/e);
2134 init_status = FLAC__stream_encoder_init_file(e->encoder, e->is_stdout? 0 : e->outfilename, encoder_progress_callback, /*client_data=*/e);
2137 if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
2138 print_error_with_init_status(e, "ERROR initializing encoder", init_status);
2139 if(FLAC__stream_encoder_get_state(e->encoder) != FLAC__STREAM_ENCODER_IO_ERROR)
2140 e->outputfile_opened = true;
2141 static_metadata_clear(&static_metadata);
2145 e->outputfile_opened = true;
2148 (FLAC__stream_encoder_get_do_exhaustive_model_search(e->encoder) && FLAC__stream_encoder_get_do_qlp_coeff_prec_search(e->encoder))? 0x07 :
2149 (FLAC__stream_encoder_get_do_exhaustive_model_search(e->encoder) || FLAC__stream_encoder_get_do_qlp_coeff_prec_search(e->encoder))? 0x0f :
2152 static_metadata_clear(&static_metadata);
2157 FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples)
2159 if(e->replay_gain) {
2160 if(!grabbag__replaygain_analyze(buffer, e->info.channels==2, e->info.bits_per_sample, samples)) {
2161 flac__utils_printf(stderr, 1, "%s: WARNING, error while calculating ReplayGain\n", e->inbasefilename);
2162 if(e->treat_warnings_as_errors)
2167 return FLAC__stream_encoder_process(e->encoder, buffer, samples);
2170 FLAC__bool EncoderSession_format_is_iff(const EncoderSession *e)
2173 e->format == FORMAT_WAVE ||
2174 e->format == FORMAT_WAVE64 ||
2175 e->format == FORMAT_RF64 ||
2176 e->format == FORMAT_AIFF ||
2177 e->format == FORMAT_AIFF_C;
2180 FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e)
2182 const FLAC__bool only_placeholders = e->is_stdout;
2183 FLAC__bool has_real_points;
2185 if(num_requested_seek_points == 0 && 0 == cuesheet)
2188 if(num_requested_seek_points < 0) {
2190 /*@@@@@@ workaround ogg bug: too many seekpoints makes table not fit in one page */
2191 if(e->use_ogg && e->total_samples_to_encode > 0 && e->total_samples_to_encode / e->info.sample_rate / 10 > 230)
2192 requested_seek_points = "230x;";
2195 requested_seek_points = "10s;";
2196 num_requested_seek_points = 1;
2199 if(num_requested_seek_points > 0) {
2200 if(!grabbag__seektable_convert_specification_to_template(requested_seek_points, only_placeholders, e->total_samples_to_encode, e->info.sample_rate, e->seek_table_template, &has_real_points))
2206 const FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
2207 for(i = 0; i < cs->num_tracks; i++) {
2208 const FLAC__StreamMetadata_CueSheet_Track *tr = cs->tracks+i;
2209 for(j = 0; j < tr->num_indices; j++) {
2210 if(!FLAC__metadata_object_seektable_template_append_point(e->seek_table_template, tr->offset + tr->indices[j].offset))
2212 has_real_points = true;
2216 if(!FLAC__metadata_object_seektable_template_sort(e->seek_table_template, /*compact=*/true))
2220 if(has_real_points) {
2222 flac__utils_printf(stderr, 1, "%s: WARNING, cannot write back seekpoints when encoding to stdout\n", e->inbasefilename);
2223 if(e->treat_warnings_as_errors)
2231 FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
2233 /* convert from mm:ss.sss to sample number if necessary */
2234 flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
2236 /* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
2237 if(spec->is_relative && spec->value.samples == 0) {
2238 spec->is_relative = false;
2242 /* in any other case the total samples in the input must be known */
2243 if(total_samples_in_input == 0) {
2244 flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when input length is unknown\n", inbasefilename);
2248 FLAC__ASSERT(spec->value_is_samples);
2250 /* convert relative specifications to absolute */
2251 if(spec->is_relative) {
2252 if(spec->value.samples <= 0)
2253 spec->value.samples += (FLAC__int64)total_samples_in_input;
2255 spec->value.samples += skip;
2256 spec->is_relative = false;
2260 if(spec->value.samples < 0) {
2261 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
2264 if((FLAC__uint64)spec->value.samples <= skip) {
2265 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
2268 if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
2269 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is after end of input\n", inbasefilename);
2276 FLAC__bool verify_metadata(const EncoderSession *e, FLAC__StreamMetadata **metadata, unsigned num_metadata)
2278 FLAC__bool metadata_picture_has_type1 = false;
2279 FLAC__bool metadata_picture_has_type2 = false;
2282 FLAC__ASSERT(0 != metadata);
2283 for(i = 0; i < num_metadata; i++) {
2284 const FLAC__StreamMetadata *m = metadata[i];
2285 if(m->type == FLAC__METADATA_TYPE_SEEKTABLE) {
2286 if(!FLAC__format_seektable_is_legal(&m->data.seek_table)) {
2287 flac__utils_printf(stderr, 1, "%s: ERROR: SEEKTABLE metadata block is invalid\n", e->inbasefilename);
2291 else if(m->type == FLAC__METADATA_TYPE_CUESHEET) {
2292 if(!FLAC__format_cuesheet_is_legal(&m->data.cue_sheet, m->data.cue_sheet.is_cd, /*violation=*/0)) {
2293 flac__utils_printf(stderr, 1, "%s: ERROR: CUESHEET metadata block is invalid\n", e->inbasefilename);
2297 else if(m->type == FLAC__METADATA_TYPE_PICTURE) {
2298 const char *error = 0;
2299 if(!FLAC__format_picture_is_legal(&m->data.picture, &error)) {
2300 flac__utils_printf(stderr, 1, "%s: ERROR: PICTURE metadata block is invalid: %s\n", e->inbasefilename, error);
2303 if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD) {
2304 if(metadata_picture_has_type1) {
2305 flac__utils_printf(stderr, 1, "%s: ERROR: there may only be one picture of type 1 (32x32 icon) in the file\n", e->inbasefilename);
2308 metadata_picture_has_type1 = true;
2310 else if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON) {
2311 if(metadata_picture_has_type2) {
2312 flac__utils_printf(stderr, 1, "%s: ERROR: there may only be one picture of type 2 (icon) in the file\n", e->inbasefilename);
2315 metadata_picture_has_type2 = true;
2323 FLAC__bool format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps, unsigned shift, size_t *channel_map)
2325 unsigned wide_sample, sample, channel, byte;
2326 FLAC__int32 *out[FLAC__MAX_CHANNELS];
2328 if(0 == channel_map) {
2329 for(channel = 0; channel < channels; channel++)
2330 out[channel] = dest[channel];
2333 for(channel = 0; channel < channels; channel++)
2334 out[channel] = dest[channel_map[channel]];
2338 if(is_unsigned_samples) {
2339 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2340 for(channel = 0; channel < channels; channel++, sample++)
2341 out[channel][wide_sample] = (FLAC__int32)ucbuffer_[sample] - 0x80;
2344 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2345 for(channel = 0; channel < channels; channel++, sample++)
2346 out[channel][wide_sample] = (FLAC__int32)scbuffer_[sample];
2349 else if(bps == 16) {
2350 if(is_big_endian != is_big_endian_host_) {
2352 const unsigned bytes = wide_samples * channels * (bps >> 3);
2353 for(byte = 0; byte < bytes; byte += 2) {
2354 tmp = ucbuffer_[byte];
2355 ucbuffer_[byte] = ucbuffer_[byte+1];
2356 ucbuffer_[byte+1] = tmp;
2359 if(is_unsigned_samples) {
2360 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2361 for(channel = 0; channel < channels; channel++, sample++)
2362 out[channel][wide_sample] = (FLAC__int32)usbuffer_[sample] - 0x8000;
2365 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2366 for(channel = 0; channel < channels; channel++, sample++)
2367 out[channel][wide_sample] = (FLAC__int32)ssbuffer_[sample];
2370 else if(bps == 24) {
2371 if(!is_big_endian) {
2373 const unsigned bytes = wide_samples * channels * (bps >> 3);
2374 for(byte = 0; byte < bytes; byte += 3) {
2375 tmp = ucbuffer_[byte];
2376 ucbuffer_[byte] = ucbuffer_[byte+2];
2377 ucbuffer_[byte+2] = tmp;
2380 if(is_unsigned_samples) {
2381 for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2382 for(channel = 0; channel < channels; channel++, sample++) {
2383 out[channel][wide_sample] = ucbuffer_[byte++]; out[channel][wide_sample] <<= 8;
2384 out[channel][wide_sample] |= ucbuffer_[byte++]; out[channel][wide_sample] <<= 8;
2385 out[channel][wide_sample] |= ucbuffer_[byte++];
2386 out[channel][wide_sample] -= 0x800000;
2390 for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2391 for(channel = 0; channel < channels; channel++, sample++) {
2392 out[channel][wide_sample] = scbuffer_[byte++]; out[channel][wide_sample] <<= 8;
2393 out[channel][wide_sample] |= ucbuffer_[byte++]; out[channel][wide_sample] <<= 8;
2394 out[channel][wide_sample] |= ucbuffer_[byte++];
2402 FLAC__int32 mask = (1<<shift)-1;
2403 for(wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2404 for(channel = 0; channel < channels; channel++) {
2405 if(out[channel][wide_sample] & mask) {
2406 flac__utils_printf(stderr, 1, "ERROR during read, sample data (channel#%u sample#%u = %d) has non-zero least-significant bits\n WAVE/AIFF header said the last %u bits are not significant and should be zero.\n", channel, wide_sample, out[channel][wide_sample], shift);
2409 out[channel][wide_sample] >>= shift;
2415 void encoder_progress_callback(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
2417 EncoderSession *e = (EncoderSession*)client_data;
2419 (void)encoder, (void)total_frames_estimate;
2421 e->bytes_written = bytes_written;
2422 e->samples_written = samples_written;
2424 if(e->total_samples_to_encode > 0 && !((frames_written-1) & e->stats_mask))
2428 FLAC__StreamDecoderReadStatus flac_decoder_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
2431 EncoderSession *e = (EncoderSession*)client_data;
2432 FLACDecoderData *data = &e->fmt.flac.client_data;
2436 if (data->fatal_error)
2437 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
2439 /* use up lookahead first */
2440 if (data->lookahead_length) {
2441 n = min(data->lookahead_length, *bytes);
2442 memcpy(buffer, data->lookahead, n);
2444 data->lookahead += n;
2445 data->lookahead_length -= n;
2448 /* get the rest from file */
2450 *bytes = n + fread(buffer, 1, *bytes-n, e->fin);
2452 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
2453 else if(0 == *bytes)
2454 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
2456 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
2459 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
2462 FLAC__StreamDecoderSeekStatus flac_decoder_seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
2464 EncoderSession *e = (EncoderSession*)client_data;
2467 if(fseeko(e->fin, (off_t)absolute_byte_offset, SEEK_SET) < 0)
2468 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
2470 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
2473 FLAC__StreamDecoderTellStatus flac_decoder_tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
2475 EncoderSession *e = (EncoderSession*)client_data;
2479 if((pos = ftello(e->fin)) < 0)
2480 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
2482 *absolute_byte_offset = (FLAC__uint64)pos;
2483 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
2487 FLAC__StreamDecoderLengthStatus flac_decoder_length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
2489 const EncoderSession *e = (EncoderSession*)client_data;
2490 const FLACDecoderData *data = &e->fmt.flac.client_data;
2493 if(data->filesize < 0)
2494 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
2496 *stream_length = (FLAC__uint64)data->filesize;
2497 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
2501 FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
2503 EncoderSession *e = (EncoderSession*)client_data;
2506 return feof(e->fin)? true : false;
2509 FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
2511 EncoderSession *e = (EncoderSession*)client_data;
2512 FLACDecoderData *data = &e->fmt.flac.client_data;
2513 FLAC__uint64 n = min(data->samples_left_to_process, frame->header.blocksize);
2516 if(!EncoderSession_process(e, buffer, (unsigned)n)) {
2517 print_error_with_state(e, "ERROR during encoding");
2518 data->fatal_error = true;
2519 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
2522 data->samples_left_to_process -= n;
2523 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
2526 void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
2528 EncoderSession *e = (EncoderSession*)client_data;
2529 FLACDecoderData *data = &e->fmt.flac.client_data;
2532 if (data->fatal_error)
2536 data->num_metadata_blocks == sizeof(data->metadata_blocks)/sizeof(data->metadata_blocks[0]) ||
2537 0 == (data->metadata_blocks[data->num_metadata_blocks] = FLAC__metadata_object_clone(metadata))
2539 data->fatal_error = true;
2541 data->num_metadata_blocks++;
2544 void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
2546 EncoderSession *e = (EncoderSession*)client_data;
2547 FLACDecoderData *data = &e->fmt.flac.client_data;
2550 flac__utils_printf(stderr, 1, "%s: ERROR got %s while decoding FLAC input\n", e->inbasefilename, FLAC__StreamDecoderErrorStatusString[status]);
2551 if(!e->continue_through_decode_errors)
2552 data->fatal_error = true;
2555 FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, unsigned sample_rate, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset, FLAC__bool treat_warnings_as_errors)
2558 unsigned last_line_read;
2559 const char *error_message;
2561 if(0 == cuesheet_filename)
2564 if(lead_out_offset == 0) {
2565 flac__utils_printf(stderr, 1, "%s: ERROR cannot import cuesheet when the number of input samples to encode is unknown\n", inbasefilename);
2569 if(0 == (f = fopen(cuesheet_filename, "r"))) {
2570 flac__utils_printf(stderr, 1, "%s: ERROR opening cuesheet \"%s\" for reading: %s\n", inbasefilename, cuesheet_filename, strerror(errno));
2574 *cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, sample_rate, is_cdda, lead_out_offset);
2578 if(0 == *cuesheet) {
2579 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\" on line %u: %s\n", inbasefilename, cuesheet_filename, last_line_read, error_message);
2583 if(!FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/false, &error_message)) {
2584 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\": %s\n", inbasefilename, cuesheet_filename, error_message);
2588 /* if we're expecting CDDA, warn about non-compliance */
2589 if(is_cdda && !FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/true, &error_message)) {
2590 flac__utils_printf(stderr, 1, "%s: WARNING cuesheet \"%s\" is not audio CD compliant: %s\n", inbasefilename, cuesheet_filename, error_message);
2591 if(treat_warnings_as_errors)
2593 (*cuesheet)->data.cue_sheet.is_cd = false;
2599 void print_stats(const EncoderSession *encoder_session)
2601 const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written);
2602 const FLAC__uint64 uesize = encoder_session->unencoded_size;
2603 #if defined _MSC_VER || defined __MINGW32__
2604 /* with MSVC you have to spoon feed it the casting */
2605 const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode;
2606 const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)(uesize? uesize:1) * min(1.0, progress));
2608 const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode;
2609 const double ratio = (double)encoder_session->bytes_written / ((double)(uesize? uesize:1) * min(1.0, progress));
2612 FLAC__ASSERT(encoder_session->total_samples_to_encode > 0);
2614 if(samples_written == encoder_session->total_samples_to_encode) {
2615 flac__utils_printf(stderr, 2, "\r%s:%s wrote %u bytes, ratio=",
2616 encoder_session->inbasefilename,
2617 encoder_session->verify? " Verify OK," : "",
2618 (unsigned)encoder_session->bytes_written
2622 flac__utils_printf(stderr, 2, "\r%s: %u%% complete, ratio=", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5));
2625 flac__utils_printf(stderr, 2, "%0.3f", ratio);
2627 flac__utils_printf(stderr, 2, "N/A");
2630 void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status)
2632 const int ilen = strlen(e->inbasefilename) + 1;
2633 const char *state_string = "";
2635 flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
2637 flac__utils_printf(stderr, 1, "%*s init_status = %s\n", ilen, "", FLAC__StreamEncoderInitStatusString[init_status]);
2639 if(init_status == FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR) {
2640 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder);
2642 flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
2644 /* print out some more info for some errors: */
2645 if(0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_CLIENT_ERROR])) {
2646 flac__utils_printf(stderr, 1,
2648 "An error occurred while writing; the most common cause is that the disk is full.\n"
2651 else if(0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_IO_ERROR])) {
2652 flac__utils_printf(stderr, 1,
2654 "An error occurred opening the output file; it is likely that the output\n"
2655 "directory does not exist or is not writable, the output file already exists and\n"
2656 "is not writable, or the disk is full.\n"
2660 else if(init_status == FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE) {
2661 flac__utils_printf(stderr, 1,
2663 "The encoding parameters specified do not conform to the FLAC Subset and may not\n"
2664 "be streamable or playable in hardware devices. If you really understand the\n"
2665 "consequences, you can add --lax to the command-line options to encode with\n"
2666 "these parameters anyway. See http://flac.sourceforge.net/format.html#subset\n"
2671 void print_error_with_state(const EncoderSession *e, const char *message)
2673 const int ilen = strlen(e->inbasefilename) + 1;
2674 const char *state_string;
2676 flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
2678 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder);
2680 flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
2682 /* print out some more info for some errors: */
2683 if(0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_CLIENT_ERROR])) {
2684 flac__utils_printf(stderr, 1,
2686 "An error occurred while writing; the most common cause is that the disk is full.\n"
2691 void print_verify_error(EncoderSession *e)
2693 FLAC__uint64 absolute_sample;
2694 unsigned frame_number;
2697 FLAC__int32 expected;
2700 FLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2702 flac__utils_printf(stderr, 1, "%s: ERROR: mismatch in decoded data, verify FAILED!\n", e->inbasefilename);
2703 flac__utils_printf(stderr, 1, " Absolute sample=%u, frame=%u, channel=%u, sample=%u, expected %d, got %d\n", (unsigned)absolute_sample, frame_number, channel, sample, expected, got);
2704 flac__utils_printf(stderr, 1, " In all known cases, verify errors are caused by hardware problems,\n");
2705 flac__utils_printf(stderr, 1, " usually overclocking or bad RAM. Delete %s\n", e->outfilename);
2706 flac__utils_printf(stderr, 1, " and repeat the flac command exactly as before. If it does not give a\n");
2707 flac__utils_printf(stderr, 1, " verify error in the exact same place each time you try it, then there is\n");
2708 flac__utils_printf(stderr, 1, " a problem with your hardware; please see the FAQ:\n");
2709 flac__utils_printf(stderr, 1, " http://flac.sourceforge.net/faq.html#tools__hardware_prob\n");
2710 flac__utils_printf(stderr, 1, " If it does fail in the exact same place every time, keep\n");
2711 flac__utils_printf(stderr, 1, " %s and submit a bug report to:\n", e->outfilename);
2712 flac__utils_printf(stderr, 1, " https://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
2713 flac__utils_printf(stderr, 1, " Make sure to upload the FLAC file and use the \"Monitor\" feature to\n");
2714 flac__utils_printf(stderr, 1, " monitor the bug status.\n");
2715 flac__utils_printf(stderr, 1, "Verify FAILED! Do not trust %s\n", e->outfilename);
2718 FLAC__bool read_bytes(FILE *f, FLAC__byte *buf, size_t n, FLAC__bool eof_ok, const char *fn)
2720 size_t bytes_read = fread(buf, 1, n, f);
2722 if(bytes_read == 0) {
2724 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2730 if(bytes_read < n) {
2731 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2737 FLAC__bool read_uint16(FILE *f, FLAC__bool big_endian, FLAC__uint16 *val, const char *fn)
2739 if(!read_bytes(f, (FLAC__byte*)val, 2, /*eof_ok=*/false, fn))
2741 if(is_big_endian_host_ != big_endian) {
2742 FLAC__byte tmp, *b = (FLAC__byte*)val;
2743 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
2748 FLAC__bool read_uint32(FILE *f, FLAC__bool big_endian, FLAC__uint32 *val, const char *fn)
2750 if(!read_bytes(f, (FLAC__byte*)val, 4, /*eof_ok=*/false, fn))
2752 if(is_big_endian_host_ != big_endian) {
2753 FLAC__byte tmp, *b = (FLAC__byte*)val;
2754 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
2755 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
2760 FLAC__bool read_uint64(FILE *f, FLAC__bool big_endian, FLAC__uint64 *val, const char *fn)
2762 if(!read_bytes(f, (FLAC__byte*)val, 8, /*eof_ok=*/false, fn))
2764 if(is_big_endian_host_ != big_endian) {
2765 FLAC__byte tmp, *b = (FLAC__byte*)val;
2766 tmp = b[7]; b[7] = b[0]; b[0] = tmp;
2767 tmp = b[6]; b[6] = b[1]; b[1] = tmp;
2768 tmp = b[5]; b[5] = b[2]; b[2] = tmp;
2769 tmp = b[4]; b[4] = b[3]; b[3] = tmp;
2774 FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, const char *fn)
2775 /* Read an IEEE 754 80-bit (aka SANE) extended floating point value from 'f',
2776 * convert it into an integral value and store in 'val'. Return false if only
2777 * between 1 and 9 bytes remain in 'f', if 0 bytes remain in 'f', or if the
2778 * value is negative, between zero and one, or too large to be represented by
2779 * 'val'; return true otherwise.
2788 if(!read_bytes(f, buf, sizeof(buf), /*eof_ok=*/false, fn))
2790 e = ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
2792 if((buf[0]>>7)==1U || e<0 || e>63) {
2793 flac__utils_printf(stderr, 1, "%s: ERROR: invalid floating-point value\n", fn);
2797 for(i = 0; i < 8; ++i)
2798 p |= (FLAC__uint64)(buf[i+2])<<(56U-i*8);
2799 *val = (FLAC__uint32)((p>>shift)+(p>>(shift-1) & 0x1));
2804 FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset)
2806 static unsigned char dump[8192];
2809 if(fstat(fileno(f), &stb) == 0 && (stb.st_mode & S_IFMT) == S_IFREG)
2811 if(fseeko(f, offset, SEEK_CUR) == 0)
2815 const long need = (long)min(offset, sizeof(dump));
2816 if((long)fread(dump, 1, need, f) < need)
2823 unsigned count_channel_mask_bits(FLAC__uint32 mask)
2835 FLAC__uint32 limit_channel_mask(FLAC__uint32 mask, unsigned channels)
2837 FLAC__uint32 x = 0x80000000;
2838 unsigned count = count_channel_mask_bits(mask);
2839 while(x && count > channels) {
2846 FLAC__ASSERT(count_channel_mask_bits(mask) == channels);