1/* flac - Command-line FLAC encoder/decoder
2 * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
3 *
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.
8 *
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.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 */
18
19#if HAVE_CONFIG_H
20#  include <config.h>
21#endif
22
23#if defined _WIN32 && !defined __CYGWIN__
24/* where MSVC puts unlink() */
25# include <io.h>
26#else
27# include <unistd.h>
28#endif
29#if defined _MSC_VER || defined __MINGW32__
30#include <sys/types.h> /* for off_t */
31#if _MSC_VER <= 1600 /* @@@ [2G limit] */
32#define fseeko fseek
33#define ftello ftell
34#endif
35#endif
36#include <errno.h>
37#include <limits.h> /* for LONG_MAX */
38#include <math.h> /* for floor() */
39#include <stdio.h> /* for FILE etc. */
40#include <stdlib.h> /* for malloc */
41#include <string.h> /* for strcmp(), strerror() */
42#include "FLAC/all.h"
43#include "share/alloc.h"
44#include "share/grabbag.h"
45#include "encode.h"
46
47#ifdef min
48#undef min
49#endif
50#define min(x,y) ((x)<(y)?(x):(y))
51#ifdef max
52#undef max
53#endif
54#define max(x,y) ((x)>(y)?(x):(y))
55
56/* this MUST be >= 588 so that sector aligning can take place with one read */
57#define CHUNK_OF_SAMPLES 2048
58
59typedef struct {
60#if FLAC__HAS_OGG
61	FLAC__bool use_ogg;
62#endif
63	FLAC__bool verify;
64	FLAC__bool is_stdout;
65	FLAC__bool outputfile_opened; /* true if we successfully opened the output file and we want it to be deleted if there is an error */
66	const char *inbasefilename;
67	const char *infilename;
68	const char *outfilename;
69
70	FLAC__uint64 skip;
71	FLAC__uint64 until; /* a value of 0 mean end-of-stream (i.e. --until=-0) */
72	FLAC__bool treat_warnings_as_errors;
73	FLAC__bool continue_through_decode_errors;
74	FLAC__bool replay_gain;
75	unsigned channels;
76	unsigned bits_per_sample;
77	unsigned sample_rate;
78	FLAC__uint64 unencoded_size;
79	FLAC__uint64 total_samples_to_encode;
80	FLAC__uint64 bytes_written;
81	FLAC__uint64 samples_written;
82	unsigned stats_mask;
83
84	FLAC__StreamEncoder *encoder;
85
86	FILE *fin;
87	FLAC__StreamMetadata *seek_table_template;
88} EncoderSession;
89
90/* this is data attached to the FLAC decoder when encoding from a FLAC file */
91typedef struct {
92	EncoderSession *encoder_session;
93	off_t filesize;
94	const FLAC__byte *lookahead;
95	unsigned lookahead_length;
96	size_t num_metadata_blocks;
97	FLAC__StreamMetadata *metadata_blocks[1024]; /*@@@ BAD MAGIC number */
98	FLAC__uint64 samples_left_to_process;
99	FLAC__bool fatal_error;
100} FLACDecoderData;
101
102const int FLAC_ENCODE__DEFAULT_PADDING = 8192;
103
104static FLAC__bool is_big_endian_host_;
105
106static unsigned char ucbuffer_[CHUNK_OF_SAMPLES*FLAC__MAX_CHANNELS*((FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE+7)/8)];
107static signed char *scbuffer_ = (signed char *)ucbuffer_;
108static FLAC__uint16 *usbuffer_ = (FLAC__uint16 *)ucbuffer_;
109static FLAC__int16 *ssbuffer_ = (FLAC__int16 *)ucbuffer_;
110
111static FLAC__int32 in_[FLAC__MAX_CHANNELS][CHUNK_OF_SAMPLES];
112static FLAC__int32 *input_[FLAC__MAX_CHANNELS];
113
114
115/*
116 * unpublished debug routines from the FLAC libs
117 */
118extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
119extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
120extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
121extern FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value);
122
123/*
124 * local routines
125 */
126static FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FILE *infile, const char *infilename, const char *outfilename);
127static void EncoderSession_destroy(EncoderSession *e);
128static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero, foreign_metadata_t *foreign_metadata);
129static int EncoderSession_finish_error(EncoderSession *e);
130static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, FLAC__uint32 channel_mask, unsigned channels, unsigned bps, unsigned sample_rate, const foreign_metadata_t *foreign_metadata, FLACDecoderData *flac_decoder_data);
131static FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples);
132static FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e);
133static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
134static FLAC__bool verify_metadata(const EncoderSession *e, FLAC__StreamMetadata **metadata, unsigned num_metadata);
135static 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);
136static 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);
137static FLAC__StreamDecoderReadStatus flac_decoder_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
138static FLAC__StreamDecoderSeekStatus flac_decoder_seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
139static FLAC__StreamDecoderTellStatus flac_decoder_tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
140static FLAC__StreamDecoderLengthStatus flac_decoder_length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
141static FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder, void *client_data);
142static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
143static void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
144static void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
145static FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset, FLAC__bool treat_warnings_as_errors);
146static void print_stats(const EncoderSession *encoder_session);
147static void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status);
148static void print_error_with_state(const EncoderSession *e, const char *message);
149static void print_verify_error(EncoderSession *e);
150static FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
151static FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
152static FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
153static FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
154static FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
155static FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset);
156static unsigned count_channel_mask_bits(FLAC__uint32 mask);
157#if 0
158static FLAC__uint32 limit_channel_mask(FLAC__uint32 mask, unsigned channels);
159#endif
160
161/*
162 * public routines
163 */
164int flac__encode_aif(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options, FLAC__bool is_aifc)
165{
166	EncoderSession encoder_session;
167	FLAC__uint16 x;
168	FLAC__uint32 xx;
169	unsigned int channels= 0U, bps= 0U, shift= 0U, sample_rate= 0U, sample_frames= 0U;
170	size_t channel_map[FLAC__MAX_CHANNELS];
171	FLAC__bool got_comm_chunk= false, got_ssnd_chunk= false;
172	int info_align_carry= -1, info_align_zero= -1;
173	FLAC__bool is_big_endian_pcm = true;
174
175	(void)infilesize; /* silence compiler warning about unused parameter */
176	(void)lookahead; /* silence compiler warning about unused parameter */
177	(void)lookahead_length; /* silence compiler warning about unused parameter */
178
179	if(!
180		EncoderSession_construct(
181			&encoder_session,
182#if FLAC__HAS_OGG
183			options.common.use_ogg,
184#else
185			/*use_ogg=*/false,
186#endif
187			options.common.verify,
188			options.common.treat_warnings_as_errors,
189			options.common.continue_through_decode_errors,
190			infile,
191			infilename,
192			outfilename
193		)
194	)
195		return 1;
196
197	/* initialize default channel map that preserves channel order */
198	{
199		size_t i;
200		for(i = 0; i < sizeof(channel_map)/sizeof(channel_map[0]); i++)
201			channel_map[i] = i;
202	}
203
204	if(options.foreign_metadata) {
205		const char *error;
206		if(!flac__foreign_metadata_read_from_aiff(options.foreign_metadata, infilename, &error)) {
207			flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", encoder_session.inbasefilename, error);
208			return EncoderSession_finish_error(&encoder_session);
209		}
210	}
211
212	/* lookahead[] already has "FORMxxxxAIFF", do sub-chunks */
213
214	while(1) {
215		size_t c= 0U;
216		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 */
217
218		/* chunk identifier; really conservative about behavior of fread() and feof() */
219		if(feof(infile) || ((c= fread(chunk_id, 1U, 4U, infile)), c==0U && feof(infile)))
220			break;
221		else if(c<4U || feof(infile)) {
222			flac__utils_printf(stderr, 1, "%s: ERROR: incomplete chunk identifier\n", encoder_session.inbasefilename);
223			return EncoderSession_finish_error(&encoder_session);
224		}
225
226		if(got_comm_chunk==false && !memcmp(chunk_id, "COMM", 4)) { /* common chunk */
227			unsigned long skip;
228			const FLAC__uint32 minimum_comm_size = (is_aifc? 22 : 18);
229
230			/* COMM chunk size */
231			if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
232				return EncoderSession_finish_error(&encoder_session);
233			else if(xx<minimum_comm_size) {
234				flac__utils_printf(stderr, 1, "%s: ERROR: non-standard %s 'COMM' chunk has length = %u\n", encoder_session.inbasefilename, is_aifc? "AIFF-C" : "AIFF", (unsigned int)xx);
235				return EncoderSession_finish_error(&encoder_session);
236			}
237			else if(!is_aifc && xx!=minimum_comm_size) {
238				flac__utils_printf(stderr, 1, "%s: WARNING: non-standard %s 'COMM' chunk has length = %u, expected %u\n", encoder_session.inbasefilename, is_aifc? "AIFF-C" : "AIFF", (unsigned int)xx, minimum_comm_size);
239				if(encoder_session.treat_warnings_as_errors)
240					return EncoderSession_finish_error(&encoder_session);
241			}
242			skip= (xx-minimum_comm_size)+(xx & 1U);
243
244			/* number of channels */
245			if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
246				return EncoderSession_finish_error(&encoder_session);
247			else if(x==0U || x>FLAC__MAX_CHANNELS) {
248				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned int)x);
249				return EncoderSession_finish_error(&encoder_session);
250			}
251			else if(x>2U && !options.common.channel_map_none) {
252				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u for AIFF\n", encoder_session.inbasefilename, (unsigned int)x);
253				return EncoderSession_finish_error(&encoder_session);
254			}
255			else if(options.common.sector_align && x!=2U) {
256				flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)x);
257				return EncoderSession_finish_error(&encoder_session);
258			}
259			channels= x;
260
261			/* number of sample frames */
262			if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
263				return EncoderSession_finish_error(&encoder_session);
264			sample_frames= xx;
265
266			/* bits per sample */
267			if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
268				return EncoderSession_finish_error(&encoder_session);
269			else if(x<4U || x>24U) {
270				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, (unsigned int)x);
271				return EncoderSession_finish_error(&encoder_session);
272			}
273			else if(options.common.sector_align && x!=16U) {
274				flac__utils_printf(stderr, 1, "%s: ERROR: file has %u bits-per-sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)x);
275				return EncoderSession_finish_error(&encoder_session);
276			}
277			bps= x;
278			shift= (bps%8)? 8-(bps%8) : 0; /* SSND data is always byte-aligned, left-justified but format_input() will double-check */
279			bps+= shift;
280
281			/* sample rate */
282			if(!read_sane_extended(infile, &xx, false, encoder_session.inbasefilename))
283				return EncoderSession_finish_error(&encoder_session);
284			else if(!FLAC__format_sample_rate_is_valid(xx)) {
285				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned int)xx);
286				return EncoderSession_finish_error(&encoder_session);
287			}
288			else if(options.common.sector_align && xx!=44100U) {
289				flac__utils_printf(stderr, 1, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)xx);
290				return EncoderSession_finish_error(&encoder_session);
291			}
292			sample_rate= xx;
293
294			/* check compression type for AIFF-C */
295			if(is_aifc) {
296				if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
297					return EncoderSession_finish_error(&encoder_session);
298				if(xx == 0x736F7774) /* "sowt" */
299					is_big_endian_pcm = false;
300				else if(xx == 0x4E4F4E45) /* "NONE" */
301					; /* nothing to do, we already default to big-endian */
302				else {
303					flac__utils_printf(stderr, 1, "%s: ERROR: can't handle AIFF-C compression type \"%c%c%c%c\"\n", encoder_session.inbasefilename, (char)(xx>>24), (char)((xx>>16)&8), (char)((xx>>8)&8), (char)(xx&8));
304					return EncoderSession_finish_error(&encoder_session);
305				}
306			}
307
308			/* set channel mapping */
309			/* FLAC order follows SMPTE and WAVEFORMATEXTENSIBLE but with fewer channels, which are: */
310			/* front left, front right, center, LFE, back left, back right, surround left, surround right */
311			/* specs say the channel ordering is:
312			 *                             1     2   3   4   5   6
313			 * ___________________________________________________
314			 * 2         stereo            l     r
315			 * 3                           l     r   c
316			 * 4                           l     c   r   S
317			 * quad (ambiguous with 4ch)  Fl    Fr   Bl  Br
318			 * 5                          Fl     Fr  Fc  Sl  Sr
319			 * 6                           l     lc  c   r   rc  S
320			 * 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
321			 * so we only have unambiguous mappings for 2, 3, and 5 channels
322			 */
323			if(
324				options.common.channel_map_none ||
325				channels == 1 || /* 1 channel: (mono) */
326				channels == 2 || /* 2 channels: left, right */
327				channels == 3 || /* 3 channels: left, right, center */
328				channels == 5    /* 5 channels: front left, front right, center, surround left, surround right */
329			) {
330				/* keep default channel order */
331			}
332			else {
333				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u for AIFF\n", encoder_session.inbasefilename, channels);
334				return EncoderSession_finish_error(&encoder_session);
335			}
336
337			/* skip any extra data in the COMM chunk */
338			if(!fskip_ahead(infile, skip)) {
339				flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over extra COMM data\n", encoder_session.inbasefilename);
340				return EncoderSession_finish_error(&encoder_session);
341			}
342
343			/*
344			 * now that we know the sample rate, canonicalize the
345			 * --skip string to a number of samples:
346			 */
347			flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
348			FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
349			encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
350			FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
351
352			got_comm_chunk= true;
353		}
354		else if(got_ssnd_chunk==false && !memcmp(chunk_id, "SSND", 4)) { /* sound data chunk */
355			unsigned int offset= 0U, block_size= 0U, align_remainder= 0U, data_bytes;
356			const size_t bytes_per_frame= channels*(bps>>3);
357			FLAC__uint64 total_samples_in_input, trim = 0;
358			FLAC__bool pad= false;
359
360			if(got_comm_chunk==false) {
361				flac__utils_printf(stderr, 1, "%s: ERROR: got 'SSND' chunk before 'COMM' chunk\n", encoder_session.inbasefilename);
362				return EncoderSession_finish_error(&encoder_session);
363			}
364
365			/* SSND chunk size */
366			if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
367				return EncoderSession_finish_error(&encoder_session);
368			if(options.common.ignore_chunk_sizes) {
369				FLAC__ASSERT(!options.common.sector_align);
370				data_bytes = (unsigned)(-(int)bytes_per_frame); /* max out data_bytes; we'll use EOF as signal to stop reading */
371			}
372			else {
373				data_bytes= xx;
374				data_bytes-= 8U; /* discount the offset and block size fields */
375			}
376			pad= (data_bytes & 1U) ? true : false;
377
378			/* offset */
379			if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
380				return EncoderSession_finish_error(&encoder_session);
381			offset= xx;
382			data_bytes-= offset;
383
384			/* block size */
385			if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
386				return EncoderSession_finish_error(&encoder_session);
387			else if(xx!=0U) {
388				flac__utils_printf(stderr, 1, "%s: ERROR: block size is %u; must be 0\n", encoder_session.inbasefilename, (unsigned int)xx);
389				return EncoderSession_finish_error(&encoder_session);
390			}
391			block_size= xx;
392
393			/* skip any SSND offset bytes */
394			FLAC__ASSERT(offset<=LONG_MAX);
395			if(!fskip_ahead(infile, offset)) {
396				flac__utils_printf(stderr, 1, "%s: ERROR: skipping offset in SSND chunk\n", encoder_session.inbasefilename);
397				return EncoderSession_finish_error(&encoder_session);
398			}
399			if(data_bytes!=(sample_frames*bytes_per_frame)) {
400				flac__utils_printf(stderr, 1, "%s: ERROR: SSND chunk size inconsistent with sample frame count\n", encoder_session.inbasefilename);
401				return EncoderSession_finish_error(&encoder_session);
402			}
403
404			/* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
405			FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
406			total_samples_in_input = data_bytes / bytes_per_frame + *options.common.align_reservoir_samples;
407
408			/*
409			 * now that we know the input size, canonicalize the
410			 * --until string to an absolute sample number:
411			 */
412			if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
413				return EncoderSession_finish_error(&encoder_session);
414			encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
415			FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
416
417			if(encoder_session.skip>0U) {
418				if(!fskip_ahead(infile, encoder_session.skip*bytes_per_frame)) {
419					flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
420					return EncoderSession_finish_error(&encoder_session);
421				}
422			}
423
424			data_bytes-= (unsigned int)encoder_session.skip*bytes_per_frame; /*@@@ WATCHOUT: 4GB limit */
425			if(options.common.ignore_chunk_sizes) {
426				encoder_session.total_samples_to_encode= 0;
427				flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
428				FLAC__ASSERT(0 == encoder_session.until);
429			}
430			else {
431				encoder_session.total_samples_to_encode= total_samples_in_input - encoder_session.skip;
432			}
433			if(encoder_session.until > 0) {
434				trim = total_samples_in_input - encoder_session.until;
435				FLAC__ASSERT(total_samples_in_input > 0);
436				FLAC__ASSERT(!options.common.sector_align);
437				data_bytes-= (unsigned int)trim*bytes_per_frame;
438				encoder_session.total_samples_to_encode-= trim;
439			}
440			if(options.common.sector_align) {
441				align_remainder= (unsigned int)(encoder_session.total_samples_to_encode % 588U);
442				if(options.common.is_last_file)
443					encoder_session.total_samples_to_encode+= (588U-align_remainder); /* will pad with zeroes */
444				else
445					encoder_session.total_samples_to_encode-= align_remainder; /* will stop short and carry over to next file */
446			}
447
448			/* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */
449			encoder_session.unencoded_size= encoder_session.total_samples_to_encode*bytes_per_frame+54;
450
451			if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, channels, bps-shift, sample_rate, options.foreign_metadata, /*flac_decoder_data=*/0))
452				return EncoderSession_finish_error(&encoder_session);
453
454			/* first do any samples in the reservoir */
455			if(options.common.sector_align && *options.common.align_reservoir_samples>0U) {
456
457				if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
458					print_error_with_state(&encoder_session, "ERROR during encoding");
459					return EncoderSession_finish_error(&encoder_session);
460				}
461			}
462
463			/* decrement the data_bytes counter if we need to align the file */
464			if(options.common.sector_align) {
465				if(options.common.is_last_file)
466					*options.common.align_reservoir_samples= 0U;
467				else {
468					*options.common.align_reservoir_samples= align_remainder;
469					data_bytes-= (*options.common.align_reservoir_samples)*bytes_per_frame;
470				}
471			}
472
473			/* now do from the file */
474			while(data_bytes>0) {
475				size_t bytes_read= fread(ucbuffer_, 1U, min(data_bytes, CHUNK_OF_SAMPLES*bytes_per_frame), infile);
476
477				if(bytes_read==0U) {
478					if(ferror(infile)) {
479						flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
480						return EncoderSession_finish_error(&encoder_session);
481					}
482					else if(feof(infile)) {
483						if(options.common.ignore_chunk_sizes) {
484							flac__utils_printf(stderr, 1, "%s: INFO: hit EOF with --ignore-chunk-sizes, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.samples_written);
485						}
486						else {
487							flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
488							if(encoder_session.treat_warnings_as_errors)
489								return EncoderSession_finish_error(&encoder_session);
490						}
491						data_bytes= 0;
492					}
493				}
494				else {
495					if(bytes_read % bytes_per_frame != 0U) {
496						flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
497						return EncoderSession_finish_error(&encoder_session);
498					}
499					else {
500						unsigned int frames= bytes_read/bytes_per_frame;
501						if(!format_input(input_, frames, is_big_endian_pcm, /*is_unsigned_samples=*/false, channels, bps, shift, channel_map))
502							return EncoderSession_finish_error(&encoder_session);
503
504						if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, frames)) {
505							print_error_with_state(&encoder_session, "ERROR during encoding");
506							return EncoderSession_finish_error(&encoder_session);
507						}
508						else
509							data_bytes-= bytes_read;
510					}
511				}
512			}
513
514			if(trim>0) {
515				FLAC__ASSERT(!options.common.sector_align);
516				if(!fskip_ahead(infile, trim*bytes_per_frame)) {
517					flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
518					return EncoderSession_finish_error(&encoder_session);
519				}
520			}
521
522			/* now read unaligned samples into reservoir or pad with zeroes if necessary */
523			if(options.common.sector_align) {
524				if(options.common.is_last_file) {
525					unsigned int pad_frames= 588U-align_remainder;
526
527					if(pad_frames<588U) {
528						unsigned int i;
529
530						info_align_zero= pad_frames;
531						for(i= 0U; i<channels; ++i)
532							memset(input_[i], 0, sizeof(input_[0][0])*pad_frames);
533
534						if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, pad_frames)) {
535							print_error_with_state(&encoder_session, "ERROR during encoding");
536							return EncoderSession_finish_error(&encoder_session);
537						}
538					}
539				}
540				else {
541					if(*options.common.align_reservoir_samples > 0) {
542						size_t bytes_read= fread(ucbuffer_, 1U, (*options.common.align_reservoir_samples)*bytes_per_frame, infile);
543
544						FLAC__ASSERT(CHUNK_OF_SAMPLES>=588U);
545						if(bytes_read==0U && ferror(infile)) {
546							flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
547							return EncoderSession_finish_error(&encoder_session);
548						}
549						else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_frame) {
550							flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)bytes_read, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written);
551							if(encoder_session.treat_warnings_as_errors)
552								return EncoderSession_finish_error(&encoder_session);
553						}
554						else {
555							info_align_carry= *options.common.align_reservoir_samples;
556							if(!format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, is_big_endian_pcm, /*is_unsigned_samples=*/false, channels, bps, shift, channel_map))
557								return EncoderSession_finish_error(&encoder_session);
558						}
559					}
560				}
561			}
562
563			if(pad==true) {
564				unsigned char tmp;
565
566				if(fread(&tmp, 1U, 1U, infile)<1U) {
567					flac__utils_printf(stderr, 1, "%s: ERROR during read of SSND pad byte\n", encoder_session.inbasefilename);
568					return EncoderSession_finish_error(&encoder_session);
569				}
570			}
571
572			got_ssnd_chunk= true;
573		}
574		else { /* other chunk */
575			if(!options.foreign_metadata) {
576				if(!memcmp(chunk_id, "COMM", 4))
577					flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
578				else if(!memcmp(chunk_id, "SSND", 4))
579					flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
580				else if(!options.foreign_metadata)
581					flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s' (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename, chunk_id);
582				if(encoder_session.treat_warnings_as_errors)
583					return EncoderSession_finish_error(&encoder_session);
584			}
585
586			/* chunk size */
587			if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
588				return EncoderSession_finish_error(&encoder_session);
589			else {
590				unsigned long skip= xx+(xx & 1U);
591
592				FLAC__ASSERT(skip<=LONG_MAX);
593				if(!fskip_ahead(infile, skip)) {
594					fprintf(stderr, "%s: ERROR during read while skipping over unknown chunk\n", encoder_session.inbasefilename);
595					return EncoderSession_finish_error(&encoder_session);
596				}
597			}
598		}
599	}
600
601	if(got_ssnd_chunk==false && sample_frames!=0U) {
602		flac__utils_printf(stderr, 1, "%s: ERROR: missing SSND chunk\n", encoder_session.inbasefilename);
603		return EncoderSession_finish_error(&encoder_session);
604	}
605
606	return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero, options.foreign_metadata);
607}
608
609int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
610{
611	EncoderSession encoder_session;
612	FLAC__bool is_unsigned_samples = false;
613	unsigned channels = 0, bps = 0, sample_rate = 0, shift = 0;
614	size_t bytes_read;
615	size_t channel_map[FLAC__MAX_CHANNELS];
616	FLAC__uint16 x, format; /* format is the wFormatTag word from the 'fmt ' chunk */
617	FLAC__uint32 xx, channel_mask = 0;
618	FLAC__bool got_fmt_chunk = false, got_data_chunk = false;
619	unsigned align_remainder = 0;
620	int info_align_carry = -1, info_align_zero = -1;
621
622	(void)infilesize;
623	(void)lookahead;
624	(void)lookahead_length;
625
626	if(!
627		EncoderSession_construct(
628			&encoder_session,
629#if FLAC__HAS_OGG
630			options.common.use_ogg,
631#else
632			/*use_ogg=*/false,
633#endif
634			options.common.verify,
635			options.common.treat_warnings_as_errors,
636			options.common.continue_through_decode_errors,
637			infile,
638			infilename,
639			outfilename
640		)
641	)
642		return 1;
643
644	/* initialize default channel map that preserves channel order */
645	{
646		size_t i;
647		for(i = 0; i < sizeof(channel_map)/sizeof(channel_map[0]); i++)
648			channel_map[i] = i;
649	}
650
651	if(options.foreign_metadata) {
652		const char *error;
653		if(!flac__foreign_metadata_read_from_wave(options.foreign_metadata, infilename, &error)) {
654			flac__utils_printf(stderr, 1, "%s: ERROR reading foreign metadata: %s\n", encoder_session.inbasefilename, error);
655			return EncoderSession_finish_error(&encoder_session);
656		}
657	}
658
659	/*
660	 * lookahead[] already has "RIFFxxxxWAVE", do sub-chunks
661	 */
662	while(!feof(infile)) {
663		if(!read_little_endian_uint32(infile, &xx, true, encoder_session.inbasefilename))
664			return EncoderSession_finish_error(&encoder_session);
665		if(feof(infile))
666			break;
667		if(xx == 0x20746d66 && !got_fmt_chunk) { /* "fmt " */
668			unsigned block_align, data_bytes;
669
670			/* see
671			 *   http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
672			 *   http://windowssdk.msdn.microsoft.com/en-us/library/ms713497.aspx
673			 *   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
674			 *
675			 * WAVEFORMAT is
676			 * 4 byte: subchunk size
677			 * 2 byte: format type: 1 for WAVE_FORMAT_PCM, 65534 for WAVE_FORMAT_EXTENSIBLE
678			 * 2 byte: # channels
679			 * 4 byte: sample rate (Hz)
680			 * 4 byte: avg bytes per sec
681			 * 2 byte: block align
682			 * 2 byte: bits per sample (not necessarily all significant)
683			 * WAVEFORMATEX adds
684			 * 2 byte: extension size in bytes (usually 0 for WAVEFORMATEX and 22 for WAVEFORMATEXTENSIBLE with PCM)
685			 * WAVEFORMATEXTENSIBLE adds
686			 * 2 byte: valid bits per sample
687			 * 4 byte: channel mask
688			 * 16 byte: subformat GUID, first 2 bytes have format type, 1 being PCM
689			 *
690			 * Current spec says WAVEFORMATEX with PCM must have bps == 8 or 16, or any multiple of 8 for WAVEFORMATEXTENSIBLE.
691			 * 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.
692			 *
693			 * Block align for WAVE_FORMAT_PCM or WAVE_FORMAT_EXTENSIBLE is also supposed to be channels*bps/8
694			 *
695			 * If the channel mask has more set bits than # of channels, the extra MSBs are ignored.
696			 * If the channel mask has less set bits than # of channels, the extra channels are unassigned to any speaker.
697			 *
698			 * Data is supposed to be unsigned for bps <= 8 else signed.
699			 */
700
701			/* fmt sub-chunk size */
702			if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
703				return EncoderSession_finish_error(&encoder_session);
704			data_bytes = xx;
705			if(data_bytes < 16) {
706				flac__utils_printf(stderr, 1, "%s: ERROR: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, data_bytes);
707				return EncoderSession_finish_error(&encoder_session);
708			}
709			/* format code */
710			if(!read_little_endian_uint16(infile, &format, false, encoder_session.inbasefilename))
711				return EncoderSession_finish_error(&encoder_session);
712			if(format != 1 /*WAVE_FORMAT_PCM*/ && format != 65534 /*WAVE_FORMAT_EXTENSIBLE*/) {
713				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported format type %u\n", encoder_session.inbasefilename, (unsigned)format);
714				return EncoderSession_finish_error(&encoder_session);
715			}
716			/* number of channels */
717			if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
718				return EncoderSession_finish_error(&encoder_session);
719			channels = (unsigned)x;
720			if(channels == 0 || channels > FLAC__MAX_CHANNELS) {
721				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number of channels %u\n", encoder_session.inbasefilename, channels);
722				return EncoderSession_finish_error(&encoder_session);
723			}
724			else if(options.common.sector_align && channels != 2) {
725				flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, channels);
726				return EncoderSession_finish_error(&encoder_session);
727			}
728			/* sample rate */
729			if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
730				return EncoderSession_finish_error(&encoder_session);
731			sample_rate = xx;
732			if(!FLAC__format_sample_rate_is_valid(sample_rate)) {
733				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, sample_rate);
734				return EncoderSession_finish_error(&encoder_session);
735			}
736			else if(options.common.sector_align && sample_rate != 44100) {
737				flac__utils_printf(stderr, 1, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_session.inbasefilename, sample_rate);
738				return EncoderSession_finish_error(&encoder_session);
739			}
740			/* avg bytes per second (ignored) */
741			if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
742				return EncoderSession_finish_error(&encoder_session);
743			/* block align */
744			if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
745				return EncoderSession_finish_error(&encoder_session);
746			block_align = (unsigned)x;
747			/* bits per sample */
748			if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
749				return EncoderSession_finish_error(&encoder_session);
750			bps = (unsigned)x;
751			is_unsigned_samples = (bps <= 8);
752			if(format == 1) {
753				if(bps != 8 && bps != 16) {
754					if(bps == 24 || bps == 32) {
755						/* let these slide with a warning since they're unambiguous */
756						flac__utils_printf(stderr, 1, "%s: WARNING: legacy WAVE file has format type %u but bits-per-sample=%u\n", encoder_session.inbasefilename, (unsigned)format, bps);
757						if(encoder_session.treat_warnings_as_errors)
758							return EncoderSession_finish_error(&encoder_session);
759					}
760					else {
761						/* @@@ we could add an option to specify left- or right-justified blocks so we knew how to set 'shift' */
762						flac__utils_printf(stderr, 1, "%s: ERROR: legacy WAVE file has format type %u but bits-per-sample=%u\n", encoder_session.inbasefilename, (unsigned)format, bps);
763						return EncoderSession_finish_error(&encoder_session);
764					}
765				}
766#if 0 /* @@@ reinstate once we can get an answer about whether the samples are left- or right-justified */
767				if((bps+7)/8 * channels == block_align) {
768					if(bps % 8) {
769						/* assume legacy file is byte aligned with some LSBs zero; this is double-checked in format_input() */
770						flac__utils_printf(stderr, 1, "%s: WARNING: legacy WAVE file (format type %d) has block alignment=%u, bits-per-sample=%u, channels=%u\n", encoder_session.inbasefilename, (unsigned)format, block_align, bps, channels);
771						if(encoder_session.treat_warnings_as_errors)
772							return EncoderSession_finish_error(&encoder_session);
773						shift = 8 - (bps % 8);
774						bps += shift;
775					}
776					else
777						shift = 0;
778				}
779				else {
780					flac__utils_printf(stderr, 1, "%s: ERROR: illegal WAVE file (format type %d) has block alignment=%u, bits-per-sample=%u, channels=%u\n", encoder_session.inbasefilename, (unsigned)format, block_align, bps, channels);
781					return EncoderSession_finish_error(&encoder_session);
782				}
783#else
784				shift = 0;
785#endif
786				if(channels > 2 && !options.common.channel_map_none) {
787					flac__utils_printf(stderr, 1, "%s: ERROR: WAVE has >2 channels but is not WAVE_FORMAT_EXTENSIBLE; cannot assign channels\n", encoder_session.inbasefilename);
788					return EncoderSession_finish_error(&encoder_session);
789				}
790				FLAC__ASSERT(data_bytes >= 16);
791				data_bytes -= 16;
792			}
793			else {
794				if(data_bytes < 40) {
795					flac__utils_printf(stderr, 1, "%s: ERROR: invalid WAVEFORMATEXTENSIBLE chunk with size %u\n", encoder_session.inbasefilename, data_bytes);
796					return EncoderSession_finish_error(&encoder_session);
797				}
798				/* cbSize */
799				if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
800					return EncoderSession_finish_error(&encoder_session);
801				if(x < 22) {
802					flac__utils_printf(stderr, 1, "%s: ERROR: invalid WAVEFORMATEXTENSIBLE chunk with cbSize %u\n", encoder_session.inbasefilename, (unsigned)x);
803					return EncoderSession_finish_error(&encoder_session);
804				}
805				/* valid bps */
806				if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
807					return EncoderSession_finish_error(&encoder_session);
808				if((unsigned)x > bps) {
809					flac__utils_printf(stderr, 1, "%s: ERROR: invalid WAVEFORMATEXTENSIBLE chunk with wValidBitsPerSample (%u) > wBitsPerSample (%u)\n", encoder_session.inbasefilename, (unsigned)x, bps);
810					return EncoderSession_finish_error(&encoder_session);
811				}
812				shift = bps - (unsigned)x;
813				/* channel mask */
814				if(!read_little_endian_uint32(infile, &channel_mask, false, encoder_session.inbasefilename))
815					return EncoderSession_finish_error(&encoder_session);
816				/* for mono/stereo and unassigned channels, we fake the mask */
817				if(channel_mask == 0) {
818					if(channels == 1)
819						channel_mask = 0x0001;
820					else if(channels == 2)
821						channel_mask = 0x0003;
822				}
823				/* set channel mapping */
824				/* FLAC order follows SMPTE and WAVEFORMATEXTENSIBLE but with fewer channels, which are: */
825				/* front left, front right, center, LFE, back left, back right, surround left, surround right */
826				/* the default mapping is sufficient for 1-6 channels and 7-8 are currently unspecified anyway */
827#if 0
828				/* @@@ example for dolby/vorbis order, for reference later in case it becomes important */
829				if(
830					options.common.channel_map_none ||
831					channel_mask == 0x0001 || /* 1 channel: (mono) */
832					channel_mask == 0x0003 || /* 2 channels: front left, front right */
833					channel_mask == 0x0033 || /* 4 channels: front left, front right, back left, back right */
834					channel_mask == 0x0603    /* 4 channels: front left, front right, side left, side right */
835				) {
836					/* keep default channel order */
837				}
838				else if(
839					channel_mask == 0x0007 || /* 3 channels: front left, front right, front center */
840					channel_mask == 0x0037 || /* 5 channels: front left, front right, front center, back left, back right */
841					channel_mask == 0x0607    /* 5 channels: front left, front right, front center, side left, side right */
842				) {
843					/* to dolby order: front left, center, front right [, surround left, surround right ] */
844					channel_map[1] = 2;
845					channel_map[2] = 1;
846				}
847				else if(
848					channel_mask == 0x003f || /* 6 channels: front left, front right, front center, LFE, back left, back right */
849					channel_mask == 0x060f    /* 6 channels: front left, front right, front center, LFE, side left, side right */
850				) {
851					/* to dolby order: front left, center, front right, surround left, surround right, LFE */
852					channel_map[1] = 2;
853					channel_map[2] = 1;
854					channel_map[3] = 5;
855					channel_map[4] = 3;
856					channel_map[5] = 4;
857				}
858#else
859				if(
860					options.common.channel_map_none ||
861					channel_mask == 0x0001 || /* 1 channel: (mono) */
862					channel_mask == 0x0003 || /* 2 channels: front left, front right */
863					channel_mask == 0x0007 || /* 3 channels: front left, front right, front center */
864					channel_mask == 0x0033 || /* 4 channels: front left, front right, back left, back right */
865					channel_mask == 0x0603 || /* 4 channels: front left, front right, side left, side right */
866					channel_mask == 0x0037 || /* 5 channels: front left, front right, front center, back left, back right */
867					channel_mask == 0x0607 || /* 5 channels: front left, front right, front center, side left, side right */
868					channel_mask == 0x003f || /* 6 channels: front left, front right, front center, LFE, back left, back right */
869					channel_mask == 0x060f    /* 6 channels: front left, front right, front center, LFE, side left, side right */
870				) {
871					/* keep default channel order */
872				}
873#endif
874				else {
875					flac__utils_printf(stderr, 1, "%s: ERROR: WAVEFORMATEXTENSIBLE chunk with unsupported channel mask=0x%04X\n", encoder_session.inbasefilename, (unsigned)channel_mask);
876					return EncoderSession_finish_error(&encoder_session);
877				}
878				if(!options.common.channel_map_none) {
879					if(count_channel_mask_bits(channel_mask) < channels) {
880						flac__utils_printf(stderr, 1, "%s: ERROR: WAVEFORMATEXTENSIBLE chunk: channel mask 0x%04X has unassigned channels (#channels=%u)\n", encoder_session.inbasefilename, (unsigned)channel_mask, channels);
881						return EncoderSession_finish_error(&encoder_session);
882					}
883#if 0
884					/* supporting this is too difficult with channel mapping; e.g. what if mask is 0x003f but #channels=4?
885					 * there would be holes in the order that would have to be filled in, or the mask would have to be
886					 * limited and the logic above rerun to see if it still fits into the FLAC mapping.
887					 */
888					else if(count_channel_mask_bits(channel_mask) > channels)
889						channel_mask = limit_channel_mask(channel_mask, channels);
890#else
891					else if(count_channel_mask_bits(channel_mask) > channels) {
892						flac__utils_printf(stderr, 1, "%s: ERROR: WAVEFORMATEXTENSIBLE chunk: channel mask 0x%04X has extra bits for non-existant channels (#channels=%u)\n", encoder_session.inbasefilename, (unsigned)channel_mask, channels);
893						return EncoderSession_finish_error(&encoder_session);
894					}
895#endif
896				}
897				/* first part of GUID */
898				if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
899					return EncoderSession_finish_error(&encoder_session);
900				if(x != 1) {
901					flac__utils_printf(stderr, 1, "%s: ERROR: unsupported WAVEFORMATEXTENSIBLE chunk with non-PCM format %u\n", encoder_session.inbasefilename, (unsigned)x);
902					return EncoderSession_finish_error(&encoder_session);
903				}
904				data_bytes -= 26;
905			}
906
907			if(bps-shift < 4 || bps-shift > 24) {
908				flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, bps-shift);
909				return EncoderSession_finish_error(&encoder_session);
910			}
911			else if(options.common.sector_align && bps-shift != 16) {
912				flac__utils_printf(stderr, 1, "%s: ERROR: file has %u bits-per-sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, bps-shift);
913				return EncoderSession_finish_error(&encoder_session);
914			}
915
916			/* skip any extra data in the fmt sub-chunk */
917			if(!fskip_ahead(infile, data_bytes)) {
918				flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over extra 'fmt' data\n", encoder_session.inbasefilename);
919				return EncoderSession_finish_error(&encoder_session);
920			}
921
922			/*
923			 * now that we know the sample rate, canonicalize the
924			 * --skip string to a number of samples:
925			 */
926			flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
927			FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
928			encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
929			FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
930
931			got_fmt_chunk = true;
932		}
933		else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
934			FLAC__uint64 total_samples_in_input, trim = 0;
935			FLAC__bool pad = false;
936			const size_t bytes_per_wide_sample = channels * (bps >> 3);
937			unsigned data_bytes;
938
939			/* data size */
940			if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
941				return EncoderSession_finish_error(&encoder_session);
942			if(options.common.ignore_chunk_sizes) {
943				FLAC__ASSERT(!options.common.sector_align);
944				data_bytes = (unsigned)(-(int)bytes_per_wide_sample); /* max out data_bytes; we'll use EOF as signal to stop reading */
945			}
946			else {
947				data_bytes = xx;
948				if(0 == data_bytes) {
949					flac__utils_printf(stderr, 1, "%s: ERROR: 'data' subchunk has size of 0\n", encoder_session.inbasefilename);
950					return EncoderSession_finish_error(&encoder_session);
951				}
952			}
953			pad = (data_bytes & 1U) ? true : false;
954
955			/* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
956			FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
957			total_samples_in_input = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;
958
959			/*
960			 * now that we know the input size, canonicalize the
961			 * --until string to an absolute sample number:
962			 */
963			if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
964				return EncoderSession_finish_error(&encoder_session);
965			encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
966			FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
967
968			if(encoder_session.skip > 0) {
969				if(!fskip_ahead(infile, encoder_session.skip * bytes_per_wide_sample)) {
970					flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
971					return EncoderSession_finish_error(&encoder_session);
972				}
973			}
974
975			data_bytes -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
976			if(options.common.ignore_chunk_sizes) {
977				encoder_session.total_samples_to_encode = 0;
978				flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
979				FLAC__ASSERT(0 == encoder_session.until);
980			}
981			else {
982				encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
983			}
984			if(encoder_session.until > 0) {
985				trim = total_samples_in_input - encoder_session.until;
986				FLAC__ASSERT(total_samples_in_input > 0);
987				FLAC__ASSERT(!options.common.sector_align);
988				data_bytes -= (unsigned int)trim * bytes_per_wide_sample;
989				encoder_session.total_samples_to_encode -= trim;
990			}
991			if(options.common.sector_align) {
992				align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
993				if(options.common.is_last_file)
994					encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
995				else
996					encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
997			}
998
999			/* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
1000			encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample + 44;
1001
1002			if(!EncoderSession_init_encoder(&encoder_session, options.common, channel_mask, channels, bps-shift, sample_rate, options.foreign_metadata, /*flac_decoder_data=*/0))
1003				return EncoderSession_finish_error(&encoder_session);
1004
1005			/*
1006			 * first do any samples in the reservoir
1007			 */
1008			if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
1009				if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
1010					print_error_with_state(&encoder_session, "ERROR during encoding");
1011					return EncoderSession_finish_error(&encoder_session);
1012				}
1013			}
1014
1015			/*
1016			 * decrement the data_bytes counter if we need to align the file
1017			 */
1018			if(options.common.sector_align) {
1019				if(options.common.is_last_file) {
1020					*options.common.align_reservoir_samples = 0;
1021				}
1022				else {
1023					*options.common.align_reservoir_samples = align_remainder;
1024					data_bytes -= (*options.common.align_reservoir_samples) * bytes_per_wide_sample;
1025				}
1026			}
1027
1028			/*
1029			 * now do from the file
1030			 */
1031			while(data_bytes > 0) {
1032				bytes_read = fread(ucbuffer_, sizeof(unsigned char), min(data_bytes, CHUNK_OF_SAMPLES * bytes_per_wide_sample), infile);
1033				if(bytes_read == 0) {
1034					if(ferror(infile)) {
1035						flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1036						return EncoderSession_finish_error(&encoder_session);
1037					}
1038					else if(feof(infile)) {
1039						if(options.common.ignore_chunk_sizes) {
1040							flac__utils_printf(stderr, 1, "%s: INFO: hit EOF with --ignore-chunk-sizes, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.samples_written);
1041						}
1042						else {
1043							flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
1044							if(encoder_session.treat_warnings_as_errors)
1045								return EncoderSession_finish_error(&encoder_session);
1046						}
1047						data_bytes = 0;
1048					}
1049				}
1050				else {
1051					if(bytes_read % bytes_per_wide_sample != 0) {
1052						flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1053						return EncoderSession_finish_error(&encoder_session);
1054					}
1055					else {
1056						unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1057						if(!format_input(input_, wide_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps, shift, channel_map))
1058							return EncoderSession_finish_error(&encoder_session);
1059
1060						if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1061							print_error_with_state(&encoder_session, "ERROR during encoding");
1062							return EncoderSession_finish_error(&encoder_session);
1063						}
1064						data_bytes -= bytes_read;
1065					}
1066				}
1067			}
1068
1069			if(trim > 0) {
1070				FLAC__ASSERT(!options.common.sector_align);
1071				if(!fskip_ahead(infile, trim * bytes_per_wide_sample)) {
1072					flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
1073					return EncoderSession_finish_error(&encoder_session);
1074				}
1075			}
1076
1077			/*
1078			 * now read unaligned samples into reservoir or pad with zeroes if necessary
1079			 */
1080			if(options.common.sector_align) {
1081				if(options.common.is_last_file) {
1082					unsigned wide_samples = 588 - align_remainder;
1083					if(wide_samples < 588) {
1084						unsigned channel;
1085
1086						info_align_zero = wide_samples;
1087						for(channel = 0; channel < channels; channel++)
1088							memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
1089
1090						if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1091							print_error_with_state(&encoder_session, "ERROR during encoding");
1092							return EncoderSession_finish_error(&encoder_session);
1093						}
1094					}
1095				}
1096				else {
1097					if(*options.common.align_reservoir_samples > 0) {
1098						FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
1099						bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
1100						if(bytes_read == 0 && ferror(infile)) {
1101							flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1102							return EncoderSession_finish_error(&encoder_session);
1103						}
1104						else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
1105							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);
1106							if(encoder_session.treat_warnings_as_errors)
1107								return EncoderSession_finish_error(&encoder_session);
1108						}
1109						else {
1110							info_align_carry = *options.common.align_reservoir_samples;
1111							if(!format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps, shift, channel_map))
1112								return EncoderSession_finish_error(&encoder_session);
1113						}
1114					}
1115				}
1116			}
1117
1118			if(pad == true) {
1119				unsigned char tmp;
1120
1121				if(fread(&tmp, 1U, 1U, infile) < 1U) {
1122					flac__utils_printf(stderr, 1, "%s: ERROR during read of data pad byte\n", encoder_session.inbasefilename);
1123					return EncoderSession_finish_error(&encoder_session);
1124				}
1125			}
1126
1127			got_data_chunk = true;
1128		}
1129		else {
1130			if(xx == 0x61746164 && !got_fmt_chunk) { /* "data" */
1131				flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
1132				return EncoderSession_finish_error(&encoder_session);
1133			}
1134
1135			if(!options.foreign_metadata) {
1136				if(xx == 0x20746d66 && got_fmt_chunk) /* "fmt " */
1137					flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
1138				else if(xx == 0x61746164) /* "data" */
1139					flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename);
1140				else
1141					flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c' (use --keep-foreign-metadata to keep)\n", encoder_session.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
1142				if(encoder_session.treat_warnings_as_errors)
1143					return EncoderSession_finish_error(&encoder_session);
1144			}
1145
1146			/* sub-chunk size */
1147			if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
1148				return EncoderSession_finish_error(&encoder_session);
1149			else {
1150				unsigned long skip = xx+(xx & 1U);
1151
1152				FLAC__ASSERT(skip<=LONG_MAX);
1153				if(!fskip_ahead(infile, skip)) {
1154					flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping over unsupported sub-chunk\n", encoder_session.inbasefilename);
1155					return EncoderSession_finish_error(&encoder_session);
1156				}
1157			}
1158		}
1159	}
1160
1161	return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero, options.foreign_metadata);
1162}
1163
1164int flac__encode_raw(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options)
1165{
1166	EncoderSession encoder_session;
1167	size_t bytes_read;
1168	const size_t bytes_per_wide_sample = options.channels * (options.bps >> 3);
1169	unsigned align_remainder = 0;
1170	int info_align_carry = -1, info_align_zero = -1;
1171	FLAC__uint64 total_samples_in_input = 0;
1172
1173	FLAC__ASSERT(!options.common.sector_align || options.channels == 2);
1174	FLAC__ASSERT(!options.common.sector_align || options.bps == 16);
1175	FLAC__ASSERT(!options.common.sector_align || options.sample_rate == 44100);
1176	FLAC__ASSERT(!options.common.sector_align || infilesize >= 0);
1177	FLAC__ASSERT(!options.common.replay_gain || options.channels <= 2);
1178	FLAC__ASSERT(!options.common.replay_gain || grabbag__replaygain_is_valid_sample_frequency(options.sample_rate));
1179
1180	if(!
1181		EncoderSession_construct(
1182			&encoder_session,
1183#if FLAC__HAS_OGG
1184			options.common.use_ogg,
1185#else
1186			/*use_ogg=*/false,
1187#endif
1188			options.common.verify,
1189			options.common.treat_warnings_as_errors,
1190			options.common.continue_through_decode_errors,
1191			infile,
1192			infilename,
1193			outfilename
1194		)
1195	)
1196		return 1;
1197
1198	/*
1199	 * now that we know the sample rate, canonicalize the
1200	 * --skip string to a number of samples:
1201	 */
1202	flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, options.sample_rate);
1203	FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
1204	encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
1205	FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
1206
1207	if(infilesize < 0)
1208		total_samples_in_input = 0;
1209	else {
1210		/* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
1211		FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
1212		total_samples_in_input = (FLAC__uint64)infilesize / bytes_per_wide_sample + *options.common.align_reservoir_samples;
1213	}
1214
1215	/*
1216	 * now that we know the input size, canonicalize the
1217	 * --until strings to a number of samples:
1218	 */
1219	if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, options.sample_rate, encoder_session.skip, total_samples_in_input))
1220		return EncoderSession_finish_error(&encoder_session);
1221	encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
1222	FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
1223
1224	infilesize -= (off_t)encoder_session.skip * bytes_per_wide_sample;
1225	encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
1226	if(encoder_session.until > 0) {
1227		const FLAC__uint64 trim = total_samples_in_input - encoder_session.until;
1228		FLAC__ASSERT(total_samples_in_input > 0);
1229		FLAC__ASSERT(!options.common.sector_align);
1230		infilesize -= (off_t)trim * bytes_per_wide_sample;
1231		encoder_session.total_samples_to_encode -= trim;
1232	}
1233	if(infilesize >= 0 && options.common.sector_align) {
1234		FLAC__ASSERT(encoder_session.skip == 0);
1235		align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
1236		if(options.common.is_last_file)
1237			encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
1238		else
1239			encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
1240	}
1241	encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample;
1242
1243	if(encoder_session.total_samples_to_encode <= 0)
1244		flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
1245
1246	if(encoder_session.skip > 0) {
1247		unsigned skip_bytes = bytes_per_wide_sample * (unsigned)encoder_session.skip;
1248		if(skip_bytes > lookahead_length) {
1249			skip_bytes -= lookahead_length;
1250			lookahead_length = 0;
1251			if(!fskip_ahead(infile, skip_bytes)) {
1252				flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
1253				return EncoderSession_finish_error(&encoder_session);
1254			}
1255		}
1256		else {
1257			lookahead += skip_bytes;
1258			lookahead_length -= skip_bytes;
1259		}
1260	}
1261
1262	if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, options.channels, options.bps, options.sample_rate, /*foreign_metadata=*/0, /*flac_decoder_data=*/0))
1263		return EncoderSession_finish_error(&encoder_session);
1264
1265	/*
1266	 * first do any samples in the reservoir
1267	 */
1268	if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
1269		if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
1270			print_error_with_state(&encoder_session, "ERROR during encoding");
1271			return EncoderSession_finish_error(&encoder_session);
1272		}
1273	}
1274
1275	/*
1276	 * decrement infilesize if we need to align the file
1277	 */
1278	if(options.common.sector_align) {
1279		FLAC__ASSERT(infilesize >= 0);
1280		if(options.common.is_last_file) {
1281			*options.common.align_reservoir_samples = 0;
1282		}
1283		else {
1284			*options.common.align_reservoir_samples = align_remainder;
1285			infilesize -= (off_t)((*options.common.align_reservoir_samples) * bytes_per_wide_sample);
1286			FLAC__ASSERT(infilesize >= 0);
1287		}
1288	}
1289
1290	/*
1291	 * now do from the file
1292	 */
1293	if(infilesize < 0) {
1294		while(!feof(infile)) {
1295			if(lookahead_length > 0) {
1296				FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * bytes_per_wide_sample);
1297				memcpy(ucbuffer_, lookahead, lookahead_length);
1298				bytes_read = fread(ucbuffer_+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
1299				if(ferror(infile)) {
1300					flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1301					return EncoderSession_finish_error(&encoder_session);
1302				}
1303				lookahead_length = 0;
1304			}
1305			else
1306				bytes_read = fread(ucbuffer_, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample, infile);
1307
1308			if(bytes_read == 0) {
1309				if(ferror(infile)) {
1310					flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1311					return EncoderSession_finish_error(&encoder_session);
1312				}
1313			}
1314			else if(bytes_read % bytes_per_wide_sample != 0) {
1315				flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1316				return EncoderSession_finish_error(&encoder_session);
1317			}
1318			else {
1319				unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1320				if(!format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps, /*shift=*/0, /*channel_map=*/0))
1321					return EncoderSession_finish_error(&encoder_session);
1322
1323				if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1324					print_error_with_state(&encoder_session, "ERROR during encoding");
1325					return EncoderSession_finish_error(&encoder_session);
1326				}
1327			}
1328		}
1329	}
1330	else {
1331		const FLAC__uint64 max_input_bytes = infilesize;
1332		FLAC__uint64 total_input_bytes_read = 0;
1333		while(total_input_bytes_read < max_input_bytes) {
1334			{
1335				size_t wanted = (CHUNK_OF_SAMPLES * bytes_per_wide_sample);
1336				wanted = (size_t) min((FLAC__uint64)wanted, max_input_bytes - total_input_bytes_read);
1337
1338				if(lookahead_length > 0) {
1339					FLAC__ASSERT(lookahead_length <= wanted);
1340					memcpy(ucbuffer_, lookahead, lookahead_length);
1341					wanted -= lookahead_length;
1342					bytes_read = lookahead_length;
1343					if(wanted > 0) {
1344						bytes_read += fread(ucbuffer_+lookahead_length, sizeof(unsigned char), wanted, infile);
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);
1348						}
1349					}
1350					lookahead_length = 0;
1351				}
1352				else
1353					bytes_read = fread(ucbuffer_, sizeof(unsigned char), wanted, infile);
1354			}
1355
1356			if(bytes_read == 0) {
1357				if(ferror(infile)) {
1358					flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1359					return EncoderSession_finish_error(&encoder_session);
1360				}
1361				else if(feof(infile)) {
1362					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);
1363					if(encoder_session.treat_warnings_as_errors)
1364						return EncoderSession_finish_error(&encoder_session);
1365					total_input_bytes_read = max_input_bytes;
1366				}
1367			}
1368			else {
1369				if(bytes_read % bytes_per_wide_sample != 0) {
1370					flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1371					return EncoderSession_finish_error(&encoder_session);
1372				}
1373				else {
1374					unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1375					if(!format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps, /*shift=*/0, /*channel_map=*/0))
1376						return EncoderSession_finish_error(&encoder_session);
1377
1378					if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1379						print_error_with_state(&encoder_session, "ERROR during encoding");
1380						return EncoderSession_finish_error(&encoder_session);
1381					}
1382					total_input_bytes_read += bytes_read;
1383				}
1384			}
1385		}
1386	}
1387
1388	/*
1389	 * now read unaligned samples into reservoir or pad with zeroes if necessary
1390	 */
1391	if(options.common.sector_align) {
1392		if(options.common.is_last_file) {
1393			unsigned wide_samples = 588 - align_remainder;
1394			if(wide_samples < 588) {
1395				unsigned channel;
1396
1397				info_align_zero = wide_samples;
1398				for(channel = 0; channel < options.channels; channel++)
1399					memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
1400
1401				if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1402					print_error_with_state(&encoder_session, "ERROR during encoding");
1403					return EncoderSession_finish_error(&encoder_session);
1404				}
1405			}
1406		}
1407		else {
1408			if(*options.common.align_reservoir_samples > 0) {
1409				FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
1410				bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
1411				if(bytes_read == 0 && ferror(infile)) {
1412					flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1413					return EncoderSession_finish_error(&encoder_session);
1414				}
1415				else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
1416					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);
1417					if(encoder_session.treat_warnings_as_errors)
1418						return EncoderSession_finish_error(&encoder_session);
1419				}
1420				else {
1421					info_align_carry = *options.common.align_reservoir_samples;
1422					if(!format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps, /*shift=*/0, /*channel_map=*/0))
1423						return EncoderSession_finish_error(&encoder_session);
1424				}
1425			}
1426		}
1427	}
1428
1429	return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero, /*foreign_metadata=*/0);
1430}
1431
1432int flac__encode_flac(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, flac_encode_options_t options, FLAC__bool input_is_ogg)
1433{
1434	EncoderSession encoder_session;
1435	FLAC__StreamDecoder *decoder = 0;
1436	FLACDecoderData decoder_data;
1437	size_t i;
1438	int retval;
1439
1440	if(!
1441		EncoderSession_construct(
1442			&encoder_session,
1443#if FLAC__HAS_OGG
1444			options.common.use_ogg,
1445#else
1446			/*use_ogg=*/false,
1447#endif
1448			options.common.verify,
1449			options.common.treat_warnings_as_errors,
1450			options.common.continue_through_decode_errors,
1451			infile,
1452			infilename,
1453			outfilename
1454		)
1455	)
1456		return 1;
1457
1458	decoder_data.encoder_session = &encoder_session;
1459	decoder_data.filesize = (infilesize == (off_t)(-1)? 0 : infilesize);
1460	decoder_data.lookahead = lookahead;
1461	decoder_data.lookahead_length = lookahead_length;
1462	decoder_data.num_metadata_blocks = 0;
1463	decoder_data.samples_left_to_process = 0;
1464	decoder_data.fatal_error = false;
1465
1466	/*
1467	 * set up FLAC decoder for the input
1468	 */
1469	if (0 == (decoder = FLAC__stream_decoder_new())) {
1470		flac__utils_printf(stderr, 1, "%s: ERROR: creating decoder for FLAC input\n", encoder_session.inbasefilename);
1471		return EncoderSession_finish_error(&encoder_session);
1472	}
1473	if (!(
1474		FLAC__stream_decoder_set_md5_checking(decoder, false) &&
1475		FLAC__stream_decoder_set_metadata_respond_all(decoder)
1476	)) {
1477		flac__utils_printf(stderr, 1, "%s: ERROR: setting up decoder for FLAC input\n", encoder_session.inbasefilename);
1478		goto fubar1; /*@@@ yuck */
1479	}
1480
1481	if (input_is_ogg) {
1482		if (FLAC__stream_decoder_init_ogg_stream(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=*/&decoder_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
1483			flac__utils_printf(stderr, 1, "%s: ERROR: initializing decoder for Ogg FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(decoder));
1484			goto fubar1; /*@@@ yuck */
1485		}
1486	}
1487	else if (FLAC__stream_decoder_init_stream(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=*/&decoder_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
1488		flac__utils_printf(stderr, 1, "%s: ERROR: initializing decoder for FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(decoder));
1489		goto fubar1; /*@@@ yuck */
1490	}
1491
1492	if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder) || decoder_data.fatal_error) {
1493		if (decoder_data.fatal_error)
1494			flac__utils_printf(stderr, 1, "%s: ERROR: out of memory or too many metadata blocks while reading metadata in FLAC input\n", encoder_session.inbasefilename);
1495		else
1496			flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(decoder));
1497		goto fubar1; /*@@@ yuck */
1498	}
1499
1500	if (decoder_data.num_metadata_blocks == 0) {
1501		flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, got no metadata blocks\n", encoder_session.inbasefilename);
1502		goto fubar2; /*@@@ yuck */
1503	}
1504	else if (decoder_data.metadata_blocks[0]->type != FLAC__METADATA_TYPE_STREAMINFO) {
1505		flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, first metadata block is not STREAMINFO\n", encoder_session.inbasefilename);
1506		goto fubar2; /*@@@ yuck */
1507	}
1508	else if (decoder_data.metadata_blocks[0]->data.stream_info.total_samples == 0) {
1509		flac__utils_printf(stderr, 1, "%s: ERROR: FLAC input has STREAMINFO with unknown total samples which is not supported\n", encoder_session.inbasefilename);
1510		goto fubar2; /*@@@ yuck */
1511	}
1512
1513	/*
1514	 * now that we have the STREAMINFO and know the sample rate,
1515	 * canonicalize the --skip string to a number of samples:
1516	 */
1517	flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate);
1518	FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
1519	encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
1520	FLAC__ASSERT(!options.common.sector_align); /* --sector-align with FLAC input is not supported */
1521
1522	{
1523		FLAC__uint64 total_samples_in_input, trim = 0;
1524
1525		total_samples_in_input = decoder_data.metadata_blocks[0]->data.stream_info.total_samples;
1526
1527		/*
1528		 * now that we know the input size, canonicalize the
1529		 * --until string to an absolute sample number:
1530		 */
1531		if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate, encoder_session.skip, total_samples_in_input))
1532			goto fubar2; /*@@@ yuck */
1533		encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
1534
1535		encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
1536		if(encoder_session.until > 0) {
1537			trim = total_samples_in_input - encoder_session.until;
1538			FLAC__ASSERT(total_samples_in_input > 0);
1539			encoder_session.total_samples_to_encode -= trim;
1540		}
1541
1542		encoder_session.unencoded_size = decoder_data.filesize;
1543
1544		/* (channel mask will get copied over from the source VORBIS_COMMENT if it exists) */
1545		if(!EncoderSession_init_encoder(&encoder_session, options.common, /*channel_mask=*/0, decoder_data.metadata_blocks[0]->data.stream_info.channels, decoder_data.metadata_blocks[0]->data.stream_info.bits_per_sample, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate, /*foreign_metadata=*/0, &decoder_data))
1546			goto fubar2; /*@@@ yuck */
1547
1548		/*
1549		 * have to wait until the FLAC encoder is set up for writing
1550		 * before any seeking in the input FLAC file, because the seek
1551		 * itself will usually call the decoder's write callback, and
1552		 * our decoder's write callback passes samples to our FLAC
1553		 * encoder
1554		 */
1555		decoder_data.samples_left_to_process = encoder_session.total_samples_to_encode;
1556		if(encoder_session.skip > 0) {
1557			if(!FLAC__stream_decoder_seek_absolute(decoder, encoder_session.skip)) {
1558				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(decoder));
1559				goto fubar2; /*@@@ yuck */
1560			}
1561		}
1562
1563		/*
1564		 * now do samples from the file
1565		 */
1566		while(!decoder_data.fatal_error && decoder_data.samples_left_to_process > 0) {
1567			/* We can also hit the end of stream without samples_left_to_process
1568			 * going to 0 if there are errors and continue_through_decode_errors
1569			 * is on, so we want to break in that case too:
1570			 */
1571			if(encoder_session.continue_through_decode_errors && FLAC__stream_decoder_get_state(decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
1572				break;
1573			if(!FLAC__stream_decoder_process_single(decoder)) {
1574				flac__utils_printf(stderr, 1, "%s: ERROR: while decoding FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(decoder));
1575				goto fubar2; /*@@@ yuck */
1576			}
1577		}
1578		if(decoder_data.fatal_error) {
1579			flac__utils_printf(stderr, 1, "%s: ERROR: while decoding FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(decoder));
1580			goto fubar2; /*@@@ yuck */
1581		}
1582	}
1583
1584	FLAC__stream_decoder_delete(decoder);
1585	retval = EncoderSession_finish_ok(&encoder_session, -1, -1, /*foreign_metadata=*/0);
1586	/* have to wail until encoder is completely finished before deleting because of the final step of writing the seekpoint offsets */
1587	for(i = 0; i < decoder_data.num_metadata_blocks; i++)
1588		FLAC__metadata_object_delete(decoder_data.metadata_blocks[i]);
1589	return retval;
1590
1591fubar2:
1592	for(i = 0; i < decoder_data.num_metadata_blocks; i++)
1593		FLAC__metadata_object_delete(decoder_data.metadata_blocks[i]);
1594fubar1:
1595	FLAC__stream_decoder_delete(decoder);
1596	return EncoderSession_finish_error(&encoder_session);
1597}
1598
1599FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FILE *infile, const char *infilename, const char *outfilename)
1600{
1601	unsigned i;
1602	FLAC__uint32 test = 1;
1603
1604	/*
1605	 * initialize globals
1606	 */
1607
1608	is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
1609
1610	for(i = 0; i < FLAC__MAX_CHANNELS; i++)
1611		input_[i] = &(in_[i][0]);
1612
1613
1614	/*
1615	 * initialize instance
1616	 */
1617
1618#if FLAC__HAS_OGG
1619	e->use_ogg = use_ogg;
1620#else
1621	(void)use_ogg;
1622#endif
1623	e->verify = verify;
1624	e->treat_warnings_as_errors = treat_warnings_as_errors;
1625	e->continue_through_decode_errors = continue_through_decode_errors;
1626
1627	e->is_stdout = (0 == strcmp(outfilename, "-"));
1628	e->outputfile_opened = false;
1629
1630	e->inbasefilename = grabbag__file_get_basename(infilename);
1631	e->infilename = infilename;
1632	e->outfilename = outfilename;
1633
1634	e->skip = 0; /* filled in later after the sample_rate is known */
1635	e->unencoded_size = 0;
1636	e->total_samples_to_encode = 0;
1637	e->bytes_written = 0;
1638	e->samples_written = 0;
1639	e->stats_mask = 0;
1640
1641	e->encoder = 0;
1642
1643	e->fin = infile;
1644	e->seek_table_template = 0;
1645
1646	if(0 == (e->seek_table_template = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE))) {
1647		flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1648		return false;
1649	}
1650
1651	e->encoder = FLAC__stream_encoder_new();
1652	if(0 == e->encoder) {
1653		flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1654		EncoderSession_destroy(e);
1655		return false;
1656	}
1657
1658	return true;
1659}
1660
1661void EncoderSession_destroy(EncoderSession *e)
1662{
1663	if(e->fin != stdin)
1664		fclose(e->fin);
1665
1666	if(0 != e->encoder) {
1667		FLAC__stream_encoder_delete(e->encoder);
1668		e->encoder = 0;
1669	}
1670
1671	if(0 != e->seek_table_template) {
1672		FLAC__metadata_object_delete(e->seek_table_template);
1673		e->seek_table_template = 0;
1674	}
1675}
1676
1677int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero, foreign_metadata_t *foreign_metadata)
1678{
1679	FLAC__StreamEncoderState fse_state = FLAC__STREAM_ENCODER_OK;
1680	int ret = 0;
1681	FLAC__bool verify_error = false;
1682
1683	if(e->encoder) {
1684		fse_state = FLAC__stream_encoder_get_state(e->encoder);
1685		ret = FLAC__stream_encoder_finish(e->encoder)? 0 : 1;
1686		verify_error =
1687			fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA ||
1688			FLAC__stream_encoder_get_state(e->encoder) == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA
1689		;
1690	}
1691	/* all errors except verify errors should interrupt the stats */
1692	if(ret && !verify_error)
1693		print_error_with_state(e, "ERROR during encoding");
1694	else if(e->total_samples_to_encode > 0) {
1695		print_stats(e);
1696		flac__utils_printf(stderr, 2, "\n");
1697	}
1698
1699	if(verify_error) {
1700		print_verify_error(e);
1701		ret = 1;
1702	}
1703	else {
1704		if(info_align_carry >= 0) {
1705			flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d samples to be carried over\n", e->inbasefilename, info_align_carry);
1706		}
1707		if(info_align_zero >= 0) {
1708			flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d zero samples to be appended\n", e->inbasefilename, info_align_zero);
1709		}
1710	}
1711
1712	/*@@@@@@ should this go here or somewhere else? */
1713	if(ret == 0 && foreign_metadata) {
1714		const char *error;
1715		if(!flac__foreign_metadata_write_to_flac(foreign_metadata, e->infilename, e->outfilename, &error)) {
1716			flac__utils_printf(stderr, 1, "%s: ERROR: updating foreign metadata in FLAC file: %s\n", e->inbasefilename, error);
1717			ret = 1;
1718		}
1719	}
1720
1721	EncoderSession_destroy(e);
1722
1723	return ret;
1724}
1725
1726int EncoderSession_finish_error(EncoderSession *e)
1727{
1728	FLAC__ASSERT(e->encoder);
1729
1730	if(e->total_samples_to_encode > 0)
1731		flac__utils_printf(stderr, 2, "\n");
1732
1733	if(FLAC__stream_encoder_get_state(e->encoder) == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
1734		print_verify_error(e);
1735	else if(e->outputfile_opened)
1736		/* only want to delete the file if we opened it; otherwise it could be an existing file and our overwrite failed */
1737		unlink(e->outfilename);
1738
1739	EncoderSession_destroy(e);
1740
1741	return 1;
1742}
1743
1744typedef struct {
1745	unsigned num_metadata;
1746	FLAC__bool *needs_delete;
1747	FLAC__StreamMetadata **metadata;
1748	FLAC__StreamMetadata *cuesheet; /* always needs to be deleted */
1749} static_metadata_t;
1750
1751static void static_metadata_init(static_metadata_t *m)
1752{
1753	m->num_metadata = 0;
1754	m->needs_delete = 0;
1755	m->metadata = 0;
1756	m->cuesheet = 0;
1757}
1758
1759static void static_metadata_clear(static_metadata_t *m)
1760{
1761	unsigned i;
1762	for(i = 0; i < m->num_metadata; i++)
1763		if(m->needs_delete[i])
1764			FLAC__metadata_object_delete(m->metadata[i]);
1765	if(m->metadata)
1766		free(m->metadata);
1767	if(m->needs_delete)
1768		free(m->needs_delete);
1769	if(m->cuesheet)
1770		FLAC__metadata_object_delete(m->cuesheet);
1771	static_metadata_init(m);
1772}
1773
1774static FLAC__bool static_metadata_append(static_metadata_t *m, FLAC__StreamMetadata *d, FLAC__bool needs_delete)
1775{
1776	void *x;
1777	if(0 == (x = safe_realloc_muladd2_(m->metadata, sizeof(*m->metadata), /*times (*/m->num_metadata, /*+*/1/*)*/)))
1778		return false;
1779	m->metadata = (FLAC__StreamMetadata**)x;
1780	if(0 == (x = safe_realloc_muladd2_(m->needs_delete, sizeof(*m->needs_delete), /*times (*/m->num_metadata, /*+*/1/*)*/)))
1781		return false;
1782	m->needs_delete = (FLAC__bool*)x;
1783	m->metadata[m->num_metadata] = d;
1784	m->needs_delete[m->num_metadata] = needs_delete;
1785	m->num_metadata++;
1786	return true;
1787}
1788
1789FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, FLAC__uint32 channel_mask, unsigned channels, unsigned bps, unsigned sample_rate, const foreign_metadata_t *foreign_metadata, FLACDecoderData *flac_decoder_data)
1790{
1791	FLAC__StreamMetadata padding;
1792	FLAC__StreamMetadata **metadata = 0;
1793	static_metadata_t static_metadata;
1794	unsigned num_metadata = 0, i;
1795	FLAC__StreamEncoderInitStatus init_status;
1796	const FLAC__bool is_cdda = (channels == 1 || channels == 2) && (bps == 16) && (sample_rate == 44100);
1797	char apodizations[2000];
1798
1799	FLAC__ASSERT(sizeof(options.pictures)/sizeof(options.pictures[0]) <= 64);
1800
1801	static_metadata_init(&static_metadata);
1802
1803	e->replay_gain = options.replay_gain;
1804	e->channels = channels;
1805	e->bits_per_sample = bps;
1806	e->sample_rate = sample_rate;
1807
1808	apodizations[0] = '\0';
1809
1810	if(e->replay_gain) {
1811		if(channels != 1 && channels != 2) {
1812			flac__utils_printf(stderr, 1, "%s: ERROR, number of channels (%u) must be 1 or 2 for --replay-gain\n", e->inbasefilename, channels);
1813			return false;
1814		}
1815		if(!grabbag__replaygain_is_valid_sample_frequency(sample_rate)) {
1816			flac__utils_printf(stderr, 1, "%s: ERROR, invalid sample rate (%u) for --replay-gain\n", e->inbasefilename, sample_rate);
1817			return false;
1818		}
1819		if(options.is_first_file) {
1820			if(!grabbag__replaygain_init(sample_rate)) {
1821				flac__utils_printf(stderr, 1, "%s: ERROR initializing ReplayGain stage\n", e->inbasefilename);
1822				return false;
1823			}
1824		}
1825	}
1826
1827	if(!parse_cuesheet(&static_metadata.cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode, e->treat_warnings_as_errors))
1828		return false;
1829
1830	if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? static_metadata.cuesheet : 0, e)) {
1831		flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1832		static_metadata_clear(&static_metadata);
1833		return false;
1834	}
1835
1836	/* build metadata */
1837	if(flac_decoder_data) {
1838		/*
1839		 * we're encoding from FLAC so we will use the FLAC file's
1840		 * metadata as the basis for the encoded file
1841		 */
1842		{
1843			/*
1844			 * first handle pictures: simple append any --pictures
1845			 * specified.
1846			 */
1847			for(i = 0; i < options.num_pictures; i++) {
1848				FLAC__StreamMetadata *pic = FLAC__metadata_object_clone(options.pictures[i]);
1849				if(0 == pic) {
1850					flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PICTURE block\n", e->inbasefilename);
1851					static_metadata_clear(&static_metadata);
1852					return false;
1853				}
1854				flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks++] = pic;
1855			}
1856		}
1857		{
1858			/*
1859			 * next handle vorbis comment: if any tags were specified
1860			 * or there is no existing vorbis comment, we create a
1861			 * new vorbis comment (discarding any existing one); else
1862			 * we keep the existing one.  also need to make sure to
1863			 * propagate any channel mask tag.
1864			 */
1865			/* @@@ change to append -T values from options.vorbis_comment if input has VC already? */
1866			size_t i, j;
1867			FLAC__bool vc_found = false;
1868			for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1869				if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
1870					vc_found = true;
1871				if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT && options.vorbis_comment->data.vorbis_comment.num_comments > 0) {
1872					(void) flac__utils_get_channel_mask_tag(flac_decoder_data->metadata_blocks[i], &channel_mask);
1873					flac__utils_printf(stderr, 1, "%s: WARNING, replacing tags from input FLAC file with those given on the command-line\n", e->inbasefilename);
1874					if(e->treat_warnings_as_errors) {
1875						static_metadata_clear(&static_metadata);
1876						return false;
1877					}
1878					FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1879					flac_decoder_data->metadata_blocks[i] = 0;
1880				}
1881				else
1882					flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1883			}
1884			flac_decoder_data->num_metadata_blocks = j;
1885			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])) {
1886				/* prepend ours */
1887				FLAC__StreamMetadata *vc = FLAC__metadata_object_clone(options.vorbis_comment);
1888				if(0 == vc || (channel_mask && !flac__utils_set_channel_mask_tag(vc, channel_mask))) {
1889					flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for VORBIS_COMMENT block\n", e->inbasefilename);
1890					static_metadata_clear(&static_metadata);
1891					return false;
1892				}
1893				for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1894					flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1895				flac_decoder_data->metadata_blocks[1] = vc;
1896				flac_decoder_data->num_metadata_blocks++;
1897			}
1898		}
1899		{
1900			/*
1901			 * next handle cuesheet: if --cuesheet was specified, use
1902			 * it; else if file has existing CUESHEET and cuesheet's
1903			 * lead-out offset is correct, keep it; else no CUESHEET
1904			 */
1905			size_t i, j;
1906			for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1907				FLAC__bool existing_cuesheet_is_bad = false;
1908				/* check if existing cuesheet matches the input audio */
1909				if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && 0 == static_metadata.cuesheet) {
1910					const FLAC__StreamMetadata_CueSheet *cs = &flac_decoder_data->metadata_blocks[i]->data.cue_sheet;
1911					if(e->total_samples_to_encode == 0) {
1912						flac__utils_printf(stderr, 1, "%s: WARNING, cuesheet in input FLAC file cannot be kept if input size is not known, dropping it...\n", e->inbasefilename);
1913						if(e->treat_warnings_as_errors) {
1914							static_metadata_clear(&static_metadata);
1915							return false;
1916						}
1917						existing_cuesheet_is_bad = true;
1918					}
1919					else if(e->total_samples_to_encode != cs->tracks[cs->num_tracks-1].offset) {
1920						flac__utils_printf(stderr, 1, "%s: WARNING, lead-out offset of cuesheet in input FLAC file does not match input length, dropping existing cuesheet...\n", e->inbasefilename);
1921						if(e->treat_warnings_as_errors) {
1922							static_metadata_clear(&static_metadata);
1923							return false;
1924						}
1925						existing_cuesheet_is_bad = true;
1926					}
1927				}
1928				if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != static_metadata.cuesheet)) {
1929					if(0 != static_metadata.cuesheet) {
1930						flac__utils_printf(stderr, 1, "%s: WARNING, replacing cuesheet in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1931						if(e->treat_warnings_as_errors) {
1932							static_metadata_clear(&static_metadata);
1933							return false;
1934						}
1935					}
1936					FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1937					flac_decoder_data->metadata_blocks[i] = 0;
1938				}
1939				else
1940					flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1941			}
1942			flac_decoder_data->num_metadata_blocks = j;
1943			if(0 != static_metadata.cuesheet && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1944				/* prepend ours */
1945				FLAC__StreamMetadata *cs = FLAC__metadata_object_clone(static_metadata.cuesheet);
1946				if(0 == cs) {
1947					flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for CUESHEET block\n", e->inbasefilename);
1948					static_metadata_clear(&static_metadata);
1949					return false;
1950				}
1951				for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1952					flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1953				flac_decoder_data->metadata_blocks[1] = cs;
1954				flac_decoder_data->num_metadata_blocks++;
1955			}
1956		}
1957		{
1958			/*
1959			 * next handle seektable: if -S- was specified, no
1960			 * SEEKTABLE; else if -S was specified, use it/them;
1961			 * else if file has existing SEEKTABLE and input size is
1962			 * preserved (no --skip/--until/etc specified), keep it;
1963			 * else use default seektable options
1964			 *
1965			 * note: meanings of num_requested_seek_points:
1966			 *  -1 : no -S option given, default to some value
1967			 *   0 : -S- given (no seektable)
1968			 *  >0 : one or more -S options given
1969			 */
1970			size_t i, j;
1971			FLAC__bool existing_seektable = false;
1972			for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1973				if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE)
1974					existing_seektable = true;
1975				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)) {
1976					if(options.num_requested_seek_points > 0) {
1977						flac__utils_printf(stderr, 1, "%s: WARNING, replacing seektable in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1978						if(e->treat_warnings_as_errors) {
1979							static_metadata_clear(&static_metadata);
1980							return false;
1981						}
1982					}
1983					else if(options.num_requested_seek_points == 0)
1984						; /* no warning, silently delete existing SEEKTABLE since user specified --no-seektable (-S-) */
1985					else {
1986						flac__utils_printf(stderr, 1, "%s: WARNING, can't use existing seektable in input FLAC since the input size is changing or unknown, dropping existing SEEKTABLE block...\n", e->inbasefilename);
1987						if(e->treat_warnings_as_errors) {
1988							static_metadata_clear(&static_metadata);
1989							return false;
1990						}
1991					}
1992					FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1993					flac_decoder_data->metadata_blocks[i] = 0;
1994					existing_seektable = false;
1995				}
1996				else
1997					flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1998			}
1999			flac_decoder_data->num_metadata_blocks = j;
2000			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])) {
2001				/* prepend ours */
2002				FLAC__StreamMetadata *st = FLAC__metadata_object_clone(e->seek_table_template);
2003				if(0 == st) {
2004					flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for SEEKTABLE block\n", e->inbasefilename);
2005					static_metadata_clear(&static_metadata);
2006					return false;
2007				}
2008				for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
2009					flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
2010				flac_decoder_data->metadata_blocks[1] = st;
2011				flac_decoder_data->num_metadata_blocks++;
2012			}
2013		}
2014		{
2015			/*
2016			 * finally handle padding: if --no-padding was specified,
2017			 * then delete all padding; else if -P was specified,
2018			 * use that instead of existing padding (if any); else
2019			 * if existing file has padding, move all existing
2020			 * padding blocks to one padding block at the end; else
2021			 * use default padding.
2022			 */
2023			int p = -1;
2024			size_t i, j;
2025			for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
2026				if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_PADDING) {
2027					if(p < 0)
2028						p = 0;
2029					p += flac_decoder_data->metadata_blocks[i]->length;
2030					FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
2031					flac_decoder_data->metadata_blocks[i] = 0;
2032				}
2033				else
2034					flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
2035			}
2036			flac_decoder_data->num_metadata_blocks = j;
2037			if(options.padding > 0)
2038				p = options.padding;
2039			if(p < 0)
2040				p = e->total_samples_to_encode / e->sample_rate < 20*60? FLAC_ENCODE__DEFAULT_PADDING : FLAC_ENCODE__DEFAULT_PADDING*8;
2041			if(options.padding != 0) {
2042				if(p > 0 && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
2043					flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
2044					if(0 == flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]) {
2045						flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PADDING block\n", e->inbasefilename);
2046						static_metadata_clear(&static_metadata);
2047						return false;
2048					}
2049					flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->is_last = false; /* the encoder will set this for us */
2050					flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->length = p;
2051					flac_decoder_data->num_metadata_blocks++;
2052				}
2053			}
2054		}
2055		metadata = &flac_decoder_data->metadata_blocks[1]; /* don't include STREAMINFO */
2056		num_metadata = flac_decoder_data->num_metadata_blocks - 1;
2057	}
2058	else {
2059		/*
2060		 * we're not encoding from FLAC so we will build the metadata
2061		 * from scratch
2062		 */
2063		if(e->seek_table_template->data.seek_table.num_points > 0) {
2064			e->seek_table_template->is_last = false; /* the encoder will set this for us */
2065			static_metadata_append(&static_metadata, e->seek_table_template, /*needs_delete=*/false);
2066		}
2067		if(0 != static_metadata.cuesheet)
2068			static_metadata_append(&static_metadata, static_metadata.cuesheet, /*needs_delete=*/false);
2069		if(channel_mask) {
2070			if(!flac__utils_set_channel_mask_tag(options.vorbis_comment, channel_mask)) {
2071				flac__utils_printf(stderr, 1, "%s: ERROR adding channel mask tag\n", e->inbasefilename);
2072				static_metadata_clear(&static_metadata);
2073				return false;
2074			}
2075		}
2076		static_metadata_append(&static_metadata, options.vorbis_comment, /*needs_delete=*/false);
2077		for(i = 0; i < options.num_pictures; i++)
2078			static_metadata_append(&static_metadata, options.pictures[i], /*needs_delete=*/false);
2079		if(foreign_metadata) {
2080			for(i = 0; i < foreign_metadata->num_blocks; i++) {
2081				FLAC__StreamMetadata *p = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
2082				if(!p) {
2083					flac__utils_printf(stderr, 1, "%s: ERROR: out of memory\n", e->inbasefilename);
2084					static_metadata_clear(&static_metadata);
2085					return false;
2086				}
2087				static_metadata_append(&static_metadata, p, /*needs_delete=*/true);
2088				static_metadata.metadata[static_metadata.num_metadata-1]->length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8 + foreign_metadata->blocks[i].size;
2089/*fprintf(stderr,"@@@@@@ add PADDING=%u\n",static_metadata.metadata[static_metadata.num_metadata-1]->length);*/
2090			}
2091		}
2092		if(options.padding != 0) {
2093			padding.is_last = false; /* the encoder will set this for us */
2094			padding.type = FLAC__METADATA_TYPE_PADDING;
2095			padding.length = (unsigned)(options.padding>0? options.padding : (e->total_samples_to_encode / e->sample_rate < 20*60? FLAC_ENCODE__DEFAULT_PADDING : FLAC_ENCODE__DEFAULT_PADDING*8));
2096			static_metadata_append(&static_metadata, &padding, /*needs_delete=*/false);
2097		}
2098		metadata = static_metadata.metadata;
2099		num_metadata = static_metadata.num_metadata;
2100	}
2101
2102	/* check for a few things that have not already been checked.  the
2103	 * FLAC__stream_encoder_init*() will check it but only return
2104	 * FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA so we check some
2105	 * up front to give a better error message.
2106	 */
2107	if(!verify_metadata(e, metadata, num_metadata)) {
2108		static_metadata_clear(&static_metadata);
2109		return false;
2110	}
2111
2112	FLAC__stream_encoder_set_verify(e->encoder, options.verify);
2113	FLAC__stream_encoder_set_streamable_subset(e->encoder, !options.lax);
2114	FLAC__stream_encoder_set_channels(e->encoder, channels);
2115	FLAC__stream_encoder_set_bits_per_sample(e->encoder, bps);
2116	FLAC__stream_encoder_set_sample_rate(e->encoder, sample_rate);
2117	for(i = 0; i < options.num_compression_settings; i++) {
2118		switch(options.compression_settings[i].type) {
2119			case CST_BLOCKSIZE:
2120				FLAC__stream_encoder_set_blocksize(e->encoder, options.compression_settings[i].value.t_unsigned);
2121				break;
2122			case CST_COMPRESSION_LEVEL:
2123				FLAC__stream_encoder_set_compression_level(e->encoder, options.compression_settings[i].value.t_unsigned);
2124				apodizations[0] = '\0';
2125				break;
2126			case CST_DO_MID_SIDE:
2127				FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder, options.compression_settings[i].value.t_bool);
2128				break;
2129			case CST_LOOSE_MID_SIDE:
2130				FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder, options.compression_settings[i].value.t_bool);
2131				break;
2132			case CST_APODIZATION:
2133				if(strlen(apodizations)+strlen(options.compression_settings[i].value.t_string)+2 >= sizeof(apodizations)) {
2134					flac__utils_printf(stderr, 1, "%s: ERROR: too many apodization functions requested\n", e->inbasefilename);
2135					static_metadata_clear(&static_metadata);
2136					return false;
2137				}
2138				else {
2139					strcat(apodizations, options.compression_settings[i].value.t_string);
2140					strcat(apodizations, ";");
2141				}
2142				break;
2143			case CST_MAX_LPC_ORDER:
2144				FLAC__stream_encoder_set_max_lpc_order(e->encoder, options.compression_settings[i].value.t_unsigned);
2145				break;
2146			case CST_QLP_COEFF_PRECISION:
2147				FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder, options.compression_settings[i].value.t_unsigned);
2148				break;
2149			case CST_DO_QLP_COEFF_PREC_SEARCH:
2150				FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder, options.compression_settings[i].value.t_bool);
2151				break;
2152			case CST_DO_ESCAPE_CODING:
2153				FLAC__stream_encoder_set_do_escape_coding(e->encoder, options.compression_settings[i].value.t_bool);
2154				break;
2155			case CST_DO_EXHAUSTIVE_MODEL_SEARCH:
2156				FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder, options.compression_settings[i].value.t_bool);
2157				break;
2158			case CST_MIN_RESIDUAL_PARTITION_ORDER:
2159				FLAC__stream_encoder_set_min_residual_partition_order(e->encoder, options.compression_settings[i].value.t_unsigned);
2160				break;
2161			case CST_MAX_RESIDUAL_PARTITION_ORDER:
2162				FLAC__stream_encoder_set_max_residual_partition_order(e->encoder, options.compression_settings[i].value.t_unsigned);
2163				break;
2164			case CST_RICE_PARAMETER_SEARCH_DIST:
2165				FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder, options.compression_settings[i].value.t_unsigned);
2166				break;
2167		}
2168	}
2169	if(*apodizations)
2170		FLAC__stream_encoder_set_apodization(e->encoder, apodizations);
2171	FLAC__stream_encoder_set_total_samples_estimate(e->encoder, e->total_samples_to_encode);
2172	FLAC__stream_encoder_set_metadata(e->encoder, (num_metadata > 0)? metadata : 0, num_metadata);
2173
2174	FLAC__stream_encoder_disable_constant_subframes(e->encoder, options.debug.disable_constant_subframes);
2175	FLAC__stream_encoder_disable_fixed_subframes(e->encoder, options.debug.disable_fixed_subframes);
2176	FLAC__stream_encoder_disable_verbatim_subframes(e->encoder, options.debug.disable_verbatim_subframes);
2177	if(!options.debug.do_md5) {
2178		flac__utils_printf(stderr, 1, "%s: WARNING, MD5 computation disabled, resulting file will not have MD5 sum\n", e->inbasefilename);
2179		if(e->treat_warnings_as_errors) {
2180			static_metadata_clear(&static_metadata);
2181			return false;
2182		}
2183		FLAC__stream_encoder_set_do_md5(e->encoder, false);
2184	}
2185
2186#if FLAC__HAS_OGG
2187	if(e->use_ogg) {
2188		FLAC__stream_encoder_set_ogg_serial_number(e->encoder, options.serial_number);
2189
2190		init_status = FLAC__stream_encoder_init_ogg_file(e->encoder, e->is_stdout? 0 : e->outfilename, encoder_progress_callback, /*client_data=*/e);
2191	}
2192	else
2193#endif
2194	{
2195		init_status = FLAC__stream_encoder_init_file(e->encoder, e->is_stdout? 0 : e->outfilename, encoder_progress_callback, /*client_data=*/e);
2196	}
2197
2198	if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
2199		print_error_with_init_status(e, "ERROR initializing encoder", init_status);
2200		if(FLAC__stream_encoder_get_state(e->encoder) != FLAC__STREAM_ENCODER_IO_ERROR)
2201			e->outputfile_opened = true;
2202		static_metadata_clear(&static_metadata);
2203		return false;
2204	}
2205	else
2206		e->outputfile_opened = true;
2207
2208	e->stats_mask =
2209		(FLAC__stream_encoder_get_do_exhaustive_model_search(e->encoder) && FLAC__stream_encoder_get_do_qlp_coeff_prec_search(e->encoder))? 0x07 :
2210		(FLAC__stream_encoder_get_do_exhaustive_model_search(e->encoder) || FLAC__stream_encoder_get_do_qlp_coeff_prec_search(e->encoder))? 0x0f :
2211		0x3f;
2212
2213	static_metadata_clear(&static_metadata);
2214
2215	return true;
2216}
2217
2218FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples)
2219{
2220	if(e->replay_gain) {
2221		if(!grabbag__replaygain_analyze(buffer, e->channels==2, e->bits_per_sample, samples)) {
2222			flac__utils_printf(stderr, 1, "%s: WARNING, error while calculating ReplayGain\n", e->inbasefilename);
2223			if(e->treat_warnings_as_errors)
2224				return false;
2225		}
2226	}
2227
2228	return FLAC__stream_encoder_process(e->encoder, buffer, samples);
2229}
2230
2231FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e)
2232{
2233	const FLAC__bool only_placeholders = e->is_stdout;
2234	FLAC__bool has_real_points;
2235
2236	if(num_requested_seek_points == 0 && 0 == cuesheet)
2237		return true;
2238
2239	if(num_requested_seek_points < 0) {
2240#if FLAC__HAS_OGG
2241		/*@@@@@@ workaround ogg bug: too many seekpoints makes table not fit in one page */
2242		if(e->use_ogg && e->total_samples_to_encode > 0 && e->total_samples_to_encode / e->sample_rate / 10 > 230)
2243			requested_seek_points = "230x;";
2244		else
2245#endif
2246			requested_seek_points = "10s;";
2247		num_requested_seek_points = 1;
2248	}
2249
2250	if(num_requested_seek_points > 0) {
2251		if(!grabbag__seektable_convert_specification_to_template(requested_seek_points, only_placeholders, e->total_samples_to_encode, e->sample_rate, e->seek_table_template, &has_real_points))
2252			return false;
2253	}
2254
2255	if(0 != cuesheet) {
2256		unsigned i, j;
2257		const FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
2258		for(i = 0; i < cs->num_tracks; i++) {
2259			const FLAC__StreamMetadata_CueSheet_Track *tr = cs->tracks+i;
2260			for(j = 0; j < tr->num_indices; j++) {
2261				if(!FLAC__metadata_object_seektable_template_append_point(e->seek_table_template, tr->offset + tr->indices[j].offset))
2262					return false;
2263				has_real_points = true;
2264			}
2265		}
2266		if(has_real_points)
2267			if(!FLAC__metadata_object_seektable_template_sort(e->seek_table_template, /*compact=*/true))
2268				return false;
2269	}
2270
2271	if(has_real_points) {
2272		if(e->is_stdout) {
2273			flac__utils_printf(stderr, 1, "%s: WARNING, cannot write back seekpoints when encoding to stdout\n", e->inbasefilename);
2274			if(e->treat_warnings_as_errors)
2275				return false;
2276		}
2277	}
2278
2279	return true;
2280}
2281
2282FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
2283{
2284	/* convert from mm:ss.sss to sample number if necessary */
2285	flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
2286
2287	/* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
2288	if(spec->is_relative && spec->value.samples == 0) {
2289		spec->is_relative = false;
2290		return true;
2291	}
2292
2293	/* in any other case the total samples in the input must be known */
2294	if(total_samples_in_input == 0) {
2295		flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when input length is unknown\n", inbasefilename);
2296		return false;
2297	}
2298
2299	FLAC__ASSERT(spec->value_is_samples);
2300
2301	/* convert relative specifications to absolute */
2302	if(spec->is_relative) {
2303		if(spec->value.samples <= 0)
2304			spec->value.samples += (FLAC__int64)total_samples_in_input;
2305		else
2306			spec->value.samples += skip;
2307		spec->is_relative = false;
2308	}
2309
2310	/* error check */
2311	if(spec->value.samples < 0) {
2312		flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
2313		return false;
2314	}
2315	if((FLAC__uint64)spec->value.samples <= skip) {
2316		flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
2317		return false;
2318	}
2319	if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
2320		flac__utils_printf(stderr, 1, "%s: ERROR, --until value is after end of input\n", inbasefilename);
2321		return false;
2322	}
2323
2324	return true;
2325}
2326
2327FLAC__bool verify_metadata(const EncoderSession *e, FLAC__StreamMetadata **metadata, unsigned num_metadata)
2328{
2329	FLAC__bool metadata_picture_has_type1 = false;
2330	FLAC__bool metadata_picture_has_type2 = false;
2331	unsigned i;
2332
2333	FLAC__ASSERT(0 != metadata);
2334	for(i = 0; i < num_metadata; i++) {
2335		const FLAC__StreamMetadata *m = metadata[i];
2336		if(m->type == FLAC__METADATA_TYPE_SEEKTABLE) {
2337			if(!FLAC__format_seektable_is_legal(&m->data.seek_table)) {
2338				flac__utils_printf(stderr, 1, "%s: ERROR: SEEKTABLE metadata block is invalid\n", e->inbasefilename);
2339				return false;
2340			}
2341		}
2342		else if(m->type == FLAC__METADATA_TYPE_CUESHEET) {
2343			if(!FLAC__format_cuesheet_is_legal(&m->data.cue_sheet, m->data.cue_sheet.is_cd, /*violation=*/0)) {
2344				flac__utils_printf(stderr, 1, "%s: ERROR: CUESHEET metadata block is invalid\n", e->inbasefilename);
2345				return false;
2346			}
2347		}
2348		else if(m->type == FLAC__METADATA_TYPE_PICTURE) {
2349			const char *error = 0;
2350			if(!FLAC__format_picture_is_legal(&m->data.picture, &error)) {
2351				flac__utils_printf(stderr, 1, "%s: ERROR: PICTURE metadata block is invalid: %s\n", e->inbasefilename, error);
2352				return false;
2353			}
2354			if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD) {
2355				if(metadata_picture_has_type1) {
2356					flac__utils_printf(stderr, 1, "%s: ERROR: there may only be one picture of type 1 (32x32 icon) in the file\n", e->inbasefilename);
2357					return false;
2358				}
2359				metadata_picture_has_type1 = true;
2360			}
2361			else if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON) {
2362				if(metadata_picture_has_type2) {
2363					flac__utils_printf(stderr, 1, "%s: ERROR: there may only be one picture of type 2 (icon) in the file\n", e->inbasefilename);
2364					return false;
2365				}
2366				metadata_picture_has_type2 = true;
2367			}
2368		}
2369	}
2370
2371	return true;
2372}
2373
2374FLAC__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)
2375{
2376	unsigned wide_sample, sample, channel, byte;
2377	FLAC__int32 *out[FLAC__MAX_CHANNELS];
2378
2379	if(0 == channel_map) {
2380		for(channel = 0; channel < channels; channel++)
2381			out[channel] = dest[channel];
2382	}
2383	else {
2384		for(channel = 0; channel < channels; channel++)
2385			out[channel] = dest[channel_map[channel]];
2386	}
2387
2388	if(bps == 8) {
2389		if(is_unsigned_samples) {
2390			for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2391				for(channel = 0; channel < channels; channel++, sample++)
2392					out[channel][wide_sample] = (FLAC__int32)ucbuffer_[sample] - 0x80;
2393		}
2394		else {
2395			for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2396				for(channel = 0; channel < channels; channel++, sample++)
2397					out[channel][wide_sample] = (FLAC__int32)scbuffer_[sample];
2398		}
2399	}
2400	else if(bps == 16) {
2401		if(is_big_endian != is_big_endian_host_) {
2402			unsigned char tmp;
2403			const unsigned bytes = wide_samples * channels * (bps >> 3);
2404			for(byte = 0; byte < bytes; byte += 2) {
2405				tmp = ucbuffer_[byte];
2406				ucbuffer_[byte] = ucbuffer_[byte+1];
2407				ucbuffer_[byte+1] = tmp;
2408			}
2409		}
2410		if(is_unsigned_samples) {
2411			for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2412				for(channel = 0; channel < channels; channel++, sample++)
2413					out[channel][wide_sample] = (FLAC__int32)usbuffer_[sample] - 0x8000;
2414		}
2415		else {
2416			for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2417				for(channel = 0; channel < channels; channel++, sample++)
2418					out[channel][wide_sample] = (FLAC__int32)ssbuffer_[sample];
2419		}
2420	}
2421	else if(bps == 24) {
2422		if(!is_big_endian) {
2423			unsigned char tmp;
2424			const unsigned bytes = wide_samples * channels * (bps >> 3);
2425			for(byte = 0; byte < bytes; byte += 3) {
2426				tmp = ucbuffer_[byte];
2427				ucbuffer_[byte] = ucbuffer_[byte+2];
2428				ucbuffer_[byte+2] = tmp;
2429			}
2430		}
2431		if(is_unsigned_samples) {
2432			for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2433				for(channel = 0; channel < channels; channel++, sample++) {
2434					out[channel][wide_sample]  = ucbuffer_[byte++]; out[channel][wide_sample] <<= 8;
2435					out[channel][wide_sample] |= ucbuffer_[byte++]; out[channel][wide_sample] <<= 8;
2436					out[channel][wide_sample] |= ucbuffer_[byte++];
2437					out[channel][wide_sample] -= 0x800000;
2438				}
2439		}
2440		else {
2441			for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2442				for(channel = 0; channel < channels; channel++, sample++) {
2443					out[channel][wide_sample]  = scbuffer_[byte++]; out[channel][wide_sample] <<= 8;
2444					out[channel][wide_sample] |= ucbuffer_[byte++]; out[channel][wide_sample] <<= 8;
2445					out[channel][wide_sample] |= ucbuffer_[byte++];
2446				}
2447		}
2448	}
2449	else {
2450		FLAC__ASSERT(0);
2451	}
2452	if(shift > 0) {
2453		FLAC__int32 mask = (1<<shift)-1;
2454		for(wide_sample = 0; wide_sample < wide_samples; wide_sample++)
2455			for(channel = 0; channel < channels; channel++) {
2456				if(out[channel][wide_sample] & mask) {
2457					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);
2458					return false;
2459				}
2460				out[channel][wide_sample] >>= shift;
2461			}
2462	}
2463	return true;
2464}
2465
2466void 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)
2467{
2468	EncoderSession *encoder_session = (EncoderSession*)client_data;
2469
2470	(void)encoder, (void)total_frames_estimate;
2471
2472	encoder_session->bytes_written = bytes_written;
2473	encoder_session->samples_written = samples_written;
2474
2475	if(encoder_session->total_samples_to_encode > 0 && !((frames_written-1) & encoder_session->stats_mask))
2476		print_stats(encoder_session);
2477}
2478
2479FLAC__StreamDecoderReadStatus flac_decoder_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
2480{
2481	size_t n = 0;
2482	FLACDecoderData *data = (FLACDecoderData*)client_data;
2483	(void)decoder;
2484
2485	if (data->fatal_error)
2486		return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
2487
2488	/* use up lookahead first */
2489	if (data->lookahead_length) {
2490		n = min(data->lookahead_length, *bytes);
2491		memcpy(buffer, data->lookahead, n);
2492		buffer += n;
2493		data->lookahead += n;
2494		data->lookahead_length -= n;
2495	}
2496
2497	/* get the rest from file */
2498	if (*bytes > n) {
2499		*bytes = n + fread(buffer, 1, *bytes-n, data->encoder_session->fin);
2500		if(ferror(data->encoder_session->fin))
2501			return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
2502		else if(0 == *bytes)
2503			return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
2504		else
2505			return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
2506	}
2507	else
2508		return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
2509}
2510
2511FLAC__StreamDecoderSeekStatus flac_decoder_seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
2512{
2513	FLACDecoderData *data = (FLACDecoderData*)client_data;
2514	(void)decoder;
2515
2516	if(fseeko(data->encoder_session->fin, (off_t)absolute_byte_offset, SEEK_SET) < 0)
2517		return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
2518	else
2519		return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
2520}
2521
2522FLAC__StreamDecoderTellStatus flac_decoder_tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
2523{
2524	FLACDecoderData *data = (FLACDecoderData*)client_data;
2525	off_t pos;
2526	(void)decoder;
2527
2528	if((pos = ftello(data->encoder_session->fin)) < 0)
2529		return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
2530	else {
2531		*absolute_byte_offset = (FLAC__uint64)pos;
2532		return FLAC__STREAM_DECODER_TELL_STATUS_OK;
2533	}
2534}
2535
2536FLAC__StreamDecoderLengthStatus flac_decoder_length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
2537{
2538	FLACDecoderData *data = (FLACDecoderData*)client_data;
2539	(void)decoder;
2540
2541	if(0 == data->filesize)
2542		return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
2543	else {
2544		*stream_length = (FLAC__uint64)data->filesize;
2545		return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
2546	}
2547}
2548
2549FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
2550{
2551	FLACDecoderData *data = (FLACDecoderData*)client_data;
2552	(void)decoder;
2553
2554	return feof(data->encoder_session->fin)? true : false;
2555}
2556
2557FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
2558{
2559	FLACDecoderData *data = (FLACDecoderData*)client_data;
2560	FLAC__uint64 n = min(data->samples_left_to_process, frame->header.blocksize);
2561	(void)decoder;
2562
2563	if(!EncoderSession_process(data->encoder_session, buffer, (unsigned)n)) {
2564		print_error_with_state(data->encoder_session, "ERROR during encoding");
2565		data->fatal_error = true;
2566		return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
2567	}
2568
2569	data->samples_left_to_process -= n;
2570	return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
2571}
2572
2573void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
2574{
2575	FLACDecoderData *data = (FLACDecoderData*)client_data;
2576	(void)decoder;
2577
2578	if (data->fatal_error)
2579		return;
2580
2581	if (
2582		data->num_metadata_blocks == sizeof(data->metadata_blocks)/sizeof(data->metadata_blocks[0]) ||
2583		0 == (data->metadata_blocks[data->num_metadata_blocks] = FLAC__metadata_object_clone(metadata))
2584	)
2585		data->fatal_error = true;
2586	else
2587		data->num_metadata_blocks++;
2588}
2589
2590void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
2591{
2592	FLACDecoderData *data = (FLACDecoderData*)client_data;
2593	(void)decoder;
2594
2595	flac__utils_printf(stderr, 1, "%s: ERROR got %s while decoding FLAC input\n", data->encoder_session->inbasefilename, FLAC__StreamDecoderErrorStatusString[status]);
2596	if(!data->encoder_session->continue_through_decode_errors)
2597		data->fatal_error = true;
2598}
2599
2600FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset, FLAC__bool treat_warnings_as_errors)
2601{
2602	FILE *f;
2603	unsigned last_line_read;
2604	const char *error_message;
2605
2606	if(0 == cuesheet_filename)
2607		return true;
2608
2609	if(lead_out_offset == 0) {
2610		flac__utils_printf(stderr, 1, "%s: ERROR cannot import cuesheet when the number of input samples to encode is unknown\n", inbasefilename);
2611		return false;
2612	}
2613
2614	if(0 == (f = fopen(cuesheet_filename, "r"))) {
2615		flac__utils_printf(stderr, 1, "%s: ERROR opening cuesheet \"%s\" for reading: %s\n", inbasefilename, cuesheet_filename, strerror(errno));
2616		return false;
2617	}
2618
2619	*cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, is_cdda, lead_out_offset);
2620
2621	fclose(f);
2622
2623	if(0 == *cuesheet) {
2624		flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\" on line %u: %s\n", inbasefilename, cuesheet_filename, last_line_read, error_message);
2625		return false;
2626	}
2627
2628	if(!FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/false, &error_message)) {
2629		flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\": %s\n", inbasefilename, cuesheet_filename, error_message);
2630		return false;
2631	}
2632
2633	/* if we're expecting CDDA, warn about non-compliance */
2634	if(is_cdda && !FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/true, &error_message)) {
2635		flac__utils_printf(stderr, 1, "%s: WARNING cuesheet \"%s\" is not audio CD compliant: %s\n", inbasefilename, cuesheet_filename, error_message);
2636		if(treat_warnings_as_errors)
2637			return false;
2638		(*cuesheet)->data.cue_sheet.is_cd = false;
2639	}
2640
2641	return true;
2642}
2643
2644void print_stats(const EncoderSession *encoder_session)
2645{
2646	const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written);
2647#if defined _MSC_VER || defined __MINGW32__
2648	/* with MSVC you have to spoon feed it the casting */
2649	const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode;
2650	const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)encoder_session->unencoded_size * min(1.0, progress));
2651#else
2652	const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode;
2653	const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * min(1.0, progress));
2654#endif
2655
2656	FLAC__ASSERT(encoder_session->total_samples_to_encode > 0);
2657
2658	if(samples_written == encoder_session->total_samples_to_encode) {
2659		flac__utils_printf(stderr, 2, "\r%s:%s wrote %u bytes, ratio=%0.3f",
2660			encoder_session->inbasefilename,
2661			encoder_session->verify? " Verify OK," : "",
2662			(unsigned)encoder_session->bytes_written,
2663			ratio
2664		);
2665	}
2666	else {
2667		flac__utils_printf(stderr, 2, "\r%s: %u%% complete, ratio=%0.3f", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio);
2668	}
2669}
2670
2671void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status)
2672{
2673	const int ilen = strlen(e->inbasefilename) + 1;
2674	const char *state_string = "";
2675
2676	flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
2677
2678	flac__utils_printf(stderr, 1, "%*s init_status = %s\n", ilen, "", FLAC__StreamEncoderInitStatusString[init_status]);
2679
2680	if(init_status == FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR) {
2681		state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder);
2682
2683		flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
2684
2685		/* print out some more info for some errors: */
2686		if(0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_CLIENT_ERROR])) {
2687			flac__utils_printf(stderr, 1,
2688				"\n"
2689				"An error occurred while writing; the most common cause is that the disk is full.\n"
2690			);
2691		}
2692		else if(0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_IO_ERROR])) {
2693			flac__utils_printf(stderr, 1,
2694				"\n"
2695				"An error occurred opening the output file; it is likely that the output\n"
2696				"directory does not exist or is not writable, the output file already exists and\n"
2697				"is not writable, or the disk is full.\n"
2698			);
2699		}
2700	}
2701	else if(init_status == FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE) {
2702		flac__utils_printf(stderr, 1,
2703			"\n"
2704			"The encoding parameters specified do not conform to the FLAC Subset and may not\n"
2705			"be streamable or playable in hardware devices.  If you really understand the\n"
2706			"consequences, you can add --lax to the command-line options to encode with\n"
2707			"these parameters anyway.  See http://flac.sourceforge.net/format.html#subset\n"
2708		);
2709	}
2710}
2711
2712void print_error_with_state(const EncoderSession *e, const char *message)
2713{
2714	const int ilen = strlen(e->inbasefilename) + 1;
2715	const char *state_string;
2716
2717	flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
2718
2719	state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder);
2720
2721	flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
2722
2723	/* print out some more info for some errors: */
2724	if(0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_CLIENT_ERROR])) {
2725		flac__utils_printf(stderr, 1,
2726			"\n"
2727			"An error occurred while writing; the most common cause is that the disk is full.\n"
2728		);
2729	}
2730}
2731
2732void print_verify_error(EncoderSession *e)
2733{
2734	FLAC__uint64 absolute_sample;
2735	unsigned frame_number;
2736	unsigned channel;
2737	unsigned sample;
2738	FLAC__int32 expected;
2739	FLAC__int32 got;
2740
2741	FLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2742
2743	flac__utils_printf(stderr, 1, "%s: ERROR: mismatch in decoded data, verify FAILED!\n", e->inbasefilename);
2744	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);
2745	flac__utils_printf(stderr, 1, "       In all known cases, verify errors are caused by hardware problems,\n");
2746	flac__utils_printf(stderr, 1, "       usually overclocking or bad RAM.  Delete %s\n", e->outfilename);
2747	flac__utils_printf(stderr, 1, "       and repeat the flac command exactly as before.  If it does not give a\n");
2748	flac__utils_printf(stderr, 1, "       verify error in the exact same place each time you try it, then there is\n");
2749	flac__utils_printf(stderr, 1, "       a problem with your hardware; please see the FAQ:\n");
2750	flac__utils_printf(stderr, 1, "           http://flac.sourceforge.net/faq.html#tools__hardware_prob\n");
2751	flac__utils_printf(stderr, 1, "       If it does fail in the exact same place every time, keep\n");
2752	flac__utils_printf(stderr, 1, "       %s and submit a bug report to:\n", e->outfilename);
2753	flac__utils_printf(stderr, 1, "           https://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
2754	flac__utils_printf(stderr, 1, "       Make sure to upload the FLAC file and use the \"Monitor\" feature to\n");
2755	flac__utils_printf(stderr, 1, "       monitor the bug status.\n");
2756	flac__utils_printf(stderr, 1, "Verify FAILED!  Do not trust %s\n", e->outfilename);
2757}
2758
2759FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2760{
2761	size_t bytes_read = fread(val, 1, 2, f);
2762
2763	if(bytes_read == 0) {
2764		if(!eof_ok) {
2765			flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2766			return false;
2767		}
2768		else
2769			return true;
2770	}
2771	else if(bytes_read < 2) {
2772		flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2773		return false;
2774	}
2775	else {
2776		if(is_big_endian_host_) {
2777			FLAC__byte tmp, *b = (FLAC__byte*)val;
2778			tmp = b[1]; b[1] = b[0]; b[0] = tmp;
2779		}
2780		return true;
2781	}
2782}
2783
2784FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2785{
2786	size_t bytes_read = fread(val, 1, 4, f);
2787
2788	if(bytes_read == 0) {
2789		if(!eof_ok) {
2790			flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2791			return false;
2792		}
2793		else
2794			return true;
2795	}
2796	else if(bytes_read < 4) {
2797		flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2798		return false;
2799	}
2800	else {
2801		if(is_big_endian_host_) {
2802			FLAC__byte tmp, *b = (FLAC__byte*)val;
2803			tmp = b[3]; b[3] = b[0]; b[0] = tmp;
2804			tmp = b[2]; b[2] = b[1]; b[1] = tmp;
2805		}
2806		return true;
2807	}
2808}
2809
2810FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2811{
2812	unsigned char buf[4];
2813	size_t bytes_read= fread(buf, 1, 2, f);
2814
2815	if(bytes_read==0U && eof_ok)
2816		return true;
2817	else if(bytes_read<2U) {
2818		flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2819		return false;
2820	}
2821
2822	/* this is independent of host endianness */
2823	*val= (FLAC__uint16)(buf[0])<<8 | buf[1];
2824
2825	return true;
2826}
2827
2828FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2829{
2830	unsigned char buf[4];
2831	size_t bytes_read= fread(buf, 1, 4, f);
2832
2833	if(bytes_read==0U && eof_ok)
2834		return true;
2835	else if(bytes_read<4U) {
2836		flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2837		return false;
2838	}
2839
2840	/* this is independent of host endianness */
2841	*val= (FLAC__uint32)(buf[0])<<24 | (FLAC__uint32)(buf[1])<<16 |
2842		(FLAC__uint32)(buf[2])<<8 | buf[3];
2843
2844	return true;
2845}
2846
2847FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2848	/* Read an IEEE 754 80-bit (aka SANE) extended floating point value from 'f',
2849	 * convert it into an integral value and store in 'val'.  Return false if only
2850	 * between 1 and 9 bytes remain in 'f', if 0 bytes remain in 'f' and 'eof_ok' is
2851	 * false, or if the value is negative, between zero and one, or too large to be
2852	 * represented by 'val'; return true otherwise.
2853	 */
2854{
2855	unsigned int i;
2856	unsigned char buf[10];
2857	size_t bytes_read= fread(buf, 1U, 10U, f);
2858	FLAC__int16 e= ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
2859	FLAC__int16 shift= 63-e;
2860	FLAC__uint64 p= 0U;
2861
2862	if(bytes_read==0U && eof_ok)
2863		return true;
2864	else if(bytes_read<10U) {
2865		flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2866		return false;
2867	}
2868	else if((buf[0]>>7)==1U || e<0 || e>63) {
2869		flac__utils_printf(stderr, 1, "%s: ERROR: invalid floating-point value\n", fn);
2870		return false;
2871	}
2872
2873	for(i= 0U; i<8U; ++i)
2874		p|= (FLAC__uint64)(buf[i+2])<<(56U-i*8);
2875	*val= (FLAC__uint32)((p>>shift)+(p>>(shift-1) & 0x1));
2876
2877	return true;
2878}
2879
2880FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset)
2881{
2882	static unsigned char dump[8192];
2883
2884#ifdef _MSC_VER
2885	if(f == stdin) {
2886		/* MS' stdio impl can't even seek forward on stdin, have to use pure non-fseek() version: */
2887		while(offset > 0) {
2888			const long need = (long)min(offset, sizeof(dump));
2889			if((long)fread(dump, 1, need, f) < need)
2890				return false;
2891			offset -= need;
2892		}
2893	}
2894	else
2895#endif
2896	{
2897		while(offset > 0) {
2898			long need = (long)min(offset, LONG_MAX);
2899			if(fseeko(f, need, SEEK_CUR) < 0) {
2900				need = (long)min(offset, sizeof(dump));
2901				if((long)fread(dump, 1, need, f) < need)
2902					return false;
2903			}
2904			offset -= need;
2905		}
2906	}
2907	return true;
2908}
2909
2910unsigned count_channel_mask_bits(FLAC__uint32 mask)
2911{
2912	unsigned count = 0;
2913	while(mask) {
2914		if(mask & 1)
2915			count++;
2916		mask >>= 1;
2917	}
2918	return count;
2919}
2920
2921#if 0
2922FLAC__uint32 limit_channel_mask(FLAC__uint32 mask, unsigned channels)
2923{
2924	FLAC__uint32 x = 0x80000000;
2925	unsigned count = count_channel_mask_bits(mask);
2926	while(x && count > channels) {
2927		if(mask & x) {
2928			mask &= ~x;
2929			count--;
2930		}
2931		x >>= 1;
2932	}
2933	FLAC__ASSERT(count_channel_mask_bits(mask) == channels);
2934	return mask;
2935}
2936#endif
2937