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