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