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