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