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