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