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