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