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