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