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