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