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