add functions/switches for disabling certain subframe types for use by the test suite
[platform/upstream/flac.git] / src / flac / encode.c
1 /* flac - Command-line FLAC encoder/decoder
2  * Copyright (C) 2000,2001,2002  Josh Coalson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18
19 #if defined _WIN32 && !defined __CYGWIN__
20 /* where MSVC puts unlink() */
21 # include <io.h>
22 #else
23 # include <unistd.h>
24 #endif
25 #include <limits.h> /* for LONG_MAX */
26 #include <math.h> /* for floor() */
27 #include <stdarg.h>
28 #include <stdio.h> /* for FILE etc. */
29 #include <stdlib.h> /* for malloc */
30 #include <string.h> /* for strcmp() */
31 #include "FLAC/all.h"
32 #include "encode.h"
33 #include "file.h"
34 #ifdef FLAC__HAS_OGG
35 #include "OggFLAC/stream_encoder.h"
36 #endif
37
38 #ifdef min
39 #undef min
40 #endif
41 #define min(x,y) ((x)<(y)?(x):(y))
42
43 /* this MUST be >= 588 so that sector aligning can take place with one read */
44 #define CHUNK_OF_SAMPLES 2048
45
46 typedef struct {
47 #ifdef FLAC__HAS_OGG
48         FLAC__bool use_ogg;
49 #endif
50         FLAC__bool verify;
51         FLAC__bool verbose;
52         FLAC__bool is_stdout;
53         const char *inbasefilename;
54         const char *outfilename;
55
56         FLAC__uint64 unencoded_size;
57         FLAC__uint64 total_samples_to_encode;
58         FLAC__uint64 bytes_written;
59         FLAC__uint64 samples_written;
60         unsigned blocksize;
61         unsigned stats_mask;
62
63         /*
64          * We use flac.stream for encoding native FLAC to stdout
65          * We use flac.file for encoding native FLAC to a regular file
66          * We use ogg.stream for encoding Ogg FLAC to either stdout or a regular file
67          */
68         union {
69                 union {
70                         FLAC__StreamEncoder *stream;
71                         FLAC__FileEncoder *file;
72                 } flac;
73 #ifdef FLAC__HAS_OGG
74                 union {
75                         OggFLAC__StreamEncoder *stream;
76                 } ogg;
77 #endif
78         } encoder;
79
80         FILE *fin;
81         FILE *fout;
82         FLAC__StreamMetadata *seek_table_template;
83 } EncoderSession;
84
85
86 static FLAC__bool is_big_endian_host_;
87
88 static unsigned char ucbuffer_[CHUNK_OF_SAMPLES*FLAC__MAX_CHANNELS*((FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE+7)/8)];
89 static signed char *scbuffer_ = (signed char *)ucbuffer_;
90 static FLAC__uint16 *usbuffer_ = (FLAC__uint16 *)ucbuffer_;
91 static FLAC__int16 *ssbuffer_ = (FLAC__int16 *)ucbuffer_;
92
93 static FLAC__int32 in_[FLAC__MAX_CHANNELS][CHUNK_OF_SAMPLES];
94 static FLAC__int32 *input_[FLAC__MAX_CHANNELS];
95
96
97 /*
98  * unpublished debug routines from the FLAC libs
99  */
100 extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
101 extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
102 extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
103 extern FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value);
104 extern FLAC__bool FLAC__file_encoder_disable_fixed_subframes(FLAC__FileEncoder *encoder, FLAC__bool value);
105 extern FLAC__bool FLAC__file_encoder_disable_verbatim_subframes(FLAC__FileEncoder *encoder, FLAC__bool value);
106 extern FLAC__bool OggFLAC__stream_encoder_disable_constant_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
107 extern FLAC__bool OggFLAC__stream_encoder_disable_fixed_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
108 extern FLAC__bool OggFLAC__stream_encoder_disable_verbatim_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
109
110 /*
111  * local routines
112  */
113 static FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FLAC__bool verbose, FILE *infile, const char *infilename, const char *outfilename);
114 static void EncoderSession_destroy(EncoderSession *e);
115 static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero);
116 static int EncoderSession_finish_error(EncoderSession *e);
117 static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate);
118 static FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples);
119 static FLAC__bool convert_to_seek_table_template(char *requested_seek_points, int num_requested_seek_points, EncoderSession *e);
120 static void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps);
121 #ifdef FLAC__HAS_OGG
122 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);
123 #endif
124 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);
125 static void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
126 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);
127 static void print_stats(const EncoderSession *encoder_session);
128 static void print_error_with_state(const EncoderSession *e, const char *message);
129 static void print_verify_error(EncoderSession *e);
130 static FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
131 static FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
132 static FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
133 static FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
134 static FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
135
136 /*
137  * public routines
138  */
139 int
140 flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const char *outfilename,
141         const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
142 {
143         EncoderSession encoder_session;
144         FLAC__uint16 x;
145         FLAC__uint32 xx;
146         unsigned int channels= 0U, bps= 0U, sample_rate= 0U, sample_frames= 0U;
147         FLAC__bool got_comm_chunk= false, got_ssnd_chunk= false;
148         int info_align_carry= -1, info_align_zero= -1;
149
150         FLAC__ASSERT(!options.common.sector_align || options.common.skip == 0);
151
152         (void)infilesize; /* silence compiler warning about unused parameter */
153         (void)lookahead; /* silence compiler warning about unused parameter */
154         (void)lookahead_length; /* silence compiler warning about unused parameter */
155
156         if(!
157                 EncoderSession_construct(
158                         &encoder_session,
159 #ifdef FLAC__HAS_OGG
160                         options.common.use_ogg,
161 #else
162                         /*use_ogg=*/false,
163 #endif
164                         options.common.verify,
165                         options.common.verbose,
166                         infile,
167                         infilename,
168                         outfilename
169                 )
170         )
171                 return 1;
172
173         /* lookahead[] already has "FORMxxxxAIFF", do sub-chunks */
174
175         while(1) {
176                 size_t c= 0U;
177                 char chunk_id[4];
178
179                 /* chunk identifier; really conservative about behavior of fread() and feof() */
180                 if(feof(infile) || ((c= fread(chunk_id, 1U, 4U, infile)), c==0U && feof(infile)))
181                         break;
182                 else if(c<4U || feof(infile)) {
183                         fprintf(stderr, "%s: ERROR: incomplete chunk identifier\n", encoder_session.inbasefilename);
184                         return EncoderSession_finish_error(&encoder_session);
185                 }
186
187                 if(got_comm_chunk==false && !strncmp(chunk_id, "COMM", 4)) { /* common chunk */
188                         unsigned long skip;
189
190                         /* COMM chunk size */
191                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
192                                 return EncoderSession_finish_error(&encoder_session);
193                         else if(xx<18U) {
194                                 fprintf(stderr, "%s: ERROR: non-standard 'COMM' chunk has length = %u\n", encoder_session.inbasefilename, (unsigned int)xx);
195                                 return EncoderSession_finish_error(&encoder_session);
196                         }
197                         else if(xx!=18U)
198                                 fprintf(stderr, "%s: WARNING: non-standard 'COMM' chunk has length = %u\n", encoder_session.inbasefilename, (unsigned int)xx);
199                         skip= (xx-18U)+(xx & 1U);
200
201                         /* number of channels */
202                         if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
203                                 return EncoderSession_finish_error(&encoder_session);
204                         else if(x==0U || x>FLAC__MAX_CHANNELS) {
205                                 fprintf(stderr, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned int)x);
206                                 return EncoderSession_finish_error(&encoder_session);
207                         }
208                         else if(options.common.sector_align && x!=2U) {
209                                 fprintf(stderr, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)x);
210                                 return EncoderSession_finish_error(&encoder_session);
211                         }
212                         channels= x;
213
214                         /* number of sample frames */
215                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
216                                 return EncoderSession_finish_error(&encoder_session);
217                         sample_frames= xx;
218
219                         /* bits per sample */
220                         if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
221                                 return EncoderSession_finish_error(&encoder_session);
222                         else if(x!=8U && x!=16U && x!=24U) {
223                                 fprintf(stderr, "%s: ERROR: unsupported bits per sample %u\n", encoder_session.inbasefilename, (unsigned int)x);
224                                 return EncoderSession_finish_error(&encoder_session);
225                         }
226                         else if(options.common.sector_align && x!=16U) {
227                                 fprintf(stderr, "%s: ERROR: file has %u bits per sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)x);
228                                 return EncoderSession_finish_error(&encoder_session);
229                         }
230                         bps= x;
231
232                         /* sample rate */
233                         if(!read_sane_extended(infile, &xx, false, encoder_session.inbasefilename))
234                                 return EncoderSession_finish_error(&encoder_session);
235                         else if(!FLAC__format_sample_rate_is_valid(xx)) {
236                                 fprintf(stderr, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned int)xx);
237                                 return EncoderSession_finish_error(&encoder_session);
238                         }
239                         else if(options.common.sector_align && xx!=44100U) {
240                                 fprintf(stderr, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)xx);
241                                 return EncoderSession_finish_error(&encoder_session);
242                         }
243                         sample_rate= xx;
244
245                         /* skip any extra data in the COMM chunk */
246                         FLAC__ASSERT(skip<=LONG_MAX);
247                         while(skip>0U && fseek(infile, skip, SEEK_CUR)<0) {
248                                 unsigned int need= min(skip, sizeof ucbuffer_);
249                                 if(fread(ucbuffer_, 1U, need, infile)<need) {
250                                         fprintf(stderr, "%s: ERROR during read while skipping extra COMM data\n", encoder_session.inbasefilename);
251                                         return EncoderSession_finish_error(&encoder_session);
252                                 }
253                                 skip-= need;
254                         }
255
256                         got_comm_chunk= true;
257                 }
258                 else if(got_ssnd_chunk==false && !strncmp(chunk_id, "SSND", 4)) { /* sound data chunk */
259                         unsigned int offset= 0U, block_size= 0U, align_remainder= 0U, data_bytes;
260                         size_t bytes_per_frame= channels*(bps>>3);
261                         FLAC__bool pad= false;
262
263                         if(got_comm_chunk==false) {
264                                 fprintf(stderr, "%s: ERROR: got 'SSND' chunk before 'COMM' chunk\n", encoder_session.inbasefilename);
265                                 return EncoderSession_finish_error(&encoder_session);
266                         }
267
268                         /* SSND chunk size */
269                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
270                                 return EncoderSession_finish_error(&encoder_session);
271                         else if(xx!=(sample_frames*bytes_per_frame + 8U)) {
272                                 fprintf(stderr, "%s: ERROR: SSND chunk size inconsistent with sample frame count\n", encoder_session.inbasefilename);
273                                 return EncoderSession_finish_error(&encoder_session);
274                         }
275                         data_bytes= xx;
276                         pad= (data_bytes & 1U) ? true : false;
277
278                         /* offset */
279                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
280                                 return EncoderSession_finish_error(&encoder_session);
281                         else if(xx!=0U) {
282                                 fprintf(stderr, "%s: ERROR: offset is %u; must be 0\n", encoder_session.inbasefilename, (unsigned int)xx);
283                                 return EncoderSession_finish_error(&encoder_session);
284                         }
285                         offset= xx;
286
287                         /* block size */
288                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
289                                 return EncoderSession_finish_error(&encoder_session);
290                         else if(xx!=0U) {
291                                 fprintf(stderr, "%s: ERROR: block size is %u; must be 0\n", encoder_session.inbasefilename, (unsigned int)xx);
292                                 return EncoderSession_finish_error(&encoder_session);
293                         }
294                         block_size= xx;
295
296                         if(options.common.skip>0U) {
297                                 FLAC__uint64 remaining= options.common.skip*bytes_per_frame;
298
299                                 /* do 1<<30 bytes at a time, since 1<<30 is a nice round number, and */
300                                 /* is guaranteed to be less than LONG_MAX */
301                                 for(; remaining>0U; remaining-= remaining>(1U<<30) ? remaining : (1U<<30))
302                                 {
303                                         unsigned long skip= (unsigned long)(remaining % (1U<<30));
304
305                                         FLAC__ASSERT(skip<=LONG_MAX);
306                                         while(skip>0 && fseek(infile, skip, SEEK_CUR)<0) {
307                                                 unsigned int need= min(skip, sizeof ucbuffer_);
308                                                 if(fread(ucbuffer_, 1U, need, infile)<need) {
309                                                         fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
310                                                         return EncoderSession_finish_error(&encoder_session);
311                                                 }
312                                                 skip-= need;
313                                         }
314                                 }
315                         }
316
317                         data_bytes-= (8U + (unsigned int)options.common.skip*bytes_per_frame); /*@@@ WATCHOUT: 4GB limit */
318                         encoder_session.total_samples_to_encode= data_bytes/bytes_per_frame + *options.common.align_reservoir_samples;
319                         if(options.common.sector_align) {
320                                 align_remainder= (unsigned int)(encoder_session.total_samples_to_encode % 588U);
321                                 if(options.common.is_last_file)
322                                         encoder_session.total_samples_to_encode+= (588U-align_remainder); /* will pad with zeroes */
323                                 else
324                                         encoder_session.total_samples_to_encode-= align_remainder; /* will stop short and carry over to next file */
325                         }
326
327                         /* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */
328                         encoder_session.unencoded_size= encoder_session.total_samples_to_encode*bytes_per_frame+54;
329
330                         if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate))
331                                 return EncoderSession_finish_error(&encoder_session);
332
333                         /* first do any samples in the reservoir */
334                         if(options.common.sector_align && *options.common.align_reservoir_samples>0U) {
335
336                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
337                                         print_error_with_state(&encoder_session, "ERROR during encoding");
338                                         return EncoderSession_finish_error(&encoder_session);
339                                 }
340                         }
341
342                         /* decrement the data_bytes counter if we need to align the file */
343                         if(options.common.sector_align) {
344                                 if(options.common.is_last_file)
345                                         *options.common.align_reservoir_samples= 0U;
346                                 else {
347                                         *options.common.align_reservoir_samples= align_remainder;
348                                         data_bytes-= (*options.common.align_reservoir_samples)*bytes_per_frame;
349                                 }
350                         }
351
352                         /* now do from the file */
353                         while(data_bytes>0) {
354                                 size_t bytes_read= fread(ucbuffer_, 1U, min(data_bytes, CHUNK_OF_SAMPLES*bytes_per_frame), infile);
355
356                                 if(bytes_read==0U) {
357                                         if(ferror(infile)) {
358                                                 fprintf(stderr, "%s: ERROR during read\n", encoder_session.inbasefilename);
359                                                 return EncoderSession_finish_error(&encoder_session);
360                                         }
361                                         else if(feof(infile)) {
362                                                 fprintf(stderr, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written);
363                                                 data_bytes= 0;
364                                         }
365                                 }
366                                 else {
367                                         if(bytes_read % bytes_per_frame != 0U) {
368                                                 fprintf(stderr, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
369                                                 return EncoderSession_finish_error(&encoder_session);
370                                         }
371                                         else {
372                                                 unsigned int frames= bytes_read/bytes_per_frame;
373                                                 format_input(input_, frames, true, false, channels, bps);
374
375                                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, frames)) {
376                                                         print_error_with_state(&encoder_session, "ERROR during encoding");
377                                                         return EncoderSession_finish_error(&encoder_session);
378                                                 }
379                                                 else
380                                                         data_bytes-= bytes_read;
381                                         }
382                                 }
383                         }
384
385                         /* now read unaligned samples into reservoir or pad with zeroes if necessary */
386                         if(options.common.sector_align) {
387                                 if(options.common.is_last_file) {
388                                         unsigned int pad_frames= 588U-align_remainder;
389
390                                         if(pad_frames<588U) {
391                                                 unsigned int i;
392
393                                                 info_align_zero= pad_frames;
394                                                 for(i= 0U; i<channels; ++i)
395                                                         memset(input_[i], 0, pad_frames*(bps>>3));
396
397                                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, pad_frames)) {
398                                                         print_error_with_state(&encoder_session, "ERROR during encoding");
399                                                         return EncoderSession_finish_error(&encoder_session);
400                                                 }
401                                         }
402                                 }
403                                 else {
404                                         if(*options.common.align_reservoir_samples > 0) {
405                                                 size_t bytes_read= fread(ucbuffer_, 1U, (*options.common.align_reservoir_samples)*bytes_per_frame, infile);
406
407                                                 FLAC__ASSERT(CHUNK_OF_SAMPLES>=588U);
408                                                 if(bytes_read==0U && ferror(infile)) {
409                                                         fprintf(stderr, "%s: ERROR during read\n", encoder_session.inbasefilename);
410                                                         return EncoderSession_finish_error(&encoder_session);
411                                                 }
412                                                 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_frame)
413                                                         fprintf(stderr, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)bytes_read, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written);
414                                                 else {
415                                                         info_align_carry= *options.common.align_reservoir_samples;
416                                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, true, false, channels, bps);
417                                                 }
418                                         }
419                                 }
420                         }
421
422                         if(pad==true) {
423                                 unsigned char tmp;
424
425                                 if(fread(&tmp, 1U, 1U, infile)<1U) {
426                                         fprintf(stderr, "%s: ERROR during read of SSND pad byte\n", encoder_session.inbasefilename);
427                                         return EncoderSession_finish_error(&encoder_session);
428                                 }
429                         }
430
431                         got_ssnd_chunk= true;
432                 }
433                 else { /* other chunk */
434                         if(!strncmp(chunk_id, "COMM", 4))
435                                 fprintf(stderr, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_session.inbasefilename);
436                         else if(!strncmp(chunk_id, "SSND", 4))
437                                 fprintf(stderr, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename);
438                         else
439                                 fprintf(stderr, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_session.inbasefilename, chunk_id);
440
441                         /* chunk size */
442                         if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
443                                 return EncoderSession_finish_error(&encoder_session);
444                         else {
445                                 unsigned long skip= xx+(xx & 1U);
446
447                                 FLAC__ASSERT(skip<=LONG_MAX);
448                                 while(skip>0U && fseek(infile, skip, SEEK_CUR)<0) {
449                                         unsigned int need= min(skip, sizeof ucbuffer_);
450                                         if(fread(ucbuffer_, 1U, need, infile)<need) {
451                                                 fprintf(stderr, "%s: ERROR during read while skipping unknown chunk\n", encoder_session.inbasefilename);
452                                                 return EncoderSession_finish_error(&encoder_session);
453                                         }
454                                         skip-= need;
455                                 }
456                         }
457                 }
458         }
459
460         if(got_ssnd_chunk==false && sample_frames!=0U) {
461                 fprintf(stderr, "%s: ERROR: missing SSND chunk\n", encoder_session.inbasefilename);
462                 return EncoderSession_finish_error(&encoder_session);
463         }
464
465         return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
466 }
467
468 int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
469 {
470         EncoderSession encoder_session;
471         FLAC__bool is_unsigned_samples = false;
472         unsigned channels = 0, bps = 0, sample_rate = 0, data_bytes;
473         size_t bytes_per_wide_sample, bytes_read;
474         FLAC__uint16 x;
475         FLAC__uint32 xx;
476         FLAC__bool got_fmt_chunk = false, got_data_chunk = false;
477         unsigned align_remainder = 0;
478         int info_align_carry = -1, info_align_zero = -1;
479
480         FLAC__ASSERT(!options.common.sector_align || options.common.skip == 0);
481
482         (void)infilesize;
483         (void)lookahead;
484         (void)lookahead_length;
485
486         if(!
487                 EncoderSession_construct(
488                         &encoder_session,
489 #ifdef FLAC__HAS_OGG
490                         options.common.use_ogg,
491 #else
492                         /*use_ogg=*/false,
493 #endif
494                         options.common.verify,
495                         options.common.verbose,
496                         infile,
497                         infilename,
498                         outfilename
499                 )
500         )
501                 return 1;
502
503         /*
504          * lookahead[] already has "RIFFxxxxWAVE", do sub-chunks
505          */
506         while(!feof(infile)) {
507                 if(!read_little_endian_uint32(infile, &xx, true, encoder_session.inbasefilename))
508                         return EncoderSession_finish_error(&encoder_session);
509                 if(feof(infile))
510                         break;
511                 if(xx == 0x20746d66 && !got_fmt_chunk) { /* "fmt " */
512                         /* fmt sub-chunk size */
513                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
514                                 return EncoderSession_finish_error(&encoder_session);
515                         if(xx < 16) {
516                                 fprintf(stderr, "%s: ERROR: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx);
517                                 return EncoderSession_finish_error(&encoder_session);
518                         }
519                         else if(xx != 16 && xx != 18) {
520                                 fprintf(stderr, "%s: WARNING: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx);
521                         }
522                         data_bytes = xx;
523                         /* compression code */
524                         if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
525                                 return EncoderSession_finish_error(&encoder_session);
526                         if(x != 1) {
527                                 fprintf(stderr, "%s: ERROR: unsupported compression type %u\n", encoder_session.inbasefilename, (unsigned)x);
528                                 return EncoderSession_finish_error(&encoder_session);
529                         }
530                         /* number of channels */
531                         if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
532                                 return EncoderSession_finish_error(&encoder_session);
533                         if(x == 0 || x > FLAC__MAX_CHANNELS) {
534                                 fprintf(stderr, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned)x);
535                                 return EncoderSession_finish_error(&encoder_session);
536                         }
537                         else if(options.common.sector_align && x != 2) {
538                                 fprintf(stderr, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x);
539                                 return EncoderSession_finish_error(&encoder_session);
540                         }
541                         channels = x;
542                         /* sample rate */
543                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
544                                 return EncoderSession_finish_error(&encoder_session);
545                         if(!FLAC__format_sample_rate_is_valid(xx)) {
546                                 fprintf(stderr, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned)xx);
547                                 return EncoderSession_finish_error(&encoder_session);
548                         }
549                         else if(options.common.sector_align && xx != 44100) {
550                                 fprintf(stderr, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_session.inbasefilename, (unsigned)xx);
551                                 return EncoderSession_finish_error(&encoder_session);
552                         }
553                         sample_rate = xx;
554                         /* avg bytes per second (ignored) */
555                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
556                                 return EncoderSession_finish_error(&encoder_session);
557                         /* block align (ignored) */
558                         if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
559                                 return EncoderSession_finish_error(&encoder_session);
560                         /* bits per sample */
561                         if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
562                                 return EncoderSession_finish_error(&encoder_session);
563                         if(x != 8 && x != 16 && x != 24) {
564                                 fprintf(stderr, "%s: ERROR: unsupported bits per sample %u\n", encoder_session.inbasefilename, (unsigned)x);
565                                 return EncoderSession_finish_error(&encoder_session);
566                         }
567                         else if(options.common.sector_align && x != 16) {
568                                 fprintf(stderr, "%s: ERROR: file has %u bits per sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x);
569                                 return EncoderSession_finish_error(&encoder_session);
570                         }
571                         bps = x;
572                         is_unsigned_samples = (x == 8);
573
574                         /* skip any extra data in the fmt sub-chunk */
575                         data_bytes -= 16;
576                         if(data_bytes > 0) {
577                                 unsigned left, need;
578                                 for(left = data_bytes; left > 0; ) {
579                                         need = min(left, CHUNK_OF_SAMPLES);
580                                         if(fread(ucbuffer_, 1U, need, infile) < need) {
581                                                 fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
582                                                 return EncoderSession_finish_error(&encoder_session);
583                                         }
584                                         left -= need;
585                                 }
586                         }
587
588                         got_fmt_chunk = true;
589                 }
590                 else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
591                         /* data size */
592                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
593                                 return EncoderSession_finish_error(&encoder_session);
594                         data_bytes = xx;
595
596                         bytes_per_wide_sample = channels * (bps >> 3);
597
598                         if(options.common.skip > 0) {
599                                 if(fseek(infile, bytes_per_wide_sample * (unsigned)options.common.skip, SEEK_CUR) < 0) {
600                                         /* can't seek input, read ahead manually... */
601                                         unsigned left, need;
602                                         for(left = (unsigned)options.common.skip; left > 0; ) { /*@@@ WATCHOUT: 4GB limit */
603                                                 need = min(left, CHUNK_OF_SAMPLES);
604                                                 if(fread(ucbuffer_, bytes_per_wide_sample, need, infile) < need) {
605                                                         fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
606                                                         return EncoderSession_finish_error(&encoder_session);
607                                                 }
608                                                 left -= need;
609                                         }
610                                 }
611                         }
612
613                         data_bytes -= (unsigned)options.common.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
614                         encoder_session.total_samples_to_encode = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;
615                         if(options.common.sector_align) {
616                                 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
617                                 if(options.common.is_last_file)
618                                         encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
619                                 else
620                                         encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
621                         }
622
623                         /* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
624                         encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample + 44;
625
626                         if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate))
627                                 return EncoderSession_finish_error(&encoder_session);
628
629                         /*
630                          * first do any samples in the reservoir
631                          */
632                         if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
633                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
634                                         print_error_with_state(&encoder_session, "ERROR during encoding");
635                                         return EncoderSession_finish_error(&encoder_session);
636                                 }
637                         }
638
639                         /*
640                          * decrement the data_bytes counter if we need to align the file
641                          */
642                         if(options.common.sector_align) {
643                                 if(options.common.is_last_file) {
644                                         *options.common.align_reservoir_samples = 0;
645                                 }
646                                 else {
647                                         *options.common.align_reservoir_samples = align_remainder;
648                                         data_bytes -= (*options.common.align_reservoir_samples) * bytes_per_wide_sample;
649                                 }
650                         }
651
652                         /*
653                          * now do from the file
654                          */
655                         while(data_bytes > 0) {
656                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), min(data_bytes, CHUNK_OF_SAMPLES * bytes_per_wide_sample), infile);
657                                 if(bytes_read == 0) {
658                                         if(ferror(infile)) {
659                                                 fprintf(stderr, "%s: ERROR during read\n", encoder_session.inbasefilename);
660                                                 return EncoderSession_finish_error(&encoder_session);
661                                         }
662                                         else if(feof(infile)) {
663                                                 fprintf(stderr, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
664                                                 data_bytes = 0;
665                                         }
666                                 }
667                                 else {
668                                         if(bytes_read % bytes_per_wide_sample != 0) {
669                                                 fprintf(stderr, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
670                                                 return EncoderSession_finish_error(&encoder_session);
671                                         }
672                                         else {
673                                                 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
674                                                 format_input(input_, wide_samples, false, is_unsigned_samples, channels, bps);
675
676                                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
677                                                         print_error_with_state(&encoder_session, "ERROR during encoding");
678                                                         return EncoderSession_finish_error(&encoder_session);
679                                                 }
680                                                 data_bytes -= bytes_read;
681                                         }
682                                 }
683                         }
684
685                         /*
686                          * now read unaligned samples into reservoir or pad with zeroes if necessary
687                          */
688                         if(options.common.sector_align) {
689                                 if(options.common.is_last_file) {
690                                         unsigned wide_samples = 588 - align_remainder;
691                                         if(wide_samples < 588) {
692                                                 unsigned channel;
693
694                                                 info_align_zero = wide_samples;
695                                                 data_bytes = wide_samples * (bps >> 3);
696                                                 for(channel = 0; channel < channels; channel++)
697                                                         memset(input_[channel], 0, data_bytes);
698
699                                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
700                                                         print_error_with_state(&encoder_session, "ERROR during encoding");
701                                                         return EncoderSession_finish_error(&encoder_session);
702                                                 }
703                                         }
704                                 }
705                                 else {
706                                         if(*options.common.align_reservoir_samples > 0) {
707                                                 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
708                                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
709                                                 if(bytes_read == 0 && ferror(infile)) {
710                                                         fprintf(stderr, "%s: ERROR during read\n", encoder_session.inbasefilename);
711                                                         return EncoderSession_finish_error(&encoder_session);
712                                                 }
713                                                 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
714                                                         fprintf(stderr, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
715                                                         data_bytes = 0;
716                                                 }
717                                                 else {
718                                                         info_align_carry = *options.common.align_reservoir_samples;
719                                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, false, is_unsigned_samples, channels, bps);
720                                                 }
721                                         }
722                                 }
723                         }
724
725                         got_data_chunk = true;
726                 }
727                 else {
728                         if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
729                                 fprintf(stderr, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename);
730                         }
731                         else if(xx == 0x61746164) { /* "data" */
732                                 if(got_data_chunk) {
733                                         fprintf(stderr, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename);
734                                 }
735                                 else if(!got_fmt_chunk) {
736                                         fprintf(stderr, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
737                                         return EncoderSession_finish_error(&encoder_session);
738                                 }
739                                 else {
740                                         FLAC__ASSERT(0);
741                                 }
742                         }
743                         else {
744                                 fprintf(stderr, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c'\n", encoder_session.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
745                         }
746                         /* sub-chunk size */
747                         if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
748                                 return EncoderSession_finish_error(&encoder_session);
749                         if(fseek(infile, xx, SEEK_CUR) < 0) {
750                                 /* can't seek input, read ahead manually... */
751                                 unsigned left, need;
752                                 const unsigned chunk = sizeof(ucbuffer_);
753                                 for(left = xx; left > 0; ) {
754                                         need = min(left, chunk);
755                                         if(fread(ucbuffer_, 1, need, infile) < need) {
756                                                 fprintf(stderr, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_session.inbasefilename);
757                                                 return EncoderSession_finish_error(&encoder_session);
758                                         }
759                                         left -= need;
760                                 }
761                         }
762                 }
763         }
764
765         return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
766 }
767
768 int flac__encode_raw(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options)
769 {
770         EncoderSession encoder_session;
771         size_t bytes_read;
772         const size_t bytes_per_wide_sample = options.channels * (options.bps >> 3);
773         unsigned align_remainder = 0;
774         int info_align_carry = -1, info_align_zero = -1;
775
776         FLAC__ASSERT(!options.common.sector_align || options.common.skip == 0);
777         FLAC__ASSERT(!options.common.sector_align || options.channels == 2);
778         FLAC__ASSERT(!options.common.sector_align || options.bps == 16);
779         FLAC__ASSERT(!options.common.sector_align || options.sample_rate == 44100);
780         FLAC__ASSERT(!options.common.sector_align || infilesize >= 0);
781
782         if(!
783                 EncoderSession_construct(
784                         &encoder_session,
785 #ifdef FLAC__HAS_OGG
786                         options.common.use_ogg,
787 #else
788                         /*use_ogg=*/false,
789 #endif
790                         options.common.verify,
791                         options.common.verbose,
792                         infile,
793                         infilename,
794                         outfilename
795                 )
796         )
797                 return 1;
798
799         /* get the file length */
800         if(infilesize < 0) {
801                 encoder_session.total_samples_to_encode = encoder_session.unencoded_size = 0;
802         }
803         else {
804                 if(options.common.sector_align) {
805                         FLAC__ASSERT(options.common.skip == 0);
806                         encoder_session.total_samples_to_encode = (unsigned)infilesize / bytes_per_wide_sample + *options.common.align_reservoir_samples;
807                         align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
808                         if(options.common.is_last_file)
809                                 encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
810                         else
811                                 encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
812                 }
813                 else {
814                         encoder_session.total_samples_to_encode = (unsigned)infilesize / bytes_per_wide_sample - options.common.skip;
815                 }
816
817                 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample;
818         }
819
820         if(encoder_session.verbose && encoder_session.total_samples_to_encode <= 0)
821                 fprintf(stderr, "(No runtime statistics possible; please wait for encoding to finish...)\n");
822
823         if(options.common.skip > 0) {
824                 unsigned skip_bytes = bytes_per_wide_sample * (unsigned)options.common.skip;
825                 if(skip_bytes > lookahead_length) {
826                         skip_bytes -= lookahead_length;
827                         lookahead_length = 0;
828                         if(fseek(infile, (long)skip_bytes, SEEK_CUR) < 0) {
829                                 /* can't seek input, read ahead manually... */
830                                 unsigned left, need;
831                                 const unsigned chunk = sizeof(ucbuffer_);
832                                 for(left = skip_bytes; left > 0; ) {
833                                         need = min(left, chunk);
834                                         if(fread(ucbuffer_, 1, need, infile) < need) {
835                                                 fprintf(stderr, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
836                                                 return EncoderSession_finish_error(&encoder_session);
837                                         }
838                                         left -= need;
839                                 }
840                         }
841                 }
842                 else {
843                         lookahead += skip_bytes;
844                         lookahead_length -= skip_bytes;
845                 }
846         }
847
848         if(!EncoderSession_init_encoder(&encoder_session, options.common, options.channels, options.bps, options.sample_rate))
849                 return EncoderSession_finish_error(&encoder_session);
850
851         /*
852          * first do any samples in the reservoir
853          */
854         if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
855                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
856                         print_error_with_state(&encoder_session, "ERROR during encoding");
857                         return EncoderSession_finish_error(&encoder_session);
858                 }
859         }
860
861         /*
862          * decrement infilesize if we need to align the file
863          */
864         if(options.common.sector_align) {
865                 FLAC__ASSERT(infilesize >= 0);
866                 if(options.common.is_last_file) {
867                         *options.common.align_reservoir_samples = 0;
868                 }
869                 else {
870                         *options.common.align_reservoir_samples = align_remainder;
871                         infilesize -= (long)((*options.common.align_reservoir_samples) * bytes_per_wide_sample);
872                 }
873         }
874
875         /*
876          * now do from the file
877          */
878         while(!feof(infile)) {
879                 if(lookahead_length > 0) {
880                         FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * bytes_per_wide_sample);
881                         memcpy(ucbuffer_, lookahead, lookahead_length);
882                         bytes_read = fread(ucbuffer_+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
883                         if(ferror(infile)) {
884                                 fprintf(stderr, "%s: ERROR during read\n", encoder_session.inbasefilename);
885                                 return EncoderSession_finish_error(&encoder_session);
886                         }
887                         lookahead_length = 0;
888                 }
889                 else
890                         bytes_read = fread(ucbuffer_, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample, infile);
891
892                 if(bytes_read == 0) {
893                         if(ferror(infile)) {
894                                 fprintf(stderr, "%s: ERROR during read\n", encoder_session.inbasefilename);
895                                 return EncoderSession_finish_error(&encoder_session);
896                         }
897                 }
898                 else if(bytes_read % bytes_per_wide_sample != 0) {
899                         fprintf(stderr, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
900                         return EncoderSession_finish_error(&encoder_session);
901                 }
902                 else {
903                         unsigned wide_samples = bytes_read / bytes_per_wide_sample;
904                         format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
905
906                         if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
907                                 print_error_with_state(&encoder_session, "ERROR during encoding");
908                                 return EncoderSession_finish_error(&encoder_session);
909                         }
910                 }
911         }
912
913         /*
914          * now read unaligned samples into reservoir or pad with zeroes if necessary
915          */
916         if(options.common.sector_align) {
917                 if(options.common.is_last_file) {
918                         unsigned wide_samples = 588 - align_remainder;
919                         if(wide_samples < 588) {
920                                 unsigned channel, data_bytes;
921
922                                 info_align_zero = wide_samples;
923                                 data_bytes = wide_samples * (options.bps >> 3);
924                                 for(channel = 0; channel < options.channels; channel++)
925                                         memset(input_[channel], 0, data_bytes);
926
927                                 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
928                                         print_error_with_state(&encoder_session, "ERROR during encoding");
929                                         return EncoderSession_finish_error(&encoder_session);
930                                 }
931                         }
932                 }
933                 else {
934                         if(*options.common.align_reservoir_samples > 0) {
935                                 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
936                                 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
937                                 if(bytes_read == 0 && ferror(infile)) {
938                                         fprintf(stderr, "%s: ERROR during read\n", encoder_session.inbasefilename);
939                                         return EncoderSession_finish_error(&encoder_session);
940                                 }
941                                 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
942                                         fprintf(stderr, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
943                                 }
944                                 else {
945                                         info_align_carry = *options.common.align_reservoir_samples;
946                                         format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, false, options.is_unsigned_samples, options.channels, options.bps);
947                                 }
948                         }
949                 }
950         }
951
952         return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
953 }
954
955 FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FLAC__bool verbose, FILE *infile, const char *infilename, const char *outfilename)
956 {
957         unsigned i;
958         FLAC__uint32 test = 1;
959
960         /*
961          * initialize globals
962          */
963
964         is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
965
966         for(i = 0; i < FLAC__MAX_CHANNELS; i++)
967                 input_[i] = &(in_[i][0]);
968
969
970         /*
971          * initialize instance
972          */
973
974 #ifdef FLAC__HAS_OGG
975         e->use_ogg = use_ogg;
976 #else
977         (void)use_ogg;
978 #endif
979         e->verify = verify;
980         e->verbose = verbose;
981
982         e->is_stdout = (0 == strcmp(outfilename, "-"));
983
984         e->inbasefilename = flac__file_get_basename(infilename);
985         e->outfilename = outfilename;
986
987         e->unencoded_size = 0;
988         e->total_samples_to_encode = 0;
989         e->bytes_written = 0;
990         e->samples_written = 0;
991         e->blocksize = 0;
992         e->stats_mask = 0;
993
994         e->encoder.flac.stream = 0;
995         e->encoder.flac.file = 0;
996 #ifdef FLAC__HAS_OGG
997         e->encoder.ogg.stream = 0;
998 #endif
999
1000         e->fin = infile;
1001         e->fout = 0;
1002         e->seek_table_template = 0;
1003
1004         if(e->is_stdout) {
1005                 e->fout = file__get_binary_stdout();
1006         }
1007 #ifdef FLAC__HAS_OGG
1008         else {
1009                 if(e->use_ogg) {
1010                         if(0 == (e->fout = fopen(outfilename, "wb"))) {
1011                                 fprintf(stderr, "%s: ERROR: can't open output file %s\n", e->inbasefilename, outfilename);
1012                                 EncoderSession_destroy(e);
1013                                 return false;
1014                         }
1015                 }
1016         }
1017 #endif
1018
1019         if(0 == (e->seek_table_template = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE))) {
1020                 fprintf(stderr, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1021                 return false;
1022         }
1023
1024 #ifdef FLAC__HAS_OGG
1025         if(e->use_ogg) {
1026                 e->encoder.ogg.stream = OggFLAC__stream_encoder_new();
1027                 if(0 == e->encoder.ogg.stream) {
1028                         fprintf(stderr, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1029                         EncoderSession_destroy(e);
1030                         return false;
1031                 }
1032         }
1033         else
1034 #endif
1035         if(e->is_stdout) {
1036                 e->encoder.flac.stream = FLAC__stream_encoder_new();
1037                 if(0 == e->encoder.flac.stream) {
1038                         fprintf(stderr, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1039                         EncoderSession_destroy(e);
1040                         return false;
1041                 }
1042         }
1043         else {
1044                 e->encoder.flac.file = FLAC__file_encoder_new();
1045                 if(0 == e->encoder.flac.file) {
1046                         fprintf(stderr, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1047                         EncoderSession_destroy(e);
1048                         return false;
1049                 }
1050         }
1051
1052         return true;
1053 }
1054
1055 void EncoderSession_destroy(EncoderSession *e)
1056 {
1057         if(e->fin != stdin)
1058                 fclose(e->fin);
1059
1060 #ifdef FLAC__HAS_OGG
1061         if(e->use_ogg) {
1062                 if(0 != e->encoder.ogg.stream) {
1063                         OggFLAC__stream_encoder_delete(e->encoder.ogg.stream);
1064                         e->encoder.ogg.stream = 0;
1065                 }
1066         }
1067         else
1068 #endif
1069         if(e->is_stdout) {
1070                 if(0 != e->encoder.flac.stream) {
1071                         FLAC__stream_encoder_delete(e->encoder.flac.stream);
1072                         e->encoder.flac.stream = 0;
1073                 }
1074         }
1075         else {
1076                 if(0 != e->encoder.flac.file) {
1077                         FLAC__file_encoder_delete(e->encoder.flac.file);
1078                         e->encoder.flac.file = 0;
1079                 }
1080         }
1081
1082         if(0 != e->seek_table_template) {
1083                 FLAC__metadata_object_delete(e->seek_table_template);
1084                 e->seek_table_template = 0;
1085         }
1086 }
1087
1088 int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero)
1089 {
1090         FLAC__StreamEncoderState fse_state = FLAC__STREAM_ENCODER_OK;
1091         int ret = 0;
1092
1093 #ifdef FLAC__HAS_OGG
1094         if(e->use_ogg) {
1095                 if(e->encoder.ogg.stream) {
1096                         fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.stream);
1097                         OggFLAC__stream_encoder_finish(e->encoder.ogg.stream);
1098                 }
1099         }
1100         else
1101 #endif
1102         if(e->is_stdout) {
1103                 if(e->encoder.flac.stream) {
1104                         fse_state = FLAC__stream_encoder_get_state(e->encoder.flac.stream);
1105                         FLAC__stream_encoder_finish(e->encoder.flac.stream);
1106                 }
1107         }
1108         else {
1109                 if(e->encoder.flac.file) {
1110                         fse_state = FLAC__file_encoder_get_stream_encoder_state(e->encoder.flac.file);
1111                         FLAC__file_encoder_finish(e->encoder.flac.file);
1112                 }
1113         }
1114
1115         if(e->verbose && e->total_samples_to_encode > 0) {
1116                 print_stats(e);
1117                 fprintf(stderr, "\n");
1118         }
1119
1120         if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) {
1121                 print_verify_error(e);
1122                 ret = 1;
1123         }
1124         else {
1125                 if(info_align_carry >= 0)
1126                         fprintf(stderr, "%s: INFO: sector alignment causing %d samples to be carried over\n", e->inbasefilename, info_align_carry);
1127                 if(info_align_zero >= 0)
1128                         fprintf(stderr, "%s: INFO: sector alignment causing %d zero samples to be appended\n", e->inbasefilename, info_align_zero);
1129         }
1130
1131         EncoderSession_destroy(e);
1132
1133         return ret;
1134 }
1135
1136 int EncoderSession_finish_error(EncoderSession *e)
1137 {
1138         FLAC__StreamEncoderState fse_state;
1139
1140         if(e->verbose && e->total_samples_to_encode > 0)
1141                 fprintf(stderr, "\n");
1142
1143 #ifdef FLAC__HAS_OGG
1144         if(e->use_ogg) {
1145                 fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.stream);
1146         }
1147         else
1148 #endif
1149         if(e->is_stdout) {
1150                 fse_state = FLAC__stream_encoder_get_state(e->encoder.flac.stream);
1151         }
1152         else {
1153                 fse_state = FLAC__file_encoder_get_stream_encoder_state(e->encoder.flac.file);
1154         }
1155
1156         if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
1157                 print_verify_error(e);
1158         else
1159                 unlink(e->outfilename);
1160
1161         EncoderSession_destroy(e);
1162
1163         return 1;
1164 }
1165
1166 FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate)
1167 {
1168         unsigned num_metadata;
1169         FLAC__StreamMetadata padding;
1170         FLAC__StreamMetadata *metadata[3];
1171
1172         if(channels != 2)
1173                 options.do_mid_side = options.loose_mid_side = false;
1174
1175         if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, e)) {
1176                 fprintf(stderr, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1177                 return false;
1178         }
1179
1180         num_metadata = 0;
1181         metadata[num_metadata++] = options.vorbis_comment;
1182         if(e->seek_table_template->data.seek_table.num_points > 0) {
1183                 e->seek_table_template->is_last = false; /* the encoder will set this for us */
1184                 metadata[num_metadata++] = e->seek_table_template;
1185         }
1186         if(options.padding > 0) {
1187                 padding.is_last = false; /* the encoder will set this for us */
1188                 padding.type = FLAC__METADATA_TYPE_PADDING;
1189                 padding.length = (unsigned)options.padding;
1190                 metadata[num_metadata++] = &padding;
1191         }
1192
1193         e->blocksize = options.blocksize;
1194         e->stats_mask = (options.do_exhaustive_model_search || options.do_qlp_coeff_prec_search)? 0x0f : 0x3f;
1195
1196 #ifdef FLAC__HAS_OGG
1197         if(e->use_ogg) {
1198                 if(options.has_serial_number)
1199                         OggFLAC__stream_encoder_set_serial_number(e->encoder.ogg.stream, options.serial_number);
1200                 OggFLAC__stream_encoder_set_verify(e->encoder.ogg.stream, options.verify);
1201                 OggFLAC__stream_encoder_set_streamable_subset(e->encoder.ogg.stream, !options.lax);
1202                 OggFLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.ogg.stream, options.do_mid_side);
1203                 OggFLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.ogg.stream, options.loose_mid_side);
1204                 OggFLAC__stream_encoder_set_channels(e->encoder.ogg.stream, channels);
1205                 OggFLAC__stream_encoder_set_bits_per_sample(e->encoder.ogg.stream, bps);
1206                 OggFLAC__stream_encoder_set_sample_rate(e->encoder.ogg.stream, sample_rate);
1207                 OggFLAC__stream_encoder_set_blocksize(e->encoder.ogg.stream, options.blocksize);
1208                 OggFLAC__stream_encoder_set_max_lpc_order(e->encoder.ogg.stream, options.max_lpc_order);
1209                 OggFLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.ogg.stream, options.qlp_coeff_precision);
1210                 OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.stream, options.do_qlp_coeff_prec_search);
1211                 OggFLAC__stream_encoder_set_do_escape_coding(e->encoder.ogg.stream, options.do_escape_coding);
1212                 OggFLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.ogg.stream, options.do_exhaustive_model_search);
1213                 OggFLAC__stream_encoder_set_min_residual_partition_order(e->encoder.ogg.stream, options.min_residual_partition_order);
1214                 OggFLAC__stream_encoder_set_max_residual_partition_order(e->encoder.ogg.stream, options.max_residual_partition_order);
1215                 OggFLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.ogg.stream, options.rice_parameter_search_dist);
1216                 OggFLAC__stream_encoder_set_total_samples_estimate(e->encoder.ogg.stream, e->total_samples_to_encode);
1217                 OggFLAC__stream_encoder_set_metadata(e->encoder.ogg.stream, (num_metadata > 0)? metadata : 0, num_metadata);
1218                 OggFLAC__stream_encoder_set_write_callback(e->encoder.ogg.stream, ogg_stream_encoder_write_callback);
1219                 OggFLAC__stream_encoder_set_client_data(e->encoder.ogg.stream, e);
1220
1221                 OggFLAC__stream_encoder_disable_constant_subframes(e->encoder.ogg.stream, options.debug.disable_constant_subframes);
1222                 OggFLAC__stream_encoder_disable_fixed_subframes(e->encoder.ogg.stream, options.debug.disable_fixed_subframes);
1223                 OggFLAC__stream_encoder_disable_verbatim_subframes(e->encoder.ogg.stream, options.debug.disable_verbatim_subframes);
1224
1225                 if(OggFLAC__stream_encoder_init(e->encoder.ogg.stream) != FLAC__STREAM_ENCODER_OK) {
1226                         print_error_with_state(e, "ERROR initializing encoder");
1227                         return false;
1228                 }
1229         }
1230         else
1231 #endif
1232         if(e->is_stdout) {
1233                 FLAC__stream_encoder_set_verify(e->encoder.flac.stream, options.verify);
1234                 FLAC__stream_encoder_set_streamable_subset(e->encoder.flac.stream, !options.lax);
1235                 FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.flac.stream, options.do_mid_side);
1236                 FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.flac.stream, options.loose_mid_side);
1237                 FLAC__stream_encoder_set_channels(e->encoder.flac.stream, channels);
1238                 FLAC__stream_encoder_set_bits_per_sample(e->encoder.flac.stream, bps);
1239                 FLAC__stream_encoder_set_sample_rate(e->encoder.flac.stream, sample_rate);
1240                 FLAC__stream_encoder_set_blocksize(e->encoder.flac.stream, options.blocksize);
1241                 FLAC__stream_encoder_set_max_lpc_order(e->encoder.flac.stream, options.max_lpc_order);
1242                 FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.flac.stream, options.qlp_coeff_precision);
1243                 FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.stream, options.do_qlp_coeff_prec_search);
1244                 FLAC__stream_encoder_set_do_escape_coding(e->encoder.flac.stream, options.do_escape_coding);
1245                 FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.flac.stream, options.do_exhaustive_model_search);
1246                 FLAC__stream_encoder_set_min_residual_partition_order(e->encoder.flac.stream, options.min_residual_partition_order);
1247                 FLAC__stream_encoder_set_max_residual_partition_order(e->encoder.flac.stream, options.max_residual_partition_order);
1248                 FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.flac.stream, options.rice_parameter_search_dist);
1249                 FLAC__stream_encoder_set_total_samples_estimate(e->encoder.flac.stream, e->total_samples_to_encode);
1250                 FLAC__stream_encoder_set_metadata(e->encoder.flac.stream, (num_metadata > 0)? metadata : 0, num_metadata);
1251                 FLAC__stream_encoder_set_write_callback(e->encoder.flac.stream, flac_stream_encoder_write_callback);
1252                 FLAC__stream_encoder_set_metadata_callback(e->encoder.flac.stream, flac_stream_encoder_metadata_callback);
1253                 FLAC__stream_encoder_set_client_data(e->encoder.flac.stream, e);
1254
1255                 FLAC__stream_encoder_disable_constant_subframes(e->encoder.flac.stream, options.debug.disable_constant_subframes);
1256                 FLAC__stream_encoder_disable_fixed_subframes(e->encoder.flac.stream, options.debug.disable_fixed_subframes);
1257                 FLAC__stream_encoder_disable_verbatim_subframes(e->encoder.flac.stream, options.debug.disable_verbatim_subframes);
1258
1259                 if(FLAC__stream_encoder_init(e->encoder.flac.stream) != FLAC__STREAM_ENCODER_OK) {
1260                         print_error_with_state(e, "ERROR initializing encoder");
1261                         return false;
1262                 }
1263         }
1264         else {
1265                 FLAC__file_encoder_set_filename(e->encoder.flac.file, e->outfilename);
1266                 FLAC__file_encoder_set_verify(e->encoder.flac.file, options.verify);
1267                 FLAC__file_encoder_set_streamable_subset(e->encoder.flac.file, !options.lax);
1268                 FLAC__file_encoder_set_do_mid_side_stereo(e->encoder.flac.file, options.do_mid_side);
1269                 FLAC__file_encoder_set_loose_mid_side_stereo(e->encoder.flac.file, options.loose_mid_side);
1270                 FLAC__file_encoder_set_channels(e->encoder.flac.file, channels);
1271                 FLAC__file_encoder_set_bits_per_sample(e->encoder.flac.file, bps);
1272                 FLAC__file_encoder_set_sample_rate(e->encoder.flac.file, sample_rate);
1273                 FLAC__file_encoder_set_blocksize(e->encoder.flac.file, options.blocksize);
1274                 FLAC__file_encoder_set_max_lpc_order(e->encoder.flac.file, options.max_lpc_order);
1275                 FLAC__file_encoder_set_qlp_coeff_precision(e->encoder.flac.file, options.qlp_coeff_precision);
1276                 FLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.file, options.do_qlp_coeff_prec_search);
1277                 FLAC__file_encoder_set_do_escape_coding(e->encoder.flac.file, options.do_escape_coding);
1278                 FLAC__file_encoder_set_do_exhaustive_model_search(e->encoder.flac.file, options.do_exhaustive_model_search);
1279                 FLAC__file_encoder_set_min_residual_partition_order(e->encoder.flac.file, options.min_residual_partition_order);
1280                 FLAC__file_encoder_set_max_residual_partition_order(e->encoder.flac.file, options.max_residual_partition_order);
1281                 FLAC__file_encoder_set_rice_parameter_search_dist(e->encoder.flac.file, options.rice_parameter_search_dist);
1282                 FLAC__file_encoder_set_total_samples_estimate(e->encoder.flac.file, e->total_samples_to_encode);
1283                 FLAC__file_encoder_set_metadata(e->encoder.flac.file, (num_metadata > 0)? metadata : 0, num_metadata);
1284                 FLAC__file_encoder_set_progress_callback(e->encoder.flac.file, flac_file_encoder_progress_callback);
1285                 FLAC__file_encoder_set_client_data(e->encoder.flac.file, e);
1286
1287                 FLAC__file_encoder_disable_constant_subframes(e->encoder.flac.file, options.debug.disable_constant_subframes);
1288                 FLAC__file_encoder_disable_fixed_subframes(e->encoder.flac.file, options.debug.disable_fixed_subframes);
1289                 FLAC__file_encoder_disable_verbatim_subframes(e->encoder.flac.file, options.debug.disable_verbatim_subframes);
1290
1291                 if(FLAC__file_encoder_init(e->encoder.flac.file) != FLAC__FILE_ENCODER_OK) {
1292                         print_error_with_state(e, "ERROR initializing encoder");
1293                         return false;
1294                 }
1295         }
1296
1297         return true;
1298 }
1299
1300 FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples)
1301 {
1302 #ifdef FLAC__HAS_OGG
1303         if(e->use_ogg) {
1304                 return OggFLAC__stream_encoder_process(e->encoder.ogg.stream, buffer, samples);
1305         }
1306         else
1307 #endif
1308         if(e->is_stdout) {
1309                 return FLAC__stream_encoder_process(e->encoder.flac.stream, buffer, samples);
1310         }
1311         else {
1312                 return FLAC__file_encoder_process(e->encoder.flac.file, buffer, samples);
1313         }
1314 }
1315
1316 FLAC__bool convert_to_seek_table_template(char *requested_seek_points, int num_requested_seek_points, EncoderSession *e)
1317 {
1318         unsigned i;
1319         char *pt = requested_seek_points, *q;
1320         FLAC__bool only_placeholders = false;
1321         FLAC__bool needs_warning = false;
1322
1323         if(num_requested_seek_points == 0)
1324                 return true;
1325
1326         if(num_requested_seek_points < 0) {
1327                 strcpy(requested_seek_points, "100x<");
1328                 num_requested_seek_points = 1;
1329         }
1330
1331         if(e->is_stdout) {
1332                 only_placeholders = true;
1333         }
1334 #ifdef HAS_OGG
1335         else if(e->is_ogg) {
1336                 only_placeholders = true;
1337         }
1338 #endif
1339
1340         for(i = 0; i < (unsigned)num_requested_seek_points; i++) {
1341                 q = strchr(pt, '<');
1342                 FLAC__ASSERT(0 != q);
1343                 *q++ = '\0';
1344
1345                 if(0 == strcmp(pt, "X")) { /* -S X */
1346                         if(!FLAC__metadata_object_seektable_template_append_placeholders(e->seek_table_template, 1))
1347                                 return false;
1348                 }
1349                 else if(!only_placeholders) {
1350                         if(pt[strlen(pt)-1] == 'x') { /* -S #x */
1351                                 if(e->total_samples_to_encode > 0) { /* we can only do these if we know the number of samples to encode up front */
1352                                         if(!FLAC__metadata_object_seektable_template_append_spaced_points(e->seek_table_template, atoi(pt), e->total_samples_to_encode))
1353                                                 return false;
1354                                 }
1355                         }
1356                         else { /* -S # */
1357                                 FLAC__uint64 n = (unsigned)atoi(pt);
1358                                 if(!FLAC__metadata_object_seektable_template_append_point(e->seek_table_template, n))
1359                                         return false;
1360                         }
1361                 }
1362                 else
1363                         needs_warning = true;
1364
1365                 pt = q;
1366         }
1367
1368         if(!FLAC__metadata_object_seektable_template_sort(e->seek_table_template, /*compact=*/true))
1369                 return false;
1370
1371         if(needs_warning) {
1372                 if(e->is_stdout) {
1373                         fprintf(stderr, "%s: WARNING, cannot write back seektable when encoding to stdout\n", e->inbasefilename);
1374                 }
1375 #ifdef HAS_OGG
1376                 else if(e->is_ogg) {
1377                         fprintf(stderr, "%s: WARNING, cannot write back seektable when encoding to Ogg\n", e->inbasefilename);
1378                 }
1379 #endif
1380                 else {
1381                         FLAC__ASSERT(0);
1382                 }
1383         }
1384
1385         return true;
1386 }
1387
1388 void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps)
1389 {
1390         unsigned wide_sample, sample, channel, byte;
1391
1392         if(bps == 8) {
1393                 if(is_unsigned_samples) {
1394                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1395                                 for(channel = 0; channel < channels; channel++, sample++)
1396                                         dest[channel][wide_sample] = (FLAC__int32)ucbuffer_[sample] - 0x80;
1397                 }
1398                 else {
1399                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1400                                 for(channel = 0; channel < channels; channel++, sample++)
1401                                         dest[channel][wide_sample] = (FLAC__int32)scbuffer_[sample];
1402                 }
1403         }
1404         else if(bps == 16) {
1405                 if(is_big_endian != is_big_endian_host_) {
1406                         unsigned char tmp;
1407                         const unsigned bytes = wide_samples * channels * (bps >> 3);
1408                         for(byte = 0; byte < bytes; byte += 2) {
1409                                 tmp = ucbuffer_[byte];
1410                                 ucbuffer_[byte] = ucbuffer_[byte+1];
1411                                 ucbuffer_[byte+1] = tmp;
1412                         }
1413                 }
1414                 if(is_unsigned_samples) {
1415                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1416                                 for(channel = 0; channel < channels; channel++, sample++)
1417                                         dest[channel][wide_sample] = (FLAC__int32)usbuffer_[sample] - 0x8000;
1418                 }
1419                 else {
1420                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1421                                 for(channel = 0; channel < channels; channel++, sample++)
1422                                         dest[channel][wide_sample] = (FLAC__int32)ssbuffer_[sample];
1423                 }
1424         }
1425         else if(bps == 24) {
1426                 if(!is_big_endian) {
1427                         unsigned char tmp;
1428                         const unsigned bytes = wide_samples * channels * (bps >> 3);
1429                         for(byte = 0; byte < bytes; byte += 3) {
1430                                 tmp = ucbuffer_[byte];
1431                                 ucbuffer_[byte] = ucbuffer_[byte+2];
1432                                 ucbuffer_[byte+2] = tmp;
1433                         }
1434                 }
1435                 if(is_unsigned_samples) {
1436                         for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1437                                 for(channel = 0; channel < channels; channel++, sample++) {
1438                                         dest[channel][wide_sample]  = ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1439                                         dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1440                                         dest[channel][wide_sample] |= ucbuffer_[byte++];
1441                                         dest[channel][wide_sample] -= 0x800000;
1442                                 }
1443                 }
1444                 else {
1445                         for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1446                                 for(channel = 0; channel < channels; channel++, sample++) {
1447                                         dest[channel][wide_sample]  = scbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1448                                         dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1449                                         dest[channel][wide_sample] |= ucbuffer_[byte++];
1450                                 }
1451                 }
1452         }
1453         else {
1454                 FLAC__ASSERT(0);
1455         }
1456 }
1457
1458 #ifdef FLAC__HAS_OGG
1459 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)
1460 {
1461         EncoderSession *encoder_session = (EncoderSession*)client_data;
1462
1463         (void)encoder;
1464
1465         encoder_session->bytes_written += bytes;
1466         /*
1467          * With Ogg FLAC we don't get one write callback per frame and
1468          * we don't have good number for 'samples', so we estimate based
1469          * on the frame number and the knowledge that all blocks (except
1470          * the last) are the same size.
1471          */
1472         (void)samples;
1473         encoder_session->samples_written = (current_frame+1) * encoder_session->blocksize;
1474
1475         if(encoder_session->verbose && encoder_session->total_samples_to_encode > 0 && !(current_frame & encoder_session->stats_mask))
1476                 print_stats(encoder_session);
1477
1478         if(fwrite(buffer, sizeof(FLAC__byte), bytes, encoder_session->fout) == bytes)
1479                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
1480         else
1481                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1482 }
1483 #endif
1484
1485 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)
1486 {
1487         EncoderSession *encoder_session = (EncoderSession*)client_data;
1488
1489         (void)encoder;
1490
1491         encoder_session->bytes_written += bytes;
1492         encoder_session->samples_written += samples;
1493
1494         if(samples && encoder_session->verbose && encoder_session->total_samples_to_encode > 0 && !(current_frame & encoder_session->stats_mask))
1495                 print_stats(encoder_session);
1496
1497         if(fwrite(buffer, sizeof(FLAC__byte), bytes, encoder_session->fout) == bytes)
1498                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
1499         else
1500                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1501 }
1502
1503 void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
1504 {
1505         /*
1506          * Nothing to do; if we get here, we're decoding to stdout, in
1507          * which case we can't seek backwards to write new metadata.
1508          */
1509         (void)encoder, (void)metadata, (void)client_data;
1510 }
1511
1512 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)
1513 {
1514         EncoderSession *encoder_session = (EncoderSession*)client_data;
1515
1516         (void)encoder, (void)total_frames_estimate;
1517
1518         encoder_session->bytes_written = bytes_written;
1519         encoder_session->samples_written = samples_written;
1520
1521         if(encoder_session->verbose && encoder_session->total_samples_to_encode > 0 && !((frames_written-1) & encoder_session->stats_mask))
1522                 print_stats(encoder_session);
1523 }
1524
1525 void print_stats(const EncoderSession *encoder_session)
1526 {
1527         const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written);
1528 #if defined _MSC_VER || defined __MINGW32__
1529         /* with VC++ you have to spoon feed it the casting */
1530         const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode;
1531         const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)encoder_session->unencoded_size * progress);
1532 #else
1533         const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode;
1534         const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * progress);
1535 #endif
1536
1537         if(samples_written == encoder_session->total_samples_to_encode) {
1538                 fprintf(stderr, "\r%s:%s wrote %u bytes, ratio=%0.3f",
1539                         encoder_session->inbasefilename,
1540                         encoder_session->verify? " Verify OK," : "",
1541                         (unsigned)encoder_session->bytes_written,
1542                         ratio
1543                 );
1544         }
1545         else {
1546                 fprintf(stderr, "\r%s: %u%% complete, ratio=%0.3f", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio);
1547         }
1548 }
1549
1550 void print_error_with_state(const EncoderSession *e, const char *message)
1551 {
1552         const int ilen = strlen(e->inbasefilename) + 1;
1553
1554         fprintf(stderr, "\n%s: %s\n", e->inbasefilename, message);
1555
1556 #ifdef FLAC__HAS_OGG
1557         if(e->use_ogg) {
1558                 const OggFLAC__StreamEncoderState ose_state = OggFLAC__stream_encoder_get_state(e->encoder.ogg.stream);
1559                 if(ose_state != OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR) {
1560                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)ose_state, OggFLAC__StreamEncoderStateString[ose_state]);
1561                 }
1562                 else {
1563                         const FLAC__StreamEncoderState fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.stream);
1564                         if(fse_state != FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) {
1565                                 fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fse_state, FLAC__StreamEncoderStateString[fse_state]);
1566                         }
1567                         else {
1568                                 const FLAC__StreamDecoderState fsd_state = OggFLAC__stream_encoder_get_verify_decoder_state(e->encoder.ogg.stream);
1569                                 fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fsd_state, FLAC__StreamDecoderStateString[fsd_state]);
1570                         }
1571                 }
1572         }
1573         else
1574 #endif
1575         if(e->is_stdout) {
1576                 const FLAC__StreamEncoderState fse_state = FLAC__stream_encoder_get_state(e->encoder.flac.stream);
1577                 if(fse_state != FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) {
1578                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fse_state, FLAC__StreamEncoderStateString[fse_state]);
1579                 }
1580                 else {
1581                         const FLAC__StreamDecoderState fsd_state = FLAC__stream_encoder_get_verify_decoder_state(e->encoder.flac.stream);
1582                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fsd_state, FLAC__StreamDecoderStateString[fsd_state]);
1583                 }
1584         }
1585         else {
1586                 const FLAC__FileEncoderState ffe_state = FLAC__file_encoder_get_state(e->encoder.flac.file);
1587                 if(ffe_state != FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR) {
1588                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)ffe_state, FLAC__FileEncoderStateString[ffe_state]);
1589                 }
1590                 else {
1591                         const FLAC__SeekableStreamEncoderState fsse_state = FLAC__file_encoder_get_seekable_stream_encoder_state(e->encoder.flac.file);
1592                         if(fsse_state != FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR) {
1593                                 fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fsse_state, FLAC__SeekableStreamEncoderStateString[fsse_state]);
1594                         }
1595                         else {
1596                                 const FLAC__StreamEncoderState fse_state = FLAC__file_encoder_get_stream_encoder_state(e->encoder.flac.file);
1597                                 if(fse_state != FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) {
1598                                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fse_state, FLAC__StreamEncoderStateString[fse_state]);
1599                                 }
1600                                 else {
1601                                         const FLAC__StreamDecoderState fsd_state = FLAC__file_encoder_get_verify_decoder_state(e->encoder.flac.file);
1602                                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fsd_state, FLAC__StreamDecoderStateString[fsd_state]);
1603                                 }
1604                         }
1605                 }
1606         }
1607 }
1608
1609 void print_verify_error(EncoderSession *e)
1610 {
1611         FLAC__uint64 absolute_sample;
1612         unsigned frame_number;
1613         unsigned channel;
1614         unsigned sample;
1615         FLAC__int32 expected;
1616         FLAC__int32 got;
1617
1618 #ifdef FLAC__HAS_OGG
1619         if(e->use_ogg) {
1620                 OggFLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.ogg.stream, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1621         }
1622         else
1623 #endif
1624         if(e->is_stdout) {
1625                 FLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.flac.stream, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1626         }
1627         else {
1628                 FLAC__file_encoder_get_verify_decoder_error_stats(e->encoder.flac.file, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1629         }
1630
1631         fprintf(stderr, "%s: ERROR: mismatch in decoded data, verify FAILED!\n", e->inbasefilename);
1632         fprintf(stderr, "       Absolute sample=%u, frame=%u, channel=%u, sample=%u, expected %d, got %d\n", (unsigned)absolute_sample, frame_number, channel, sample, expected, got);
1633         fprintf(stderr, "       Please submit a bug report to\n");
1634         fprintf(stderr, "           http://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
1635         fprintf(stderr, "       Make sure to include an email contact in the comment and/or use the\n");
1636         fprintf(stderr, "       \"Monitor\" feature to monitor the bug status.\n");
1637         fprintf(stderr, "Verify FAILED!  Do not trust %s\n", e->outfilename);
1638 }
1639
1640 FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
1641 {
1642         size_t bytes_read = fread(val, 1, 2, f);
1643
1644         if(bytes_read == 0) {
1645                 if(!eof_ok) {
1646                         fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1647                         return false;
1648                 }
1649                 else
1650                         return true;
1651         }
1652         else if(bytes_read < 2) {
1653                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1654                 return false;
1655         }
1656         else {
1657                 if(is_big_endian_host_) {
1658                         FLAC__byte tmp, *b = (FLAC__byte*)val;
1659                         tmp = b[1]; b[1] = b[0]; b[0] = tmp;
1660                 }
1661                 return true;
1662         }
1663 }
1664
1665 FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
1666 {
1667         size_t bytes_read = fread(val, 1, 4, f);
1668
1669         if(bytes_read == 0) {
1670                 if(!eof_ok) {
1671                         fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1672                         return false;
1673                 }
1674                 else
1675                         return true;
1676         }
1677         else if(bytes_read < 4) {
1678                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1679                 return false;
1680         }
1681         else {
1682                 if(is_big_endian_host_) {
1683                         FLAC__byte tmp, *b = (FLAC__byte*)val;
1684                         tmp = b[3]; b[3] = b[0]; b[0] = tmp;
1685                         tmp = b[2]; b[2] = b[1]; b[1] = tmp;
1686                 }
1687                 return true;
1688         }
1689 }
1690
1691 FLAC__bool
1692 read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
1693 {
1694         unsigned char buf[4];
1695         size_t bytes_read= fread(buf, 1, 2, f);
1696
1697         if(bytes_read==0U && eof_ok)
1698                 return true;
1699         else if(bytes_read<2U) {
1700                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1701                 return false;
1702         }
1703
1704         /* this is independent of host endianness */
1705         *val= (FLAC__uint16)(buf[0])<<8 | buf[1];
1706
1707         return true;
1708 }
1709
1710 FLAC__bool
1711 read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
1712 {
1713         unsigned char buf[4];
1714         size_t bytes_read= fread(buf, 1, 4, f);
1715
1716         if(bytes_read==0U && eof_ok)
1717                 return true;
1718         else if(bytes_read<4U) {
1719                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1720                 return false;
1721         }
1722
1723         /* this is independent of host endianness */
1724         *val= (FLAC__uint32)(buf[0])<<24 | (FLAC__uint32)(buf[1])<<16 |
1725                 (FLAC__uint32)(buf[2])<<8 | buf[3];
1726
1727         return true;
1728 }
1729
1730 FLAC__bool
1731 read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
1732         /* Read an IEEE 754 80-bit (aka SANE) extended floating point value from 'f',
1733          * convert it into an integral value and store in 'val'.  Return false if only
1734          * between 1 and 9 bytes remain in 'f', if 0 bytes remain in 'f' and 'eof_ok' is
1735          * false, or if the value is negative, between zero and one, or too large to be
1736          * represented by 'val'; return true otherwise.
1737          */
1738 {
1739         unsigned int i;
1740         unsigned char buf[10];
1741         size_t bytes_read= fread(buf, 1U, 10U, f);
1742         FLAC__int16 e= ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
1743         FLAC__int16 shift= 63-e;
1744         FLAC__uint64 p= 0U;
1745
1746         if(bytes_read==0U && eof_ok)
1747                 return true;
1748         else if(bytes_read<10U) {
1749                 fprintf(stderr, "%s: ERROR: unexpected EOF\n", fn);
1750                 return false;
1751         }
1752         else if((buf[0]>>7)==1U || e<0 || e>63) {
1753                 fprintf(stderr, "%s: ERROR: invalid floating-point value\n", fn);
1754                 return false;
1755         }
1756
1757         for(i= 0U; i<8U; ++i)
1758                 p|= (FLAC__uint64)(buf[i+2])<<(56U-i*8);
1759         *val= (FLAC__uint32)((p>>shift)+(p>>(shift-1) & 0x1));
1760
1761         return true;
1762 }