64cd0e231073c82d16070da65bedf221f1bb9519
[platform/upstream/flac.git] / src / flac / decode.c
1 /* flac - Command-line FLAC encoder/decoder
2  * Copyright (C) 2000,2001,2002,2003  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 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #if defined _WIN32 && !defined __CYGWIN__
24 /* where MSVC puts unlink() */
25 # include <io.h>
26 #else
27 # include <unistd.h>
28 #endif
29 #include <math.h> /* for floor() */
30 #include <stdio.h> /* for FILE et al. */
31 #include <string.h> /* for strcmp() */
32 #include "FLAC/all.h"
33 #include "share/grabbag.h"
34 #include "share/replaygain_synthesis.h"
35 #include "decode.h"
36
37 #ifdef FLAC__HAS_OGG
38 #include "OggFLAC/stream_decoder.h"
39 #endif
40
41 typedef struct {
42 #ifdef FLAC__HAS_OGG
43         FLAC__bool is_ogg;
44 #endif
45
46         FLAC__bool verbose;
47         FLAC__bool is_aiff_out;
48         FLAC__bool is_wave_out;
49         FLAC__bool continue_through_decode_errors;
50
51         struct {
52                 replaygain_synthesis_spec_t spec;
53                 double scale;
54                 DitherContext dither_context;
55         } replaygain;
56
57         FLAC__bool test_only;
58         FLAC__bool analysis_mode;
59         analysis_options aopts;
60         utils__SkipUntilSpecification *skip_specification;
61         utils__SkipUntilSpecification *until_specification; /* a canonicalized value of 0 mean end-of-stream (i.e. --until=-0) */
62
63         const char *inbasefilename;
64         const char *outfilename;
65
66         FLAC__uint64 samples_processed;
67         unsigned frame_counter;
68         FLAC__bool abort_flag;
69
70         struct {
71                 FLAC__bool needs_fixup;
72                 unsigned riff_offset; /* or FORM offset for AIFF */
73                 unsigned data_offset; /* or SSND offset for AIFF */
74                 unsigned frames_offset; /* AIFF only */
75         } wave_chunk_size_fixup;
76
77         FLAC__bool is_big_endian;
78         FLAC__bool is_unsigned_samples;
79         FLAC__uint64 total_samples;
80         unsigned bps;
81         unsigned channels;
82         unsigned sample_rate;
83
84         union {
85                 union {
86                         FLAC__FileDecoder *file;
87                 } flac;
88 #ifdef FLAC__HAS_OGG
89                 union {
90                         OggFLAC__StreamDecoder *stream;
91                 } ogg;
92 #endif
93         } decoder;
94
95 #ifdef FLAC__HAS_OGG
96         FILE *fin;
97 #endif
98         FILE *fout;
99 } DecoderSession;
100
101
102 static FLAC__bool is_big_endian_host_;
103
104
105 /*
106  * local routines
107  */
108 static FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool verbose, FLAC__bool is_aiff_out, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, const char *infilename, const char *outfilename);
109 static void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred);
110 static FLAC__bool DecoderSession_init_decoder(DecoderSession *d, decode_options_t decode_options, const char *infilename);
111 static FLAC__bool DecoderSession_process(DecoderSession *d);
112 static int DecoderSession_finish_ok(DecoderSession *d);
113 static int DecoderSession_finish_error(DecoderSession *d);
114 static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
115 static FLAC__bool write_little_endian_uint16(FILE *f, FLAC__uint16 val);
116 static FLAC__bool write_little_endian_uint32(FILE *f, FLAC__uint32 val);
117 static FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 val);
118 static FLAC__bool write_big_endian_uint32(FILE *f, FLAC__uint32 val);
119 static FLAC__bool write_sane_extended(FILE *f, unsigned val);
120 static FLAC__bool fixup_wave_chunk_size(const char *outfilename, FLAC__bool is_wave_out, unsigned riff_offset, unsigned data_offset, unsigned frames_offset, FLAC__uint32 total_samples, unsigned channels, unsigned bps);
121 #ifdef FLAC__HAS_OGG
122 static FLAC__StreamDecoderReadStatus read_callback(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
123 #endif
124 /*
125  * We use 'void *' so that we can use the same callbacks for the
126  * FLAC__StreamDecoder and FLAC__FileDecoder.  The 'decoder' argument is
127  * actually never used in the callbacks.
128  */
129 static FLAC__StreamDecoderWriteStatus write_callback(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
130 static void metadata_callback(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
131 static void error_callback(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
132 static void print_error_with_state(const DecoderSession *d, const char *message);
133 static void print_stats(const DecoderSession *decoder_session);
134
135
136 /*
137  * public routines
138  */
139 int flac__decode_aiff(const char *infilename, const char *outfilename, FLAC__bool analysis_mode, analysis_options aopts, wav_decode_options_t options)
140 {
141         DecoderSession decoder_session;
142
143         if(!
144                 DecoderSession_construct(
145                         &decoder_session,
146 #ifdef FLAC__HAS_OGG
147                         options.common.is_ogg,
148 #else
149                         /*is_ogg=*/false,
150 #endif
151                         options.common.verbose,
152                         /*is_aiff_out=*/true,
153                         /*is_wave_out=*/false,
154                         options.common.continue_through_decode_errors,
155                         options.common.replaygain_synthesis_spec,
156                         analysis_mode,
157                         aopts,
158                         &options.common.skip_specification,
159                         &options.common.until_specification,
160                         infilename,
161                         outfilename
162                 )
163         )
164                 return 1;
165
166         if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename))
167                 return DecoderSession_finish_error(&decoder_session);
168
169         if(!DecoderSession_process(&decoder_session))
170                 return DecoderSession_finish_error(&decoder_session);
171
172         return DecoderSession_finish_ok(&decoder_session);
173 }
174
175 int flac__decode_wav(const char *infilename, const char *outfilename, FLAC__bool analysis_mode, analysis_options aopts, wav_decode_options_t options)
176 {
177         DecoderSession decoder_session;
178
179         if(!
180                 DecoderSession_construct(
181                         &decoder_session,
182 #ifdef FLAC__HAS_OGG
183                         options.common.is_ogg,
184 #else
185                         /*is_ogg=*/false,
186 #endif
187                         options.common.verbose,
188                         /*is_aiff_out=*/false,
189                         /*is_wave_out=*/true,
190                         options.common.continue_through_decode_errors,
191                         options.common.replaygain_synthesis_spec,
192                         analysis_mode,
193                         aopts,
194                         &options.common.skip_specification,
195                         &options.common.until_specification,
196                         infilename,
197                         outfilename
198                 )
199         )
200                 return 1;
201
202         if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename))
203                 return DecoderSession_finish_error(&decoder_session);
204
205         if(!DecoderSession_process(&decoder_session))
206                 return DecoderSession_finish_error(&decoder_session);
207
208         return DecoderSession_finish_ok(&decoder_session);
209 }
210
211 int flac__decode_raw(const char *infilename, const char *outfilename, FLAC__bool analysis_mode, analysis_options aopts, raw_decode_options_t options)
212 {
213         DecoderSession decoder_session;
214
215         decoder_session.is_big_endian = options.is_big_endian;
216         decoder_session.is_unsigned_samples = options.is_unsigned_samples;
217
218         if(!
219                 DecoderSession_construct(
220                         &decoder_session,
221 #ifdef FLAC__HAS_OGG
222                         options.common.is_ogg,
223 #else
224                         /*is_ogg=*/false,
225 #endif
226                         options.common.verbose,
227                         /*is_aiff_out=*/false,
228                         /*is_wave_out=*/false,
229                         options.common.continue_through_decode_errors,
230                         options.common.replaygain_synthesis_spec,
231                         analysis_mode,
232                         aopts,
233                         &options.common.skip_specification,
234                         &options.common.until_specification,
235                         infilename,
236                         outfilename
237                 )
238         )
239                 return 1;
240
241         if(!DecoderSession_init_decoder(&decoder_session, options.common, infilename))
242                 return DecoderSession_finish_error(&decoder_session);
243
244         if(!DecoderSession_process(&decoder_session))
245                 return DecoderSession_finish_error(&decoder_session);
246
247         return DecoderSession_finish_ok(&decoder_session);
248 }
249
250 FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool verbose, FLAC__bool is_aiff_out, FLAC__bool is_wave_out, FLAC__bool continue_through_decode_errors, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, const char *infilename, const char *outfilename)
251 {
252 #ifdef FLAC__HAS_OGG
253         d->is_ogg = is_ogg;
254 #else
255         (void)is_ogg;
256 #endif
257
258         d->verbose = verbose;
259         d->is_aiff_out = is_aiff_out;
260         d->is_wave_out = is_wave_out;
261         d->continue_through_decode_errors = continue_through_decode_errors;
262         d->replaygain.spec = replaygain_synthesis_spec;
263         d->replaygain.scale = 0.0;
264         /* d->replaygain.dither_context gets initialized later once we know the sample resolution */
265         d->test_only = (0 == outfilename);
266         d->analysis_mode = analysis_mode;
267         d->aopts = aopts;
268         d->skip_specification = skip_specification;
269         d->until_specification = until_specification;
270
271         d->inbasefilename = grabbag__file_get_basename(infilename);
272         d->outfilename = outfilename;
273
274         d->samples_processed = 0;
275         d->frame_counter = 0;
276         d->abort_flag = false;
277
278         d->wave_chunk_size_fixup.needs_fixup = false;
279
280         d->decoder.flac.file = 0;
281 #ifdef FLAC__HAS_OGG
282         d->decoder.ogg.stream = 0;
283 #endif
284
285 #ifdef FLAC__HAS_OGG
286         d->fin = 0;
287 #endif
288         d->fout = 0; /* initialized with an open file later if necessary */
289
290         FLAC__ASSERT(!(d->test_only && d->analysis_mode));
291
292         if(!d->test_only) {
293                 if(0 == strcmp(outfilename, "-")) {
294                         d->fout = grabbag__file_get_binary_stdout();
295                 }
296                 else {
297                         if(0 == (d->fout = fopen(outfilename, "wb"))) {
298                                 fprintf(stderr, "%s: ERROR: can't open output file %s\n", d->inbasefilename, outfilename);
299                                 DecoderSession_destroy(d, /*error_occurred=*/true);
300                                 return false;
301                         }
302                 }
303         }
304
305 #ifdef FLAC__HAS_OGG
306         if(d->is_ogg) {
307                 if (0 == strcmp(infilename, "-")) {
308                         d->fin = grabbag__file_get_binary_stdin();
309                 } else {
310                         if (0 == (d->fin = fopen(infilename, "rb"))) {
311                                 fprintf(stderr, "%s: ERROR: can't open input file %s\n", d->inbasefilename, infilename);
312                                 DecoderSession_destroy(d, /*error_occurred=*/true);
313                                 return false;
314                         }
315                 }
316         }
317 #endif
318
319         if(analysis_mode)
320                 flac__analyze_init(aopts);
321
322         return true;
323 }
324
325 void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred)
326 {
327         if(0 != d->fout && d->fout != stdout) {
328                 fclose(d->fout);
329                 if(error_occurred)
330                         unlink(d->outfilename);
331         }
332 #ifdef FLAC__HAS_OGG
333         if(0 != d->fin && d->fin != stdin)
334                 fclose(d->fin);
335 #endif
336 }
337
338 FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, decode_options_t decode_options, const char *infilename)
339 {
340         FLAC__uint32 test = 1;
341
342         is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
343
344 #ifdef FLAC__HAS_OGG
345         if(decoder_session->is_ogg) {
346                 decoder_session->decoder.ogg.stream = OggFLAC__stream_decoder_new();
347
348                 if(0 == decoder_session->decoder.ogg.stream) {
349                         fprintf(stderr, "%s: ERROR creating the decoder instance\n", decoder_session->inbasefilename);
350                         return false;
351                 }
352
353                 if(!decode_options.use_first_serial_number)
354                         OggFLAC__stream_decoder_set_serial_number(decoder_session->decoder.ogg.stream, decode_options.serial_number);
355                 if (decoder_session->replaygain.spec.apply)
356                         OggFLAC__stream_decoder_set_metadata_respond(decoder_session->decoder.ogg.stream, FLAC__METADATA_TYPE_VORBIS_COMMENT);
357
358                 OggFLAC__stream_decoder_set_read_callback(decoder_session->decoder.ogg.stream, read_callback);
359                 /*
360                  * The three ugly casts here are to 'downcast' the 'void *' argument of
361                  * the callback down to 'FLAC__StreamDecoder *'.  In C++ this would be
362                  * unnecessary but here the cast makes the C compiler happy.
363                  */
364                 OggFLAC__stream_decoder_set_write_callback(decoder_session->decoder.ogg.stream, (FLAC__StreamDecoderWriteStatus (*)(const OggFLAC__StreamDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback);
365                 OggFLAC__stream_decoder_set_metadata_callback(decoder_session->decoder.ogg.stream, (void (*)(const OggFLAC__StreamDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback);
366                 OggFLAC__stream_decoder_set_error_callback(decoder_session->decoder.ogg.stream, (void (*)(const OggFLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback);
367                 OggFLAC__stream_decoder_set_client_data(decoder_session->decoder.ogg.stream, decoder_session);
368
369                 if(OggFLAC__stream_decoder_init(decoder_session->decoder.ogg.stream) != OggFLAC__STREAM_DECODER_OK) {
370                         print_error_with_state(decoder_session, "ERROR initializing decoder");
371                         return false;
372                 }
373         }
374         else
375 #else
376         (void)decode_options;
377 #endif
378         {
379                 decoder_session->decoder.flac.file = FLAC__file_decoder_new();
380
381                 if(0 == decoder_session->decoder.flac.file) {
382                         fprintf(stderr, "%s: ERROR creating the decoder instance\n", decoder_session->inbasefilename);
383                         return false;
384                 }
385
386                 FLAC__file_decoder_set_md5_checking(decoder_session->decoder.flac.file, true);
387                 FLAC__file_decoder_set_filename(decoder_session->decoder.flac.file, infilename);
388                 if (decoder_session->replaygain.spec.apply)
389                         FLAC__file_decoder_set_metadata_respond(decoder_session->decoder.flac.file, FLAC__METADATA_TYPE_VORBIS_COMMENT);
390                 /*
391                  * The three ugly casts here are to 'downcast' the 'void *' argument of
392                  * the callback down to 'FLAC__FileDecoder *'.
393                  */
394                 FLAC__file_decoder_set_write_callback(decoder_session->decoder.flac.file, (FLAC__StreamDecoderWriteStatus (*)(const FLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback);
395                 FLAC__file_decoder_set_metadata_callback(decoder_session->decoder.flac.file, (void (*)(const FLAC__FileDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback);
396                 FLAC__file_decoder_set_error_callback(decoder_session->decoder.flac.file, (void (*)(const FLAC__FileDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback);
397                 FLAC__file_decoder_set_client_data(decoder_session->decoder.flac.file, decoder_session);
398
399                 if(FLAC__file_decoder_init(decoder_session->decoder.flac.file) != FLAC__FILE_DECODER_OK) {
400                         print_error_with_state(decoder_session, "ERROR initializing decoder");
401                         return false;
402                 }
403         }
404
405         return true;
406 }
407
408 FLAC__bool DecoderSession_process(DecoderSession *d)
409 {
410 #ifdef FLAC__HAS_OGG
411         if(d->is_ogg) {
412                 if(!OggFLAC__stream_decoder_process_until_end_of_metadata(d->decoder.ogg.stream)) {
413                         if(d->verbose) fprintf(stderr, "\n");
414                         print_error_with_state(d, "ERROR while decoding metadata");
415                         return false;
416                 }
417                 if(OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(d->decoder.ogg.stream) != FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC && OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(d->decoder.ogg.stream) != FLAC__STREAM_DECODER_END_OF_STREAM) {
418                         if(d->verbose) fprintf(stderr, "\n");
419                         print_error_with_state(d, "ERROR during metadata decoding");
420                         return false;
421                 }
422         }
423         else
424 #endif
425         {
426                 if(!FLAC__file_decoder_process_until_end_of_metadata(d->decoder.flac.file)) {
427                         if(d->verbose) fprintf(stderr, "\n");
428                         print_error_with_state(d, "ERROR while decoding metadata");
429                         return false;
430                 }
431                 if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE) {
432                         if(d->verbose) fprintf(stderr, "\n");
433                         print_error_with_state(d, "ERROR during metadata decoding");
434                         return false;
435                 }
436         }
437         if(d->abort_flag)
438                 return false;
439
440         if(d->skip_specification->value.samples > 0) {
441                 const FLAC__uint64 skip = (FLAC__uint64)d->skip_specification->value.samples;
442
443 #ifdef FLAC__HAS_OGG
444                 if(d->is_ogg) { /*@@@ (move this check into main.c) */
445                         fprintf(stderr, "%s: ERROR, can't skip when decoding Ogg-FLAC yet; convert to native-FLAC first\n", d->inbasefilename);
446                         return false;
447                 }
448 #endif
449                 if(!FLAC__file_decoder_seek_absolute(d->decoder.flac.file, skip)) {
450                         print_error_with_state(d, "ERROR seeking while skipping bytes");
451                         return false;
452                 }
453                 if(!FLAC__file_decoder_process_until_end_of_file(d->decoder.flac.file)) {
454                         if(d->verbose) fprintf(stderr, "\n");
455                         print_error_with_state(d, "ERROR while decoding frames");
456                         return false;
457                 }
458                 if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE) {
459                         if(d->verbose) fprintf(stderr, "\n");
460                         print_error_with_state(d, "ERROR during decoding");
461                         return false;
462                 }
463         }
464         else {
465 #ifdef FLAC__HAS_OGG
466                 if(d->is_ogg) {
467                         if(!OggFLAC__stream_decoder_process_until_end_of_stream(d->decoder.ogg.stream)) {
468                                 if(d->verbose) fprintf(stderr, "\n");
469                                 print_error_with_state(d, "ERROR while decoding data");
470                                 return false;
471                         }
472                         if(OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(d->decoder.ogg.stream) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA && OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(d->decoder.ogg.stream) != FLAC__STREAM_DECODER_END_OF_STREAM) {
473                                 if(d->verbose) fprintf(stderr, "\n");
474                                 print_error_with_state(d, "ERROR during decoding");
475                                 return false;
476                         }
477                 }
478                 else
479 #endif
480                 {
481                         if(!FLAC__file_decoder_process_until_end_of_file(d->decoder.flac.file)) {
482                                 if(d->verbose) fprintf(stderr, "\n");
483                                 print_error_with_state(d, "ERROR while decoding data");
484                                 return false;
485                         }
486                         if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE) {
487                                 if(d->verbose) fprintf(stderr, "\n");
488                                 print_error_with_state(d, "ERROR during decoding");
489                                 return false;
490                         }
491                 }
492         }
493
494         if(d->is_aiff_out && ((d->total_samples * d->channels * ((d->bps+7)/8)) & 1)) {
495                 if(flac__utils_fwrite("\000", 1, 1, d->fout) != 1) {
496                         print_error_with_state(d, "ERROR writing pad byte to AIFF SSND chunk");
497                         return false;
498                 }
499         }
500
501         return true;
502 }
503
504 int DecoderSession_finish_ok(DecoderSession *d)
505 {
506         FLAC__bool md5_failure = false;
507
508 #ifdef FLAC__HAS_OGG
509         if(d->is_ogg) {
510                 if(d->decoder.ogg.stream) {
511                         OggFLAC__stream_decoder_finish(d->decoder.ogg.stream);
512                         md5_failure = false;
513                         print_stats(d);
514                         OggFLAC__stream_decoder_delete(d->decoder.ogg.stream);
515                 }
516         }
517         else
518 #endif
519         {
520                 if(d->decoder.flac.file) {
521                         md5_failure = !FLAC__file_decoder_finish(d->decoder.flac.file);
522                         print_stats(d);
523                         FLAC__file_decoder_delete(d->decoder.flac.file);
524                 }
525         }
526         if(d->analysis_mode)
527                 flac__analyze_finish(d->aopts);
528         if(md5_failure) {
529                 fprintf(stderr, "\r%s: WARNING, MD5 signature mismatch\n", d->inbasefilename);
530         }
531         else {
532                 if(d->verbose)
533                         fprintf(stderr, "\r%s: %s         \n", d->inbasefilename, d->test_only? "ok           ":d->analysis_mode?"done           ":"done");
534         }
535         DecoderSession_destroy(d, /*error_occurred=*/false);
536         if((d->is_wave_out || d->is_aiff_out) && d->wave_chunk_size_fixup.needs_fixup)
537                 if(!fixup_wave_chunk_size(d->outfilename, d->is_wave_out, d->wave_chunk_size_fixup.riff_offset, d->wave_chunk_size_fixup.data_offset, d->wave_chunk_size_fixup.frames_offset, (FLAC__uint32)d->samples_processed, d->channels, d->bps))
538                         return 1;
539         return 0;
540 }
541
542 int DecoderSession_finish_error(DecoderSession *d)
543 {
544 #ifdef FLAC__HAS_OGG
545         if(d->is_ogg) {
546                 if(d->decoder.ogg.stream) {
547                         OggFLAC__stream_decoder_finish(d->decoder.ogg.stream);
548                         OggFLAC__stream_decoder_delete(d->decoder.ogg.stream);
549                 }
550         }
551         else
552 #endif
553         {
554                 if(d->decoder.flac.file) {
555                         FLAC__file_decoder_finish(d->decoder.flac.file);
556                         FLAC__file_decoder_delete(d->decoder.flac.file);
557                 }
558         }
559         if(d->analysis_mode)
560                 flac__analyze_finish(d->aopts);
561         DecoderSession_destroy(d, /*error_occurred=*/true);
562         return 1;
563 }
564
565 FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
566 {
567         /* convert from mm:ss.sss to sample number if necessary */
568         flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
569
570         /* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
571         if(spec->is_relative && spec->value.samples == 0) {
572                 spec->is_relative = false;
573                 return true;
574         }
575
576         /* in any other case the total samples in the input must be known */
577         if(total_samples_in_input == 0) {
578                 fprintf(stderr, "%s: ERROR, cannot use --until when FLAC metadata has total sample count of 0\n", inbasefilename);
579                 return false;
580         }
581
582         FLAC__ASSERT(spec->value_is_samples);
583
584         /* convert relative specifications to absolute */
585         if(spec->is_relative) {
586                 if(spec->value.samples <= 0)
587                         spec->value.samples += (FLAC__int64)total_samples_in_input;
588                 else
589                         spec->value.samples += skip;
590                 spec->is_relative = false;
591         }
592
593         /* error check */
594         if(spec->value.samples < 0) {
595                 fprintf(stderr, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
596                 return false;
597         }
598         if((FLAC__uint64)spec->value.samples <= skip) {
599                 fprintf(stderr, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
600                 return false;
601         }
602         if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
603                 fprintf(stderr, "%s: ERROR, --until value is after end of input\n", inbasefilename);
604                 return false;
605         }
606
607         return true;
608 }
609
610 FLAC__bool write_little_endian_uint16(FILE *f, FLAC__uint16 val)
611 {
612         FLAC__byte *b = (FLAC__byte*)(&val);
613         if(is_big_endian_host_) {
614                 FLAC__byte tmp;
615                 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
616         }
617         return flac__utils_fwrite(b, 1, 2, f) == 2;
618 }
619
620 FLAC__bool write_little_endian_uint32(FILE *f, FLAC__uint32 val)
621 {
622         FLAC__byte *b = (FLAC__byte*)(&val);
623         if(is_big_endian_host_) {
624                 FLAC__byte tmp;
625                 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
626                 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
627         }
628         return flac__utils_fwrite(b, 1, 4, f) == 4;
629 }
630
631 FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 val)
632 {
633         FLAC__byte *b = (FLAC__byte*)(&val);
634         if(!is_big_endian_host_) {
635                 FLAC__byte tmp;
636                 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
637         }
638         return flac__utils_fwrite(b, 1, 2, f) == 2;
639 }
640
641 FLAC__bool write_big_endian_uint32(FILE *f, FLAC__uint32 val)
642 {
643         FLAC__byte *b = (FLAC__byte*)(&val);
644         if(!is_big_endian_host_) {
645                 FLAC__byte tmp;
646                 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
647                 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
648         }
649         return flac__utils_fwrite(b, 1, 4, f) == 4;
650 }
651
652 FLAC__bool write_sane_extended(FILE *f, unsigned val)
653         /* Write to 'f' a SANE extended representation of 'val'.  Return false if
654         * the write succeeds; return true otherwise.
655         *
656         * SANE extended is an 80-bit IEEE-754 representation with sign bit, 15 bits
657         * of exponent, and 64 bits of significand (mantissa).  Unlike most IEEE-754
658         * representations, it does not imply a 1 above the MSB of the significand.
659         *
660         * Preconditions:
661         *  val!=0U
662         */
663 {
664         unsigned int shift, exponent;
665
666         FLAC__ASSERT(val!=0U); /* handling 0 would require a special case */
667
668         for(shift= 0U; (val>>(31-shift))==0U; ++shift)
669                 ;
670         val<<= shift;
671         exponent= 63U-(shift+32U); /* add 32 for unused second word */
672
673         if(!write_big_endian_uint16(f, (FLAC__uint16)(exponent+0x3FFF)))
674                 return false;
675         if(!write_big_endian_uint32(f, val))
676                 return false;
677         if(!write_big_endian_uint32(f, 0)) /* unused second word */
678                 return false;
679
680         return true;
681 }
682
683 FLAC__bool fixup_wave_chunk_size(const char *outfilename, FLAC__bool is_wave_out, unsigned riff_offset, unsigned data_offset, unsigned frames_offset, FLAC__uint32 total_samples, unsigned channels, unsigned bps)
684 {
685         const char *fmt_desc = (is_wave_out? "WAVE" : "AIFF");
686         FLAC__bool (*write_it)(FILE *, FLAC__uint32) = (is_wave_out? write_little_endian_uint32 : write_big_endian_uint32);
687         FILE *f = fopen(outfilename, "r+b");
688         FLAC__uint32 data_size, aligned_data_size;
689
690         if(0 == f) {
691                 fprintf(stderr, "ERROR, couldn't open file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
692                 return false;
693         }
694
695         data_size = aligned_data_size = total_samples * channels * ((bps+7)/8);
696         if(!is_wave_out && (aligned_data_size & 1))
697                 aligned_data_size++;
698
699         if(fseek(f, riff_offset, SEEK_SET) < 0) {
700                 fprintf(stderr, "ERROR, couldn't seek in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
701                 fclose(f);
702                 return false;
703         }
704         if(!write_it(f, aligned_data_size + (is_wave_out? 36 : 46))) {
705                 fprintf(stderr, "ERROR, couldn't write size in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
706                 fclose(f);
707                 return false;
708         }
709         if(!is_wave_out) {
710                 if(fseek(f, frames_offset, SEEK_SET) < 0) {
711                         fprintf(stderr, "ERROR, couldn't seek in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
712                         fclose(f);
713                         return false;
714                 }
715                 if(!write_it(f, total_samples)) {
716                         fprintf(stderr, "ERROR, couldn't write size in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
717                         fclose(f);
718                         return false;
719                 }
720         }
721         if(fseek(f, data_offset, SEEK_SET) < 0) {
722                 fprintf(stderr, "ERROR, couldn't seek in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
723                 fclose(f);
724                 return false;
725         }
726         if(!write_it(f, data_size + (is_wave_out? 0 : 8))) {
727                 fprintf(stderr, "ERROR, couldn't write size in file %s while fixing up %s chunk size\n", outfilename, fmt_desc);
728                 fclose(f);
729                 return false;
730         }
731         fclose(f);
732         return true;
733 }
734
735 #ifdef FLAC__HAS_OGG
736 FLAC__StreamDecoderReadStatus read_callback(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
737 {
738         DecoderSession *decoder_session = (DecoderSession*)client_data;
739         FILE *fin = decoder_session->fin;
740         size_t bytes_read;
741
742         (void)decoder; /* avoid compiler warning */
743
744         if (decoder_session->abort_flag)
745                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
746
747         if(feof(fin))
748                 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
749
750         bytes_read = fread(buffer, 1, *bytes, fin);
751
752         if(ferror(fin))
753                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
754
755         *bytes = (unsigned)bytes_read;
756
757         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
758 }
759 #endif
760
761 FLAC__StreamDecoderWriteStatus write_callback(const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
762 {
763         DecoderSession *decoder_session = (DecoderSession*)client_data;
764         FILE *fout = decoder_session->fout;
765         const unsigned bps = frame->header.bits_per_sample, channels = frame->header.channels;
766         FLAC__bool is_big_endian = (decoder_session->is_aiff_out? true : (decoder_session->is_wave_out? false : decoder_session->is_big_endian));
767         FLAC__bool is_unsigned_samples = (decoder_session->is_aiff_out? false : (decoder_session->is_wave_out? bps<=8 : decoder_session->is_unsigned_samples));
768         unsigned wide_samples = frame->header.blocksize, wide_sample, sample, channel, byte;
769         static FLAC__int8 s8buffer[FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(FLAC__int32)]; /* WATCHOUT: can be up to 2 megs */
770         FLAC__uint8  *u8buffer  = (FLAC__uint8  *)s8buffer;
771         FLAC__int16  *s16buffer = (FLAC__int16  *)s8buffer;
772         FLAC__uint16 *u16buffer = (FLAC__uint16 *)s8buffer;
773         FLAC__int32  *s32buffer = (FLAC__int32  *)s8buffer;
774         FLAC__uint32 *u32buffer = (FLAC__uint32 *)s8buffer;
775
776         (void)decoder;
777
778         if(decoder_session->abort_flag)
779                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
780
781         if(bps != decoder_session->bps) {
782                 fprintf(stderr, "%s: ERROR, bits-per-sample is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, bps, decoder_session->bps);
783                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
784         }
785         if(channels != decoder_session->channels) {
786                 fprintf(stderr, "%s: ERROR, channels is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, channels, decoder_session->channels);
787                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
788         }
789         if(frame->header.sample_rate != decoder_session->sample_rate) {
790                 fprintf(stderr, "%s: ERROR, sample rate is %u in frame but %u in STREAMINFO\n", decoder_session->inbasefilename, frame->header.sample_rate, decoder_session->sample_rate);
791                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
792         }
793
794         /*
795          * limit the number of samples to accept based on --until
796          */
797         FLAC__ASSERT(!decoder_session->skip_specification->is_relative);
798         FLAC__ASSERT(decoder_session->skip_specification->value.samples >= 0);
799         FLAC__ASSERT(!decoder_session->until_specification->is_relative);
800         FLAC__ASSERT(decoder_session->until_specification->value.samples >= 0);
801         if(decoder_session->until_specification->value.samples > 0) {
802                 const FLAC__uint64 skip = (FLAC__uint64)decoder_session->skip_specification->value.samples;
803                 const FLAC__uint64 until = (FLAC__uint64)decoder_session->until_specification->value.samples;
804                 const FLAC__uint64 input_samples_passed = skip + decoder_session->samples_processed;
805                 FLAC__ASSERT(until >= input_samples_passed);
806                 if(input_samples_passed + wide_samples > until)
807                         wide_samples = (unsigned)(until - input_samples_passed);
808         }
809
810         if(wide_samples > 0) {
811                 decoder_session->samples_processed += wide_samples;
812                 decoder_session->frame_counter++;
813
814                 if(decoder_session->verbose && !(decoder_session->frame_counter & 0x3f))
815                         print_stats(decoder_session);
816
817                 if(decoder_session->analysis_mode) {
818                         flac__analyze_frame(frame, decoder_session->frame_counter-1, decoder_session->aopts, fout);
819                 }
820                 else if(!decoder_session->test_only) {
821                         if (decoder_session->replaygain.spec.apply) {
822                                 const size_t n = FLAC__replaygain_synthesis__apply_gain(
823                                         u8buffer,
824                                         is_big_endian,
825                                         is_unsigned_samples,
826                                         buffer,
827                                         wide_samples,
828                                         channels,
829                                         bps, /* source_bps */
830                                         bps, /* target_bps */
831                                         decoder_session->replaygain.scale,
832                                         decoder_session->replaygain.spec.limiter == RGSS_LIMIT__HARD, /* hard_limit */
833                                         decoder_session->replaygain.spec.noise_shaping != NOISE_SHAPING_NONE, /* do_dithering */
834                                         &decoder_session->replaygain.dither_context
835                                 );
836                                 if(flac__utils_fwrite(u8buffer, 1, n, fout) != n)
837                                         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
838                         }
839                         else if(bps == 8) {
840                                 if(is_unsigned_samples) {
841                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
842                                                 for(channel = 0; channel < channels; channel++, sample++)
843                                                         u8buffer[sample] = (FLAC__uint8)(buffer[channel][wide_sample] + 0x80);
844                                 }
845                                 else {
846                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
847                                                 for(channel = 0; channel < channels; channel++, sample++)
848                                                         s8buffer[sample] = (FLAC__int8)(buffer[channel][wide_sample]);
849                                 }
850                                 if(flac__utils_fwrite(u8buffer, 1, sample, fout) != sample)
851                                         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
852                         }
853                         else if(bps == 16) {
854                                 if(is_unsigned_samples) {
855                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
856                                                 for(channel = 0; channel < channels; channel++, sample++)
857                                                         u16buffer[sample] = (FLAC__uint16)(buffer[channel][wide_sample] + 0x8000);
858                                 }
859                                 else {
860                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
861                                                 for(channel = 0; channel < channels; channel++, sample++)
862                                                         s16buffer[sample] = (FLAC__int16)(buffer[channel][wide_sample]);
863                                 }
864                                 if(is_big_endian != is_big_endian_host_) {
865                                         unsigned char tmp;
866                                         const unsigned bytes = sample * 2;
867                                         for(byte = 0; byte < bytes; byte += 2) {
868                                                 tmp = u8buffer[byte];
869                                                 u8buffer[byte] = u8buffer[byte+1];
870                                                 u8buffer[byte+1] = tmp;
871                                         }
872                                 }
873                                 if(flac__utils_fwrite(u16buffer, 2, sample, fout) != sample)
874                                         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
875                         }
876                         else if(bps == 24) {
877                                 if(is_unsigned_samples) {
878                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
879                                                 for(channel = 0; channel < channels; channel++, sample++)
880                                                         u32buffer[sample] = buffer[channel][wide_sample] + 0x800000;
881                                 }
882                                 else {
883                                         for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
884                                                 for(channel = 0; channel < channels; channel++, sample++)
885                                                         s32buffer[sample] = buffer[channel][wide_sample];
886                                 }
887                                 if(is_big_endian != is_big_endian_host_) {
888                                         unsigned char tmp;
889                                         const unsigned bytes = sample * 4;
890                                         for(byte = 0; byte < bytes; byte += 4) {
891                                                 tmp = u8buffer[byte];
892                                                 u8buffer[byte] = u8buffer[byte+3];
893                                                 u8buffer[byte+3] = tmp;
894                                                 tmp = u8buffer[byte+1];
895                                                 u8buffer[byte+1] = u8buffer[byte+2];
896                                                 u8buffer[byte+2] = tmp;
897                                         }
898                                 }
899                                 if(is_big_endian) {
900                                         unsigned lbyte;
901                                         const unsigned bytes = sample * 4;
902                                         for(lbyte = byte = 0; byte < bytes; ) {
903                                                 byte++;
904                                                 u8buffer[lbyte++] = u8buffer[byte++];
905                                                 u8buffer[lbyte++] = u8buffer[byte++];
906                                                 u8buffer[lbyte++] = u8buffer[byte++];
907                                         }
908                                 }
909                                 else {
910                                         unsigned lbyte;
911                                         const unsigned bytes = sample * 4;
912                                         for(lbyte = byte = 0; byte < bytes; ) {
913                                                 u8buffer[lbyte++] = u8buffer[byte++];
914                                                 u8buffer[lbyte++] = u8buffer[byte++];
915                                                 u8buffer[lbyte++] = u8buffer[byte++];
916                                                 byte++;
917                                         }
918                                 }
919                                 if(flac__utils_fwrite(u8buffer, 3, sample, fout) != sample)
920                                         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
921                         }
922                         else {
923                                 FLAC__ASSERT(0);
924                         }
925                 }
926         }
927         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
928 }
929
930 void metadata_callback(const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
931 {
932         DecoderSession *decoder_session = (DecoderSession*)client_data;
933         (void)decoder;
934         if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
935                 FLAC__uint64 skip, until;
936                 decoder_session->bps = metadata->data.stream_info.bits_per_sample;
937                 decoder_session->channels = metadata->data.stream_info.channels;
938                 decoder_session->sample_rate = metadata->data.stream_info.sample_rate;
939
940                 flac__utils_canonicalize_skip_until_specification(decoder_session->skip_specification, decoder_session->sample_rate);
941                 FLAC__ASSERT(decoder_session->skip_specification->value.samples >= 0);
942                 skip = (FLAC__uint64)decoder_session->skip_specification->value.samples;
943
944                 /* remember, metadata->data.stream_info.total_samples can be 0, meaning 'unknown' */
945                 if(metadata->data.stream_info.total_samples > 0 && skip >= metadata->data.stream_info.total_samples) {
946                         fprintf(stderr, "%s: ERROR trying to --skip more samples than in stream\n", decoder_session->inbasefilename);
947                         decoder_session->abort_flag = true;
948                         return;
949                 }
950                 else if(metadata->data.stream_info.total_samples == 0 && skip > 0) {
951                         fprintf(stderr, "%s: ERROR, can't --skip when FLAC metadata has total sample count of 0\n", decoder_session->inbasefilename);
952                         decoder_session->abort_flag = true;
953                         return;
954                 }
955                 decoder_session->total_samples = metadata->data.stream_info.total_samples - skip;
956
957                 /* note that we use metadata->data.stream_info.total_samples instead of decoder_session->total_samples */
958                 if(!canonicalize_until_specification(decoder_session->until_specification, decoder_session->inbasefilename, decoder_session->sample_rate, skip, metadata->data.stream_info.total_samples)) {
959                         decoder_session->abort_flag = true;
960                         return;
961                 }
962                 FLAC__ASSERT(decoder_session->until_specification->value.samples >= 0);
963                 until = (FLAC__uint64)decoder_session->until_specification->value.samples;
964
965                 if(until > 0)
966                         decoder_session->total_samples -= (metadata->data.stream_info.total_samples - until);
967
968                 if(decoder_session->bps != 8 && decoder_session->bps != 16 && decoder_session->bps != 24) {
969                         fprintf(stderr, "%s: ERROR: bits per sample is not 8/16/24\n", decoder_session->inbasefilename);
970                         decoder_session->abort_flag = true;
971                         return;
972                 }
973
974                 /* write the WAVE/AIFF headers if necessary */
975                 if(!decoder_session->analysis_mode && !decoder_session->test_only && (decoder_session->is_wave_out || decoder_session->is_aiff_out)) {
976                         const char *fmt_desc = decoder_session->is_wave_out? "WAVE" : "AIFF";
977                         FLAC__uint64 data_size = decoder_session->total_samples * decoder_session->channels * ((decoder_session->bps+7)/8);
978                         if(decoder_session->total_samples == 0) {
979                                 if(decoder_session->fout == stdout) {
980                                         fprintf(stderr, "%s: WARNING, don't have accurate sample count available for %s header.\n", decoder_session->inbasefilename, fmt_desc);
981                                         fprintf(stderr, "             Generated %s file will have a data chunk size of 0.  Try\n", fmt_desc);
982                                         fprintf(stderr, "             decoding directly to a file instead.\n");
983                                 }
984                                 else {
985                                         decoder_session->wave_chunk_size_fixup.needs_fixup = true;
986                                 }
987                         }
988                         if(data_size >= 0xFFFFFFDC) {
989                                 fprintf(stderr, "%s: ERROR: stream is too big to fit in a single %s file chunk\n", decoder_session->inbasefilename, fmt_desc);
990                                 decoder_session->abort_flag = true;
991                                 return;
992                         }
993                         if(decoder_session->is_wave_out) {
994                                 if(flac__utils_fwrite("RIFF", 1, 4, decoder_session->fout) != 4)
995                                         decoder_session->abort_flag = true;
996
997                                 if(decoder_session->wave_chunk_size_fixup.needs_fixup)
998                                         decoder_session->wave_chunk_size_fixup.riff_offset = ftell(decoder_session->fout);
999
1000                                 if(!write_little_endian_uint32(decoder_session->fout, (FLAC__uint32)(data_size+36))) /* filesize-8 */
1001                                         decoder_session->abort_flag = true;
1002
1003                                 if(flac__utils_fwrite("WAVEfmt ", 1, 8, decoder_session->fout) != 8)
1004                                         decoder_session->abort_flag = true;
1005
1006                                 if(flac__utils_fwrite("\020\000\000\000", 1, 4, decoder_session->fout) != 4) /* chunk size = 16 */
1007                                         decoder_session->abort_flag = true;
1008
1009                                 if(flac__utils_fwrite("\001\000", 1, 2, decoder_session->fout) != 2) /* compression code == 1 */
1010                                         decoder_session->abort_flag = true;
1011
1012                                 if(!write_little_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->channels)))
1013                                         decoder_session->abort_flag = true;
1014
1015                                 if(!write_little_endian_uint32(decoder_session->fout, decoder_session->sample_rate))
1016                                         decoder_session->abort_flag = true;
1017
1018                                 if(!write_little_endian_uint32(decoder_session->fout, decoder_session->sample_rate * decoder_session->channels * ((decoder_session->bps+7) / 8))) /* @@@ or is it (sample_rate*channels*bps) / 8 ??? */
1019                                         decoder_session->abort_flag = true;
1020
1021                                 if(!write_little_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->channels * ((decoder_session->bps+7) / 8)))) /* block align */
1022                                         decoder_session->abort_flag = true;
1023
1024                                 if(!write_little_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->bps))) /* bits per sample */
1025                                         decoder_session->abort_flag = true;
1026
1027                                 if(flac__utils_fwrite("data", 1, 4, decoder_session->fout) != 4)
1028                                         decoder_session->abort_flag = true;
1029
1030                                 if(decoder_session->wave_chunk_size_fixup.needs_fixup)
1031                                         decoder_session->wave_chunk_size_fixup.data_offset = ftell(decoder_session->fout);
1032
1033                                 if(!write_little_endian_uint32(decoder_session->fout, (FLAC__uint32)data_size)) /* data size */
1034                                         decoder_session->abort_flag = true;
1035                         }
1036                         else {
1037                                 const FLAC__uint32 aligned_data_size = (FLAC__uint32)((data_size+1) & (~1U));
1038
1039                                 if(flac__utils_fwrite("FORM", 1, 4, decoder_session->fout) != 4)
1040                                         decoder_session->abort_flag = true;
1041
1042                                 if(decoder_session->wave_chunk_size_fixup.needs_fixup)
1043                                         decoder_session->wave_chunk_size_fixup.riff_offset = ftell(decoder_session->fout);
1044
1045                                 if(!write_big_endian_uint32(decoder_session->fout, (FLAC__uint32)(aligned_data_size+46))) /* filesize-8 */
1046                                         decoder_session->abort_flag = true;
1047
1048                                 if(flac__utils_fwrite("AIFFCOMM", 1, 8, decoder_session->fout) != 8)
1049                                         decoder_session->abort_flag = true;
1050
1051                                 if(flac__utils_fwrite("\000\000\000\022", 1, 4, decoder_session->fout) != 4) /* chunk size = 18 */
1052                                         decoder_session->abort_flag = true;
1053
1054                                 if(!write_big_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->channels)))
1055                                         decoder_session->abort_flag = true;
1056
1057                                 if(decoder_session->wave_chunk_size_fixup.needs_fixup)
1058                                         decoder_session->wave_chunk_size_fixup.frames_offset = ftell(decoder_session->fout);
1059
1060                                 if(!write_big_endian_uint32(decoder_session->fout, (FLAC__uint32)decoder_session->total_samples))
1061                                         decoder_session->abort_flag = true;
1062
1063                                 if(!write_big_endian_uint16(decoder_session->fout, (FLAC__uint16)(decoder_session->bps)))
1064                                         decoder_session->abort_flag = true;
1065
1066                                 if(!write_sane_extended(decoder_session->fout, decoder_session->sample_rate))
1067                                         decoder_session->abort_flag = true;
1068
1069                                 if(flac__utils_fwrite("SSND", 1, 4, decoder_session->fout) != 4)
1070                                         decoder_session->abort_flag = true;
1071
1072                                 if(decoder_session->wave_chunk_size_fixup.needs_fixup)
1073                                         decoder_session->wave_chunk_size_fixup.data_offset = ftell(decoder_session->fout);
1074
1075                                 if(!write_big_endian_uint32(decoder_session->fout, (FLAC__uint32)data_size+8)) /* data size */
1076                                         decoder_session->abort_flag = true;
1077
1078                                 if(!write_big_endian_uint32(decoder_session->fout, 0/*offset*/))
1079                                         decoder_session->abort_flag = true;
1080
1081                                 if(!write_big_endian_uint32(decoder_session->fout, 0/*block_size*/))
1082                                         decoder_session->abort_flag = true;
1083                         }
1084                 }
1085         }
1086         else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
1087                 if (decoder_session->replaygain.spec.apply) {
1088                         double gain, peak;
1089                         if (!(decoder_session->replaygain.spec.apply = grabbag__replaygain_load_from_vorbiscomment(metadata, decoder_session->replaygain.spec.use_album_gain, &gain, &peak))) {
1090                                 fprintf(stderr, "%s: WARNING: can't get %s ReplayGain tag\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track");
1091                         }
1092                         else {
1093                                 const char *ls[] = { "no", "peak", "hard" };
1094                                 const char *ns[] = { "no", "low", "medium", "high" };
1095                                 decoder_session->replaygain.scale = grabbag__replaygain_compute_scale_factor(peak, gain, decoder_session->replaygain.spec.preamp, decoder_session->replaygain.spec.limiter == RGSS_LIMIT__PEAK);
1096                                 FLAC__assert(decoder_session->bps > 0 && decoder_session->bps <= 32);
1097                                 FLAC__replaygain_synthesis__init_dither_context(&decoder_session->replaygain.dither_context, decoder_session->bps, decoder_session->replaygain.spec.noise_shaping);
1098                                 fprintf(stderr, "%s: INFO: applying %s ReplayGain (gain=%0.2fdB+preamp=%0.1fdB, %s noise shaping, %s limiting) to output\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track", gain, decoder_session->replaygain.spec.preamp, ns[decoder_session->replaygain.spec.noise_shaping], ls[decoder_session->replaygain.spec.limiter]);
1099                                 fprintf(stderr, "%s: WARNING: applying ReplayGain is not lossless\n", decoder_session->inbasefilename);
1100                         }
1101                 }
1102         }
1103 }
1104
1105 void error_callback(const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
1106 {
1107         DecoderSession *decoder_session = (DecoderSession*)client_data;
1108         (void)decoder;
1109         fprintf(stderr, "%s: *** Got error code %d:%s\n", decoder_session->inbasefilename, status, FLAC__StreamDecoderErrorStatusString[status]);
1110         if(!decoder_session->continue_through_decode_errors)
1111                 decoder_session->abort_flag = true;
1112 }
1113
1114 void print_error_with_state(const DecoderSession *d, const char *message)
1115 {
1116         const int ilen = strlen(d->inbasefilename) + 1;
1117
1118         fprintf(stderr, "\n%s: %s\n", d->inbasefilename, message);
1119
1120 #ifdef FLAC__HAS_OGG
1121         if(d->is_ogg) {
1122                 const OggFLAC__StreamDecoderState osd_state = OggFLAC__stream_decoder_get_state(d->decoder.ogg.stream);
1123                 if(osd_state != OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
1124                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)osd_state, OggFLAC__StreamDecoderStateString[osd_state]);
1125                 }
1126                 else {
1127                         const FLAC__StreamDecoderState fsd_state = OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(d->decoder.ogg.stream);
1128                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fsd_state, FLAC__StreamDecoderStateString[fsd_state]);
1129                 }
1130         }
1131         else
1132 #endif
1133         {
1134                 const FLAC__FileDecoderState ffd_state = FLAC__file_decoder_get_state(d->decoder.flac.file);
1135                 if(ffd_state != FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR) {
1136                         fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)ffd_state, FLAC__FileDecoderStateString[ffd_state]);
1137                 }
1138                 else {
1139                         const FLAC__SeekableStreamDecoderState fssd_state = FLAC__file_decoder_get_seekable_stream_decoder_state(d->decoder.flac.file);
1140                         if(fssd_state != FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
1141                                 fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fssd_state, FLAC__SeekableStreamDecoderStateString[fssd_state]);
1142                         }
1143                         else {
1144                                 const FLAC__StreamDecoderState fsd_state = FLAC__file_decoder_get_stream_decoder_state(d->decoder.flac.file);
1145                                 fprintf(stderr, "%*s state = %d:%s\n", ilen, "", (int)fsd_state, FLAC__StreamDecoderStateString[fsd_state]);
1146                         }
1147                 }
1148         }
1149 }
1150
1151 void print_stats(const DecoderSession *decoder_session)
1152 {
1153         if(decoder_session->verbose) {
1154 #if defined _MSC_VER || defined __MINGW32__
1155                 /* with VC++ you have to spoon feed it the casting */
1156                 const double progress = (double)(FLAC__int64)decoder_session->samples_processed / (double)(FLAC__int64)decoder_session->total_samples * 100.0;
1157 #else
1158                 const double progress = (double)decoder_session->samples_processed / (double)decoder_session->total_samples * 100.0;
1159 #endif
1160                 if(decoder_session->total_samples > 0) {
1161                         fprintf(stderr, "\r%s: %s%u%% complete",
1162                                 decoder_session->inbasefilename,
1163                                 decoder_session->test_only? "testing, " : decoder_session->analysis_mode? "analyzing, " : "",
1164                                 (unsigned)floor(progress + 0.5)
1165                         );
1166                 }
1167                 else {
1168                         fprintf(stderr, "\r%s: %s %u samples",
1169                                 decoder_session->inbasefilename,
1170                                 decoder_session->test_only? "tested" : decoder_session->analysis_mode? "analyzed" : "wrote",
1171                                 (unsigned)decoder_session->samples_processed
1172                         );
1173                 }
1174         }
1175 }