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