add 2206 to copyright notice
[platform/upstream/flac.git] / src / flac / encode.c
1 /* flac - Command-line FLAC encoder/decoder
2  * Copyright (C) 2000,2001,2002,2003,2004,2005,2006  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                         FLAC__ASSERT(data_bytes >= 16);
640                         data_bytes -= 16;
641                         if(!fskip_ahead(infile, data_bytes)) {
642                                 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra 'fmt' data\n", encoder_session.inbasefilename);
643                                 return EncoderSession_finish_error(&encoder_session);
644                         }
645
646                         /*
647                          * now that we know the sample rate, canonicalize the
648                          * --skip string to a number of samples:
649                          */
650                         flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
651                         FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
652                         encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
653                         FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
654
655                         got_fmt_chunk = true;
656                 }
657                 else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
658                         FLAC__uint64 total_samples_in_input, trim = 0;
659                         FLAC__bool pad = false;
660                         unsigned data_bytes;
661
662                         /* data size */
663                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
664                                 return EncoderSession_finish_error(&encoder_session);
665                         data_bytes = xx;
666                         pad = (data_bytes & 1U) ? true : false;
667
668                         bytes_per_wide_sample = channels * (bps >> 3);
669
670                         /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
671                         FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
672                         total_samples_in_input = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;
673
674                         /*
675                          * now that we know the input size, canonicalize the
676                          * --until string to an absolute sample number:
677                          */
678                         if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
679                                 return EncoderSession_finish_error(&encoder_session);
680                         encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
681                         FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
682
683                         if(encoder_session.skip > 0) {
684                                 if(!fskip_ahead(infile, encoder_session.skip * bytes_per_wide_sample)) {
685                                         flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
686                                         return EncoderSession_finish_error(&encoder_session);
687                                 }
688                         }
689
690                         data_bytes -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
691                         encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
692                         if(encoder_session.until > 0) {
693                                 trim = total_samples_in_input - encoder_session.until;
694                                 FLAC__ASSERT(total_samples_in_input > 0);
695                                 FLAC__ASSERT(!options.common.sector_align);
696                                 data_bytes -= (unsigned int)trim * bytes_per_wide_sample;
697                                 encoder_session.total_samples_to_encode -= trim;
698                         }
699                         if(options.common.sector_align) {
700                                 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
701                                 if(options.common.is_last_file)
702                                         encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
703                                 else
704                                         encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
705                         }
706
707                         /* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
708                         encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample + 44;
709
710                         if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate))
711                                 return EncoderSession_finish_error(&encoder_session);
712
713                         /*
714                          * first do any samples in the reservoir
715                          */
716                         if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
717                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
718                                         print_error_with_state(&encoder_session, "ERROR during encoding");
719                                         return EncoderSession_finish_error(&encoder_session);
720                                 }
721                         }
722
723                         /*
724                          * decrement the data_bytes counter if we need to align the file
725                          */
726                         if(options.common.sector_align) {
727                                 if(options.common.is_last_file) {
728                                         *options.common.align_reservoir_samples = 0;
729                                 }
730                                 else {
731                                         *options.common.align_reservoir_samples = align_remainder;
732                                         data_bytes -= (*options.common.align_reservoir_samples) * bytes_per_wide_sample;
733                                 }
734                         }
735
736                         /*
737                          * now do from the file
738                          */
739                         while(data_bytes > 0) {
740                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), min(data_bytes, CHUNK_OF_SAMPLES * bytes_per_wide_sample), infile);
741                                 if(bytes_read == 0) {
742                                         if(ferror(infile)) {
743                                                 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
744                                                 return EncoderSession_finish_error(&encoder_session);
745                                         }
746                                         else if(feof(infile)) {
747                                                 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);
748                                                 data_bytes = 0;
749                                         }
750                                 }
751                                 else {
752                                         if(bytes_read % bytes_per_wide_sample != 0) {
753                                                 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
754                                                 return EncoderSession_finish_error(&encoder_session);
755                                         }
756                                         else {
757                                                 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
758                                                 format_input(input_, wide_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps);
759
760                                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
761                                                         print_error_with_state(&encoder_session, "ERROR during encoding");
762                                                         return EncoderSession_finish_error(&encoder_session);
763                                                 }
764                                                 data_bytes -= bytes_read;
765                                         }
766                                 }
767                         }
768
769                         if(trim > 0) {
770                                 FLAC__ASSERT(!options.common.sector_align);
771                                 if(!fskip_ahead(infile, trim * bytes_per_wide_sample)) {
772                                         flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
773                                         return EncoderSession_finish_error(&encoder_session);
774                                 }
775                         }
776
777                         /*
778                          * now read unaligned samples into reservoir or pad with zeroes if necessary
779                          */
780                         if(options.common.sector_align) {
781                                 if(options.common.is_last_file) {
782                                         unsigned wide_samples = 588 - align_remainder;
783                                         if(wide_samples < 588) {
784                                                 unsigned channel;
785
786                                                 info_align_zero = wide_samples;
787                                                 for(channel = 0; channel < channels; channel++)
788                                                         memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
789
790                                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
791                                                         print_error_with_state(&encoder_session, "ERROR during encoding");
792                                                         return EncoderSession_finish_error(&encoder_session);
793                                                 }
794                                         }
795                                 }
796                                 else {
797                                         if(*options.common.align_reservoir_samples > 0) {
798                                                 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
799                                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
800                                                 if(bytes_read == 0 && ferror(infile)) {
801                                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
802                                                         return EncoderSession_finish_error(&encoder_session);
803                                                 }
804                                                 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
805                                                         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);
806                                                 }
807                                                 else {
808                                                         info_align_carry = *options.common.align_reservoir_samples;
809                                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps);
810                                                 }
811                                         }
812                                 }
813                         }
814
815                         if(pad == true) {
816                                 unsigned char tmp;
817
818                                 if(fread(&tmp, 1U, 1U, infile) < 1U) {
819                                         flac__utils_printf(stderr, 1, "%s: ERROR during read of data pad byte\n", encoder_session.inbasefilename);
820                                         return EncoderSession_finish_error(&encoder_session);
821                                 }
822                         }
823
824                         got_data_chunk = true;
825                 }
826                 else {
827                         if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
828                                 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename);
829                         }
830                         else if(xx == 0x61746164) { /* "data" */
831                                 if(got_data_chunk) {
832                                         flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename);
833                                 }
834                                 else if(!got_fmt_chunk) {
835                                         flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
836                                         return EncoderSession_finish_error(&encoder_session);
837                                 }
838                                 else {
839                                         FLAC__ASSERT(0);
840                                 }
841                         }
842                         else {
843                                 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));
844                         }
845                         /* sub-chunk size */
846                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
847                                 return EncoderSession_finish_error(&encoder_session);
848                         else {
849                                 unsigned long skip = xx+(xx & 1U);
850
851                                 FLAC__ASSERT(skip<=LONG_MAX);
852                                 if(!fskip_ahead(infile, skip)) {
853                                         flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_session.inbasefilename);
854                                         return EncoderSession_finish_error(&encoder_session);
855                                 }
856                         }
857                 }
858         }
859
860         return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
861 }
862
863 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)
864 {
865         EncoderSession encoder_session;
866         size_t bytes_read;
867         const size_t bytes_per_wide_sample = options.channels * (options.bps >> 3);
868         unsigned align_remainder = 0;
869         int info_align_carry = -1, info_align_zero = -1;
870         FLAC__uint64 total_samples_in_input = 0;
871
872         FLAC__ASSERT(!options.common.sector_align || options.channels == 2);
873         FLAC__ASSERT(!options.common.sector_align || options.bps == 16);
874         FLAC__ASSERT(!options.common.sector_align || options.sample_rate == 44100);
875         FLAC__ASSERT(!options.common.sector_align || infilesize >= 0);
876         FLAC__ASSERT(!options.common.replay_gain || options.channels <= 2);
877         FLAC__ASSERT(!options.common.replay_gain || grabbag__replaygain_is_valid_sample_frequency(options.sample_rate));
878
879         if(!
880                 EncoderSession_construct(
881                         &encoder_session,
882 #ifdef FLAC__HAS_OGG
883                         options.common.use_ogg,
884 #else
885                         /*use_ogg=*/false,
886 #endif
887                         options.common.verify,
888                         infile,
889                         infilename,
890                         outfilename
891                 )
892         )
893                 return 1;
894
895         /*
896          * now that we know the sample rate, canonicalize the
897          * --skip string to a number of samples:
898          */
899         flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, options.sample_rate);
900         FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
901         encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
902         FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
903
904         if(infilesize < 0)
905                 total_samples_in_input = 0;
906         else {
907                 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
908                 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
909                 total_samples_in_input = (unsigned)infilesize / bytes_per_wide_sample + *options.common.align_reservoir_samples;
910         }
911
912         /*
913          * now that we know the input size, canonicalize the
914          * --until strings to a number of samples:
915          */
916         if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, options.sample_rate, encoder_session.skip, total_samples_in_input))
917                 return EncoderSession_finish_error(&encoder_session);
918         encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
919         FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
920
921         infilesize -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
922         encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
923         if(encoder_session.until > 0) {
924                 const FLAC__uint64 trim = total_samples_in_input - encoder_session.until;
925                 FLAC__ASSERT(total_samples_in_input > 0);
926                 FLAC__ASSERT(!options.common.sector_align);
927                 infilesize -= (unsigned int)trim * bytes_per_wide_sample;
928                 encoder_session.total_samples_to_encode -= trim;
929         }
930         if(infilesize >= 0 && options.common.sector_align) {
931                 FLAC__ASSERT(encoder_session.skip == 0);
932                 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
933                 if(options.common.is_last_file)
934                         encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
935                 else
936                         encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
937         }
938         encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample;
939
940         if(encoder_session.total_samples_to_encode <= 0)
941                 flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
942
943         if(encoder_session.skip > 0) {
944                 unsigned skip_bytes = bytes_per_wide_sample * (unsigned)encoder_session.skip;
945                 if(skip_bytes > lookahead_length) {
946                         skip_bytes -= lookahead_length;
947                         lookahead_length = 0;
948                         if(!fskip_ahead(infile, skip_bytes)) {
949                                 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
950                                 return EncoderSession_finish_error(&encoder_session);
951                         }
952                 }
953                 else {
954                         lookahead += skip_bytes;
955                         lookahead_length -= skip_bytes;
956                 }
957         }
958
959         if(!EncoderSession_init_encoder(&encoder_session, options.common, options.channels, options.bps, options.sample_rate))
960                 return EncoderSession_finish_error(&encoder_session);
961
962         /*
963          * first do any samples in the reservoir
964          */
965         if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
966                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
967                         print_error_with_state(&encoder_session, "ERROR during encoding");
968                         return EncoderSession_finish_error(&encoder_session);
969                 }
970         }
971
972         /*
973          * decrement infilesize if we need to align the file
974          */
975         if(options.common.sector_align) {
976                 FLAC__ASSERT(infilesize >= 0);
977                 if(options.common.is_last_file) {
978                         *options.common.align_reservoir_samples = 0;
979                 }
980                 else {
981                         *options.common.align_reservoir_samples = align_remainder;
982                         infilesize -= (long)((*options.common.align_reservoir_samples) * bytes_per_wide_sample);
983                         FLAC__ASSERT(infilesize >= 0);
984                 }
985         }
986
987         /*
988          * now do from the file
989          */
990         if(infilesize < 0) {
991                 while(!feof(infile)) {
992                         if(lookahead_length > 0) {
993                                 FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * bytes_per_wide_sample);
994                                 memcpy(ucbuffer_, lookahead, lookahead_length);
995                                 bytes_read = fread(ucbuffer_+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
996                                 if(ferror(infile)) {
997                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
998                                         return EncoderSession_finish_error(&encoder_session);
999                                 }
1000                                 lookahead_length = 0;
1001                         }
1002                         else
1003                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample, infile);
1004
1005                         if(bytes_read == 0) {
1006                                 if(ferror(infile)) {
1007                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1008                                         return EncoderSession_finish_error(&encoder_session);
1009                                 }
1010                         }
1011                         else if(bytes_read % bytes_per_wide_sample != 0) {
1012                                 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1013                                 return EncoderSession_finish_error(&encoder_session);
1014                         }
1015                         else {
1016                                 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1017                                 format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1018
1019                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1020                                         print_error_with_state(&encoder_session, "ERROR during encoding");
1021                                         return EncoderSession_finish_error(&encoder_session);
1022                                 }
1023                         }
1024                 }
1025         }
1026         else {
1027                 const FLAC__uint64 max_input_bytes = (FLAC__uint64)infilesize;
1028                 FLAC__uint64 total_input_bytes_read = 0;
1029                 while(total_input_bytes_read < max_input_bytes) {
1030                         {
1031                                 size_t wanted = (CHUNK_OF_SAMPLES * bytes_per_wide_sample);
1032                                 wanted = min(wanted, (size_t)(max_input_bytes - total_input_bytes_read));
1033
1034                                 if(lookahead_length > 0) {
1035                                         FLAC__ASSERT(lookahead_length <= wanted);
1036                                         memcpy(ucbuffer_, lookahead, lookahead_length);
1037                                         wanted -= lookahead_length;
1038                                         bytes_read = lookahead_length;
1039                                         if(wanted > 0) {
1040                                                 bytes_read += fread(ucbuffer_+lookahead_length, sizeof(unsigned char), wanted, infile);
1041                                                 if(ferror(infile)) {
1042                                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1043                                                         return EncoderSession_finish_error(&encoder_session);
1044                                                 }
1045                                         }
1046                                         lookahead_length = 0;
1047                                 }
1048                                 else
1049                                         bytes_read = fread(ucbuffer_, sizeof(unsigned char), wanted, infile);
1050                         }
1051
1052                         if(bytes_read == 0) {
1053                                 if(ferror(infile)) {
1054                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1055                                         return EncoderSession_finish_error(&encoder_session);
1056                                 }
1057                                 else if(feof(infile)) {
1058                                         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);
1059                                         total_input_bytes_read = max_input_bytes;
1060                                 }
1061                         }
1062                         else {
1063                                 if(bytes_read % bytes_per_wide_sample != 0) {
1064                                         flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1065                                         return EncoderSession_finish_error(&encoder_session);
1066                                 }
1067                                 else {
1068                                         unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1069                                         format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1070
1071                                         if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1072                                                 print_error_with_state(&encoder_session, "ERROR during encoding");
1073                                                 return EncoderSession_finish_error(&encoder_session);
1074                                         }
1075                                         total_input_bytes_read += bytes_read;
1076                                 }
1077                         }
1078                 }
1079         }
1080
1081         /*
1082          * now read unaligned samples into reservoir or pad with zeroes if necessary
1083          */
1084         if(options.common.sector_align) {
1085                 if(options.common.is_last_file) {
1086                         unsigned wide_samples = 588 - align_remainder;
1087                         if(wide_samples < 588) {
1088                                 unsigned channel;
1089
1090                                 info_align_zero = wide_samples;
1091                                 for(channel = 0; channel < options.channels; channel++)
1092                                         memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
1093
1094                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1095                                         print_error_with_state(&encoder_session, "ERROR during encoding");
1096                                         return EncoderSession_finish_error(&encoder_session);
1097                                 }
1098                         }
1099                 }
1100                 else {
1101                         if(*options.common.align_reservoir_samples > 0) {
1102                                 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
1103                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
1104                                 if(bytes_read == 0 && ferror(infile)) {
1105                                         flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1106                                         return EncoderSession_finish_error(&encoder_session);
1107                                 }
1108                                 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
1109                                         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);
1110                                 }
1111                                 else {
1112                                         info_align_carry = *options.common.align_reservoir_samples;
1113                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1114                                 }
1115                         }
1116                 }
1117         }
1118
1119         return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
1120 }
1121
1122 FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FILE *infile, const char *infilename, const char *outfilename)
1123 {
1124         unsigned i;
1125         FLAC__uint32 test = 1;
1126
1127         /*
1128          * initialize globals
1129          */
1130
1131         is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
1132
1133         for(i = 0; i < FLAC__MAX_CHANNELS; i++)
1134                 input_[i] = &(in_[i][0]);
1135
1136
1137         /*
1138          * initialize instance
1139          */
1140
1141 #ifdef FLAC__HAS_OGG
1142         e->use_ogg = use_ogg;
1143 #else
1144         (void)use_ogg;
1145 #endif
1146         e->verify = verify;
1147
1148         e->is_stdout = (0 == strcmp(outfilename, "-"));
1149
1150         e->inbasefilename = grabbag__file_get_basename(infilename);
1151         e->outfilename = outfilename;
1152
1153         e->skip = 0; /* filled in later after the sample_rate is known */
1154         e->unencoded_size = 0;
1155         e->total_samples_to_encode = 0;
1156         e->bytes_written = 0;
1157         e->samples_written = 0;
1158         e->blocksize = 0;
1159         e->stats_mask = 0;
1160
1161         e->encoder.flac.stream = 0;
1162         e->encoder.flac.file = 0;
1163 #ifdef FLAC__HAS_OGG
1164         e->encoder.ogg.stream = 0;
1165         e->encoder.ogg.file = 0;
1166 #endif
1167
1168         e->fin = infile;
1169         e->fout = 0;
1170         e->seek_table_template = 0;
1171
1172         if(e->is_stdout) {
1173                 e->fout = grabbag__file_get_binary_stdout();
1174         }
1175
1176         if(0 == (e->seek_table_template = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE))) {
1177                 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1178                 return false;
1179         }
1180
1181 #ifdef FLAC__HAS_OGG
1182         if(e->use_ogg) {
1183                 if(e->is_stdout) {
1184                         e->encoder.ogg.stream = OggFLAC__stream_encoder_new();
1185                         if(0 == e->encoder.ogg.stream) {
1186                                 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1187                                 EncoderSession_destroy(e);
1188                                 return false;
1189                         }
1190                 }
1191                 else {
1192                         e->encoder.ogg.file = OggFLAC__file_encoder_new();
1193                         if(0 == e->encoder.ogg.file) {
1194                                 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1195                                 EncoderSession_destroy(e);
1196                                 return false;
1197                         }
1198                 }
1199         }
1200         else
1201 #endif
1202         if(e->is_stdout) {
1203                 e->encoder.flac.stream = FLAC__stream_encoder_new();
1204                 if(0 == e->encoder.flac.stream) {
1205                         flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1206                         EncoderSession_destroy(e);
1207                         return false;
1208                 }
1209         }
1210         else {
1211                 e->encoder.flac.file = FLAC__file_encoder_new();
1212                 if(0 == e->encoder.flac.file) {
1213                         flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1214                         EncoderSession_destroy(e);
1215                         return false;
1216                 }
1217         }
1218
1219         return true;
1220 }
1221
1222 void EncoderSession_destroy(EncoderSession *e)
1223 {
1224         if(e->fin != stdin)
1225                 fclose(e->fin);
1226         if(0 != e->fout && e->fout != stdout)
1227                 fclose(e->fout);
1228
1229 #ifdef FLAC__HAS_OGG
1230         if(e->use_ogg) {
1231                 if(e->is_stdout) {
1232                         if(0 != e->encoder.ogg.stream) {
1233                                 OggFLAC__stream_encoder_delete(e->encoder.ogg.stream);
1234                                 e->encoder.ogg.stream = 0;
1235                         }
1236                 }
1237                 else {
1238                         if(0 != e->encoder.ogg.file) {
1239                                 OggFLAC__file_encoder_delete(e->encoder.ogg.file);
1240                                 e->encoder.ogg.file = 0;
1241                         }
1242                 }
1243         }
1244         else
1245 #endif
1246         if(e->is_stdout) {
1247                 if(0 != e->encoder.flac.stream) {
1248                         FLAC__stream_encoder_delete(e->encoder.flac.stream);
1249                         e->encoder.flac.stream = 0;
1250                 }
1251         }
1252         else {
1253                 if(0 != e->encoder.flac.file) {
1254                         FLAC__file_encoder_delete(e->encoder.flac.file);
1255                         e->encoder.flac.file = 0;
1256                 }
1257         }
1258
1259         if(0 != e->seek_table_template) {
1260                 FLAC__metadata_object_delete(e->seek_table_template);
1261                 e->seek_table_template = 0;
1262         }
1263 }
1264
1265 int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero)
1266 {
1267         FLAC__StreamEncoderState fse_state = FLAC__STREAM_ENCODER_OK;
1268         int ret = 0;
1269
1270 #ifdef FLAC__HAS_OGG
1271         if(e->use_ogg) {
1272                 if(e->is_stdout) {
1273                         if(e->encoder.ogg.stream) {
1274                                 fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.stream);
1275                                 OggFLAC__stream_encoder_finish(e->encoder.ogg.stream);
1276                         }
1277                 }
1278                 else {
1279                         if(e->encoder.ogg.file) {
1280                                 fse_state = OggFLAC__file_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.file);
1281                                 OggFLAC__file_encoder_finish(e->encoder.ogg.file);
1282                         }
1283                 }
1284         }
1285         else
1286 #endif
1287         if(e->is_stdout) {
1288                 if(e->encoder.flac.stream) {
1289                         fse_state = FLAC__stream_encoder_get_state(e->encoder.flac.stream);
1290                         FLAC__stream_encoder_finish(e->encoder.flac.stream);
1291                 }
1292         }
1293         else {
1294                 if(e->encoder.flac.file) {
1295                         fse_state = FLAC__file_encoder_get_stream_encoder_state(e->encoder.flac.file);
1296                         FLAC__file_encoder_finish(e->encoder.flac.file);
1297                 }
1298         }
1299
1300         if(e->total_samples_to_encode > 0) {
1301                 print_stats(e);
1302                 flac__utils_printf(stderr, 2, "\n");
1303         }
1304
1305         if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) {
1306                 print_verify_error(e);
1307                 ret = 1;
1308         }
1309         else {
1310                 if(info_align_carry >= 0) {
1311                         flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d samples to be carried over\n", e->inbasefilename, info_align_carry);
1312                 }
1313                 if(info_align_zero >= 0) {
1314                         flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d zero samples to be appended\n", e->inbasefilename, info_align_zero);
1315                 }
1316         }
1317
1318         EncoderSession_destroy(e);
1319
1320         return ret;
1321 }
1322
1323 int EncoderSession_finish_error(EncoderSession *e)
1324 {
1325         FLAC__StreamEncoderState fse_state;
1326
1327         if(e->total_samples_to_encode > 0)
1328                 flac__utils_printf(stderr, 2, "\n");
1329
1330 #ifdef FLAC__HAS_OGG
1331         if(e->use_ogg) {
1332                 if(e->is_stdout) {
1333                         fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.stream);
1334                 }
1335                 else {
1336                         fse_state = OggFLAC__file_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.file);
1337                 }
1338         }
1339         else
1340 #endif
1341         if(e->is_stdout) {
1342                 fse_state = FLAC__stream_encoder_get_state(e->encoder.flac.stream);
1343         }
1344         else {
1345                 fse_state = FLAC__file_encoder_get_stream_encoder_state(e->encoder.flac.file);
1346         }
1347
1348         if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
1349                 print_verify_error(e);
1350         else
1351                 unlink(e->outfilename);
1352
1353         EncoderSession_destroy(e);
1354
1355         return 1;
1356 }
1357
1358 FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate)
1359 {
1360         unsigned num_metadata;
1361         FLAC__StreamMetadata padding, *cuesheet = 0;
1362         FLAC__StreamMetadata *metadata[4];
1363         const FLAC__bool is_cdda = (channels == 1 || channels == 2) && (bps == 16) && (sample_rate == 44100);
1364
1365         e->replay_gain = options.replay_gain;
1366         e->channels = channels;
1367         e->bits_per_sample = bps;
1368         e->sample_rate = sample_rate;
1369
1370         if(e->replay_gain) {
1371                 if(channels != 1 && channels != 2) {
1372                         flac__utils_printf(stderr, 1, "%s: ERROR, number of channels (%u) must be 1 or 2 for --replay-gain\n", e->inbasefilename, channels);
1373                         return false;
1374                 }
1375                 if(!grabbag__replaygain_is_valid_sample_frequency(sample_rate)) {
1376                         flac__utils_printf(stderr, 1, "%s: ERROR, invalid sample rate (%u) for --replay-gain\n", e->inbasefilename, sample_rate);
1377                         return false;
1378                 }
1379                 if(options.is_first_file) {
1380                         if(!grabbag__replaygain_init(sample_rate)) {
1381                                 flac__utils_printf(stderr, 1, "%s: ERROR initializing ReplayGain stage\n", e->inbasefilename);
1382                                 return false;
1383                         }
1384                 }
1385         }
1386
1387         if(channels != 2)
1388                 options.do_mid_side = options.loose_mid_side = false;
1389
1390         if(!parse_cuesheet_(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode))
1391                 return false;
1392
1393         if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? cuesheet : 0, e)) {
1394                 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1395                 if(0 != cuesheet)
1396                         FLAC__metadata_object_delete(cuesheet);
1397                 return false;
1398         }
1399
1400         num_metadata = 0;
1401         if(e->seek_table_template->data.seek_table.num_points > 0) {
1402                 e->seek_table_template->is_last = false; /* the encoder will set this for us */
1403                 metadata[num_metadata++] = e->seek_table_template;
1404         }
1405         if(0 != cuesheet)
1406                 metadata[num_metadata++] = cuesheet;
1407         metadata[num_metadata++] = options.vorbis_comment;
1408         if(options.padding > 0) {
1409                 padding.is_last = false; /* the encoder will set this for us */
1410                 padding.type = FLAC__METADATA_TYPE_PADDING;
1411                 padding.length = (unsigned)options.padding;
1412                 metadata[num_metadata++] = &padding;
1413         }
1414
1415         e->blocksize = options.blocksize;
1416         e->stats_mask = (options.do_exhaustive_model_search || options.do_qlp_coeff_prec_search)? 0x0f : 0x3f;
1417
1418 #ifdef FLAC__HAS_OGG
1419         if(e->use_ogg) {
1420                 if(e->is_stdout) {
1421                         OggFLAC__stream_encoder_set_serial_number(e->encoder.ogg.stream, options.serial_number);
1422                         OggFLAC__stream_encoder_set_verify(e->encoder.ogg.stream, options.verify);
1423                         OggFLAC__stream_encoder_set_streamable_subset(e->encoder.ogg.stream, !options.lax);
1424                         OggFLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.ogg.stream, options.do_mid_side);
1425                         OggFLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.ogg.stream, options.loose_mid_side);
1426                         OggFLAC__stream_encoder_set_channels(e->encoder.ogg.stream, channels);
1427                         OggFLAC__stream_encoder_set_bits_per_sample(e->encoder.ogg.stream, bps);
1428                         OggFLAC__stream_encoder_set_sample_rate(e->encoder.ogg.stream, sample_rate);
1429                         OggFLAC__stream_encoder_set_blocksize(e->encoder.ogg.stream, options.blocksize);
1430                         OggFLAC__stream_encoder_set_apodization(e->encoder.ogg.stream, options.apodizations);
1431                         OggFLAC__stream_encoder_set_max_lpc_order(e->encoder.ogg.stream, options.max_lpc_order);
1432                         OggFLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.ogg.stream, options.qlp_coeff_precision);
1433                         OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.stream, options.do_qlp_coeff_prec_search);
1434                         OggFLAC__stream_encoder_set_do_escape_coding(e->encoder.ogg.stream, options.do_escape_coding);
1435                         OggFLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.ogg.stream, options.do_exhaustive_model_search);
1436                         OggFLAC__stream_encoder_set_min_residual_partition_order(e->encoder.ogg.stream, options.min_residual_partition_order);
1437                         OggFLAC__stream_encoder_set_max_residual_partition_order(e->encoder.ogg.stream, options.max_residual_partition_order);
1438                         OggFLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.ogg.stream, options.rice_parameter_search_dist);
1439                         OggFLAC__stream_encoder_set_total_samples_estimate(e->encoder.ogg.stream, e->total_samples_to_encode);
1440                         OggFLAC__stream_encoder_set_metadata(e->encoder.ogg.stream, (num_metadata > 0)? metadata : 0, num_metadata);
1441                         OggFLAC__stream_encoder_set_write_callback(e->encoder.ogg.stream, ogg_stream_encoder_write_callback);
1442                         OggFLAC__stream_encoder_set_metadata_callback(e->encoder.ogg.stream, ogg_stream_encoder_metadata_callback);
1443                         OggFLAC__stream_encoder_set_client_data(e->encoder.ogg.stream, e);
1444
1445                         OggFLAC__stream_encoder_disable_constant_subframes(e->encoder.ogg.stream, options.debug.disable_constant_subframes);
1446                         OggFLAC__stream_encoder_disable_fixed_subframes(e->encoder.ogg.stream, options.debug.disable_fixed_subframes);
1447                         OggFLAC__stream_encoder_disable_verbatim_subframes(e->encoder.ogg.stream, options.debug.disable_verbatim_subframes);
1448
1449                         if(OggFLAC__stream_encoder_init(e->encoder.ogg.stream) != FLAC__STREAM_ENCODER_OK) {
1450                                 print_error_with_state(e, "ERROR initializing encoder");
1451                                 if(0 != cuesheet)
1452                                         FLAC__metadata_object_delete(cuesheet);
1453                                 return false;
1454                         }
1455                 }
1456                 else {
1457                         OggFLAC__file_encoder_set_serial_number(e->encoder.ogg.file, options.serial_number);
1458                         OggFLAC__file_encoder_set_filename(e->encoder.ogg.file, e->outfilename);
1459                         OggFLAC__file_encoder_set_verify(e->encoder.ogg.file, options.verify);
1460                         OggFLAC__file_encoder_set_streamable_subset(e->encoder.ogg.file, !options.lax);
1461                         OggFLAC__file_encoder_set_do_mid_side_stereo(e->encoder.ogg.file, options.do_mid_side);
1462                         OggFLAC__file_encoder_set_loose_mid_side_stereo(e->encoder.ogg.file, options.loose_mid_side);
1463                         OggFLAC__file_encoder_set_channels(e->encoder.ogg.file, channels);
1464                         OggFLAC__file_encoder_set_bits_per_sample(e->encoder.ogg.file, bps);
1465                         OggFLAC__file_encoder_set_sample_rate(e->encoder.ogg.file, sample_rate);
1466                         OggFLAC__file_encoder_set_blocksize(e->encoder.ogg.file, options.blocksize);
1467                         OggFLAC__file_encoder_set_apodization(e->encoder.ogg.file, options.apodizations);
1468                         OggFLAC__file_encoder_set_max_lpc_order(e->encoder.ogg.file, options.max_lpc_order);
1469                         OggFLAC__file_encoder_set_qlp_coeff_precision(e->encoder.ogg.file, options.qlp_coeff_precision);
1470                         OggFLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.file, options.do_qlp_coeff_prec_search);
1471                         OggFLAC__file_encoder_set_do_escape_coding(e->encoder.ogg.file, options.do_escape_coding);
1472                         OggFLAC__file_encoder_set_do_exhaustive_model_search(e->encoder.ogg.file, options.do_exhaustive_model_search);
1473                         OggFLAC__file_encoder_set_min_residual_partition_order(e->encoder.ogg.file, options.min_residual_partition_order);
1474                         OggFLAC__file_encoder_set_max_residual_partition_order(e->encoder.ogg.file, options.max_residual_partition_order);
1475                         OggFLAC__file_encoder_set_rice_parameter_search_dist(e->encoder.ogg.file, options.rice_parameter_search_dist);
1476                         OggFLAC__file_encoder_set_total_samples_estimate(e->encoder.ogg.file, e->total_samples_to_encode);
1477                         OggFLAC__file_encoder_set_metadata(e->encoder.ogg.file, (num_metadata > 0)? metadata : 0, num_metadata);
1478                         OggFLAC__file_encoder_set_progress_callback(e->encoder.ogg.file, ogg_file_encoder_progress_callback);
1479                         OggFLAC__file_encoder_set_client_data(e->encoder.ogg.file, e);
1480
1481                         OggFLAC__file_encoder_disable_constant_subframes(e->encoder.ogg.file, options.debug.disable_constant_subframes);
1482                         OggFLAC__file_encoder_disable_fixed_subframes(e->encoder.ogg.file, options.debug.disable_fixed_subframes);
1483                         OggFLAC__file_encoder_disable_verbatim_subframes(e->encoder.ogg.file, options.debug.disable_verbatim_subframes);
1484
1485                         if(OggFLAC__file_encoder_init(e->encoder.ogg.file) != OggFLAC__FILE_ENCODER_OK) {
1486                                 print_error_with_state(e, "ERROR initializing encoder");
1487                                 if(0 != cuesheet)
1488                                         FLAC__metadata_object_delete(cuesheet);
1489                                 return false;
1490                         }
1491                 }
1492         }
1493         else
1494 #endif
1495         if(e->is_stdout) {
1496                 FLAC__stream_encoder_set_verify(e->encoder.flac.stream, options.verify);
1497                 FLAC__stream_encoder_set_streamable_subset(e->encoder.flac.stream, !options.lax);
1498                 FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.flac.stream, options.do_mid_side);
1499                 FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.flac.stream, options.loose_mid_side);
1500                 FLAC__stream_encoder_set_channels(e->encoder.flac.stream, channels);
1501                 FLAC__stream_encoder_set_bits_per_sample(e->encoder.flac.stream, bps);
1502                 FLAC__stream_encoder_set_sample_rate(e->encoder.flac.stream, sample_rate);
1503                 FLAC__stream_encoder_set_blocksize(e->encoder.flac.stream, options.blocksize);
1504                 FLAC__stream_encoder_set_apodization(e->encoder.flac.stream, options.apodizations);
1505                 FLAC__stream_encoder_set_max_lpc_order(e->encoder.flac.stream, options.max_lpc_order);
1506                 FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.flac.stream, options.qlp_coeff_precision);
1507                 FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.stream, options.do_qlp_coeff_prec_search);
1508                 FLAC__stream_encoder_set_do_escape_coding(e->encoder.flac.stream, options.do_escape_coding);
1509                 FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.flac.stream, options.do_exhaustive_model_search);
1510                 FLAC__stream_encoder_set_min_residual_partition_order(e->encoder.flac.stream, options.min_residual_partition_order);
1511                 FLAC__stream_encoder_set_max_residual_partition_order(e->encoder.flac.stream, options.max_residual_partition_order);
1512                 FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.flac.stream, options.rice_parameter_search_dist);
1513                 FLAC__stream_encoder_set_total_samples_estimate(e->encoder.flac.stream, e->total_samples_to_encode);
1514                 FLAC__stream_encoder_set_metadata(e->encoder.flac.stream, (num_metadata > 0)? metadata : 0, num_metadata);
1515                 FLAC__stream_encoder_set_write_callback(e->encoder.flac.stream, flac_stream_encoder_write_callback);
1516                 FLAC__stream_encoder_set_metadata_callback(e->encoder.flac.stream, flac_stream_encoder_metadata_callback);
1517                 FLAC__stream_encoder_set_client_data(e->encoder.flac.stream, e);
1518
1519                 FLAC__stream_encoder_disable_constant_subframes(e->encoder.flac.stream, options.debug.disable_constant_subframes);
1520                 FLAC__stream_encoder_disable_fixed_subframes(e->encoder.flac.stream, options.debug.disable_fixed_subframes);
1521                 FLAC__stream_encoder_disable_verbatim_subframes(e->encoder.flac.stream, options.debug.disable_verbatim_subframes);
1522
1523                 if(FLAC__stream_encoder_init(e->encoder.flac.stream) != FLAC__STREAM_ENCODER_OK) {
1524                         print_error_with_state(e, "ERROR initializing encoder");
1525                         if(0 != cuesheet)
1526                                 FLAC__metadata_object_delete(cuesheet);
1527                         return false;
1528                 }
1529         }
1530         else {
1531                 FLAC__file_encoder_set_filename(e->encoder.flac.file, e->outfilename);
1532                 FLAC__file_encoder_set_verify(e->encoder.flac.file, options.verify);
1533                 FLAC__file_encoder_set_streamable_subset(e->encoder.flac.file, !options.lax);
1534                 FLAC__file_encoder_set_do_mid_side_stereo(e->encoder.flac.file, options.do_mid_side);
1535                 FLAC__file_encoder_set_loose_mid_side_stereo(e->encoder.flac.file, options.loose_mid_side);
1536                 FLAC__file_encoder_set_channels(e->encoder.flac.file, channels);
1537                 FLAC__file_encoder_set_bits_per_sample(e->encoder.flac.file, bps);
1538                 FLAC__file_encoder_set_sample_rate(e->encoder.flac.file, sample_rate);
1539                 FLAC__file_encoder_set_blocksize(e->encoder.flac.file, options.blocksize);
1540                 FLAC__file_encoder_set_apodization(e->encoder.flac.file, options.apodizations);
1541                 FLAC__file_encoder_set_max_lpc_order(e->encoder.flac.file, options.max_lpc_order);
1542                 FLAC__file_encoder_set_qlp_coeff_precision(e->encoder.flac.file, options.qlp_coeff_precision);
1543                 FLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.file, options.do_qlp_coeff_prec_search);
1544                 FLAC__file_encoder_set_do_escape_coding(e->encoder.flac.file, options.do_escape_coding);
1545                 FLAC__file_encoder_set_do_exhaustive_model_search(e->encoder.flac.file, options.do_exhaustive_model_search);
1546                 FLAC__file_encoder_set_min_residual_partition_order(e->encoder.flac.file, options.min_residual_partition_order);
1547                 FLAC__file_encoder_set_max_residual_partition_order(e->encoder.flac.file, options.max_residual_partition_order);
1548                 FLAC__file_encoder_set_rice_parameter_search_dist(e->encoder.flac.file, options.rice_parameter_search_dist);
1549                 FLAC__file_encoder_set_total_samples_estimate(e->encoder.flac.file, e->total_samples_to_encode);
1550                 FLAC__file_encoder_set_metadata(e->encoder.flac.file, (num_metadata > 0)? metadata : 0, num_metadata);
1551                 FLAC__file_encoder_set_progress_callback(e->encoder.flac.file, flac_file_encoder_progress_callback);
1552                 FLAC__file_encoder_set_client_data(e->encoder.flac.file, e);
1553
1554                 FLAC__file_encoder_disable_constant_subframes(e->encoder.flac.file, options.debug.disable_constant_subframes);
1555                 FLAC__file_encoder_disable_fixed_subframes(e->encoder.flac.file, options.debug.disable_fixed_subframes);
1556                 FLAC__file_encoder_disable_verbatim_subframes(e->encoder.flac.file, options.debug.disable_verbatim_subframes);
1557
1558                 if(FLAC__file_encoder_init(e->encoder.flac.file) != FLAC__FILE_ENCODER_OK) {
1559                         print_error_with_state(e, "ERROR initializing encoder");
1560                         if(0 != cuesheet)
1561                                 FLAC__metadata_object_delete(cuesheet);
1562                         return false;
1563                 }
1564         }
1565
1566         if(0 != cuesheet)
1567                 FLAC__metadata_object_delete(cuesheet);
1568
1569         return true;
1570 }
1571
1572 FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples)
1573 {
1574         if(e->replay_gain) {
1575                 if(!grabbag__replaygain_analyze(buffer, e->channels==2, e->bits_per_sample, samples)) {
1576                         flac__utils_printf(stderr, 1, "%s: WARNING, error while calculating ReplayGain\n", e->inbasefilename);
1577                 }
1578         }
1579
1580 #ifdef FLAC__HAS_OGG
1581         if(e->use_ogg) {
1582                 if(e->is_stdout) {
1583                         return OggFLAC__stream_encoder_process(e->encoder.ogg.stream, buffer, samples);
1584                 }
1585                 else {
1586                         return OggFLAC__file_encoder_process(e->encoder.ogg.file, buffer, samples);
1587                 }
1588         }
1589         else
1590 #endif
1591         if(e->is_stdout) {
1592                 return FLAC__stream_encoder_process(e->encoder.flac.stream, buffer, samples);
1593         }
1594         else {
1595                 return FLAC__file_encoder_process(e->encoder.flac.file, buffer, samples);
1596         }
1597 }
1598
1599 FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e)
1600 {
1601         const FLAC__bool only_placeholders = e->is_stdout;
1602         FLAC__bool has_real_points;
1603
1604         if(num_requested_seek_points == 0 && 0 == cuesheet)
1605                 return true;
1606
1607         if(num_requested_seek_points < 0) {
1608                 requested_seek_points = "10s;";
1609                 num_requested_seek_points = 1;
1610         }
1611
1612         if(num_requested_seek_points > 0) {
1613                 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))
1614                         return false;
1615         }
1616
1617         if(0 != cuesheet) {
1618                 unsigned i, j;
1619                 const FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
1620                 for(i = 0; i < cs->num_tracks; i++) {
1621                         const FLAC__StreamMetadata_CueSheet_Track *tr = cs->tracks+i;
1622                         for(j = 0; j < tr->num_indices; j++) {
1623                                 if(!FLAC__metadata_object_seektable_template_append_point(e->seek_table_template, tr->offset + tr->indices[j].offset))
1624                                         return false;
1625                                 has_real_points = true;
1626                         }
1627                 }
1628                 if(has_real_points)
1629                         if(!FLAC__metadata_object_seektable_template_sort(e->seek_table_template, /*compact=*/true))
1630                                 return false;
1631         }
1632
1633         if(has_real_points) {
1634                 if(e->is_stdout) {
1635                         flac__utils_printf(stderr, 1, "%s: WARNING, cannot write back seekpoints when encoding to stdout\n", e->inbasefilename);
1636                 }
1637         }
1638
1639         return true;
1640 }
1641
1642 FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
1643 {
1644         /* convert from mm:ss.sss to sample number if necessary */
1645         flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
1646
1647         /* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
1648         if(spec->is_relative && spec->value.samples == 0) {
1649                 spec->is_relative = false;
1650                 return true;
1651         }
1652
1653         /* in any other case the total samples in the input must be known */
1654         if(total_samples_in_input == 0) {
1655                 flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when input length is unknown\n", inbasefilename);
1656                 return false;
1657         }
1658
1659         FLAC__ASSERT(spec->value_is_samples);
1660
1661         /* convert relative specifications to absolute */
1662         if(spec->is_relative) {
1663                 if(spec->value.samples <= 0)
1664                         spec->value.samples += (FLAC__int64)total_samples_in_input;
1665                 else
1666                         spec->value.samples += skip;
1667                 spec->is_relative = false;
1668         }
1669
1670         /* error check */
1671         if(spec->value.samples < 0) {
1672                 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
1673                 return false;
1674         }
1675         if((FLAC__uint64)spec->value.samples <= skip) {
1676                 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
1677                 return false;
1678         }
1679         if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
1680                 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is after end of input\n", inbasefilename);
1681                 return false;
1682         }
1683
1684         return true;
1685 }
1686
1687 void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps)
1688 {
1689         unsigned wide_sample, sample, channel, byte;
1690
1691         if(bps == 8) {
1692                 if(is_unsigned_samples) {
1693                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1694                                 for(channel = 0; channel < channels; channel++, sample++)
1695                                         dest[channel][wide_sample] = (FLAC__int32)ucbuffer_[sample] - 0x80;
1696                 }
1697                 else {
1698                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1699                                 for(channel = 0; channel < channels; channel++, sample++)
1700                                         dest[channel][wide_sample] = (FLAC__int32)scbuffer_[sample];
1701                 }
1702         }
1703         else if(bps == 16) {
1704                 if(is_big_endian != is_big_endian_host_) {
1705                         unsigned char tmp;
1706                         const unsigned bytes = wide_samples * channels * (bps >> 3);
1707                         for(byte = 0; byte < bytes; byte += 2) {
1708                                 tmp = ucbuffer_[byte];
1709                                 ucbuffer_[byte] = ucbuffer_[byte+1];
1710                                 ucbuffer_[byte+1] = tmp;
1711                         }
1712                 }
1713                 if(is_unsigned_samples) {
1714                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1715                                 for(channel = 0; channel < channels; channel++, sample++)
1716                                         dest[channel][wide_sample] = (FLAC__int32)usbuffer_[sample] - 0x8000;
1717                 }
1718                 else {
1719                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1720                                 for(channel = 0; channel < channels; channel++, sample++)
1721                                         dest[channel][wide_sample] = (FLAC__int32)ssbuffer_[sample];
1722                 }
1723         }
1724         else if(bps == 24) {
1725                 if(!is_big_endian) {
1726                         unsigned char tmp;
1727                         const unsigned bytes = wide_samples * channels * (bps >> 3);
1728                         for(byte = 0; byte < bytes; byte += 3) {
1729                                 tmp = ucbuffer_[byte];
1730                                 ucbuffer_[byte] = ucbuffer_[byte+2];
1731                                 ucbuffer_[byte+2] = tmp;
1732                         }
1733                 }
1734                 if(is_unsigned_samples) {
1735                         for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1736                                 for(channel = 0; channel < channels; channel++, sample++) {
1737                                         dest[channel][wide_sample]  = ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1738                                         dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1739                                         dest[channel][wide_sample] |= ucbuffer_[byte++];
1740                                         dest[channel][wide_sample] -= 0x800000;
1741                                 }
1742                 }
1743                 else {
1744                         for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1745                                 for(channel = 0; channel < channels; channel++, sample++) {
1746                                         dest[channel][wide_sample]  = scbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1747                                         dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1748                                         dest[channel][wide_sample] |= ucbuffer_[byte++];
1749                                 }
1750                 }
1751         }
1752         else {
1753                 FLAC__ASSERT(0);
1754         }
1755 }
1756
1757 #ifdef FLAC__HAS_OGG
1758 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)
1759 {
1760         EncoderSession *encoder_session = (EncoderSession*)client_data;
1761
1762         (void)encoder;
1763
1764         encoder_session->bytes_written += bytes;
1765         /*
1766          * With Ogg FLAC we don't get one write callback per frame and
1767          * we don't have a good number for 'samples', so we estimate based
1768          * on the frame number and the knowledge that all blocks (except
1769          * the last) are the same size.
1770          */
1771         (void)samples;
1772         encoder_session->samples_written = (current_frame+1) * encoder_session->blocksize;
1773
1774         if(encoder_session->total_samples_to_encode > 0 && !(current_frame & encoder_session->stats_mask))
1775                 print_stats(encoder_session);
1776
1777         if(flac__utils_fwrite(buffer, sizeof(FLAC__byte), bytes, encoder_session->fout) == bytes)
1778                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
1779         else
1780                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1781 }
1782
1783 void ogg_stream_encoder_metadata_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
1784 {
1785         // do nothing, for compatibilty.  soon we will be using the ogg file encoder anyway.
1786         (void)encoder, (void)metadata, (void)client_data;
1787 }
1788
1789 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)
1790 {
1791         EncoderSession *encoder_session = (EncoderSession*)client_data;
1792
1793         (void)encoder;
1794
1795         /*
1796          * With Ogg FLAC we don't get a value for 'samples_written', so we
1797          * estimate based on the frames written and the knowledge that all
1798          * blocks (except the last) are the same size.
1799          */
1800         samples_written = frames_written * encoder_session->blocksize;
1801         flac_file_encoder_progress_callback(0, bytes_written, samples_written, frames_written, total_frames_estimate, client_data);
1802 }
1803
1804 #endif
1805
1806 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)
1807 {
1808         EncoderSession *encoder_session = (EncoderSession*)client_data;
1809
1810         (void)encoder;
1811
1812         encoder_session->bytes_written += bytes;
1813         encoder_session->samples_written += samples;
1814
1815         if(samples && encoder_session->total_samples_to_encode > 0 && !(current_frame & encoder_session->stats_mask))
1816                 print_stats(encoder_session);
1817
1818         if(flac__utils_fwrite(buffer, sizeof(FLAC__byte), bytes, encoder_session->fout) == bytes)
1819                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
1820         else
1821                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1822 }
1823
1824 void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
1825 {
1826         /*
1827          * Nothing to do; if we get here, we're decoding to stdout, in
1828          * which case we can't seek backwards to write new metadata.
1829          */
1830         (void)encoder, (void)metadata, (void)client_data;
1831 }
1832
1833 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)
1834 {
1835         EncoderSession *encoder_session = (EncoderSession*)client_data;
1836
1837         (void)encoder, (void)total_frames_estimate;
1838
1839         encoder_session->bytes_written = bytes_written;
1840         encoder_session->samples_written = samples_written;
1841
1842         if(encoder_session->total_samples_to_encode > 0 && !((frames_written-1) & encoder_session->stats_mask))
1843                 print_stats(encoder_session);
1844 }
1845
1846 FLAC__bool parse_cuesheet_(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
1847 {
1848         FILE *f;
1849         unsigned last_line_read;
1850         const char *error_message;
1851
1852         if(0 == cuesheet_filename)
1853                 return true;
1854
1855         if(lead_out_offset == 0) {
1856                 flac__utils_printf(stderr, 1, "%s: ERROR cannot import cuesheet when the number of input samples to encode is unknown\n", inbasefilename);
1857                 return false;
1858         }
1859
1860         if(0 == (f = fopen(cuesheet_filename, "r"))) {
1861                 flac__utils_printf(stderr, 1, "%s: ERROR opening cuesheet \"%s\" for reading\n", inbasefilename, cuesheet_filename);
1862                 return false;
1863         }
1864
1865         *cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, is_cdda, lead_out_offset);
1866
1867         fclose(f);
1868
1869         if(0 == *cuesheet) {
1870                 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\" on line %u: %s\n", inbasefilename, cuesheet_filename, last_line_read, error_message);
1871                 return false;
1872         }
1873
1874         if(!FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/false, &error_message)) {
1875                 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\": %s\n", inbasefilename, cuesheet_filename, error_message);
1876                 return false;
1877         }
1878
1879         /* if we're expecting CDDA, warn about non-compliance */
1880         if(is_cdda && !FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/true, &error_message)) {
1881                 flac__utils_printf(stderr, 1, "%s: WARNING cuesheet \"%s\" is not audio CD compliant: %s\n", inbasefilename, cuesheet_filename, error_message);
1882                 (*cuesheet)->data.cue_sheet.is_cd = false;
1883         }
1884
1885         return true;
1886 }
1887
1888 void print_stats(const EncoderSession *encoder_session)
1889 {
1890         const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written);
1891 #if defined _MSC_VER || defined __MINGW32__
1892         /* with MSVC you have to spoon feed it the casting */
1893         const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode;
1894         const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)encoder_session->unencoded_size * min(1.0, progress));
1895 #else
1896         const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode;
1897         const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * min(1.0, progress));
1898 #endif
1899
1900
1901         if(samples_written == encoder_session->total_samples_to_encode) {
1902                 flac__utils_printf(stderr, 2, "\r%s:%s wrote %u bytes, ratio=%0.3f",
1903                         encoder_session->inbasefilename,
1904                         encoder_session->verify? " Verify OK," : "",
1905                         (unsigned)encoder_session->bytes_written,
1906                         ratio
1907                 );
1908         }
1909         else {
1910                 flac__utils_printf(stderr, 2, "\r%s: %u%% complete, ratio=%0.3f", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio);
1911         }
1912 }
1913
1914 void print_error_with_state(const EncoderSession *e, const char *message)
1915 {
1916         const int ilen = strlen(e->inbasefilename) + 1;
1917         const char *state_string;
1918
1919         flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
1920
1921 #ifdef FLAC__HAS_OGG
1922         if(e->use_ogg) {
1923                 if(e->is_stdout) {
1924                         state_string = OggFLAC__stream_encoder_get_resolved_state_string(e->encoder.ogg.stream);
1925                 }
1926                 else {
1927                         state_string = OggFLAC__file_encoder_get_resolved_state_string(e->encoder.ogg.file);
1928                 }
1929         }
1930         else
1931 #endif
1932         if(e->is_stdout) {
1933                 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder.flac.stream);
1934         }
1935         else {
1936                 state_string = FLAC__file_encoder_get_resolved_state_string(e->encoder.flac.file);
1937         }
1938
1939         flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
1940
1941         /* print out some more info for some errors: */
1942         if(0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_NOT_STREAMABLE])) {
1943                 flac__utils_printf(stderr, 1,
1944                         "\n"
1945                         "The encoding parameters specified do not conform to the FLAC Subset and may not\n"
1946                         "be streamable or playable in hardware devices.  Add --lax to the command-line\n"
1947                         "options to encode with these parameters.\n"
1948                 );
1949         }
1950         else if(
1951                 0 == strcmp(state_string, FLAC__FileEncoderStateString[FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING])
1952 #ifdef FLAC__HAS_OGG
1953                 || 0 == strcmp(state_string, OggFLAC__FileEncoderStateString[OggFLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING])
1954 #endif
1955         ) {
1956                 flac__utils_printf(stderr, 1,
1957                         "\n"
1958                         "An error occurred while writing; the most common cause is that the disk is full.\n"
1959                 );
1960         }
1961         else if(
1962                 0 == strcmp(state_string, FLAC__FileEncoderStateString[FLAC__FILE_ENCODER_ERROR_OPENING_FILE])
1963 #ifdef FLAC__HAS_OGG
1964                 || 0 == strcmp(state_string, OggFLAC__FileEncoderStateString[OggFLAC__FILE_ENCODER_ERROR_OPENING_FILE])
1965 #endif
1966         ) {
1967                 flac__utils_printf(stderr, 1,
1968                         "\n"
1969                         "An error occurred opening the output file; it is likely that the output\n"
1970                         "directory does not exist or is not writable, the output file already exists and\n"
1971                         "is not writable, or the disk is full.\n"
1972                 );
1973         }
1974 }
1975
1976 void print_verify_error(EncoderSession *e)
1977 {
1978         FLAC__uint64 absolute_sample;
1979         unsigned frame_number;
1980         unsigned channel;
1981         unsigned sample;
1982         FLAC__int32 expected;
1983         FLAC__int32 got;
1984
1985 #ifdef FLAC__HAS_OGG
1986         if(e->use_ogg) {
1987                 if(e->is_stdout) {
1988                         OggFLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.ogg.stream, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1989                 }
1990                 else {
1991                         OggFLAC__file_encoder_get_verify_decoder_error_stats(e->encoder.ogg.file, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1992                 }
1993         }
1994         else
1995 #endif
1996         if(e->is_stdout) {
1997                 FLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.flac.stream, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1998         }
1999         else {
2000                 FLAC__file_encoder_get_verify_decoder_error_stats(e->encoder.flac.file, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2001         }
2002
2003         flac__utils_printf(stderr, 1, "%s: ERROR: mismatch in decoded data, verify FAILED!\n", e->inbasefilename);
2004         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);
2005         flac__utils_printf(stderr, 1, "       In all known cases, verify errors are caused by hardware problems,\n");
2006         flac__utils_printf(stderr, 1, "       usually overclocking or bad RAM.  Delete %s\n", e->inbasefilename);
2007         flac__utils_printf(stderr, 1, "       and repeat the flac command exactly as before.  If it does not give a\n");
2008         flac__utils_printf(stderr, 1, "       verify error in the exact same place each time you try it, then there is\n");
2009         flac__utils_printf(stderr, 1, "       a problem with your hardware; please see the FAQ:\n");
2010         flac__utils_printf(stderr, 1, "           http://flac.sourceforge.net/faq.html#tools__hardware_prob\n");
2011         flac__utils_printf(stderr, 1, "       If it does fail in the exact same place every time, keep the bad FLAC\n");
2012         flac__utils_printf(stderr, 1, "       file and submit a bug report to:\n");
2013         flac__utils_printf(stderr, 1, "           https://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
2014         flac__utils_printf(stderr, 1, "       Make sure to upload the FLAC file and use the \"Monitor\" feature to\n");
2015         flac__utils_printf(stderr, 1, "       monitor the bug status.\n");
2016         flac__utils_printf(stderr, 1, "Verify FAILED!  Do not trust %s\n", e->outfilename);
2017 }
2018
2019 FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2020 {
2021         size_t bytes_read = fread(val, 1, 2, f);
2022
2023         if(bytes_read == 0) {
2024                 if(!eof_ok) {
2025                         flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2026                         return false;
2027                 }
2028                 else
2029                         return true;
2030         }
2031         else if(bytes_read < 2) {
2032                 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2033                 return false;
2034         }
2035         else {
2036                 if(is_big_endian_host_) {
2037                         FLAC__byte tmp, *b = (FLAC__byte*)val;
2038                         tmp = b[1]; b[1] = b[0]; b[0] = tmp;
2039                 }
2040                 return true;
2041         }
2042 }
2043
2044 FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2045 {
2046         size_t bytes_read = fread(val, 1, 4, f);
2047
2048         if(bytes_read == 0) {
2049                 if(!eof_ok) {
2050                         flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2051                         return false;
2052                 }
2053                 else
2054                         return true;
2055         }
2056         else if(bytes_read < 4) {
2057                 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2058                 return false;
2059         }
2060         else {
2061                 if(is_big_endian_host_) {
2062                         FLAC__byte tmp, *b = (FLAC__byte*)val;
2063                         tmp = b[3]; b[3] = b[0]; b[0] = tmp;
2064                         tmp = b[2]; b[2] = b[1]; b[1] = tmp;
2065                 }
2066                 return true;
2067         }
2068 }
2069
2070 FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2071 {
2072         unsigned char buf[4];
2073         size_t bytes_read= fread(buf, 1, 2, f);
2074
2075         if(bytes_read==0U && eof_ok)
2076                 return true;
2077         else if(bytes_read<2U) {
2078                 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2079                 return false;
2080         }
2081
2082         /* this is independent of host endianness */
2083         *val= (FLAC__uint16)(buf[0])<<8 | buf[1];
2084
2085         return true;
2086 }
2087
2088 FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2089 {
2090         unsigned char buf[4];
2091         size_t bytes_read= fread(buf, 1, 4, f);
2092
2093         if(bytes_read==0U && eof_ok)
2094                 return true;
2095         else if(bytes_read<4U) {
2096                 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2097                 return false;
2098         }
2099
2100         /* this is independent of host endianness */
2101         *val= (FLAC__uint32)(buf[0])<<24 | (FLAC__uint32)(buf[1])<<16 |
2102                 (FLAC__uint32)(buf[2])<<8 | buf[3];
2103
2104         return true;
2105 }
2106
2107 FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2108         /* Read an IEEE 754 80-bit (aka SANE) extended floating point value from 'f',
2109          * convert it into an integral value and store in 'val'.  Return false if only
2110          * between 1 and 9 bytes remain in 'f', if 0 bytes remain in 'f' and 'eof_ok' is
2111          * false, or if the value is negative, between zero and one, or too large to be
2112          * represented by 'val'; return true otherwise.
2113          */
2114 {
2115         unsigned int i;
2116         unsigned char buf[10];
2117         size_t bytes_read= fread(buf, 1U, 10U, f);
2118         FLAC__int16 e= ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
2119         FLAC__int16 shift= 63-e;
2120         FLAC__uint64 p= 0U;
2121
2122         if(bytes_read==0U && eof_ok)
2123                 return true;
2124         else if(bytes_read<10U) {
2125                 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2126                 return false;
2127         }
2128         else if((buf[0]>>7)==1U || e<0 || e>63) {
2129                 flac__utils_printf(stderr, 1, "%s: ERROR: invalid floating-point value\n", fn);
2130                 return false;
2131         }
2132
2133         for(i= 0U; i<8U; ++i)
2134                 p|= (FLAC__uint64)(buf[i+2])<<(56U-i*8);
2135         *val= (FLAC__uint32)((p>>shift)+(p>>(shift-1) & 0x1));
2136
2137         return true;
2138 }
2139
2140 FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset)
2141 {
2142         static unsigned char dump[8192];
2143
2144         while(offset > 0) {
2145                 long need = (long)min(offset, LONG_MAX);
2146                 if(fseek(f, need, SEEK_CUR) < 0) {
2147                         need = (long)min(offset, sizeof(dump));
2148                         if((long)fread(dump, 1, need, f) < need)
2149                                 return false;
2150                 }
2151                 offset -= need;
2152         }
2153 #if 0 /* pure non-fseek() version */
2154         while(offset > 0) {
2155                 const long need = (long)min(offset, sizeof(dump));
2156                 if(fread(dump, 1, need, f) < need)
2157                         return false;
2158                 offset -= need;
2159         }
2160 #endif
2161         return true;
2162 }