add printing of seek points in verbose mode
[flac.git] / src / flac / decode.c
1 /* flac - Command-line FLAC encoder/decoder
2  * Copyright (C) 2000,2001  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 <assert.h> /* for FILE */
26 #include <stdio.h> /* for FILE */
27 #include <string.h> /* for strcmp() */
28 #include "FLAC/all.h"
29 #include "decode.h"
30
31 typedef struct {
32         FILE *fout;
33         bool abort_flag;
34         bool analysis_mode;
35         analysis_options aopts;
36         bool test_only;
37         bool is_wave_out;
38         bool is_big_endian;
39         bool is_unsigned_samples;
40         uint64 total_samples;
41         unsigned bps;
42         unsigned channels;
43         unsigned sample_rate;
44         bool verbose;
45         uint64 skip;
46         uint64 samples_processed;
47         unsigned frame_counter;
48 } stream_info_struct;
49
50 static FLAC__FileDecoder *decoder;
51 static bool is_big_endian_host;
52
53 /* local routines */
54 static bool init(const char *infile, stream_info_struct *stream_info);
55 static bool write_little_endian_uint16(FILE *f, uint16 val);
56 static bool write_little_endian_uint32(FILE *f, uint32 val);
57 static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data);
58 static void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
59 static void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
60 static void print_stats(const stream_info_struct *stream_info);
61
62 int decode_wav(const char *infile, const char *outfile, bool analysis_mode, analysis_options aopts, bool verbose, uint64 skip)
63 {
64         bool md5_failure = false;
65         stream_info_struct stream_info;
66
67         decoder = 0;
68         stream_info.abort_flag = false;
69         stream_info.analysis_mode = analysis_mode;
70         stream_info.aopts = aopts;
71         stream_info.test_only = (outfile == 0);
72         stream_info.is_wave_out = true;
73         stream_info.verbose = verbose;
74         stream_info.skip = skip;
75         stream_info.samples_processed = 0;
76         stream_info.frame_counter = 0;
77
78         assert(!(stream_info.test_only && stream_info.analysis_mode));
79
80         if(!stream_info.test_only) {
81                 if(0 == strcmp(outfile, "-")) {
82                         stream_info.fout = stdout;
83                 }
84                 else {
85                         if(0 == (stream_info.fout = fopen(outfile, "wb"))) {
86                                 fprintf(stderr, "ERROR: can't open output file %s\n", outfile);
87                                 return false;
88                         }
89                 }
90         }
91
92         if(analysis_mode)
93                 analyze_init(aopts);
94
95         if(!init(infile, &stream_info))
96                 goto wav_abort_;
97
98         if(skip > 0) {
99                 if(!FLAC__file_decoder_process_metadata(decoder)) {
100                         fprintf(stderr, "%s: ERROR while decoding metadata, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
101                         goto wav_abort_;
102                 }
103                 if(!FLAC__file_decoder_seek_absolute(decoder, skip)) {
104                         fprintf(stderr, "%s: ERROR seeking while skipping bytes, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
105                         goto wav_abort_;
106                 }
107                 if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
108                         if(verbose) { printf("\n"); fflush(stdout); }
109                         fprintf(stderr, "%s: ERROR while decoding frames, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
110                         goto wav_abort_;
111                 }
112                 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
113                         if(verbose) { printf("\n"); fflush(stdout); }
114                         fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
115                         goto wav_abort_;
116                 }
117         }
118         else {
119                 if(!FLAC__file_decoder_process_whole_file(decoder)) {
120                         if(verbose) { printf("\n"); fflush(stdout); }
121                         fprintf(stderr, "%s: ERROR while decoding data, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
122                         goto wav_abort_;
123                 }
124                 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
125                         if(verbose) { printf("\n"); fflush(stdout); }
126                         fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
127                         goto wav_abort_;
128                 }
129         }
130
131         if(decoder) {
132                 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
133                         md5_failure = !FLAC__file_decoder_finish(decoder);
134                 print_stats(&stream_info);
135                 FLAC__file_decoder_free_instance(decoder);
136         }
137         if(!stream_info.test_only)
138                 fclose(stream_info.fout);
139         if(verbose)
140                 printf("\n");
141         fflush(stdout);
142         if(analysis_mode)
143                 analyze_finish(aopts);
144         if(md5_failure) {
145                 fprintf(stderr, "%s: WARNING, MD5 signature mismatch\n", infile);
146                 return 1;
147         }
148         else {
149                 if(stream_info.test_only)
150                         printf("%s: ok\n", infile);
151         }
152         return 0;
153 wav_abort_:
154         if(decoder) {
155                 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
156                         FLAC__file_decoder_finish(decoder);
157                 FLAC__file_decoder_free_instance(decoder);
158         }
159         if(!stream_info.test_only) {
160                 fclose(stream_info.fout);
161                 unlink(outfile);
162         }
163         if(analysis_mode)
164                 analyze_finish(aopts);
165         return 1;
166 }
167
168 int decode_raw(const char *infile, const char *outfile, bool analysis_mode, analysis_options aopts, bool verbose, uint64 skip, bool is_big_endian, bool is_unsigned_samples)
169 {
170         bool md5_failure = false;
171         stream_info_struct stream_info;
172
173         decoder = 0;
174         stream_info.abort_flag = false;
175         stream_info.analysis_mode = analysis_mode;
176         stream_info.aopts = aopts;
177         stream_info.test_only = (outfile == 0);
178         stream_info.is_wave_out = false;
179         stream_info.is_big_endian = is_big_endian;
180         stream_info.is_unsigned_samples = is_unsigned_samples;
181         stream_info.verbose = verbose;
182         stream_info.skip = skip;
183         stream_info.samples_processed = 0;
184         stream_info.frame_counter = 0;
185
186         assert(!(stream_info.test_only && stream_info.analysis_mode));
187
188         if(!stream_info.test_only) {
189                 if(0 == strcmp(outfile, "-")) {
190                         stream_info.fout = stdout;
191                 }
192                 else {
193                         if(0 == (stream_info.fout = fopen(outfile, "wb"))) {
194                                 fprintf(stderr, "ERROR: can't open output file %s\n", outfile);
195                                 return false;
196                         }
197                 }
198         }
199
200         if(analysis_mode)
201                 analyze_init(aopts);
202
203         if(!init(infile, &stream_info))
204                 goto raw_abort_;
205
206         if(skip > 0) {
207                 if(!FLAC__file_decoder_process_metadata(decoder)) {
208                         fprintf(stderr, "%s: ERROR while decoding metadata, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
209                         goto raw_abort_;
210                 }
211                 if(!FLAC__file_decoder_seek_absolute(decoder, skip)) {
212                         fprintf(stderr, "%s: ERROR seeking while skipping bytes, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
213                         goto raw_abort_;
214                 }
215                 if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
216                         if(verbose) { printf("\n"); fflush(stdout); }
217                         fprintf(stderr, "%s: ERROR while decoding frames, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
218                         goto raw_abort_;
219                 }
220                 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
221                         if(verbose) { printf("\n"); fflush(stdout); }
222                         fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
223                         goto raw_abort_;
224                 }
225         }
226         else {
227                 if(!FLAC__file_decoder_process_whole_file(decoder)) {
228                         if(verbose) { printf("\n"); fflush(stdout); }
229                         fprintf(stderr, "%s: ERROR while decoding data, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
230                         goto raw_abort_;
231                 }
232                 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
233                         if(verbose) { printf("\n"); fflush(stdout); }
234                         fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
235                         goto raw_abort_;
236                 }
237         }
238
239         if(decoder) {
240                 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
241                         md5_failure = !FLAC__file_decoder_finish(decoder);
242                 print_stats(&stream_info);
243                 FLAC__file_decoder_free_instance(decoder);
244         }
245         if(!stream_info.test_only)
246                 fclose(stream_info.fout);
247         if(verbose)
248                 printf("\n");
249         fflush(stdout);
250         if(analysis_mode)
251                 analyze_finish(aopts);
252         if(md5_failure) {
253                 fprintf(stderr, "%s: WARNING, MD5 signature mismatch\n", infile);
254                 return 1;
255         }
256         else {
257                 if(stream_info.test_only)
258                         printf("%s: ok\n", infile);
259         }
260         return 0;
261 raw_abort_:
262         if(decoder) {
263                 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
264                         FLAC__file_decoder_finish(decoder);
265                 FLAC__file_decoder_free_instance(decoder);
266         }
267         if(!stream_info.test_only) {
268                 fclose(stream_info.fout);
269                 unlink(outfile);
270         }
271         if(analysis_mode)
272                 analyze_finish(aopts);
273         return 1;
274 }
275
276 bool init(const char *infile, stream_info_struct *stream_info)
277 {
278         uint32 test = 1;
279
280         is_big_endian_host = (*((byte*)(&test)))? false : true;
281
282         decoder = FLAC__file_decoder_get_new_instance();
283         if(0 == decoder) {
284                 fprintf(stderr, "ERROR creating the decoder instance\n");
285                 return false;
286         }
287         decoder->check_md5 = true;
288
289         if(FLAC__file_decoder_init(decoder, infile, write_callback, metadata_callback, error_callback, stream_info) != FLAC__FILE_DECODER_OK) {
290                 fprintf(stderr, "ERROR initializing decoder, state = %d\n", decoder->state);
291                 return false;
292         }
293
294         return true;
295 }
296
297 bool write_little_endian_uint16(FILE *f, uint16 val)
298 {
299         byte *b = (byte*)(&val);
300         if(is_big_endian_host) {
301                 byte tmp;
302                 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
303         }
304         return fwrite(b, 1, 2, f) == 2;
305 }
306
307 bool write_little_endian_uint32(FILE *f, uint32 val)
308 {
309         byte *b = (byte*)(&val);
310         if(is_big_endian_host) {
311                 byte tmp;
312                 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
313                 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
314         }
315         return fwrite(b, 1, 4, f) == 4;
316 }
317
318 FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data)
319 {
320         stream_info_struct *stream_info = (stream_info_struct *)client_data;
321         FILE *fout = stream_info->fout;
322         unsigned bps = stream_info->bps, channels = stream_info->channels;
323         bool is_big_endian = (stream_info->is_wave_out? false : stream_info->is_big_endian);
324         bool is_unsigned_samples = (stream_info->is_wave_out? bps<=8 : stream_info->is_unsigned_samples);
325         unsigned wide_samples = frame->header.blocksize, wide_sample, sample, channel, byte;
326         static int8 s8buffer[FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(int32)]; /* WATCHOUT: can be up to 2 megs */
327         /* WATCHOUT: we say 'sizeof(int32)' above instead of '(FLAC__MAX_BITS_PER_SAMPLE+7)/8' because we have to use an array int32 even for 24 bps */
328         uint8  *u8buffer  = (uint8  *)s8buffer;
329         int16  *s16buffer = (int16  *)s8buffer;
330         uint16 *u16buffer = (uint16 *)s8buffer;
331         int32  *s32buffer = (int32  *)s8buffer;
332         uint32 *u32buffer = (uint32 *)s8buffer;
333
334         (void)decoder;
335
336         if(stream_info->abort_flag)
337                 return FLAC__STREAM_DECODER_WRITE_ABORT;
338
339         stream_info->samples_processed += wide_samples;
340         stream_info->frame_counter++;
341
342         if(stream_info->verbose && !(stream_info->frame_counter & 0x1f))
343                 print_stats(stream_info);
344
345         if(stream_info->analysis_mode) {
346                 analyze_frame(frame, stream_info->frame_counter-1, stream_info->aopts, fout);
347         }
348         else if(!stream_info->test_only) {
349                 if(bps == 8) {
350                         if(is_unsigned_samples) {
351                                 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
352                                         for(channel = 0; channel < channels; channel++, sample++)
353                                                 u8buffer[sample] = buffer[channel][wide_sample] + 0x80;
354                         }
355                         else {
356                                 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
357                                         for(channel = 0; channel < channels; channel++, sample++)
358                                                 s8buffer[sample] = buffer[channel][wide_sample];
359                         }
360                         if(fwrite(u8buffer, 1, sample, fout) != sample)
361                                 return FLAC__STREAM_DECODER_WRITE_ABORT;
362                 }
363                 else if(bps == 16) {
364                         if(is_unsigned_samples) {
365                                 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
366                                         for(channel = 0; channel < channels; channel++, sample++)
367                                                 u16buffer[sample] = buffer[channel][wide_sample] + 0x8000;
368                         }
369                         else {
370                                 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
371                                         for(channel = 0; channel < channels; channel++, sample++)
372                                                 s16buffer[sample] = buffer[channel][wide_sample];
373                         }
374                         if(is_big_endian != is_big_endian_host) {
375                                 unsigned char tmp;
376                                 const unsigned bytes = sample * 2;
377                                 for(byte = 0; byte < bytes; byte += 2) {
378                                         tmp = u8buffer[byte];
379                                         u8buffer[byte] = u8buffer[byte+1];
380                                         u8buffer[byte+1] = tmp;
381                                 }
382                         }
383                         if(fwrite(u16buffer, 2, sample, fout) != sample)
384                                 return FLAC__STREAM_DECODER_WRITE_ABORT;
385                 }
386                 else if(bps == 24) {
387                         if(is_unsigned_samples) {
388                                 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
389                                         for(channel = 0; channel < channels; channel++, sample++)
390                                                 u32buffer[sample] = buffer[channel][wide_sample] + 0x800000;
391                         }
392                         else {
393                                 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
394                                         for(channel = 0; channel < channels; channel++, sample++)
395                                                 s32buffer[sample] = buffer[channel][wide_sample];
396                         }
397                         if(is_big_endian != is_big_endian_host) {
398                                 unsigned char tmp;
399                                 const unsigned bytes = sample * 4;
400                                 for(byte = 0; byte < bytes; byte += 4) {
401                                         tmp = u8buffer[byte];
402                                         u8buffer[byte] = u8buffer[byte+3];
403                                         u8buffer[byte+3] = tmp;
404                                         tmp = u8buffer[byte+1];
405                                         u8buffer[byte+1] = u8buffer[byte+2];
406                                         u8buffer[byte+2] = tmp;
407                                 }
408                         }
409                         if(is_big_endian) {
410                                 unsigned lbyte;
411                                 const unsigned bytes = sample * 4;
412                                 for(lbyte = byte = 0; byte < bytes; ) {
413                                         byte++;
414                                         u8buffer[lbyte++] = u8buffer[byte++];
415                                         u8buffer[lbyte++] = u8buffer[byte++];
416                                         u8buffer[lbyte++] = u8buffer[byte++];
417                                 }
418                         }
419                         else {
420                                 unsigned lbyte;
421                                 const unsigned bytes = sample * 4;
422                                 for(lbyte = byte = 0; byte < bytes; ) {
423                                         u8buffer[lbyte++] = u8buffer[byte++];
424                                         u8buffer[lbyte++] = u8buffer[byte++];
425                                         u8buffer[lbyte++] = u8buffer[byte++];
426                                         byte++;
427                                 }
428                         }
429                         if(fwrite(u8buffer, 3, sample, fout) != sample)
430                                 return FLAC__STREAM_DECODER_WRITE_ABORT;
431                 }
432                 else {
433                         assert(0);
434                 }
435         }
436         return FLAC__STREAM_DECODER_WRITE_CONTINUE;
437 }
438
439 void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
440 {
441         stream_info_struct *stream_info = (stream_info_struct *)client_data;
442         (void)decoder;
443         if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
444                 stream_info->total_samples = metadata->data.stream_info.total_samples - stream_info->skip;
445                 stream_info->bps = metadata->data.stream_info.bits_per_sample;
446                 stream_info->channels = metadata->data.stream_info.channels;
447                 stream_info->sample_rate = metadata->data.stream_info.sample_rate;
448
449                 if(stream_info->bps != 8 && stream_info->bps != 16 && stream_info->bps != 24) {
450                         fprintf(stderr, "ERROR: bits per sample is not 8/16/24\n");
451                         stream_info->abort_flag = true;
452                         return;
453                 }
454
455                 /* write the WAVE headers if necessary */
456                 if(!stream_info->analysis_mode && !stream_info->test_only && stream_info->is_wave_out) {
457                         uint64 data_size = stream_info->total_samples * stream_info->channels * ((stream_info->bps+7)/8);
458                         if(data_size >= 0xFFFFFFDC) {
459                                 fprintf(stderr, "ERROR: stream is too big for a wave file\n");
460                                 stream_info->abort_flag = true;
461                                 return;
462                         }
463                         if(fwrite("RIFF", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true;
464                         if(!write_little_endian_uint32(stream_info->fout, (uint32)(data_size+36))) stream_info->abort_flag = true; /* filesize-8 */
465                         if(fwrite("WAVEfmt ", 1, 8, stream_info->fout) != 8) stream_info->abort_flag = true;
466                         if(fwrite("\020\000\000\000", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true; /* chunk size = 16 */
467                         if(fwrite("\001\000", 1, 2, stream_info->fout) != 2) stream_info->abort_flag = true; /* compression code == 1 */
468                         if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->channels))) stream_info->abort_flag = true;
469                         if(!write_little_endian_uint32(stream_info->fout, stream_info->sample_rate)) stream_info->abort_flag = true;
470                         if(!write_little_endian_uint32(stream_info->fout, stream_info->sample_rate * stream_info->channels * ((stream_info->bps+7) / 8))) stream_info->abort_flag = true; /* @@@ or is it (sample_rate*channels*bps) / 8 ??? */
471                         if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->channels * ((stream_info->bps+7) / 8)))) stream_info->abort_flag = true; /* block align */
472                         if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->bps))) stream_info->abort_flag = true; /* bits per sample */
473                         if(fwrite("data", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true;
474                         if(!write_little_endian_uint32(stream_info->fout, (uint32)data_size)) stream_info->abort_flag = true; /* data size */
475                 }
476         }
477 }
478
479 void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
480 {
481         stream_info_struct *stream_info = (stream_info_struct *)client_data;
482         (void)decoder;
483         fprintf(stderr, "*** Got error code %d:%s\n", status, FLAC__StreamDecoderErrorStatusString[status]);
484         stream_info->abort_flag = true;
485 }
486
487 void print_stats(const stream_info_struct *stream_info)
488 {
489         if(stream_info->verbose) {
490                 printf("\r%s %u of %u samples, %6.2f%% complete",
491                         stream_info->test_only? "tested" : stream_info->analysis_mode? "analyzed" : "wrote",
492                         (unsigned)stream_info->samples_processed,
493                         (unsigned)stream_info->total_samples,
494 #ifdef _MSC_VER
495                         /* with VC++ you have to spoon feed it the casting */
496                         (double)(int64)stream_info->samples_processed / (double)(int64)stream_info->total_samples * 100.0
497 #else
498                         (double)stream_info->samples_processed / (double)stream_info->total_samples * 100.0
499 #endif
500                 );
501                 fflush(stdout);
502         }
503 }