fix minor bug printing unknown aiff subchunks (SF bug #1267476: https://sourceforge...
[flac.git] / src / flac / encode.c
1 /* flac - Command-line FLAC encoder/decoder
2  * Copyright (C) 2000,2001,2002,2003,2004,2005  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 defined _WIN32 && !defined __CYGWIN__
20 /* where MSVC puts unlink() */
21 # include <io.h>
22 #else
23 # include <unistd.h>
24 #endif
25 #include <limits.h> /* for LONG_MAX */
26 #include <math.h> /* for floor() */
27 #include <stdio.h> /* for FILE etc. */
28 #include <stdlib.h> /* for malloc */
29 #include <string.h> /* for strcmp() */
30 #include "FLAC/all.h"
31 #include "share/grabbag.h"
32 #include "encode.h"
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #ifdef FLAC__HAS_OGG
39 #include "OggFLAC/stream_encoder.h"
40 #include "OggFLAC/file_encoder.h"
41 #endif
42
43 #ifdef min
44 #undef min
45 #endif
46 #define min(x,y) ((x)<(y)?(x):(y))
47 #ifdef max
48 #undef max
49 #endif
50 #define max(x,y) ((x)>(y)?(x):(y))
51
52 /* this MUST be >= 588 so that sector aligning can take place with one read */
53 #define CHUNK_OF_SAMPLES 2048
54
55 typedef struct {
56 #ifdef FLAC__HAS_OGG
57         FLAC__bool use_ogg;
58 #endif
59         FLAC__bool verify;
60         FLAC__bool is_stdout;
61         const char *inbasefilename;
62         const char *outfilename;
63
64         FLAC__uint64 skip;
65         FLAC__uint64 until; /* a value of 0 mean end-of-stream (i.e. --until=-0) */
66         FLAC__bool replay_gain;
67         unsigned channels;
68         unsigned bits_per_sample;
69         unsigned sample_rate;
70         FLAC__uint64 unencoded_size;
71         FLAC__uint64 total_samples_to_encode;
72         FLAC__uint64 bytes_written;
73         FLAC__uint64 samples_written;
74         unsigned blocksize;
75         unsigned stats_mask;
76
77         /*
78          * We use *.stream for encoding to stdout
79          * We use *.file for encoding to a regular file
80          */
81         union {
82                 union {
83                         FLAC__StreamEncoder *stream;
84                         FLAC__FileEncoder *file;
85                 } flac;
86 #ifdef FLAC__HAS_OGG
87                 union {
88                         OggFLAC__StreamEncoder *stream;
89                         OggFLAC__FileEncoder *file;
90                 } ogg;
91 #endif
92         } encoder;
93
94         FILE *fin;
95         FILE *fout;
96         FLAC__StreamMetadata *seek_table_template;
97 } EncoderSession;
98
99
100 static FLAC__bool is_big_endian_host_;
101
102 static unsigned char ucbuffer_[CHUNK_OF_SAMPLES*FLAC__MAX_CHANNELS*((FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE+7)/8)];
103 static signed char *scbuffer_ = (signed char *)ucbuffer_;
104 static FLAC__uint16 *usbuffer_ = (FLAC__uint16 *)ucbuffer_;
105 static FLAC__int16 *ssbuffer_ = (FLAC__int16 *)ucbuffer_;
106
107 static FLAC__int32 in_[FLAC__MAX_CHANNELS][CHUNK_OF_SAMPLES];
108 static FLAC__int32 *input_[FLAC__MAX_CHANNELS];
109
110
111 /*
112  * unpublished debug routines from the FLAC libs
113  */
114 extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
115 extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
116 extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
117 extern FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value);
118 extern FLAC__bool FLAC__file_encoder_disable_fixed_subframes(FLAC__FileEncoder *encoder, FLAC__bool value);
119 extern FLAC__bool FLAC__file_encoder_disable_verbatim_subframes(FLAC__FileEncoder *encoder, FLAC__bool value);
120 #ifdef FLAC__HAS_OGG
121 extern FLAC__bool OggFLAC__stream_encoder_disable_constant_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
122 extern FLAC__bool OggFLAC__stream_encoder_disable_fixed_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
123 extern FLAC__bool OggFLAC__stream_encoder_disable_verbatim_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
124 extern FLAC__bool OggFLAC__file_encoder_disable_constant_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value);
125 extern FLAC__bool OggFLAC__file_encoder_disable_fixed_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value);
126 extern FLAC__bool OggFLAC__file_encoder_disable_verbatim_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value);
127 #endif
128
129 /*
130  * local routines
131  */
132 static FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FILE *infile, const char *infilename, const char *outfilename);
133 static void EncoderSession_destroy(EncoderSession *e);
134 static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero);
135 static int EncoderSession_finish_error(EncoderSession *e);
136 static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate);
137 static FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples);
138 static FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e);
139 static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
140 static void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps);
141 #ifdef FLAC__HAS_OGG
142 static FLAC__StreamEncoderWriteStatus ogg_stream_encoder_write_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
143 static void ogg_stream_encoder_metadata_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
144 static void ogg_file_encoder_progress_callback(const OggFLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data);
145 #endif
146 static FLAC__StreamEncoderWriteStatus flac_stream_encoder_write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
147 static void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
148 static void flac_file_encoder_progress_callback(const FLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data);
149 static FLAC__bool parse_cuesheet_(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset);
150 static void print_stats(const EncoderSession *encoder_session);
151 static void print_error_with_state(const EncoderSession *e, const char *message);
152 static void print_verify_error(EncoderSession *e);
153 static FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
154 static FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
155 static FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
156 static FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
157 static FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
158 static FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset);
159
160 /*
161  * public routines
162  */
163 int flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options, FLAC__bool is_aifc)
164 {
165         EncoderSession encoder_session;
166         FLAC__uint16 x;
167         FLAC__uint32 xx;
168         unsigned int channels= 0U, bps= 0U, sample_rate= 0U, sample_frames= 0U;
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 #ifdef FLAC__HAS_OGG
181                         options.common.use_ogg,
182 #else
183                         /*use_ogg=*/false,
184 #endif
185                         options.common.verify,
186                         infile,
187                         infilename,
188                         outfilename
189                 )
190         )
191                 return 1;
192
193         /* lookahead[] already has "FORMxxxxAIFF", do sub-chunks */
194
195         while(1) {
196                 size_t c= 0U;
197                 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 */
198
199                 /* chunk identifier; really conservative about behavior of fread() and feof() */
200                 if(feof(infile) || ((c= fread(chunk_id, 1U, 4U, infile)), c==0U && feof(infile)))
201                         break;
202                 else if(c<4U || feof(infile)) {
203                         flac__utils_printf(stderr, 1, "%s: ERROR: incomplete chunk identifier\n", encoder_session.inbasefilename);
204                         return EncoderSession_finish_error(&encoder_session);
205                 }
206
207                 if(got_comm_chunk==false && !memcmp(chunk_id, "COMM", 4)) { /* common chunk */
208                         unsigned long skip;
209                         const FLAC__uint32 minimum_comm_size = (is_aifc? 22 : 18);
210
211                         /* COMM chunk size */
212                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
213                                 return EncoderSession_finish_error(&encoder_session);
214                         else if(xx<minimum_comm_size) {
215                                 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);
216                                 return EncoderSession_finish_error(&encoder_session);
217                         }
218                         else if(!is_aifc && xx!=minimum_comm_size) {
219                                 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);
220                         }
221                         skip= (xx-minimum_comm_size)+(xx & 1U);
222
223                         /* number of channels */
224                         if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
225                                 return EncoderSession_finish_error(&encoder_session);
226                         else if(x==0U || x>FLAC__MAX_CHANNELS) {
227                                 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned int)x);
228                                 return EncoderSession_finish_error(&encoder_session);
229                         }
230                         else if(options.common.sector_align && x!=2U) {
231                                 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)x);
232                                 return EncoderSession_finish_error(&encoder_session);
233                         }
234                         channels= x;
235
236                         /* number of sample frames */
237                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
238                                 return EncoderSession_finish_error(&encoder_session);
239                         sample_frames= xx;
240
241                         /* bits per sample */
242                         if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
243                                 return EncoderSession_finish_error(&encoder_session);
244                         else if(x!=8U && x!=16U && x!=24U) {
245                                 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits per sample %u\n", encoder_session.inbasefilename, (unsigned int)x);
246                                 return EncoderSession_finish_error(&encoder_session);
247                         }
248                         else if(options.common.sector_align && x!=16U) {
249                                 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);
250                                 return EncoderSession_finish_error(&encoder_session);
251                         }
252                         bps= x;
253
254                         /* sample rate */
255                         if(!read_sane_extended(infile, &xx, false, encoder_session.inbasefilename))
256                                 return EncoderSession_finish_error(&encoder_session);
257                         else if(!FLAC__format_sample_rate_is_valid(xx)) {
258                                 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned int)xx);
259                                 return EncoderSession_finish_error(&encoder_session);
260                         }
261                         else if(options.common.sector_align && xx!=44100U) {
262                                 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);
263                                 return EncoderSession_finish_error(&encoder_session);
264                         }
265                         sample_rate= xx;
266
267                         /* check compression type for AIFF-C */
268                         if(is_aifc) {
269                                 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
270                                         return EncoderSession_finish_error(&encoder_session);
271                                 if(xx == 0x736F7774) /* "sowt" */
272                                         is_big_endian_pcm = false;
273                                 else if(xx == 0x4E4F4E45) /* "NONE" */
274                                         ; /* nothing to do, we already default to big-endian */
275                                 else {
276                                         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));
277                                         return EncoderSession_finish_error(&encoder_session);
278                                 }
279                         }
280
281                         /* skip any extra data in the COMM chunk */
282                         if(!fskip_ahead(infile, skip)) {
283                                 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra COMM data\n", encoder_session.inbasefilename);
284                                 return EncoderSession_finish_error(&encoder_session);
285                         }
286
287                         /*
288                          * now that we know the sample rate, canonicalize the
289                          * --skip string to a number of samples:
290                          */
291                         flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
292                         FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
293                         encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
294                         FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
295
296                         got_comm_chunk= true;
297                 }
298                 else if(got_ssnd_chunk==false && !memcmp(chunk_id, "SSND", 4)) { /* sound data chunk */
299                         unsigned int offset= 0U, block_size= 0U, align_remainder= 0U, data_bytes;
300                         size_t bytes_per_frame= channels*(bps>>3);
301                         FLAC__uint64 total_samples_in_input, trim = 0;
302                         FLAC__bool pad= false;
303
304                         if(got_comm_chunk==false) {
305                                 flac__utils_printf(stderr, 1, "%s: ERROR: got 'SSND' chunk before 'COMM' chunk\n", encoder_session.inbasefilename);
306                                 return EncoderSession_finish_error(&encoder_session);
307                         }
308
309                         /* SSND chunk size */
310                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
311                                 return EncoderSession_finish_error(&encoder_session);
312                         data_bytes= xx;
313                         pad= (data_bytes & 1U) ? true : false;
314                         data_bytes-= 8U; /* discount the offset and block size fields */
315
316                         /* offset */
317                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
318                                 return EncoderSession_finish_error(&encoder_session);
319                         offset= xx;
320                         data_bytes-= offset;
321
322                         /* block size */
323                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
324                                 return EncoderSession_finish_error(&encoder_session);
325                         else if(xx!=0U) {
326                                 flac__utils_printf(stderr, 1, "%s: ERROR: block size is %u; must be 0\n", encoder_session.inbasefilename, (unsigned int)xx);
327                                 return EncoderSession_finish_error(&encoder_session);
328                         }
329                         block_size= xx;
330
331                         /* skip any SSND offset bytes */
332                         FLAC__ASSERT(offset<=LONG_MAX);
333                         if(!fskip_ahead(infile, offset)) {
334                                 flac__utils_printf(stderr, 1, "%s: ERROR: skipping offset in SSND chunk\n", encoder_session.inbasefilename);
335                                 return EncoderSession_finish_error(&encoder_session);
336                         }
337                         if(data_bytes!=(sample_frames*bytes_per_frame)) {
338                                 flac__utils_printf(stderr, 1, "%s: ERROR: SSND chunk size inconsistent with sample frame count\n", encoder_session.inbasefilename);
339                                 return EncoderSession_finish_error(&encoder_session);
340                         }
341
342                         /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
343                         FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
344                         total_samples_in_input = data_bytes / bytes_per_frame + *options.common.align_reservoir_samples;
345
346                         /*
347                          * now that we know the input size, canonicalize the
348                          * --until string to an absolute sample number:
349                          */
350                         if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
351                                 return EncoderSession_finish_error(&encoder_session);
352                         encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
353                         FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
354
355                         if(encoder_session.skip>0U) {
356                                 if(!fskip_ahead(infile, encoder_session.skip*bytes_per_frame)) {
357                                         flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
358                                         return EncoderSession_finish_error(&encoder_session);
359                                 }
360                         }
361
362                         data_bytes-= (unsigned int)encoder_session.skip*bytes_per_frame; /*@@@ WATCHOUT: 4GB limit */
363                         encoder_session.total_samples_to_encode= total_samples_in_input - encoder_session.skip;
364                         if(encoder_session.until > 0) {
365                                 trim = total_samples_in_input - encoder_session.until;
366                                 FLAC__ASSERT(total_samples_in_input > 0);
367                                 FLAC__ASSERT(!options.common.sector_align);
368                                 data_bytes-= (unsigned int)trim*bytes_per_frame;
369                                 encoder_session.total_samples_to_encode-= trim;
370                         }
371                         if(options.common.sector_align) {
372                                 align_remainder= (unsigned int)(encoder_session.total_samples_to_encode % 588U);
373                                 if(options.common.is_last_file)
374                                         encoder_session.total_samples_to_encode+= (588U-align_remainder); /* will pad with zeroes */
375                                 else
376                                         encoder_session.total_samples_to_encode-= align_remainder; /* will stop short and carry over to next file */
377                         }
378
379                         /* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */
380                         encoder_session.unencoded_size= encoder_session.total_samples_to_encode*bytes_per_frame+54;
381
382                         if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate))
383                                 return EncoderSession_finish_error(&encoder_session);
384
385                         /* first do any samples in the reservoir */
386                         if(options.common.sector_align && *options.common.align_reservoir_samples>0U) {
387
388                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
389                                         print_error_with_state(&encoder_session, "ERROR during encoding");
390                                         return EncoderSession_finish_error(&encoder_session);
391                                 }
392                         }
393
394                         /* decrement the data_bytes counter if we need to align the file */
395                         if(options.common.sector_align) {
396                                 if(options.common.is_last_file)
397                                         *options.common.align_reservoir_samples= 0U;
398                                 else {
399                                         *options.common.align_reservoir_samples= align_remainder;
400                                         data_bytes-= (*options.common.align_reservoir_samples)*bytes_per_frame;
401                                 }
402                         }
403
404                         /* now do from the file */
405                         while(data_bytes>0) {
406                                 size_t bytes_read= fread(ucbuffer_, 1U, min(data_bytes, CHUNK_OF_SAMPLES*bytes_per_frame), infile);
407
408                                 if(bytes_read==0U) {
409                                         if(ferror(infile)) {
410                                                 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
411                                                 return EncoderSession_finish_error(&encoder_session);
412                                         }
413                                         else if(feof(infile)) {
414                                                 flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written);
415                                                 data_bytes= 0;
416                                         }
417                                 }
418                                 else {
419                                         if(bytes_read % bytes_per_frame != 0U) {
420                                                 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
421                                                 return EncoderSession_finish_error(&encoder_session);
422                                         }
423                                         else {
424                                                 unsigned int frames= bytes_read/bytes_per_frame;
425                                                 format_input(input_, frames, is_big_endian_pcm, /*is_unsigned_samples=*/false, channels, bps);
426
427                                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, frames)) {
428                                                         print_error_with_state(&encoder_session, "ERROR during encoding");
429                                                         return EncoderSession_finish_error(&encoder_session);
430                                                 }
431                                                 else
432                                                         data_bytes-= bytes_read;
433                                         }
434                                 }
435                         }
436
437                         if(trim>0) {
438                                 FLAC__ASSERT(!options.common.sector_align);
439                                 if(!fskip_ahead(infile, trim*bytes_per_frame)) {
440                                         flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
441                                         return EncoderSession_finish_error(&encoder_session);
442                                 }
443                         }
444
445                         /* now read unaligned samples into reservoir or pad with zeroes if necessary */
446                         if(options.common.sector_align) {
447                                 if(options.common.is_last_file) {
448                                         unsigned int pad_frames= 588U-align_remainder;
449
450                                         if(pad_frames<588U) {
451                                                 unsigned int i;
452
453                                                 info_align_zero= pad_frames;
454                                                 for(i= 0U; i<channels; ++i)
455                                                         memset(input_[i], 0, sizeof(input_[0][0])*pad_frames);
456
457                                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, pad_frames)) {
458                                                         print_error_with_state(&encoder_session, "ERROR during encoding");
459                                                         return EncoderSession_finish_error(&encoder_session);
460                                                 }
461                                         }
462                                 }
463                                 else {
464                                         if(*options.common.align_reservoir_samples > 0) {
465                                                 size_t bytes_read= fread(ucbuffer_, 1U, (*options.common.align_reservoir_samples)*bytes_per_frame, infile);
466
467                                                 FLAC__ASSERT(CHUNK_OF_SAMPLES>=588U);
468                                                 if(bytes_read==0U && 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(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_frame) {
473                                                         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);
474                                                 }
475                                                 else {
476                                                         info_align_carry= *options.common.align_reservoir_samples;
477                                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, is_big_endian_pcm, /*is_unsigned_samples=*/false, channels, bps);
478                                                 }
479                                         }
480                                 }
481                         }
482
483                         if(pad==true) {
484                                 unsigned char tmp;
485
486                                 if(fread(&tmp, 1U, 1U, infile)<1U) {
487                                         flac__utils_printf(stderr, 1, "%s: ERROR during read of SSND pad byte\n", encoder_session.inbasefilename);
488                                         return EncoderSession_finish_error(&encoder_session);
489                                 }
490                         }
491
492                         got_ssnd_chunk= true;
493                 }
494                 else { /* other chunk */
495                         if(!memcmp(chunk_id, "COMM", 4)) {
496                                 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_session.inbasefilename);
497                         }
498                         else if(!memcmp(chunk_id, "SSND", 4)) {
499                                 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename);
500                         }
501                         else {
502                                 flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_session.inbasefilename, chunk_id);
503                         }
504
505                         /* chunk size */
506                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
507                                 return EncoderSession_finish_error(&encoder_session);
508                         else {
509                                 unsigned long skip= xx+(xx & 1U);
510
511                                 FLAC__ASSERT(skip<=LONG_MAX);
512                                 if(!fskip_ahead(infile, skip)) {
513                                         fprintf(stderr, "%s: ERROR during read while skipping unknown chunk\n", encoder_session.inbasefilename);
514                                         return EncoderSession_finish_error(&encoder_session);
515                                 }
516                         }
517                 }
518         }
519
520         if(got_ssnd_chunk==false && sample_frames!=0U) {
521                 flac__utils_printf(stderr, 1, "%s: ERROR: missing SSND chunk\n", encoder_session.inbasefilename);
522                 return EncoderSession_finish_error(&encoder_session);
523         }
524
525         return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
526 }
527
528 int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
529 {
530         EncoderSession encoder_session;
531         FLAC__bool is_unsigned_samples = false;
532         unsigned channels = 0, bps = 0, sample_rate = 0;
533         size_t bytes_per_wide_sample, bytes_read;
534         FLAC__uint16 x;
535         FLAC__uint32 xx;
536         FLAC__bool got_fmt_chunk = false, got_data_chunk = false;
537         unsigned align_remainder = 0;
538         int info_align_carry = -1, info_align_zero = -1;
539
540         (void)infilesize;
541         (void)lookahead;
542         (void)lookahead_length;
543
544         if(!
545                 EncoderSession_construct(
546                         &encoder_session,
547 #ifdef FLAC__HAS_OGG
548                         options.common.use_ogg,
549 #else
550                         /*use_ogg=*/false,
551 #endif
552                         options.common.verify,
553                         infile,
554                         infilename,
555                         outfilename
556                 )
557         )
558                 return 1;
559
560         /*
561          * lookahead[] already has "RIFFxxxxWAVE", do sub-chunks
562          */
563         while(!feof(infile)) {
564                 if(!read_little_endian_uint32(infile, &xx, true, encoder_session.inbasefilename))
565                         return EncoderSession_finish_error(&encoder_session);
566                 if(feof(infile))
567                         break;
568                 if(xx == 0x20746d66 && !got_fmt_chunk) { /* "fmt " */
569                         unsigned block_align, data_bytes;
570
571                         /* fmt sub-chunk size */
572                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
573                                 return EncoderSession_finish_error(&encoder_session);
574                         if(xx < 16) {
575                                 flac__utils_printf(stderr, 1, "%s: ERROR: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx);
576                                 return EncoderSession_finish_error(&encoder_session);
577                         }
578                         else if(xx != 16 && xx != 18) {
579                                 flac__utils_printf(stderr, 1, "%s: WARNING: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx);
580                         }
581                         data_bytes = xx;
582                         /* compression code */
583                         if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
584                                 return EncoderSession_finish_error(&encoder_session);
585                         if(x != 1) {
586                                 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported compression type %u\n", encoder_session.inbasefilename, (unsigned)x);
587                                 return EncoderSession_finish_error(&encoder_session);
588                         }
589                         /* number of channels */
590                         if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
591                                 return EncoderSession_finish_error(&encoder_session);
592                         if(x == 0 || x > FLAC__MAX_CHANNELS) {
593                                 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned)x);
594                                 return EncoderSession_finish_error(&encoder_session);
595                         }
596                         else if(options.common.sector_align && x != 2) {
597                                 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x);
598                                 return EncoderSession_finish_error(&encoder_session);
599                         }
600                         channels = x;
601                         /* sample rate */
602                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
603                                 return EncoderSession_finish_error(&encoder_session);
604                         if(!FLAC__format_sample_rate_is_valid(xx)) {
605                                 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned)xx);
606                                 return EncoderSession_finish_error(&encoder_session);
607                         }
608                         else if(options.common.sector_align && xx != 44100) {
609                                 flac__utils_printf(stderr, 1, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_session.inbasefilename, (unsigned)xx);
610                                 return EncoderSession_finish_error(&encoder_session);
611                         }
612                         sample_rate = xx;
613                         /* avg bytes per second (ignored) */
614                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
615                                 return EncoderSession_finish_error(&encoder_session);
616                         /* block align */
617                         if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
618                                 return EncoderSession_finish_error(&encoder_session);
619                         block_align = x;
620                         /* bits per sample */
621                         if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
622                                 return EncoderSession_finish_error(&encoder_session);
623                         if(x != 8 && x != 16 && x != 24) {
624                                 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, (unsigned)x);
625                                 return EncoderSession_finish_error(&encoder_session);
626                         }
627                         else if(options.common.sector_align && x != 16) {
628                                 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u bits per sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x);
629                                 return EncoderSession_finish_error(&encoder_session);
630                         }
631                         bps = x;
632                         if(bps * channels != block_align * 8) {
633                                 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported block alignment (%u), for bits-per-sample=%u, channels=%u\n", encoder_session.inbasefilename, block_align, bps, channels);
634                                 return EncoderSession_finish_error(&encoder_session);
635                         }
636                         is_unsigned_samples = (x == 8);
637
638                         /* skip any extra data in the fmt sub-chunk */
639                         data_bytes -= 16;
640                         if(data_bytes > 0) {
641                                 unsigned left, need;
642                                 for(left = data_bytes; left > 0; ) {
643                                         need = min(left, CHUNK_OF_SAMPLES);
644                                         if(fread(ucbuffer_, 1U, need, infile) < need) {
645                                                 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
646                                                 return EncoderSession_finish_error(&encoder_session);
647                                         }
648                                         left -= need;
649                                 }
650                         }
651
652                         /*
653                          * now that we know the sample rate, canonicalize the
654                          * --skip string to a number of samples:
655                          */
656                         flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
657                         FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
658                         encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
659                         FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
660
661                         got_fmt_chunk = true;
662                 }
663                 else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
664                         FLAC__uint64 total_samples_in_input, trim = 0;
665                         FLAC__bool pad = false;
666                         unsigned data_bytes;
667
668                         /* data size */
669                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
670                                 return EncoderSession_finish_error(&encoder_session);
671                         data_bytes = xx;
672                         pad = (data_bytes & 1U) ? true : false;
673
674                         bytes_per_wide_sample = channels * (bps >> 3);
675
676                         /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
677                         FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
678                         total_samples_in_input = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;
679
680                         /*
681                          * now that we know the input size, canonicalize the
682                          * --until string to an absolute sample number:
683                          */
684                         if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
685                                 return EncoderSession_finish_error(&encoder_session);
686                         encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
687                         FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
688
689                         if(encoder_session.skip > 0) {
690                                 if(!fskip_ahead(infile, encoder_session.skip * bytes_per_wide_sample)) {
691                                         flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
692                                         return EncoderSession_finish_error(&encoder_session);
693                                 }
694                         }
695
696                         data_bytes -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
697                         encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
698                         if(encoder_session.until > 0) {
699                                 trim = total_samples_in_input - encoder_session.until;
700                                 FLAC__ASSERT(total_samples_in_input > 0);
701                                 FLAC__ASSERT(!options.common.sector_align);
702                                 data_bytes -= (unsigned int)trim * bytes_per_wide_sample;
703                                 encoder_session.total_samples_to_encode -= trim;
704                         }
705                         if(options.common.sector_align) {
706                                 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
707                                 if(options.common.is_last_file)
708                                         encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
709                                 else
710                                         encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
711                         }
712
713                         /* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
714                         encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample + 44;
715
716                         if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate))
717                                 return EncoderSession_finish_error(&encoder_session);
718
719                         /*
720                          * first do any samples in the reservoir
721                          */
722                         if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
723                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
724                                         print_error_with_state(&encoder_session, "ERROR during encoding");
725                                         return EncoderSession_finish_error(&encoder_session);
726                                 }
727                         }
728
729                         /*
730                          * decrement the data_bytes counter if we need to align the file
731                          */
732                         if(options.common.sector_align) {
733                                 if(options.common.is_last_file) {
734                                         *options.common.align_reservoir_samples = 0;
735                                 }
736                                 else {
737                                         *options.common.align_reservoir_samples = align_remainder;
738                                         data_bytes -= (*options.common.align_reservoir_samples) * bytes_per_wide_sample;
739                                 }
740                         }
741
742                         /*
743                          * now do from the file
744                          */
745                         while(data_bytes > 0) {
746                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), min(data_bytes, CHUNK_OF_SAMPLES * bytes_per_wide_sample), infile);
747                                 if(bytes_read == 0) {
748                                         if(ferror(infile)) {
749                                                 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
750                                                 return EncoderSession_finish_error(&encoder_session);
751                                         }
752                                         else if(feof(infile)) {
753                                                 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);
754                                                 data_bytes = 0;
755                                         }
756                                 }
757                                 else {
758                                         if(bytes_read % bytes_per_wide_sample != 0) {
759                                                 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
760                                                 return EncoderSession_finish_error(&encoder_session);
761                                         }
762                                         else {
763                                                 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
764                                                 format_input(input_, wide_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps);
765
766                                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
767                                                         print_error_with_state(&encoder_session, "ERROR during encoding");
768                                                         return EncoderSession_finish_error(&encoder_session);
769                                                 }
770                                                 data_bytes -= bytes_read;
771                                         }
772                                 }
773                         }
774
775                         if(trim > 0) {
776                                 FLAC__ASSERT(!options.common.sector_align);
777                                 if(!fskip_ahead(infile, trim * bytes_per_wide_sample)) {
778                                         flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
779                                         return EncoderSession_finish_error(&encoder_session);
780                                 }
781                         }
782
783                         /*
784                          * now read unaligned samples into reservoir or pad with zeroes if necessary
785                          */
786                         if(options.common.sector_align) {
787                                 if(options.common.is_last_file) {
788                                         unsigned wide_samples = 588 - align_remainder;
789                                         if(wide_samples < 588) {
790                                                 unsigned channel;
791
792                                                 info_align_zero = wide_samples;
793                                                 for(channel = 0; channel < channels; channel++)
794                                                         memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
795
796                                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
797                                                         print_error_with_state(&encoder_session, "ERROR during encoding");
798                                                         return EncoderSession_finish_error(&encoder_session);
799                                                 }
800                                         }
801                                 }
802                                 else {
803                                         if(*options.common.align_reservoir_samples > 0) {
804                                                 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
805                                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
806                                                 if(bytes_read == 0 && ferror(infile)) {
807                                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
808                                                         return EncoderSession_finish_error(&encoder_session);
809                                                 }
810                                                 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
811                                                         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);
812                                                 }
813                                                 else {
814                                                         info_align_carry = *options.common.align_reservoir_samples;
815                                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps);
816                                                 }
817                                         }
818                                 }
819                         }
820
821                         if(pad == true) {
822                                 unsigned char tmp;
823
824                                 if(fread(&tmp, 1U, 1U, infile) < 1U) {
825                                         flac__utils_printf(stderr, 1, "%s: ERROR during read of data pad byte\n", encoder_session.inbasefilename);
826                                         return EncoderSession_finish_error(&encoder_session);
827                                 }
828                         }
829
830                         got_data_chunk = true;
831                 }
832                 else {
833                         if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
834                                 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename);
835                         }
836                         else if(xx == 0x61746164) { /* "data" */
837                                 if(got_data_chunk) {
838                                         flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename);
839                                 }
840                                 else if(!got_fmt_chunk) {
841                                         flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
842                                         return EncoderSession_finish_error(&encoder_session);
843                                 }
844                                 else {
845                                         FLAC__ASSERT(0);
846                                 }
847                         }
848                         else {
849                                 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));
850                         }
851                         /* sub-chunk size */
852                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
853                                 return EncoderSession_finish_error(&encoder_session);
854                         else {
855                                 unsigned long skip = xx+(xx & 1U);
856
857                                 FLAC__ASSERT(skip<=LONG_MAX);
858                                 if(!fskip_ahead(infile, skip)) {
859                                         flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_session.inbasefilename);
860                                         return EncoderSession_finish_error(&encoder_session);
861                                 }
862                         }
863                 }
864         }
865
866         return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
867 }
868
869 int flac__encode_raw(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options)
870 {
871         EncoderSession encoder_session;
872         size_t bytes_read;
873         const size_t bytes_per_wide_sample = options.channels * (options.bps >> 3);
874         unsigned align_remainder = 0;
875         int info_align_carry = -1, info_align_zero = -1;
876         FLAC__uint64 total_samples_in_input = 0;
877
878         FLAC__ASSERT(!options.common.sector_align || options.channels == 2);
879         FLAC__ASSERT(!options.common.sector_align || options.bps == 16);
880         FLAC__ASSERT(!options.common.sector_align || options.sample_rate == 44100);
881         FLAC__ASSERT(!options.common.sector_align || infilesize >= 0);
882         FLAC__ASSERT(!options.common.replay_gain || options.channels <= 2);
883         FLAC__ASSERT(!options.common.replay_gain || grabbag__replaygain_is_valid_sample_frequency(options.sample_rate));
884
885         if(!
886                 EncoderSession_construct(
887                         &encoder_session,
888 #ifdef FLAC__HAS_OGG
889                         options.common.use_ogg,
890 #else
891                         /*use_ogg=*/false,
892 #endif
893                         options.common.verify,
894                         infile,
895                         infilename,
896                         outfilename
897                 )
898         )
899                 return 1;
900
901         /*
902          * now that we know the sample rate, canonicalize the
903          * --skip string to a number of samples:
904          */
905         flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, options.sample_rate);
906         FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
907         encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
908         FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
909
910         if(infilesize < 0)
911                 total_samples_in_input = 0;
912         else {
913                 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
914                 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
915                 total_samples_in_input = (unsigned)infilesize / bytes_per_wide_sample + *options.common.align_reservoir_samples;
916         }
917
918         /*
919          * now that we know the input size, canonicalize the
920          * --until strings to a number of samples:
921          */
922         if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, options.sample_rate, encoder_session.skip, total_samples_in_input))
923                 return EncoderSession_finish_error(&encoder_session);
924         encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
925         FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
926
927         infilesize -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
928         encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
929         if(encoder_session.until > 0) {
930                 const FLAC__uint64 trim = total_samples_in_input - encoder_session.until;
931                 FLAC__ASSERT(total_samples_in_input > 0);
932                 FLAC__ASSERT(!options.common.sector_align);
933                 infilesize -= (unsigned int)trim * bytes_per_wide_sample;
934                 encoder_session.total_samples_to_encode -= trim;
935         }
936         if(infilesize >= 0 && options.common.sector_align) {
937                 FLAC__ASSERT(encoder_session.skip == 0);
938                 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
939                 if(options.common.is_last_file)
940                         encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
941                 else
942                         encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
943         }
944         encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample;
945
946         if(encoder_session.total_samples_to_encode <= 0)
947                 flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
948
949         if(encoder_session.skip > 0) {
950                 unsigned skip_bytes = bytes_per_wide_sample * (unsigned)encoder_session.skip;
951                 if(skip_bytes > lookahead_length) {
952                         skip_bytes -= lookahead_length;
953                         lookahead_length = 0;
954                         if(!fskip_ahead(infile, skip_bytes)) {
955                                 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
956                                 return EncoderSession_finish_error(&encoder_session);
957                         }
958                 }
959                 else {
960                         lookahead += skip_bytes;
961                         lookahead_length -= skip_bytes;
962                 }
963         }
964
965         if(!EncoderSession_init_encoder(&encoder_session, options.common, options.channels, options.bps, options.sample_rate))
966                 return EncoderSession_finish_error(&encoder_session);
967
968         /*
969          * first do any samples in the reservoir
970          */
971         if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
972                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
973                         print_error_with_state(&encoder_session, "ERROR during encoding");
974                         return EncoderSession_finish_error(&encoder_session);
975                 }
976         }
977
978         /*
979          * decrement infilesize if we need to align the file
980          */
981         if(options.common.sector_align) {
982                 FLAC__ASSERT(infilesize >= 0);
983                 if(options.common.is_last_file) {
984                         *options.common.align_reservoir_samples = 0;
985                 }
986                 else {
987                         *options.common.align_reservoir_samples = align_remainder;
988                         infilesize -= (long)((*options.common.align_reservoir_samples) * bytes_per_wide_sample);
989                         FLAC__ASSERT(infilesize >= 0);
990                 }
991         }
992
993         /*
994          * now do from the file
995          */
996         if(infilesize < 0) {
997                 while(!feof(infile)) {
998                         if(lookahead_length > 0) {
999                                 FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * bytes_per_wide_sample);
1000                                 memcpy(ucbuffer_, lookahead, lookahead_length);
1001                                 bytes_read = fread(ucbuffer_+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
1002                                 if(ferror(infile)) {
1003                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1004                                         return EncoderSession_finish_error(&encoder_session);
1005                                 }
1006                                 lookahead_length = 0;
1007                         }
1008                         else
1009                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample, infile);
1010
1011                         if(bytes_read == 0) {
1012                                 if(ferror(infile)) {
1013                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1014                                         return EncoderSession_finish_error(&encoder_session);
1015                                 }
1016                         }
1017                         else if(bytes_read % bytes_per_wide_sample != 0) {
1018                                 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1019                                 return EncoderSession_finish_error(&encoder_session);
1020                         }
1021                         else {
1022                                 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1023                                 format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1024
1025                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1026                                         print_error_with_state(&encoder_session, "ERROR during encoding");
1027                                         return EncoderSession_finish_error(&encoder_session);
1028                                 }
1029                         }
1030                 }
1031         }
1032         else {
1033                 const FLAC__uint64 max_input_bytes = (FLAC__uint64)infilesize;
1034                 FLAC__uint64 total_input_bytes_read = 0;
1035                 while(total_input_bytes_read < max_input_bytes) {
1036                         {
1037                                 size_t wanted = (CHUNK_OF_SAMPLES * bytes_per_wide_sample);
1038                                 wanted = min(wanted, (size_t)(max_input_bytes - total_input_bytes_read));
1039
1040                                 if(lookahead_length > 0) {
1041                                         FLAC__ASSERT(lookahead_length <= wanted);
1042                                         memcpy(ucbuffer_, lookahead, lookahead_length);
1043                                         wanted -= lookahead_length;
1044                                         bytes_read = lookahead_length;
1045                                         if(wanted > 0) {
1046                                                 bytes_read += fread(ucbuffer_+lookahead_length, sizeof(unsigned char), wanted, infile);
1047                                                 if(ferror(infile)) {
1048                                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1049                                                         return EncoderSession_finish_error(&encoder_session);
1050                                                 }
1051                                         }
1052                                         lookahead_length = 0;
1053                                 }
1054                                 else
1055                                         bytes_read = fread(ucbuffer_, sizeof(unsigned char), wanted, infile);
1056                         }
1057
1058                         if(bytes_read == 0) {
1059                                 if(ferror(infile)) {
1060                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1061                                         return EncoderSession_finish_error(&encoder_session);
1062                                 }
1063                                 else if(feof(infile)) {
1064                                         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);
1065                                         total_input_bytes_read = max_input_bytes;
1066                                 }
1067                         }
1068                         else {
1069                                 if(bytes_read % bytes_per_wide_sample != 0) {
1070                                         flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1071                                         return EncoderSession_finish_error(&encoder_session);
1072                                 }
1073                                 else {
1074                                         unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1075                                         format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
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                                         total_input_bytes_read += bytes_read;
1082                                 }
1083                         }
1084                 }
1085         }
1086
1087         /*
1088          * now read unaligned samples into reservoir or pad with zeroes if necessary
1089          */
1090         if(options.common.sector_align) {
1091                 if(options.common.is_last_file) {
1092                         unsigned wide_samples = 588 - align_remainder;
1093                         if(wide_samples < 588) {
1094                                 unsigned channel;
1095
1096                                 info_align_zero = wide_samples;
1097                                 for(channel = 0; channel < options.channels; channel++)
1098                                         memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
1099
1100                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1101                                         print_error_with_state(&encoder_session, "ERROR during encoding");
1102                                         return EncoderSession_finish_error(&encoder_session);
1103                                 }
1104                         }
1105                 }
1106                 else {
1107                         if(*options.common.align_reservoir_samples > 0) {
1108                                 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
1109                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
1110                                 if(bytes_read == 0 && ferror(infile)) {
1111                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1112                                         return EncoderSession_finish_error(&encoder_session);
1113                                 }
1114                                 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
1115                                         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);
1116                                 }
1117                                 else {
1118                                         info_align_carry = *options.common.align_reservoir_samples;
1119                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1120                                 }
1121                         }
1122                 }
1123         }
1124
1125         return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
1126 }
1127
1128 FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FILE *infile, const char *infilename, const char *outfilename)
1129 {
1130         unsigned i;
1131         FLAC__uint32 test = 1;
1132
1133         /*
1134          * initialize globals
1135          */
1136
1137         is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
1138
1139         for(i = 0; i < FLAC__MAX_CHANNELS; i++)
1140                 input_[i] = &(in_[i][0]);
1141
1142
1143         /*
1144          * initialize instance
1145          */
1146
1147 #ifdef FLAC__HAS_OGG
1148         e->use_ogg = use_ogg;
1149 #else
1150         (void)use_ogg;
1151 #endif
1152         e->verify = verify;
1153
1154         e->is_stdout = (0 == strcmp(outfilename, "-"));
1155
1156         e->inbasefilename = grabbag__file_get_basename(infilename);
1157         e->outfilename = outfilename;
1158
1159         e->skip = 0; /* filled in later after the sample_rate is known */
1160         e->unencoded_size = 0;
1161         e->total_samples_to_encode = 0;
1162         e->bytes_written = 0;
1163         e->samples_written = 0;
1164         e->blocksize = 0;
1165         e->stats_mask = 0;
1166
1167         e->encoder.flac.stream = 0;
1168         e->encoder.flac.file = 0;
1169 #ifdef FLAC__HAS_OGG
1170         e->encoder.ogg.stream = 0;
1171         e->encoder.ogg.file = 0;
1172 #endif
1173
1174         e->fin = infile;
1175         e->fout = 0;
1176         e->seek_table_template = 0;
1177
1178         if(e->is_stdout) {
1179                 e->fout = grabbag__file_get_binary_stdout();
1180         }
1181
1182         if(0 == (e->seek_table_template = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE))) {
1183                 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1184                 return false;
1185         }
1186
1187 #ifdef FLAC__HAS_OGG
1188         if(e->use_ogg) {
1189                 if(e->is_stdout) {
1190                         e->encoder.ogg.stream = OggFLAC__stream_encoder_new();
1191                         if(0 == e->encoder.ogg.stream) {
1192                                 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1193                                 EncoderSession_destroy(e);
1194                                 return false;
1195                         }
1196                 }
1197                 else {
1198                         e->encoder.ogg.file = OggFLAC__file_encoder_new();
1199                         if(0 == e->encoder.ogg.file) {
1200                                 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1201                                 EncoderSession_destroy(e);
1202                                 return false;
1203                         }
1204                 }
1205         }
1206         else
1207 #endif
1208         if(e->is_stdout) {
1209                 e->encoder.flac.stream = FLAC__stream_encoder_new();
1210                 if(0 == e->encoder.flac.stream) {
1211                         flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1212                         EncoderSession_destroy(e);
1213                         return false;
1214                 }
1215         }
1216         else {
1217                 e->encoder.flac.file = FLAC__file_encoder_new();
1218                 if(0 == e->encoder.flac.file) {
1219                         flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1220                         EncoderSession_destroy(e);
1221                         return false;
1222                 }
1223         }
1224
1225         return true;
1226 }
1227
1228 void EncoderSession_destroy(EncoderSession *e)
1229 {
1230         if(e->fin != stdin)
1231                 fclose(e->fin);
1232         if(0 != e->fout && e->fout != stdout)
1233                 fclose(e->fout);
1234
1235 #ifdef FLAC__HAS_OGG
1236         if(e->use_ogg) {
1237                 if(e->is_stdout) {
1238                         if(0 != e->encoder.ogg.stream) {
1239                                 OggFLAC__stream_encoder_delete(e->encoder.ogg.stream);
1240                                 e->encoder.ogg.stream = 0;
1241                         }
1242                 }
1243                 else {
1244                         if(0 != e->encoder.ogg.file) {
1245                                 OggFLAC__file_encoder_delete(e->encoder.ogg.file);
1246                                 e->encoder.ogg.file = 0;
1247                         }
1248                 }
1249         }
1250         else
1251 #endif
1252         if(e->is_stdout) {
1253                 if(0 != e->encoder.flac.stream) {
1254                         FLAC__stream_encoder_delete(e->encoder.flac.stream);
1255                         e->encoder.flac.stream = 0;
1256                 }
1257         }
1258         else {
1259                 if(0 != e->encoder.flac.file) {
1260                         FLAC__file_encoder_delete(e->encoder.flac.file);
1261                         e->encoder.flac.file = 0;
1262                 }
1263         }
1264
1265         if(0 != e->seek_table_template) {
1266                 FLAC__metadata_object_delete(e->seek_table_template);
1267                 e->seek_table_template = 0;
1268         }
1269 }
1270
1271 int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero)
1272 {
1273         FLAC__StreamEncoderState fse_state = FLAC__STREAM_ENCODER_OK;
1274         int ret = 0;
1275
1276 #ifdef FLAC__HAS_OGG
1277         if(e->use_ogg) {
1278                 if(e->is_stdout) {
1279                         if(e->encoder.ogg.stream) {
1280                                 fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.stream);
1281                                 OggFLAC__stream_encoder_finish(e->encoder.ogg.stream);
1282                         }
1283                 }
1284                 else {
1285                         if(e->encoder.ogg.file) {
1286                                 fse_state = OggFLAC__file_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.file);
1287                                 OggFLAC__file_encoder_finish(e->encoder.ogg.file);
1288                         }
1289                 }
1290         }
1291         else
1292 #endif
1293         if(e->is_stdout) {
1294                 if(e->encoder.flac.stream) {
1295                         fse_state = FLAC__stream_encoder_get_state(e->encoder.flac.stream);
1296                         FLAC__stream_encoder_finish(e->encoder.flac.stream);
1297                 }
1298         }
1299         else {
1300                 if(e->encoder.flac.file) {
1301                         fse_state = FLAC__file_encoder_get_stream_encoder_state(e->encoder.flac.file);
1302                         FLAC__file_encoder_finish(e->encoder.flac.file);
1303                 }
1304         }
1305
1306         if(e->total_samples_to_encode > 0) {
1307                 print_stats(e);
1308                 flac__utils_printf(stderr, 2, "\n");
1309         }
1310
1311         if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) {
1312                 print_verify_error(e);
1313                 ret = 1;
1314         }
1315         else {
1316                 if(info_align_carry >= 0) {
1317                         flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d samples to be carried over\n", e->inbasefilename, info_align_carry);
1318                 }
1319                 if(info_align_zero >= 0) {
1320                         flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d zero samples to be appended\n", e->inbasefilename, info_align_zero);
1321                 }
1322         }
1323
1324         EncoderSession_destroy(e);
1325
1326         return ret;
1327 }
1328
1329 int EncoderSession_finish_error(EncoderSession *e)
1330 {
1331         FLAC__StreamEncoderState fse_state;
1332
1333         if(e->total_samples_to_encode > 0)
1334                 flac__utils_printf(stderr, 2, "\n");
1335
1336 #ifdef FLAC__HAS_OGG
1337         if(e->use_ogg) {
1338                 if(e->is_stdout) {
1339                         fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.stream);
1340                 }
1341                 else {
1342                         fse_state = OggFLAC__file_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.file);
1343                 }
1344         }
1345         else
1346 #endif
1347         if(e->is_stdout) {
1348                 fse_state = FLAC__stream_encoder_get_state(e->encoder.flac.stream);
1349         }
1350         else {
1351                 fse_state = FLAC__file_encoder_get_stream_encoder_state(e->encoder.flac.file);
1352         }
1353
1354         if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
1355                 print_verify_error(e);
1356         else
1357                 unlink(e->outfilename);
1358
1359         EncoderSession_destroy(e);
1360
1361         return 1;
1362 }
1363
1364 FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate)
1365 {
1366         unsigned num_metadata;
1367         FLAC__StreamMetadata padding, *cuesheet = 0;
1368         FLAC__StreamMetadata *metadata[4];
1369         const FLAC__bool is_cdda = (channels == 1 || channels == 2) && (bps == 16) && (sample_rate == 44100);
1370
1371         e->replay_gain = options.replay_gain;
1372         e->channels = channels;
1373         e->bits_per_sample = bps;
1374         e->sample_rate = sample_rate;
1375
1376         if(e->replay_gain) {
1377                 if(channels != 1 && channels != 2) {
1378                         flac__utils_printf(stderr, 1, "%s: ERROR, number of channels (%u) must be 1 or 2 for --replay-gain\n", e->inbasefilename, channels);
1379                         return false;
1380                 }
1381                 if(!grabbag__replaygain_is_valid_sample_frequency(sample_rate)) {
1382                         flac__utils_printf(stderr, 1, "%s: ERROR, invalid sample rate (%u) for --replay-gain\n", e->inbasefilename, sample_rate);
1383                         return false;
1384                 }
1385                 if(options.is_first_file) {
1386                         if(!grabbag__replaygain_init(sample_rate)) {
1387                                 flac__utils_printf(stderr, 1, "%s: ERROR initializing ReplayGain stage\n", e->inbasefilename);
1388                                 return false;
1389                         }
1390                 }
1391         }
1392
1393         if(channels != 2)
1394                 options.do_mid_side = options.loose_mid_side = false;
1395
1396         if(!parse_cuesheet_(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode))
1397                 return false;
1398
1399         if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? cuesheet : 0, e)) {
1400                 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1401                 if(0 != cuesheet)
1402                         FLAC__metadata_object_delete(cuesheet);
1403                 return false;
1404         }
1405
1406         num_metadata = 0;
1407         if(e->seek_table_template->data.seek_table.num_points > 0) {
1408                 e->seek_table_template->is_last = false; /* the encoder will set this for us */
1409                 metadata[num_metadata++] = e->seek_table_template;
1410         }
1411         if(0 != cuesheet)
1412                 metadata[num_metadata++] = cuesheet;
1413         metadata[num_metadata++] = options.vorbis_comment;
1414         if(options.padding > 0) {
1415                 padding.is_last = false; /* the encoder will set this for us */
1416                 padding.type = FLAC__METADATA_TYPE_PADDING;
1417                 padding.length = (unsigned)options.padding;
1418                 metadata[num_metadata++] = &padding;
1419         }
1420
1421         e->blocksize = options.blocksize;
1422         e->stats_mask = (options.do_exhaustive_model_search || options.do_qlp_coeff_prec_search)? 0x0f : 0x3f;
1423
1424 #ifdef FLAC__HAS_OGG
1425         if(e->use_ogg) {
1426                 if(e->is_stdout) {
1427                         OggFLAC__stream_encoder_set_serial_number(e->encoder.ogg.stream, options.serial_number);
1428                         OggFLAC__stream_encoder_set_verify(e->encoder.ogg.stream, options.verify);
1429                         OggFLAC__stream_encoder_set_streamable_subset(e->encoder.ogg.stream, !options.lax);
1430                         OggFLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.ogg.stream, options.do_mid_side);
1431                         OggFLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.ogg.stream, options.loose_mid_side);
1432                         OggFLAC__stream_encoder_set_channels(e->encoder.ogg.stream, channels);
1433                         OggFLAC__stream_encoder_set_bits_per_sample(e->encoder.ogg.stream, bps);
1434                         OggFLAC__stream_encoder_set_sample_rate(e->encoder.ogg.stream, sample_rate);
1435                         OggFLAC__stream_encoder_set_blocksize(e->encoder.ogg.stream, options.blocksize);
1436                         OggFLAC__stream_encoder_set_max_lpc_order(e->encoder.ogg.stream, options.max_lpc_order);
1437                         OggFLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.ogg.stream, options.qlp_coeff_precision);
1438                         OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.stream, options.do_qlp_coeff_prec_search);
1439                         OggFLAC__stream_encoder_set_do_escape_coding(e->encoder.ogg.stream, options.do_escape_coding);
1440                         OggFLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.ogg.stream, options.do_exhaustive_model_search);
1441                         OggFLAC__stream_encoder_set_min_residual_partition_order(e->encoder.ogg.stream, options.min_residual_partition_order);
1442                         OggFLAC__stream_encoder_set_max_residual_partition_order(e->encoder.ogg.stream, options.max_residual_partition_order);
1443                         OggFLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.ogg.stream, options.rice_parameter_search_dist);
1444                         OggFLAC__stream_encoder_set_total_samples_estimate(e->encoder.ogg.stream, e->total_samples_to_encode);
1445                         OggFLAC__stream_encoder_set_metadata(e->encoder.ogg.stream, (num_metadata > 0)? metadata : 0, num_metadata);
1446                         OggFLAC__stream_encoder_set_write_callback(e->encoder.ogg.stream, ogg_stream_encoder_write_callback);
1447                         OggFLAC__stream_encoder_set_metadata_callback(e->encoder.ogg.stream, ogg_stream_encoder_metadata_callback);
1448                         OggFLAC__stream_encoder_set_client_data(e->encoder.ogg.stream, e);
1449
1450                         OggFLAC__stream_encoder_disable_constant_subframes(e->encoder.ogg.stream, options.debug.disable_constant_subframes);
1451                         OggFLAC__stream_encoder_disable_fixed_subframes(e->encoder.ogg.stream, options.debug.disable_fixed_subframes);
1452                         OggFLAC__stream_encoder_disable_verbatim_subframes(e->encoder.ogg.stream, options.debug.disable_verbatim_subframes);
1453
1454                         if(OggFLAC__stream_encoder_init(e->encoder.ogg.stream) != FLAC__STREAM_ENCODER_OK) {
1455                                 print_error_with_state(e, "ERROR initializing encoder");
1456                                 if(0 != cuesheet)
1457                                         FLAC__metadata_object_delete(cuesheet);
1458                                 return false;
1459                         }
1460                 }
1461                 else {
1462                         OggFLAC__file_encoder_set_serial_number(e->encoder.ogg.file, options.serial_number);
1463                         OggFLAC__file_encoder_set_filename(e->encoder.ogg.file, e->outfilename);
1464                         OggFLAC__file_encoder_set_verify(e->encoder.ogg.file, options.verify);
1465                         OggFLAC__file_encoder_set_streamable_subset(e->encoder.ogg.file, !options.lax);
1466                         OggFLAC__file_encoder_set_do_mid_side_stereo(e->encoder.ogg.file, options.do_mid_side);
1467                         OggFLAC__file_encoder_set_loose_mid_side_stereo(e->encoder.ogg.file, options.loose_mid_side);
1468                         OggFLAC__file_encoder_set_channels(e->encoder.ogg.file, channels);
1469                         OggFLAC__file_encoder_set_bits_per_sample(e->encoder.ogg.file, bps);
1470                         OggFLAC__file_encoder_set_sample_rate(e->encoder.ogg.file, sample_rate);
1471                         OggFLAC__file_encoder_set_blocksize(e->encoder.ogg.file, options.blocksize);
1472                         OggFLAC__file_encoder_set_max_lpc_order(e->encoder.ogg.file, options.max_lpc_order);
1473                         OggFLAC__file_encoder_set_qlp_coeff_precision(e->encoder.ogg.file, options.qlp_coeff_precision);
1474                         OggFLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.file, options.do_qlp_coeff_prec_search);
1475                         OggFLAC__file_encoder_set_do_escape_coding(e->encoder.ogg.file, options.do_escape_coding);
1476                         OggFLAC__file_encoder_set_do_exhaustive_model_search(e->encoder.ogg.file, options.do_exhaustive_model_search);
1477                         OggFLAC__file_encoder_set_min_residual_partition_order(e->encoder.ogg.file, options.min_residual_partition_order);
1478                         OggFLAC__file_encoder_set_max_residual_partition_order(e->encoder.ogg.file, options.max_residual_partition_order);
1479                         OggFLAC__file_encoder_set_rice_parameter_search_dist(e->encoder.ogg.file, options.rice_parameter_search_dist);
1480                         OggFLAC__file_encoder_set_total_samples_estimate(e->encoder.ogg.file, e->total_samples_to_encode);
1481                         OggFLAC__file_encoder_set_metadata(e->encoder.ogg.file, (num_metadata > 0)? metadata : 0, num_metadata);
1482                         OggFLAC__file_encoder_set_progress_callback(e->encoder.ogg.file, ogg_file_encoder_progress_callback);
1483                         OggFLAC__file_encoder_set_client_data(e->encoder.ogg.file, e);
1484
1485                         OggFLAC__file_encoder_disable_constant_subframes(e->encoder.ogg.file, options.debug.disable_constant_subframes);
1486                         OggFLAC__file_encoder_disable_fixed_subframes(e->encoder.ogg.file, options.debug.disable_fixed_subframes);
1487                         OggFLAC__file_encoder_disable_verbatim_subframes(e->encoder.ogg.file, options.debug.disable_verbatim_subframes);
1488
1489                         if(OggFLAC__file_encoder_init(e->encoder.ogg.file) != OggFLAC__FILE_ENCODER_OK) {
1490                                 print_error_with_state(e, "ERROR initializing encoder");
1491                                 if(0 != cuesheet)
1492                                         FLAC__metadata_object_delete(cuesheet);
1493                                 return false;
1494                         }
1495                 }
1496         }
1497         else
1498 #endif
1499         if(e->is_stdout) {
1500                 FLAC__stream_encoder_set_verify(e->encoder.flac.stream, options.verify);
1501                 FLAC__stream_encoder_set_streamable_subset(e->encoder.flac.stream, !options.lax);
1502                 FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.flac.stream, options.do_mid_side);
1503                 FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.flac.stream, options.loose_mid_side);
1504                 FLAC__stream_encoder_set_channels(e->encoder.flac.stream, channels);
1505                 FLAC__stream_encoder_set_bits_per_sample(e->encoder.flac.stream, bps);
1506                 FLAC__stream_encoder_set_sample_rate(e->encoder.flac.stream, sample_rate);
1507                 FLAC__stream_encoder_set_blocksize(e->encoder.flac.stream, options.blocksize);
1508                 FLAC__stream_encoder_set_max_lpc_order(e->encoder.flac.stream, options.max_lpc_order);
1509                 FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.flac.stream, options.qlp_coeff_precision);
1510                 FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.stream, options.do_qlp_coeff_prec_search);
1511                 FLAC__stream_encoder_set_do_escape_coding(e->encoder.flac.stream, options.do_escape_coding);
1512                 FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.flac.stream, options.do_exhaustive_model_search);
1513                 FLAC__stream_encoder_set_min_residual_partition_order(e->encoder.flac.stream, options.min_residual_partition_order);
1514                 FLAC__stream_encoder_set_max_residual_partition_order(e->encoder.flac.stream, options.max_residual_partition_order);
1515                 FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.flac.stream, options.rice_parameter_search_dist);
1516                 FLAC__stream_encoder_set_total_samples_estimate(e->encoder.flac.stream, e->total_samples_to_encode);
1517                 FLAC__stream_encoder_set_metadata(e->encoder.flac.stream, (num_metadata > 0)? metadata : 0, num_metadata);
1518                 FLAC__stream_encoder_set_write_callback(e->encoder.flac.stream, flac_stream_encoder_write_callback);
1519                 FLAC__stream_encoder_set_metadata_callback(e->encoder.flac.stream, flac_stream_encoder_metadata_callback);
1520                 FLAC__stream_encoder_set_client_data(e->encoder.flac.stream, e);
1521
1522                 FLAC__stream_encoder_disable_constant_subframes(e->encoder.flac.stream, options.debug.disable_constant_subframes);
1523                 FLAC__stream_encoder_disable_fixed_subframes(e->encoder.flac.stream, options.debug.disable_fixed_subframes);
1524                 FLAC__stream_encoder_disable_verbatim_subframes(e->encoder.flac.stream, options.debug.disable_verbatim_subframes);
1525
1526                 if(FLAC__stream_encoder_init(e->encoder.flac.stream) != FLAC__STREAM_ENCODER_OK) {
1527                         print_error_with_state(e, "ERROR initializing encoder");
1528                         if(0 != cuesheet)
1529                                 FLAC__metadata_object_delete(cuesheet);
1530                         return false;
1531                 }
1532         }
1533         else {
1534                 FLAC__file_encoder_set_filename(e->encoder.flac.file, e->outfilename);
1535                 FLAC__file_encoder_set_verify(e->encoder.flac.file, options.verify);
1536                 FLAC__file_encoder_set_streamable_subset(e->encoder.flac.file, !options.lax);
1537                 FLAC__file_encoder_set_do_mid_side_stereo(e->encoder.flac.file, options.do_mid_side);
1538                 FLAC__file_encoder_set_loose_mid_side_stereo(e->encoder.flac.file, options.loose_mid_side);
1539                 FLAC__file_encoder_set_channels(e->encoder.flac.file, channels);
1540                 FLAC__file_encoder_set_bits_per_sample(e->encoder.flac.file, bps);
1541                 FLAC__file_encoder_set_sample_rate(e->encoder.flac.file, sample_rate);
1542                 FLAC__file_encoder_set_blocksize(e->encoder.flac.file, options.blocksize);
1543                 FLAC__file_encoder_set_max_lpc_order(e->encoder.flac.file, options.max_lpc_order);
1544                 FLAC__file_encoder_set_qlp_coeff_precision(e->encoder.flac.file, options.qlp_coeff_precision);
1545                 FLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.file, options.do_qlp_coeff_prec_search);
1546                 FLAC__file_encoder_set_do_escape_coding(e->encoder.flac.file, options.do_escape_coding);
1547                 FLAC__file_encoder_set_do_exhaustive_model_search(e->encoder.flac.file, options.do_exhaustive_model_search);
1548                 FLAC__file_encoder_set_min_residual_partition_order(e->encoder.flac.file, options.min_residual_partition_order);
1549                 FLAC__file_encoder_set_max_residual_partition_order(e->encoder.flac.file, options.max_residual_partition_order);
1550                 FLAC__file_encoder_set_rice_parameter_search_dist(e->encoder.flac.file, options.rice_parameter_search_dist);
1551                 FLAC__file_encoder_set_total_samples_estimate(e->encoder.flac.file, e->total_samples_to_encode);
1552                 FLAC__file_encoder_set_metadata(e->encoder.flac.file, (num_metadata > 0)? metadata : 0, num_metadata);
1553                 FLAC__file_encoder_set_progress_callback(e->encoder.flac.file, flac_file_encoder_progress_callback);
1554                 FLAC__file_encoder_set_client_data(e->encoder.flac.file, e);
1555
1556                 FLAC__file_encoder_disable_constant_subframes(e->encoder.flac.file, options.debug.disable_constant_subframes);
1557                 FLAC__file_encoder_disable_fixed_subframes(e->encoder.flac.file, options.debug.disable_fixed_subframes);
1558                 FLAC__file_encoder_disable_verbatim_subframes(e->encoder.flac.file, options.debug.disable_verbatim_subframes);
1559
1560                 if(FLAC__file_encoder_init(e->encoder.flac.file) != FLAC__FILE_ENCODER_OK) {
1561                         print_error_with_state(e, "ERROR initializing encoder");
1562                         if(0 != cuesheet)
1563                                 FLAC__metadata_object_delete(cuesheet);
1564                         return false;
1565                 }
1566         }
1567
1568         if(0 != cuesheet)
1569                 FLAC__metadata_object_delete(cuesheet);
1570
1571         return true;
1572 }
1573
1574 FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples)
1575 {
1576         if(e->replay_gain) {
1577                 if(!grabbag__replaygain_analyze(buffer, e->channels==2, e->bits_per_sample, samples)) {
1578                         flac__utils_printf(stderr, 1, "%s: WARNING, error while calculating ReplayGain\n", e->inbasefilename);
1579                 }
1580         }
1581
1582 #ifdef FLAC__HAS_OGG
1583         if(e->use_ogg) {
1584                 if(e->is_stdout) {
1585                         return OggFLAC__stream_encoder_process(e->encoder.ogg.stream, buffer, samples);
1586                 }
1587                 else {
1588                         return OggFLAC__file_encoder_process(e->encoder.ogg.file, buffer, samples);
1589                 }
1590         }
1591         else
1592 #endif
1593         if(e->is_stdout) {
1594                 return FLAC__stream_encoder_process(e->encoder.flac.stream, buffer, samples);
1595         }
1596         else {
1597                 return FLAC__file_encoder_process(e->encoder.flac.file, buffer, samples);
1598         }
1599 }
1600
1601 FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e)
1602 {
1603         const FLAC__bool only_placeholders = e->is_stdout;
1604         FLAC__bool has_real_points;
1605
1606         if(num_requested_seek_points == 0 && 0 == cuesheet)
1607                 return true;
1608
1609         if(num_requested_seek_points < 0) {
1610                 requested_seek_points = "10s;";
1611                 num_requested_seek_points = 1;
1612         }
1613
1614         if(num_requested_seek_points > 0) {
1615                 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))
1616                         return false;
1617         }
1618
1619         if(0 != cuesheet) {
1620                 unsigned i, j;
1621                 const FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
1622                 for(i = 0; i < cs->num_tracks; i++) {
1623                         const FLAC__StreamMetadata_CueSheet_Track *tr = cs->tracks+i;
1624                         for(j = 0; j < tr->num_indices; j++) {
1625                                 if(!FLAC__metadata_object_seektable_template_append_point(e->seek_table_template, tr->offset + tr->indices[j].offset))
1626                                         return false;
1627                                 has_real_points = true;
1628                         }
1629                 }
1630                 if(has_real_points)
1631                         if(!FLAC__metadata_object_seektable_template_sort(e->seek_table_template, /*compact=*/true))
1632                                 return false;
1633         }
1634
1635         if(has_real_points) {
1636                 if(e->is_stdout) {
1637                         flac__utils_printf(stderr, 1, "%s: WARNING, cannot write back seekpoints when encoding to stdout\n", e->inbasefilename);
1638                 }
1639         }
1640
1641         return true;
1642 }
1643
1644 FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
1645 {
1646         /* convert from mm:ss.sss to sample number if necessary */
1647         flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
1648
1649         /* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
1650         if(spec->is_relative && spec->value.samples == 0) {
1651                 spec->is_relative = false;
1652                 return true;
1653         }
1654
1655         /* in any other case the total samples in the input must be known */
1656         if(total_samples_in_input == 0) {
1657                 flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when input length is unknown\n", inbasefilename);
1658                 return false;
1659         }
1660
1661         FLAC__ASSERT(spec->value_is_samples);
1662
1663         /* convert relative specifications to absolute */
1664         if(spec->is_relative) {
1665                 if(spec->value.samples <= 0)
1666                         spec->value.samples += (FLAC__int64)total_samples_in_input;
1667                 else
1668                         spec->value.samples += skip;
1669                 spec->is_relative = false;
1670         }
1671
1672         /* error check */
1673         if(spec->value.samples < 0) {
1674                 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
1675                 return false;
1676         }
1677         if((FLAC__uint64)spec->value.samples <= skip) {
1678                 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
1679                 return false;
1680         }
1681         if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
1682                 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is after end of input\n", inbasefilename);
1683                 return false;
1684         }
1685
1686         return true;
1687 }
1688
1689 void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps)
1690 {
1691         unsigned wide_sample, sample, channel, byte;
1692
1693         if(bps == 8) {
1694                 if(is_unsigned_samples) {
1695                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1696                                 for(channel = 0; channel < channels; channel++, sample++)
1697                                         dest[channel][wide_sample] = (FLAC__int32)ucbuffer_[sample] - 0x80;
1698                 }
1699                 else {
1700                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1701                                 for(channel = 0; channel < channels; channel++, sample++)
1702                                         dest[channel][wide_sample] = (FLAC__int32)scbuffer_[sample];
1703                 }
1704         }
1705         else if(bps == 16) {
1706                 if(is_big_endian != is_big_endian_host_) {
1707                         unsigned char tmp;
1708                         const unsigned bytes = wide_samples * channels * (bps >> 3);
1709                         for(byte = 0; byte < bytes; byte += 2) {
1710                                 tmp = ucbuffer_[byte];
1711                                 ucbuffer_[byte] = ucbuffer_[byte+1];
1712                                 ucbuffer_[byte+1] = tmp;
1713                         }
1714                 }
1715                 if(is_unsigned_samples) {
1716                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1717                                 for(channel = 0; channel < channels; channel++, sample++)
1718                                         dest[channel][wide_sample] = (FLAC__int32)usbuffer_[sample] - 0x8000;
1719                 }
1720                 else {
1721                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1722                                 for(channel = 0; channel < channels; channel++, sample++)
1723                                         dest[channel][wide_sample] = (FLAC__int32)ssbuffer_[sample];
1724                 }
1725         }
1726         else if(bps == 24) {
1727                 if(!is_big_endian) {
1728                         unsigned char tmp;
1729                         const unsigned bytes = wide_samples * channels * (bps >> 3);
1730                         for(byte = 0; byte < bytes; byte += 3) {
1731                                 tmp = ucbuffer_[byte];
1732                                 ucbuffer_[byte] = ucbuffer_[byte+2];
1733                                 ucbuffer_[byte+2] = tmp;
1734                         }
1735                 }
1736                 if(is_unsigned_samples) {
1737                         for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1738                                 for(channel = 0; channel < channels; channel++, sample++) {
1739                                         dest[channel][wide_sample]  = ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1740                                         dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1741                                         dest[channel][wide_sample] |= ucbuffer_[byte++];
1742                                         dest[channel][wide_sample] -= 0x800000;
1743                                 }
1744                 }
1745                 else {
1746                         for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1747                                 for(channel = 0; channel < channels; channel++, sample++) {
1748                                         dest[channel][wide_sample]  = scbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1749                                         dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1750                                         dest[channel][wide_sample] |= ucbuffer_[byte++];
1751                                 }
1752                 }
1753         }
1754         else {
1755                 FLAC__ASSERT(0);
1756         }
1757 }
1758
1759 #ifdef FLAC__HAS_OGG
1760 FLAC__StreamEncoderWriteStatus ogg_stream_encoder_write_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
1761 {
1762         EncoderSession *encoder_session = (EncoderSession*)client_data;
1763
1764         (void)encoder;
1765
1766         encoder_session->bytes_written += bytes;
1767         /*
1768          * With Ogg FLAC we don't get one write callback per frame and
1769          * we don't have a good number for 'samples', so we estimate based
1770          * on the frame number and the knowledge that all blocks (except
1771          * the last) are the same size.
1772          */
1773         (void)samples;
1774         encoder_session->samples_written = (current_frame+1) * encoder_session->blocksize;
1775
1776         if(encoder_session->total_samples_to_encode > 0 && !(current_frame & encoder_session->stats_mask))
1777                 print_stats(encoder_session);
1778
1779         if(flac__utils_fwrite(buffer, sizeof(FLAC__byte), bytes, encoder_session->fout) == bytes)
1780                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
1781         else
1782                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1783 }
1784
1785 void ogg_stream_encoder_metadata_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
1786 {
1787         // do nothing, for compatibilty.  soon we will be using the ogg file encoder anyway.
1788         (void)encoder, (void)metadata, (void)client_data;
1789 }
1790
1791 void ogg_file_encoder_progress_callback(const OggFLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
1792 {
1793         EncoderSession *encoder_session = (EncoderSession*)client_data;
1794
1795         (void)encoder;
1796
1797         /*
1798          * With Ogg FLAC we don't get a value for 'samples_written', so we
1799          * estimate based on the frames written and the knowledge that all
1800          * blocks (except the last) are the same size.
1801          */
1802         samples_written = frames_written * encoder_session->blocksize;
1803         flac_file_encoder_progress_callback(0, bytes_written, samples_written, frames_written, total_frames_estimate, client_data);
1804 }
1805
1806 #endif
1807
1808 FLAC__StreamEncoderWriteStatus flac_stream_encoder_write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
1809 {
1810         EncoderSession *encoder_session = (EncoderSession*)client_data;
1811
1812         (void)encoder;
1813
1814         encoder_session->bytes_written += bytes;
1815         encoder_session->samples_written += samples;
1816
1817         if(samples && encoder_session->total_samples_to_encode > 0 && !(current_frame & encoder_session->stats_mask))
1818                 print_stats(encoder_session);
1819
1820         if(flac__utils_fwrite(buffer, sizeof(FLAC__byte), bytes, encoder_session->fout) == bytes)
1821                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
1822         else
1823                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1824 }
1825
1826 void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
1827 {
1828         /*
1829          * Nothing to do; if we get here, we're decoding to stdout, in
1830          * which case we can't seek backwards to write new metadata.
1831          */
1832         (void)encoder, (void)metadata, (void)client_data;
1833 }
1834
1835 void flac_file_encoder_progress_callback(const FLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
1836 {
1837         EncoderSession *encoder_session = (EncoderSession*)client_data;
1838
1839         (void)encoder, (void)total_frames_estimate;
1840
1841         encoder_session->bytes_written = bytes_written;
1842         encoder_session->samples_written = samples_written;
1843
1844         if(encoder_session->total_samples_to_encode > 0 && !((frames_written-1) & encoder_session->stats_mask))
1845                 print_stats(encoder_session);
1846 }
1847
1848 FLAC__bool parse_cuesheet_(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
1849 {
1850         FILE *f;
1851         unsigned last_line_read;
1852         const char *error_message;
1853
1854         if(0 == cuesheet_filename)
1855                 return true;
1856
1857         if(lead_out_offset == 0) {
1858                 flac__utils_printf(stderr, 1, "%s: ERROR cannot import cuesheet when the number of input samples to encode is unknown\n", inbasefilename);
1859                 return false;
1860         }
1861
1862         if(0 == (f = fopen(cuesheet_filename, "r"))) {
1863                 flac__utils_printf(stderr, 1, "%s: ERROR opening cuesheet \"%s\" for reading\n", inbasefilename, cuesheet_filename);
1864                 return false;
1865         }
1866
1867         *cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, is_cdda, lead_out_offset);
1868
1869         fclose(f);
1870
1871         if(0 == *cuesheet) {
1872                 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\" on line %u: %s\n", inbasefilename, cuesheet_filename, last_line_read, error_message);
1873                 return false;
1874         }
1875
1876         if(!FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/false, &error_message)) {
1877                 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\": %s\n", inbasefilename, cuesheet_filename, error_message);
1878                 return false;
1879         }
1880
1881         /* if we're expecting CDDA, warn about non-compliance */
1882         if(is_cdda && !FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/true, &error_message)) {
1883                 flac__utils_printf(stderr, 1, "%s: WARNING cuesheet \"%s\" is not audio CD compliant: %s\n", inbasefilename, cuesheet_filename, error_message);
1884                 (*cuesheet)->data.cue_sheet.is_cd = false;
1885         }
1886
1887         return true;
1888 }
1889
1890 void print_stats(const EncoderSession *encoder_session)
1891 {
1892         const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written);
1893 #if defined _MSC_VER || defined __MINGW32__
1894         /* with MSVC you have to spoon feed it the casting */
1895         const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode;
1896         const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)encoder_session->unencoded_size * min(1.0, progress));
1897 #else
1898         const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode;
1899         const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * min(1.0, progress));
1900 #endif
1901
1902
1903         if(samples_written == encoder_session->total_samples_to_encode) {
1904                 flac__utils_printf(stderr, 2, "\r%s:%s wrote %u bytes, ratio=%0.3f",
1905                         encoder_session->inbasefilename,
1906                         encoder_session->verify? " Verify OK," : "",
1907                         (unsigned)encoder_session->bytes_written,
1908                         ratio
1909                 );
1910         }
1911         else {
1912                 flac__utils_printf(stderr, 2, "\r%s: %u%% complete, ratio=%0.3f", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio);
1913         }
1914 }
1915
1916 void print_error_with_state(const EncoderSession *e, const char *message)
1917 {
1918         const int ilen = strlen(e->inbasefilename) + 1;
1919         const char *state_string;
1920
1921         flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
1922
1923 #ifdef FLAC__HAS_OGG
1924         if(e->use_ogg) {
1925                 if(e->is_stdout) {
1926                         state_string = OggFLAC__stream_encoder_get_resolved_state_string(e->encoder.ogg.stream);
1927                 }
1928                 else {
1929                         state_string = OggFLAC__file_encoder_get_resolved_state_string(e->encoder.ogg.file);
1930                 }
1931         }
1932         else
1933 #endif
1934         if(e->is_stdout) {
1935                 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder.flac.stream);
1936         }
1937         else {
1938                 state_string = FLAC__file_encoder_get_resolved_state_string(e->encoder.flac.file);
1939         }
1940
1941         flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
1942
1943         /* print out some more info for some errors: */
1944         if(0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_NOT_STREAMABLE])) {
1945                 flac__utils_printf(stderr, 1,
1946                         "\n"
1947                         "The encoding parameters specified do not conform to the FLAC Subset and may not\n"
1948                         "be streamable or playable in hardware devices.  Add --lax to the command-line\n"
1949                         "options to encode with these parameters.\n"
1950                 );
1951         }
1952         else if(
1953                 0 == strcmp(state_string, FLAC__FileEncoderStateString[FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING])
1954 #ifdef FLAC__HAS_OGG
1955                 || 0 == strcmp(state_string, OggFLAC__FileEncoderStateString[OggFLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING])
1956 #endif
1957         ) {
1958                 flac__utils_printf(stderr, 1,
1959                         "\n"
1960                         "An error occurred while writing; the most common cause is that the disk is full.\n"
1961                 );
1962         }
1963         else if(
1964                 0 == strcmp(state_string, FLAC__FileEncoderStateString[FLAC__FILE_ENCODER_ERROR_OPENING_FILE])
1965 #ifdef FLAC__HAS_OGG
1966                 || 0 == strcmp(state_string, OggFLAC__FileEncoderStateString[OggFLAC__FILE_ENCODER_ERROR_OPENING_FILE])
1967 #endif
1968         ) {
1969                 flac__utils_printf(stderr, 1,
1970                         "\n"
1971                         "An error occurred opening the output file; it is likely that the output\n"
1972                         "directory does not exist or is not writable, the output file already exists and\n"
1973                         "is not writable, or the disk is full.\n"
1974                 );
1975         }
1976 }
1977
1978 void print_verify_error(EncoderSession *e)
1979 {
1980         FLAC__uint64 absolute_sample;
1981         unsigned frame_number;
1982         unsigned channel;
1983         unsigned sample;
1984         FLAC__int32 expected;
1985         FLAC__int32 got;
1986
1987 #ifdef FLAC__HAS_OGG
1988         if(e->use_ogg) {
1989                 if(e->is_stdout) {
1990                         OggFLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.ogg.stream, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1991                 }
1992                 else {
1993                         OggFLAC__file_encoder_get_verify_decoder_error_stats(e->encoder.ogg.file, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1994                 }
1995         }
1996         else
1997 #endif
1998         if(e->is_stdout) {
1999                 FLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.flac.stream, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2000         }
2001         else {
2002                 FLAC__file_encoder_get_verify_decoder_error_stats(e->encoder.flac.file, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2003         }
2004
2005         flac__utils_printf(stderr, 1, "%s: ERROR: mismatch in decoded data, verify FAILED!\n", e->inbasefilename);
2006         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);
2007         flac__utils_printf(stderr, 1, "       In all known cases, verify errors are caused by hardware problems,\n");
2008         flac__utils_printf(stderr, 1, "       usually overclocking or bad RAM.  Delete %s\n", e->inbasefilename);
2009         flac__utils_printf(stderr, 1, "       and repeat the flac command exactly as before.  If it does not give a\n");
2010         flac__utils_printf(stderr, 1, "       verify error in the exact same place each time you try it, then there is\n");
2011         flac__utils_printf(stderr, 1, "       a problem with your hardware.  If it does, keep the bad FLAC file and\n");
2012         flac__utils_printf(stderr, 1, "       submit a bug report to:\n");
2013         flac__utils_printf(stderr, 1, "           http://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
2014         flac__utils_printf(stderr, 1, "       Make sure to use the \"Monitor\" feature to monitor the bug status.\n");
2015         flac__utils_printf(stderr, 1, "Verify FAILED!  Do not trust %s\n", e->outfilename);
2016 }
2017
2018 FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2019 {
2020         size_t bytes_read = fread(val, 1, 2, f);
2021
2022         if(bytes_read == 0) {
2023                 if(!eof_ok) {
2024                         flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2025                         return false;
2026                 }
2027                 else
2028                         return true;
2029         }
2030         else if(bytes_read < 2) {
2031                 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2032                 return false;
2033         }
2034         else {
2035                 if(is_big_endian_host_) {
2036                         FLAC__byte tmp, *b = (FLAC__byte*)val;
2037                         tmp = b[1]; b[1] = b[0]; b[0] = tmp;
2038                 }
2039                 return true;
2040         }
2041 }
2042
2043 FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2044 {
2045         size_t bytes_read = fread(val, 1, 4, f);
2046
2047         if(bytes_read == 0) {
2048                 if(!eof_ok) {
2049                         flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2050                         return false;
2051                 }
2052                 else
2053                         return true;
2054         }
2055         else if(bytes_read < 4) {
2056                 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2057                 return false;
2058         }
2059         else {
2060                 if(is_big_endian_host_) {
2061                         FLAC__byte tmp, *b = (FLAC__byte*)val;
2062                         tmp = b[3]; b[3] = b[0]; b[0] = tmp;
2063                         tmp = b[2]; b[2] = b[1]; b[1] = tmp;
2064                 }
2065                 return true;
2066         }
2067 }
2068
2069 FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2070 {
2071         unsigned char buf[4];
2072         size_t bytes_read= fread(buf, 1, 2, f);
2073
2074         if(bytes_read==0U && eof_ok)
2075                 return true;
2076         else if(bytes_read<2U) {
2077                 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2078                 return false;
2079         }
2080
2081         /* this is independent of host endianness */
2082         *val= (FLAC__uint16)(buf[0])<<8 | buf[1];
2083
2084         return true;
2085 }
2086
2087 FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2088 {
2089         unsigned char buf[4];
2090         size_t bytes_read= fread(buf, 1, 4, f);
2091
2092         if(bytes_read==0U && eof_ok)
2093                 return true;
2094         else if(bytes_read<4U) {
2095                 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2096                 return false;
2097         }
2098
2099         /* this is independent of host endianness */
2100         *val= (FLAC__uint32)(buf[0])<<24 | (FLAC__uint32)(buf[1])<<16 |
2101                 (FLAC__uint32)(buf[2])<<8 | buf[3];
2102
2103         return true;
2104 }
2105
2106 FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2107         /* Read an IEEE 754 80-bit (aka SANE) extended floating point value from 'f',
2108          * convert it into an integral value and store in 'val'.  Return false if only
2109          * between 1 and 9 bytes remain in 'f', if 0 bytes remain in 'f' and 'eof_ok' is
2110          * false, or if the value is negative, between zero and one, or too large to be
2111          * represented by 'val'; return true otherwise.
2112          */
2113 {
2114         unsigned int i;
2115         unsigned char buf[10];
2116         size_t bytes_read= fread(buf, 1U, 10U, f);
2117         FLAC__int16 e= ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
2118         FLAC__int16 shift= 63-e;
2119         FLAC__uint64 p= 0U;
2120
2121         if(bytes_read==0U && eof_ok)
2122                 return true;
2123         else if(bytes_read<10U) {
2124                 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2125                 return false;
2126         }
2127         else if((buf[0]>>7)==1U || e<0 || e>63) {
2128                 flac__utils_printf(stderr, 1, "%s: ERROR: invalid floating-point value\n", fn);
2129                 return false;
2130         }
2131
2132         for(i= 0U; i<8U; ++i)
2133                 p|= (FLAC__uint64)(buf[i+2])<<(56U-i*8);
2134         *val= (FLAC__uint32)((p>>shift)+(p>>(shift-1) & 0x1));
2135
2136         return true;
2137 }
2138
2139 FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset)
2140 {
2141         static unsigned char dump[8192];
2142
2143         while(offset > 0) {
2144                 long need = (long)min(offset, LONG_MAX);
2145                 if(fseek(f, need, SEEK_CUR) < 0) {
2146                         need = (long)min(offset, sizeof(dump));
2147                         if(fread(dump, need, 1, f) < 1)
2148                                 return false;
2149                 }
2150                 offset -= need;
2151         }
2152         return true;
2153 }