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