add support for new PICTURE metadata block
[platform/upstream/flac.git] / src / test_libFLAC / decoders.c
1 /* test_libFLAC - Unit tester for libFLAC
2  * Copyright (C) 2002,2003,2004,2005,2006  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 HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #if defined _MSC_VER || defined __MINGW32__
28 //@@@ [2G limit] hacks for MSVC6
29 #define fseeko fseek
30 #define ftello ftell
31 #endif
32 #include "decoders.h"
33 #include "FLAC/assert.h"
34 #include "FLAC/stream_decoder.h"
35 #include "share/grabbag.h"
36 #include "test_libs_common/file_utils_flac.h"
37 #include "test_libs_common/metadata_utils.h"
38
39 typedef enum {
40         LAYER_STREAM = 0, /* FLAC__stream_decoder_init_stream() without seeking */
41         LAYER_SEEKABLE_STREAM, /* FLAC__stream_decoder_init_stream() with seeking */
42         LAYER_FILE, /* FLAC__stream_decoder_init_FILE() */
43         LAYER_FILENAME /* FLAC__stream_decoder_init_file() */
44 } Layer;
45
46 static const char * const LayerString[] = {
47         "Stream",
48         "Seekable Stream",
49         "FILE*",
50         "Filename"
51 };
52
53 typedef struct {
54         Layer layer;
55         FILE *file;
56         unsigned current_metadata_number;
57         FLAC__bool ignore_errors;
58         FLAC__bool error_occurred;
59 } StreamDecoderClientData;
60
61 static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, picture_, unknown_;
62 static FLAC__StreamMetadata *expected_metadata_sequence_[9];
63 static unsigned num_expected_;
64 static const char *flacfilename_ = "metadata.flac";
65 static off_t flacfilesize_;
66
67 static FLAC__bool die_(const char *msg)
68 {
69         printf("ERROR: %s\n", msg);
70         return false;
71 }
72
73 static FLAC__bool die_s_(const char *msg, const FLAC__StreamDecoder *decoder)
74 {
75         FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(decoder);
76
77         if(msg)
78                 printf("FAILED, %s", msg);
79         else
80                 printf("FAILED");
81
82         printf(", state = %u (%s)\n", (unsigned)state, FLAC__StreamDecoderStateString[state]);
83
84         return false;
85 }
86
87 static void init_metadata_blocks_()
88 {
89         mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
90 }
91
92 static void free_metadata_blocks_()
93 {
94         mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
95 }
96
97 static FLAC__bool generate_file_()
98 {
99         printf("\n\ngenerating FLAC file for decoder tests...\n");
100
101         num_expected_ = 0;
102         expected_metadata_sequence_[num_expected_++] = &padding_;
103         expected_metadata_sequence_[num_expected_++] = &seektable_;
104         expected_metadata_sequence_[num_expected_++] = &application1_;
105         expected_metadata_sequence_[num_expected_++] = &application2_;
106         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
107         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
108         expected_metadata_sequence_[num_expected_++] = &picture_;
109         expected_metadata_sequence_[num_expected_++] = &unknown_;
110
111         if(!file_utils__generate_flacfile(flacfilename_, &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
112                 return die_("creating the encoded file");
113
114         return true;
115 }
116
117 static FLAC__StreamDecoderReadStatus stream_decoder_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
118 {
119         StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
120         const unsigned requested_bytes = *bytes;
121
122         (void)decoder;
123
124         if(0 == dcd) {
125                 printf("ERROR: client_data in read callback is NULL\n");
126                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
127         }
128
129         if(dcd->error_occurred)
130                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
131
132         if(feof(dcd->file)) {
133                 *bytes = 0;
134                 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
135         }
136         else if(requested_bytes > 0) {
137                 *bytes = fread(buffer, 1, requested_bytes, dcd->file);
138                 if(*bytes == 0) {
139                         if(feof(dcd->file))
140                                 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
141                         else
142                                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
143                 }
144                 else {
145                         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
146                 }
147         }
148         else
149                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
150 }
151
152 static FLAC__StreamDecoderSeekStatus stream_decoder_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
153 {
154         StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
155
156         (void)decoder;
157
158         if(0 == dcd) {
159                 printf("ERROR: client_data in seek callback is NULL\n");
160                 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
161         }
162
163         if(dcd->error_occurred)
164                 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
165
166         if(fseeko(dcd->file, (off_t)absolute_byte_offset, SEEK_SET) < 0) {
167                 dcd->error_occurred = true;
168                 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
169         }
170
171         return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
172 }
173
174 static FLAC__StreamDecoderTellStatus stream_decoder_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
175 {
176         StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
177         off_t offset;
178
179         (void)decoder;
180
181         if(0 == dcd) {
182                 printf("ERROR: client_data in tell callback is NULL\n");
183                 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
184         }
185
186         if(dcd->error_occurred)
187                 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
188
189         offset = ftello(dcd->file);
190         *absolute_byte_offset = (FLAC__uint64)offset;
191
192         if(offset < 0) {
193                 dcd->error_occurred = true;
194                 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
195         }
196
197         return FLAC__STREAM_DECODER_TELL_STATUS_OK;
198 }
199
200 static FLAC__StreamDecoderLengthStatus stream_decoder_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
201 {
202         StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
203
204         (void)decoder;
205
206         if(0 == dcd) {
207                 printf("ERROR: client_data in length callback is NULL\n");
208                 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
209         }
210
211         if(dcd->error_occurred)
212                 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
213
214         *stream_length = (FLAC__uint64)flacfilesize_;
215         return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
216 }
217
218 static FLAC__bool stream_decoder_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data)
219 {
220         StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
221
222         (void)decoder;
223
224         if(0 == dcd) {
225                 printf("ERROR: client_data in eof callback is NULL\n");
226                 return true;
227         }
228
229         if(dcd->error_occurred)
230                 return true;
231
232         return feof(dcd->file);
233 }
234
235 static FLAC__StreamDecoderWriteStatus stream_decoder_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
236 {
237         StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
238
239         (void)decoder, (void)buffer;
240
241         if(0 == dcd) {
242                 printf("ERROR: client_data in write callback is NULL\n");
243                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
244         }
245
246         if(dcd->error_occurred)
247                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
248
249         if(
250                 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
251                 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
252         ) {
253                 printf("content... ");
254                 fflush(stdout);
255         }
256
257         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
258 }
259
260 static void stream_decoder_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
261 {
262         StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
263
264         (void)decoder;
265
266         if(0 == dcd) {
267                 printf("ERROR: client_data in metadata callback is NULL\n");
268                 return;
269         }
270
271         if(dcd->error_occurred)
272                 return;
273
274         printf("%d... ", dcd->current_metadata_number);
275         fflush(stdout);
276
277         if(dcd->current_metadata_number >= num_expected_) {
278                 (void)die_("got more metadata blocks than expected");
279                 dcd->error_occurred = true;
280         }
281         else {
282                 if(!mutils__compare_block(expected_metadata_sequence_[dcd->current_metadata_number], metadata)) {
283                         (void)die_("metadata block mismatch");
284                         dcd->error_occurred = true;
285                 }
286         }
287         dcd->current_metadata_number++;
288 }
289
290 static void stream_decoder_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
291 {
292         StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
293
294         (void)decoder;
295
296         if(0 == dcd) {
297                 printf("ERROR: client_data in error callback is NULL\n");
298                 return;
299         }
300
301         if(!dcd->ignore_errors) {
302                 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, FLAC__StreamDecoderErrorStatusString[status]);
303                 dcd->error_occurred = true;
304         }
305 }
306
307 static FLAC__bool stream_decoder_test_respond_(FLAC__StreamDecoder *decoder, StreamDecoderClientData *dcd)
308 {
309         FLAC__StreamDecoderInitStatus init_status;
310
311         if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
312                 return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder);
313
314         /* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */
315         if(dcd->layer == LAYER_FILE) {
316                 printf("opening FLAC file... ");
317                 dcd->file = fopen(flacfilename_, "rb");
318                 if(0 == dcd->file) {
319                         printf("ERROR (%s)\n", strerror(errno));
320                         return false;
321                 }
322                 printf("OK\n");
323         }
324
325         printf("testing FLAC__stream_decoder_init_stream()... ");
326         switch(dcd->layer) {
327                 case LAYER_STREAM:
328                         init_status = FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
329                         break;
330                 case LAYER_SEEKABLE_STREAM:
331                         init_status = FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
332                         break;
333                 case LAYER_FILE:
334                         init_status = FLAC__stream_decoder_init_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
335                         break;
336                 case LAYER_FILENAME:
337                         init_status = FLAC__stream_decoder_init_file(decoder, flacfilename_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
338                         break;
339                 default:
340                         die_("internal error 000");
341                         return false;
342         }
343         if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
344                 return die_s_(0, decoder);
345         printf("OK\n");
346
347         dcd->current_metadata_number = 0;
348
349         if(dcd->layer < LAYER_FILE && fseeko(dcd->file, 0, SEEK_SET) < 0) {
350                 printf("FAILED rewinding input, errno = %d\n", errno);
351                 return false;
352         }
353
354         printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
355         if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
356                 return die_s_("returned false", decoder);
357         printf("OK\n");
358
359         printf("testing FLAC__stream_decoder_finish()... ");
360         FLAC__stream_decoder_finish(decoder);
361         printf("OK\n");
362
363         return true;
364 }
365
366 static FLAC__bool test_stream_decoder(Layer layer)
367 {
368         FLAC__StreamDecoder *decoder;
369         FLAC__StreamDecoderState state;
370         StreamDecoderClientData decoder_client_data;
371         FLAC__bool expect;
372
373         decoder_client_data.layer = layer;
374
375         printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s)\n\n", LayerString[layer]);
376
377         printf("testing FLAC__stream_decoder_new()... ");
378         decoder = FLAC__stream_decoder_new();
379         if(0 == decoder) {
380                 printf("FAILED, returned NULL\n");
381                 return false;
382         }
383         printf("OK\n");
384
385         printf("testing FLAC__stream_decoder_delete()... ");
386         FLAC__stream_decoder_delete(decoder);
387         printf("OK\n");
388
389         printf("testing FLAC__stream_decoder_new()... ");
390         decoder = FLAC__stream_decoder_new();
391         if(0 == decoder) {
392                 printf("FAILED, returned NULL\n");
393                 return false;
394         }
395         printf("OK\n");
396
397         switch(layer) {
398                 case LAYER_STREAM:
399                 case LAYER_SEEKABLE_STREAM:
400                         printf("testing FLAC__stream_decoder_init_stream()... ");
401                         if(FLAC__stream_decoder_init_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0) != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS)
402                                 return die_s_(0, decoder);
403                         break;
404                 case LAYER_FILE:
405                         printf("testing FLAC__stream_decoder_init_FILE()... ");
406                         if(FLAC__stream_decoder_init_FILE(decoder, stdin, 0, 0, 0, 0) != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS)
407                                 return die_s_(0, decoder);
408                         break;
409                 case LAYER_FILENAME:
410                         printf("testing FLAC__stream_decoder_init_file()... ");
411                         if(FLAC__stream_decoder_init_file(decoder, flacfilename_, 0, 0, 0, 0) != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS)
412                                 return die_s_(0, decoder);
413                         break;
414                 default:
415                         die_("internal error 003");
416                         return false;
417         }
418         printf("OK\n");
419
420         printf("testing FLAC__stream_decoder_delete()... ");
421         FLAC__stream_decoder_delete(decoder);
422         printf("OK\n");
423
424         num_expected_ = 0;
425         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
426
427         printf("testing FLAC__stream_decoder_new()... ");
428         decoder = FLAC__stream_decoder_new();
429         if(0 == decoder) {
430                 printf("FAILED, returned NULL\n");
431                 return false;
432         }
433         printf("OK\n");
434
435         printf("testing FLAC__stream_decoder_set_md5_checking()... ");
436         if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
437                 return die_s_("returned false", decoder);
438         printf("OK\n");
439
440         if(layer < LAYER_FILENAME) {
441                 printf("opening FLAC file... ");
442                 decoder_client_data.file = fopen(flacfilename_, "rb");
443                 if(0 == decoder_client_data.file) {
444                         printf("ERROR (%s)\n", strerror(errno));
445                         return false;
446                 }
447                 printf("OK\n");
448         }
449
450         switch(layer) {
451                 case LAYER_STREAM:
452                         printf("testing FLAC__stream_decoder_init_stream()... ");
453                         if(FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
454                                 return die_s_(0, decoder);
455                         break;
456                 case LAYER_SEEKABLE_STREAM:
457                         printf("testing FLAC__stream_decoder_init_stream()... ");
458                         if(FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
459                                 return die_s_(0, decoder);
460                         break;
461                 case LAYER_FILE:
462                         printf("testing FLAC__stream_decoder_init_FILE()... ");
463                         if(FLAC__stream_decoder_init_FILE(decoder, decoder_client_data.file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
464                                 return die_s_(0, decoder);
465                         break;
466                 case LAYER_FILENAME:
467                         printf("testing FLAC__stream_decoder_init_file()... ");
468                         if(FLAC__stream_decoder_init_file(decoder, flacfilename_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
469                                 return die_s_(0, decoder);
470                         break;
471                 default:
472                         die_("internal error 009");
473                         return false;
474         }
475         printf("OK\n");
476
477         printf("testing FLAC__stream_decoder_get_state()... ");
478         state = FLAC__stream_decoder_get_state(decoder);
479         printf("returned state = %u (%s)... OK\n", state, FLAC__StreamDecoderStateString[state]);
480
481         decoder_client_data.current_metadata_number = 0;
482         decoder_client_data.ignore_errors = false;
483         decoder_client_data.error_occurred = false;
484
485         printf("testing FLAC__stream_decoder_get_md5_checking()... ");
486         if(!FLAC__stream_decoder_get_md5_checking(decoder)) {
487                 printf("FAILED, returned false, expected true\n");
488                 return false;
489         }
490         printf("OK\n");
491
492         printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... ");
493         if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
494                 return die_s_("returned false", decoder);
495         printf("OK\n");
496
497         printf("testing FLAC__stream_decoder_process_single()... ");
498         if(!FLAC__stream_decoder_process_single(decoder))
499                 return die_s_("returned false", decoder);
500         printf("OK\n");
501
502         printf("testing FLAC__stream_decoder_skip_single_frame()... ");
503         if(!FLAC__stream_decoder_skip_single_frame(decoder))
504                 return die_s_("returned false", decoder);
505         printf("OK\n");
506
507         if(layer < LAYER_FILE) {
508                 printf("testing FLAC__stream_decoder_flush()... ");
509                 if(!FLAC__stream_decoder_flush(decoder))
510                         return die_s_("returned false", decoder);
511                 printf("OK\n");
512
513                 decoder_client_data.ignore_errors = true;
514                 printf("testing FLAC__stream_decoder_process_single()... ");
515                 if(!FLAC__stream_decoder_process_single(decoder))
516                         return die_s_("returned false", decoder);
517                 printf("OK\n");
518                 decoder_client_data.ignore_errors = false;
519         }
520
521         expect = (layer != LAYER_STREAM);
522         printf("testing FLAC__stream_decoder_seek_absolute()... ");
523         if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
524                 return die_s_(expect? "returned false" : "returned true", decoder);
525         printf("OK\n");
526
527         printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
528         if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
529                 return die_s_("returned false", decoder);
530         printf("OK\n");
531
532         expect = (layer != LAYER_STREAM);
533         printf("testing FLAC__stream_decoder_seek_absolute()... ");
534         if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
535                 return die_s_(expect? "returned false" : "returned true", decoder);
536         printf("OK\n");
537
538         printf("testing FLAC__stream_decoder_get_channels()... ");
539         {
540                 unsigned channels = FLAC__stream_decoder_get_channels(decoder);
541                 if(channels != streaminfo_.data.stream_info.channels) {
542                         printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
543                         return false;
544                 }
545         }
546         printf("OK\n");
547
548         printf("testing FLAC__stream_decoder_get_bits_per_sample()... ");
549         {
550                 unsigned bits_per_sample = FLAC__stream_decoder_get_bits_per_sample(decoder);
551                 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
552                         printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
553                         return false;
554                 }
555         }
556         printf("OK\n");
557
558         printf("testing FLAC__stream_decoder_get_sample_rate()... ");
559         {
560                 unsigned sample_rate = FLAC__stream_decoder_get_sample_rate(decoder);
561                 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
562                         printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
563                         return false;
564                 }
565         }
566         printf("OK\n");
567
568         printf("testing FLAC__stream_decoder_get_blocksize()... ");
569         {
570                 unsigned blocksize = FLAC__stream_decoder_get_blocksize(decoder);
571                 /* value could be anything since we're at the last block, so accept any reasonable answer */
572                 printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED");
573                 if(blocksize == 0)
574                         return false;
575         }
576
577         printf("testing FLAC__stream_decoder_get_channel_assignment()... ");
578         {
579                 FLAC__ChannelAssignment ca = FLAC__stream_decoder_get_channel_assignment(decoder);
580                 printf("returned %u (%s)... OK\n", (unsigned)ca, FLAC__ChannelAssignmentString[ca]);
581         }
582
583         if(layer < LAYER_FILE) {
584                 printf("testing FLAC__stream_decoder_reset()... ");
585                 if(!FLAC__stream_decoder_reset(decoder)) {
586                         state = FLAC__stream_decoder_get_state(decoder);
587                         printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]);
588                         return false;
589                 }
590                 printf("OK\n");
591
592                 if(layer == LAYER_STREAM) {
593                         /* after a reset() we have to rewind the input ourselves */
594                         printf("rewinding input... ");
595                         if(fseeko(decoder_client_data.file, 0, SEEK_SET) < 0) {
596                                 printf("FAILED, errno = %d\n", errno);
597                                 return false;
598                         }
599                         printf("OK\n");
600                 }
601
602                 decoder_client_data.current_metadata_number = 0;
603
604                 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
605                 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
606                         return die_s_("returned false", decoder);
607                 printf("OK\n");
608         }
609
610         printf("testing FLAC__stream_decoder_finish()... ");
611         (void) FLAC__stream_decoder_finish(decoder);
612         printf("OK\n");
613
614         /*
615          * respond all
616          */
617
618         printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
619         if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
620                 return die_s_("returned false", decoder);
621         printf("OK\n");
622
623         num_expected_ = 0;
624         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
625         expected_metadata_sequence_[num_expected_++] = &padding_;
626         expected_metadata_sequence_[num_expected_++] = &seektable_;
627         expected_metadata_sequence_[num_expected_++] = &application1_;
628         expected_metadata_sequence_[num_expected_++] = &application2_;
629         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
630         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
631         expected_metadata_sequence_[num_expected_++] = &picture_;
632         expected_metadata_sequence_[num_expected_++] = &unknown_;
633
634         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
635                 return false;
636
637         /*
638          * ignore all
639          */
640
641         printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
642         if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
643                 return die_s_("returned false", decoder);
644         printf("OK\n");
645
646         num_expected_ = 0;
647
648         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
649                 return false;
650
651         /*
652          * respond all, ignore VORBIS_COMMENT
653          */
654
655         printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
656         if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
657                 return die_s_("returned false", decoder);
658         printf("OK\n");
659
660         printf("testing FLAC__stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... ");
661         if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
662                 return die_s_("returned false", decoder);
663         printf("OK\n");
664
665         num_expected_ = 0;
666         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
667         expected_metadata_sequence_[num_expected_++] = &padding_;
668         expected_metadata_sequence_[num_expected_++] = &seektable_;
669         expected_metadata_sequence_[num_expected_++] = &application1_;
670         expected_metadata_sequence_[num_expected_++] = &application2_;
671         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
672         expected_metadata_sequence_[num_expected_++] = &picture_;
673         expected_metadata_sequence_[num_expected_++] = &unknown_;
674
675         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
676                 return false;
677
678         /*
679          * respond all, ignore APPLICATION
680          */
681
682         printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
683         if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
684                 return die_s_("returned false", decoder);
685         printf("OK\n");
686
687         printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
688         if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
689                 return die_s_("returned false", decoder);
690         printf("OK\n");
691
692         num_expected_ = 0;
693         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
694         expected_metadata_sequence_[num_expected_++] = &padding_;
695         expected_metadata_sequence_[num_expected_++] = &seektable_;
696         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
697         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
698         expected_metadata_sequence_[num_expected_++] = &picture_;
699         expected_metadata_sequence_[num_expected_++] = &unknown_;
700
701         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
702                 return false;
703
704         /*
705          * respond all, ignore APPLICATION id of app#1
706          */
707
708         printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
709         if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
710                 return die_s_("returned false", decoder);
711         printf("OK\n");
712
713         printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
714         if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
715                 return die_s_("returned false", decoder);
716         printf("OK\n");
717
718         num_expected_ = 0;
719         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
720         expected_metadata_sequence_[num_expected_++] = &padding_;
721         expected_metadata_sequence_[num_expected_++] = &seektable_;
722         expected_metadata_sequence_[num_expected_++] = &application2_;
723         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
724         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
725         expected_metadata_sequence_[num_expected_++] = &picture_;
726         expected_metadata_sequence_[num_expected_++] = &unknown_;
727
728         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
729                 return false;
730
731         /*
732          * respond all, ignore APPLICATION id of app#1 & app#2
733          */
734
735         printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
736         if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
737                 return die_s_("returned false", decoder);
738         printf("OK\n");
739
740         printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
741         if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
742                 return die_s_("returned false", decoder);
743         printf("OK\n");
744
745         printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... ");
746         if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id))
747                 return die_s_("returned false", decoder);
748         printf("OK\n");
749
750         num_expected_ = 0;
751         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
752         expected_metadata_sequence_[num_expected_++] = &padding_;
753         expected_metadata_sequence_[num_expected_++] = &seektable_;
754         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
755         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
756         expected_metadata_sequence_[num_expected_++] = &picture_;
757         expected_metadata_sequence_[num_expected_++] = &unknown_;
758
759         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
760                 return false;
761
762         /*
763          * ignore all, respond VORBIS_COMMENT
764          */
765
766         printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
767         if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
768                 return die_s_("returned false", decoder);
769         printf("OK\n");
770
771         printf("testing FLAC__stream_decoder_set_metadata_respond(VORBIS_COMMENT)... ");
772         if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
773                 return die_s_("returned false", decoder);
774         printf("OK\n");
775
776         num_expected_ = 0;
777         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
778
779         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
780                 return false;
781
782         /*
783          * ignore all, respond APPLICATION
784          */
785
786         printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
787         if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
788                 return die_s_("returned false", decoder);
789         printf("OK\n");
790
791         printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
792         if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION))
793                 return die_s_("returned false", decoder);
794         printf("OK\n");
795
796         num_expected_ = 0;
797         expected_metadata_sequence_[num_expected_++] = &application1_;
798         expected_metadata_sequence_[num_expected_++] = &application2_;
799
800         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
801                 return false;
802
803         /*
804          * ignore all, respond APPLICATION id of app#1
805          */
806
807         printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
808         if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
809                 return die_s_("returned false", decoder);
810         printf("OK\n");
811
812         printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
813         if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
814                 return die_s_("returned false", decoder);
815         printf("OK\n");
816
817         num_expected_ = 0;
818         expected_metadata_sequence_[num_expected_++] = &application1_;
819
820         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
821                 return false;
822
823         /*
824          * ignore all, respond APPLICATION id of app#1 & app#2
825          */
826
827         printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
828         if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
829                 return die_s_("returned false", decoder);
830         printf("OK\n");
831
832         printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
833         if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
834                 return die_s_("returned false", decoder);
835         printf("OK\n");
836
837         printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #2)... ");
838         if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id))
839                 return die_s_("returned false", decoder);
840         printf("OK\n");
841
842         num_expected_ = 0;
843         expected_metadata_sequence_[num_expected_++] = &application1_;
844         expected_metadata_sequence_[num_expected_++] = &application2_;
845
846         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
847                 return false;
848
849         /*
850          * respond all, ignore APPLICATION, respond APPLICATION id of app#1
851          */
852
853         printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
854         if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
855                 return die_s_("returned false", decoder);
856         printf("OK\n");
857
858         printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
859         if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
860                 return die_s_("returned false", decoder);
861         printf("OK\n");
862
863         printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
864         if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
865                 return die_s_("returned false", decoder);
866         printf("OK\n");
867
868         num_expected_ = 0;
869         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
870         expected_metadata_sequence_[num_expected_++] = &padding_;
871         expected_metadata_sequence_[num_expected_++] = &seektable_;
872         expected_metadata_sequence_[num_expected_++] = &application1_;
873         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
874         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
875         expected_metadata_sequence_[num_expected_++] = &picture_;
876         expected_metadata_sequence_[num_expected_++] = &unknown_;
877
878         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
879                 return false;
880
881         /*
882          * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
883          */
884
885         printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
886         if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
887                 return die_s_("returned false", decoder);
888         printf("OK\n");
889
890         printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
891         if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION))
892                 return die_s_("returned false", decoder);
893         printf("OK\n");
894
895         printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
896         if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
897                 return die_s_("returned false", decoder);
898         printf("OK\n");
899
900         num_expected_ = 0;
901         expected_metadata_sequence_[num_expected_++] = &application2_;
902
903         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
904                 return false;
905
906         if(layer < LAYER_FILE) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */
907                 fclose(decoder_client_data.file);
908
909         printf("testing FLAC__stream_decoder_delete()... ");
910         FLAC__stream_decoder_delete(decoder);
911         printf("OK\n");
912
913         printf("\nPASSED!\n");
914
915         return true;
916 }
917
918 FLAC__bool test_decoders()
919 {
920         init_metadata_blocks_();
921         if(!generate_file_())
922                 return false;
923
924         if(!test_stream_decoder(LAYER_STREAM))
925                 return false;
926
927         if(!test_stream_decoder(LAYER_SEEKABLE_STREAM))
928                 return false;
929
930         if(!test_stream_decoder(LAYER_FILE))
931                 return false;
932
933         if(!test_stream_decoder(LAYER_FILENAME))
934                 return false;
935
936         (void) grabbag__file_remove_file(flacfilename_);
937         free_metadata_blocks_();
938
939         return true;
940 }