a6cd9ee3c25b3d1050d015cd10cc0fb3806feaee
[flac.git] / src / test_libOggFLAC / decoders.c
1 /* test_libOggFLAC - Unit tester for libOggFLAC
2  * Copyright (C) 2002,2003  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 #include "decoders.h"
20 #include "file_utils.h"
21 #include "metadata_utils.h"
22 #include "FLAC/assert.h"
23 #include "OggFLAC/stream_decoder.h"
24 #include "share/grabbag.h"
25 #include <errno.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 typedef struct {
31         FILE *file;
32         unsigned current_metadata_number;
33         FLAC__bool ignore_errors;
34         FLAC__bool error_occurred;
35 } stream_decoder_client_data_struct;
36
37 static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_;
38 static FLAC__StreamMetadata *expected_metadata_sequence_[6];
39 static unsigned num_expected_;
40 static const char *oggflacfilename_ = "metadata.ogg";
41 static unsigned oggflacfilesize_;
42
43 static FLAC__bool die_(const char *msg)
44 {
45         printf("ERROR: %s\n", msg);
46         return false;
47 }
48
49 static FLAC__bool die_s_(const char *msg, const OggFLAC__StreamDecoder *decoder)
50 {
51         OggFLAC__StreamDecoderState state = OggFLAC__stream_decoder_get_state(decoder);
52
53         if(msg)
54                 printf("FAILED, %s", msg);
55         else
56                 printf("FAILED");
57
58         printf(", state = %u (%s)\n", (unsigned)state, OggFLAC__StreamDecoderStateString[state]);
59         if(state == OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
60                 FLAC__StreamDecoderState state_ = OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder);
61                 printf("      FLAC stream decoder state = %u (%s)\n", (unsigned)state_, FLAC__StreamDecoderStateString[state_]);
62         }
63
64         return false;
65 }
66
67 static void *malloc_or_die_(size_t size)
68 {
69         void *x = malloc(size);
70         if(0 == x) {
71                 fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
72                 exit(1);
73         }
74         return x;
75 }
76
77 static void init_metadata_blocks_()
78 {
79         /*
80                 most of the actual numbers and data in the blocks don't matter,
81                 we just want to make sure the decoder parses them correctly
82
83                 remember, the metadata interface gets tested after the decoders,
84                 so we do all the metadata manipulation here without it.
85         */
86
87         /* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
88         streaminfo_.is_last = false;
89         streaminfo_.type = FLAC__METADATA_TYPE_STREAMINFO;
90         streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
91         streaminfo_.data.stream_info.min_blocksize = 576;
92         streaminfo_.data.stream_info.max_blocksize = 576;
93         streaminfo_.data.stream_info.min_framesize = 0;
94         streaminfo_.data.stream_info.max_framesize = 0;
95         streaminfo_.data.stream_info.sample_rate = 44100;
96         streaminfo_.data.stream_info.channels = 1;
97         streaminfo_.data.stream_info.bits_per_sample = 8;
98         streaminfo_.data.stream_info.total_samples = 0;
99         memset(streaminfo_.data.stream_info.md5sum, 0, 16);
100
101         padding_.is_last = false;
102         padding_.type = FLAC__METADATA_TYPE_PADDING;
103         padding_.length = 1234;
104
105         seektable_.is_last = false;
106         seektable_.type = FLAC__METADATA_TYPE_SEEKTABLE;
107         seektable_.data.seek_table.num_points = 2;
108         seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
109         seektable_.data.seek_table.points = malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint));
110         seektable_.data.seek_table.points[0].sample_number = 0;
111         seektable_.data.seek_table.points[0].stream_offset = 0;
112         seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
113         seektable_.data.seek_table.points[1].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
114         seektable_.data.seek_table.points[1].stream_offset = 1000;
115         seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
116
117         application1_.is_last = false;
118         application1_.type = FLAC__METADATA_TYPE_APPLICATION;
119         application1_.length = 8;
120         memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
121         application1_.data.application.data = malloc_or_die_(4);
122         memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
123
124         application2_.is_last = false;
125         application2_.type = FLAC__METADATA_TYPE_APPLICATION;
126         application2_.length = 4;
127         memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
128         application2_.data.application.data = 0;
129
130         {
131                 const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
132                 vorbiscomment_.is_last = true;
133                 vorbiscomment_.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
134                 vorbiscomment_.length = (4 + vendor_string_length) + 4 + (4 + 5) + (4 + 0);
135                 vorbiscomment_.data.vorbis_comment.vendor_string.length = vendor_string_length;
136                 vorbiscomment_.data.vorbis_comment.vendor_string.entry = malloc_or_die_(vendor_string_length);
137                 memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length);
138                         vorbiscomment_.data.vorbis_comment.num_comments = 2;
139                 vorbiscomment_.data.vorbis_comment.comments = malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
140                 vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
141                 vorbiscomment_.data.vorbis_comment.comments[0].entry = malloc_or_die_(5);
142                 memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
143                 vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
144                 vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
145         }
146 }
147
148 static void free_metadata_blocks_()
149 {
150         free(seektable_.data.seek_table.points);
151         free(application1_.data.application.data);
152         free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
153         free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
154         free(vorbiscomment_.data.vorbis_comment.comments);
155 }
156
157 static FLAC__bool generate_file_()
158 {
159         printf("\n\ngenerating Ogg FLAC file for decoder tests...\n");
160
161         expected_metadata_sequence_[0] = &padding_;
162         expected_metadata_sequence_[1] = &seektable_;
163         expected_metadata_sequence_[2] = &application1_;
164         expected_metadata_sequence_[3] = &application2_;
165         expected_metadata_sequence_[4] = &vorbiscomment_;
166         num_expected_ = 5;
167
168         if(!file_utils__generate_oggflacfile(oggflacfilename_, &oggflacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
169                 return die_("creating the encoded file");
170
171         return true;
172 }
173
174 static FLAC__StreamDecoderReadStatus stream_decoder_read_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
175 {
176         stream_decoder_client_data_struct *dcd = (stream_decoder_client_data_struct*)client_data;
177
178         (void)decoder;
179
180         if(0 == dcd) {
181                 printf("ERROR: client_data in read callback is NULL\n");
182                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
183         }
184
185         if(dcd->error_occurred)
186                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
187
188         if(feof(dcd->file))
189                 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
190         else if(*bytes > 0) {
191                 unsigned bytes_read = fread(buffer, 1, *bytes, dcd->file);
192                 if(bytes_read == 0) {
193                         if(feof(dcd->file))
194                                 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
195                         else
196                                 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
197                 }
198                 else {
199                         *bytes = bytes_read;
200                         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
201                 }
202         }
203         else
204                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
205 }
206
207 static FLAC__StreamDecoderWriteStatus stream_decoder_write_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
208 {
209         stream_decoder_client_data_struct *dcd = (stream_decoder_client_data_struct*)client_data;
210
211         (void)decoder, (void)buffer;
212
213         if(0 == dcd) {
214                 printf("ERROR: client_data in write callback is NULL\n");
215                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
216         }
217
218         if(dcd->error_occurred)
219                 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
220
221         if(
222                 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
223                 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
224         ) {
225                 printf("content... ");
226                 fflush(stdout);
227         }
228
229         return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
230 }
231
232 static void stream_decoder_metadata_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
233 {
234         stream_decoder_client_data_struct *dcd = (stream_decoder_client_data_struct*)client_data;
235
236         (void)decoder;
237
238         if(0 == dcd) {
239                 printf("ERROR: client_data in metadata callback is NULL\n");
240                 return;
241         }
242
243         if(dcd->error_occurred)
244                 return;
245
246         printf("%d... ", dcd->current_metadata_number);
247         fflush(stdout);
248
249         if(dcd->current_metadata_number >= num_expected_) {
250                 (void)die_("got more metadata blocks than expected");
251                 dcd->error_occurred = true;
252         }
253         else {
254                 if(!compare_block_(expected_metadata_sequence_[dcd->current_metadata_number], metadata)) {
255                         (void)die_("metadata block mismatch");
256                         dcd->error_occurred = true;
257                 }
258         }
259         dcd->current_metadata_number++;
260 }
261
262 static void stream_decoder_error_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
263 {
264         stream_decoder_client_data_struct *dcd = (stream_decoder_client_data_struct*)client_data;
265
266         (void)decoder;
267
268         if(0 == dcd) {
269                 printf("ERROR: client_data in error callback is NULL\n");
270                 return;
271         }
272
273         if(!dcd->ignore_errors) {
274                 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, FLAC__StreamDecoderErrorStatusString[status]);
275                 dcd->error_occurred = true;
276         }
277 }
278
279 static FLAC__bool stream_decoder_test_respond_(OggFLAC__StreamDecoder *decoder, stream_decoder_client_data_struct *dcd)
280 {
281         if(!OggFLAC__stream_decoder_set_read_callback(decoder, stream_decoder_read_callback_))
282                 return die_s_("at OggFLAC__stream_decoder_set_read_callback(), returned false", decoder);
283
284         if(!OggFLAC__stream_decoder_set_write_callback(decoder, stream_decoder_write_callback_))
285                 return die_s_("at OggFLAC__stream_decoder_set_write_callback(), returned false", decoder);
286
287         if(!OggFLAC__stream_decoder_set_metadata_callback(decoder, stream_decoder_metadata_callback_))
288                 return die_s_("at OggFLAC__stream_decoder_set_metadata_callback(), returned false", decoder);
289
290         if(!OggFLAC__stream_decoder_set_error_callback(decoder, stream_decoder_error_callback_))
291                 return die_s_("at OggFLAC__stream_decoder_set_error_callback(), returned false", decoder);
292
293         if(!OggFLAC__stream_decoder_set_client_data(decoder, dcd))
294                 return die_s_("at OggFLAC__stream_decoder_set_client_data(), returned false", decoder);
295
296         printf("testing OggFLAC__stream_decoder_init()... ");
297         if(OggFLAC__stream_decoder_init(decoder) != OggFLAC__STREAM_DECODER_OK)
298                 return die_s_(0, decoder);
299         printf("OK\n");
300
301         dcd->current_metadata_number = 0;
302
303         if(fseek(dcd->file, 0, SEEK_SET) < 0) {
304                 printf("FAILED rewinding input, errno = %d\n", errno);
305                 return false;
306         }
307
308         printf("testing OggFLAC__stream_decoder_process_until_end_of_stream()... ");
309         if(!OggFLAC__stream_decoder_process_until_end_of_stream(decoder))
310                 return die_s_("returned false", decoder);
311         printf("OK\n");
312
313         printf("testing OggFLAC__stream_decoder_finish()... ");
314         OggFLAC__stream_decoder_finish(decoder);
315         printf("OK\n");
316
317         return true;
318 }
319
320 static FLAC__bool test_stream_decoder()
321 {
322         OggFLAC__StreamDecoder *decoder;
323         OggFLAC__StreamDecoderState state;
324         stream_decoder_client_data_struct decoder_client_data;
325
326         printf("\n+++ libOggFLAC unit test: OggFLAC__StreamDecoder\n\n");
327
328         printf("testing OggFLAC__stream_decoder_new()... ");
329         decoder = OggFLAC__stream_decoder_new();
330         if(0 == decoder) {
331                 printf("FAILED, returned NULL\n");
332                 return false;
333         }
334         printf("OK\n");
335
336         printf("testing OggFLAC__stream_decoder_delete()... ");
337         OggFLAC__stream_decoder_delete(decoder);
338         printf("OK\n");
339
340         printf("testing OggFLAC__stream_decoder_new()... ");
341         decoder = OggFLAC__stream_decoder_new();
342         if(0 == decoder) {
343                 printf("FAILED, returned NULL\n");
344                 return false;
345         }
346         printf("OK\n");
347
348         printf("testing OggFLAC__stream_decoder_init()... ");
349         if(OggFLAC__stream_decoder_init(decoder) == OggFLAC__STREAM_DECODER_OK)
350                 return die_s_(0, decoder);
351         printf("OK\n");
352
353         printf("testing OggFLAC__stream_decoder_delete()... ");
354         OggFLAC__stream_decoder_delete(decoder);
355         printf("OK\n");
356
357         num_expected_ = 0;
358         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
359
360         printf("testing OggFLAC__stream_decoder_new()... ");
361         decoder = OggFLAC__stream_decoder_new();
362         if(0 == decoder) {
363                 printf("FAILED, returned NULL\n");
364                 return false;
365         }
366         printf("OK\n");
367
368         printf("testing OggFLAC__stream_decoder_set_serial_number()... ");
369         if(!OggFLAC__stream_decoder_set_serial_number(decoder, file_utils__serial_number))
370                 return die_s_("returned false", decoder);
371         printf("OK\n");
372
373         printf("testing OggFLAC__stream_decoder_set_read_callback()... ");
374         if(!OggFLAC__stream_decoder_set_read_callback(decoder, stream_decoder_read_callback_))
375                 return die_s_("returned false", decoder);
376         printf("OK\n");
377
378         printf("testing OggFLAC__stream_decoder_set_write_callback()... ");
379         if(!OggFLAC__stream_decoder_set_write_callback(decoder, stream_decoder_write_callback_))
380                 return die_s_("returned false", decoder);
381         printf("OK\n");
382
383         printf("testing OggFLAC__stream_decoder_set_metadata_callback()... ");
384         if(!OggFLAC__stream_decoder_set_metadata_callback(decoder, stream_decoder_metadata_callback_))
385                 return die_s_("returned false", decoder);
386         printf("OK\n");
387
388         printf("testing OggFLAC__stream_decoder_set_error_callback()... ");
389         if(!OggFLAC__stream_decoder_set_error_callback(decoder, stream_decoder_error_callback_))
390                 return die_s_("returned false", decoder);
391         printf("OK\n");
392
393         printf("testing OggFLAC__stream_decoder_set_client_data()... ");
394         if(!OggFLAC__stream_decoder_set_client_data(decoder, &decoder_client_data))
395                 return die_s_("returned false", decoder);
396         printf("OK\n");
397
398         printf("testing OggFLAC__stream_decoder_init()... ");
399         if(OggFLAC__stream_decoder_init(decoder) != OggFLAC__STREAM_DECODER_OK)
400                 return die_s_(0, decoder);
401         printf("OK\n");
402
403         printf("testing OggFLAC__stream_decoder_get_state()... ");
404         state = OggFLAC__stream_decoder_get_state(decoder);
405         printf("returned state = %u (%s)... OK\n", state, OggFLAC__StreamDecoderStateString[state]);
406
407         decoder_client_data.current_metadata_number = 0;
408         decoder_client_data.ignore_errors = false;
409         decoder_client_data.error_occurred = false;
410
411         printf("opening Ogg FLAC file... ");
412         decoder_client_data.file = fopen(oggflacfilename_, "rb");
413         if(0 == decoder_client_data.file) {
414                 printf("ERROR\n");
415                 return false;
416         }
417         printf("OK\n");
418
419         printf("testing OggFLAC__stream_decoder_process_until_end_of_metadata()... ");
420         if(!OggFLAC__stream_decoder_process_until_end_of_metadata(decoder))
421                 return die_s_("returned false", decoder);
422         printf("OK\n");
423
424         printf("testing OggFLAC__stream_decoder_process_single()... ");
425         if(!OggFLAC__stream_decoder_process_single(decoder))
426                 return die_s_("returned false", decoder);
427         printf("OK\n");
428
429         printf("testing OggFLAC__stream_decoder_flush()... ");
430         if(!OggFLAC__stream_decoder_flush(decoder))
431                 return die_s_("returned false", decoder);
432         printf("OK\n");
433
434         decoder_client_data.ignore_errors = true;
435         printf("testing OggFLAC__stream_decoder_process_single()... ");
436         if(!OggFLAC__stream_decoder_process_single(decoder))
437                 return die_s_("returned false", decoder);
438         printf("OK\n");
439         decoder_client_data.ignore_errors = false;
440
441         printf("testing OggFLAC__stream_decoder_process_until_end_of_stream()... ");
442         if(!OggFLAC__stream_decoder_process_until_end_of_stream(decoder))
443                 return die_s_("returned false", decoder);
444         printf("OK\n");
445
446         printf("testing OggFLAC__stream_decoder_get_channels()... ");
447         {
448                 unsigned channels = OggFLAC__stream_decoder_get_channels(decoder);
449                 if(channels != streaminfo_.data.stream_info.channels) {
450                         printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
451                         return false;
452                 }
453         }
454         printf("OK\n");
455
456         printf("testing OggFLAC__stream_decoder_get_bits_per_sample()... ");
457         {
458                 unsigned bits_per_sample = OggFLAC__stream_decoder_get_bits_per_sample(decoder);
459                 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
460                         printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
461                         return false;
462                 }
463         }
464         printf("OK\n");
465
466         printf("testing OggFLAC__stream_decoder_get_sample_rate()... ");
467         {
468                 unsigned sample_rate = OggFLAC__stream_decoder_get_sample_rate(decoder);
469                 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
470                         printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
471                         return false;
472                 }
473         }
474         printf("OK\n");
475
476         printf("testing OggFLAC__stream_decoder_get_blocksize()... ");
477         {
478                 unsigned blocksize = OggFLAC__stream_decoder_get_blocksize(decoder);
479                 /* value could be anything since we're at the last block, so accept any answer */
480                 printf("returned %u... OK\n", blocksize);
481         }
482
483         printf("testing OggFLAC__stream_decoder_get_channel_assignment()... ");
484         {
485                 FLAC__ChannelAssignment ca = OggFLAC__stream_decoder_get_channel_assignment(decoder);
486                 printf("returned %u (%s)... OK\n", (unsigned)ca, FLAC__ChannelAssignmentString[ca]);
487         }
488
489         printf("testing OggFLAC__stream_decoder_reset()... ");
490         if(!OggFLAC__stream_decoder_reset(decoder)) {
491                 state = OggFLAC__stream_decoder_get_state(decoder);
492                 printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]);
493                 return false;
494         }
495         printf("OK\n");
496
497         decoder_client_data.current_metadata_number = 0;
498
499         printf("rewinding input... ");
500         if(fseek(decoder_client_data.file, 0, SEEK_SET) < 0) {
501                 printf("FAILED, errno = %d\n", errno);
502                 return false;
503         }
504         printf("OK\n");
505
506         printf("testing OggFLAC__stream_decoder_process_until_end_of_stream()... ");
507         if(!OggFLAC__stream_decoder_process_until_end_of_stream(decoder))
508                 return die_s_("returned false", decoder);
509         printf("OK\n");
510
511         printf("testing OggFLAC__stream_decoder_finish()... ");
512         OggFLAC__stream_decoder_finish(decoder);
513         printf("OK\n");
514
515         /*
516          * respond all
517          */
518
519         printf("testing OggFLAC__stream_decoder_set_metadata_respond_all()... ");
520         if(!OggFLAC__stream_decoder_set_metadata_respond_all(decoder))
521                 return die_s_("returned false", decoder);
522         printf("OK\n");
523
524         num_expected_ = 0;
525         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
526         expected_metadata_sequence_[num_expected_++] = &padding_;
527         expected_metadata_sequence_[num_expected_++] = &seektable_;
528         expected_metadata_sequence_[num_expected_++] = &application1_;
529         expected_metadata_sequence_[num_expected_++] = &application2_;
530         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
531
532         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
533                 return false;
534
535         /*
536          * ignore all
537          */
538
539         printf("testing OggFLAC__stream_decoder_set_metadata_ignore_all()... ");
540         if(!OggFLAC__stream_decoder_set_metadata_ignore_all(decoder))
541                 return die_s_("returned false", decoder);
542         printf("OK\n");
543
544         num_expected_ = 0;
545
546         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
547                 return false;
548
549         /*
550          * respond all, ignore VORBIS_COMMENT
551          */
552
553         printf("testing OggFLAC__stream_decoder_set_metadata_respond_all()... ");
554         if(!OggFLAC__stream_decoder_set_metadata_respond_all(decoder))
555                 return die_s_("returned false", decoder);
556         printf("OK\n");
557
558         printf("testing OggFLAC__stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... ");
559         if(!OggFLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
560                 return die_s_("returned false", decoder);
561         printf("OK\n");
562
563         num_expected_ = 0;
564         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
565         expected_metadata_sequence_[num_expected_++] = &padding_;
566         expected_metadata_sequence_[num_expected_++] = &seektable_;
567         expected_metadata_sequence_[num_expected_++] = &application1_;
568         expected_metadata_sequence_[num_expected_++] = &application2_;
569
570         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
571                 return false;
572
573         /*
574          * respond all, ignore APPLICATION
575          */
576
577         printf("testing OggFLAC__stream_decoder_set_metadata_respond_all()... ");
578         if(!OggFLAC__stream_decoder_set_metadata_respond_all(decoder))
579                 return die_s_("returned false", decoder);
580         printf("OK\n");
581
582         printf("testing OggFLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
583         if(!OggFLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
584                 return die_s_("returned false", decoder);
585         printf("OK\n");
586
587         num_expected_ = 0;
588         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
589         expected_metadata_sequence_[num_expected_++] = &padding_;
590         expected_metadata_sequence_[num_expected_++] = &seektable_;
591         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
592
593         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
594                 return false;
595
596         /*
597          * respond all, ignore APPLICATION id of app#1
598          */
599
600         printf("testing OggFLAC__stream_decoder_set_metadata_respond_all()... ");
601         if(!OggFLAC__stream_decoder_set_metadata_respond_all(decoder))
602                 return die_s_("returned false", decoder);
603         printf("OK\n");
604
605         printf("testing OggFLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
606         if(!OggFLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
607                 return die_s_("returned false", decoder);
608         printf("OK\n");
609
610         num_expected_ = 0;
611         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
612         expected_metadata_sequence_[num_expected_++] = &padding_;
613         expected_metadata_sequence_[num_expected_++] = &seektable_;
614         expected_metadata_sequence_[num_expected_++] = &application2_;
615         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
616
617         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
618                 return false;
619
620         /*
621          * respond all, ignore APPLICATION id of app#1 & app#2
622          */
623
624         printf("testing OggFLAC__stream_decoder_set_metadata_respond_all()... ");
625         if(!OggFLAC__stream_decoder_set_metadata_respond_all(decoder))
626                 return die_s_("returned false", decoder);
627         printf("OK\n");
628
629         printf("testing OggFLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
630         if(!OggFLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
631                 return die_s_("returned false", decoder);
632         printf("OK\n");
633
634         printf("testing OggFLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... ");
635         if(!OggFLAC__stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id))
636                 return die_s_("returned false", decoder);
637         printf("OK\n");
638
639         num_expected_ = 0;
640         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
641         expected_metadata_sequence_[num_expected_++] = &padding_;
642         expected_metadata_sequence_[num_expected_++] = &seektable_;
643         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
644
645         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
646                 return false;
647
648         /*
649          * ignore all, respond VORBIS_COMMENT
650          */
651
652         printf("testing OggFLAC__stream_decoder_set_metadata_ignore_all()... ");
653         if(!OggFLAC__stream_decoder_set_metadata_ignore_all(decoder))
654                 return die_s_("returned false", decoder);
655         printf("OK\n");
656
657         printf("testing OggFLAC__stream_decoder_set_metadata_respond(VORBIS_COMMENT)... ");
658         if(!OggFLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
659                 return die_s_("returned false", decoder);
660         printf("OK\n");
661
662         num_expected_ = 0;
663         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
664
665         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
666                 return false;
667
668         /*
669          * ignore all, respond APPLICATION
670          */
671
672         printf("testing OggFLAC__stream_decoder_set_metadata_ignore_all()... ");
673         if(!OggFLAC__stream_decoder_set_metadata_ignore_all(decoder))
674                 return die_s_("returned false", decoder);
675         printf("OK\n");
676
677         printf("testing OggFLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
678         if(!OggFLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION))
679                 return die_s_("returned false", decoder);
680         printf("OK\n");
681
682         num_expected_ = 0;
683         expected_metadata_sequence_[num_expected_++] = &application1_;
684         expected_metadata_sequence_[num_expected_++] = &application2_;
685
686         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
687                 return false;
688
689         /*
690          * ignore all, respond APPLICATION id of app#1
691          */
692
693         printf("testing OggFLAC__stream_decoder_set_metadata_ignore_all()... ");
694         if(!OggFLAC__stream_decoder_set_metadata_ignore_all(decoder))
695                 return die_s_("returned false", decoder);
696         printf("OK\n");
697
698         printf("testing OggFLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
699         if(!OggFLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
700                 return die_s_("returned false", decoder);
701         printf("OK\n");
702
703         num_expected_ = 0;
704         expected_metadata_sequence_[num_expected_++] = &application1_;
705
706         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
707                 return false;
708
709         /*
710          * ignore all, respond APPLICATION id of app#1 & app#2
711          */
712
713         printf("testing OggFLAC__stream_decoder_set_metadata_ignore_all()... ");
714         if(!OggFLAC__stream_decoder_set_metadata_ignore_all(decoder))
715                 return die_s_("returned false", decoder);
716         printf("OK\n");
717
718         printf("testing OggFLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
719         if(!OggFLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
720                 return die_s_("returned false", decoder);
721         printf("OK\n");
722
723         printf("testing OggFLAC__stream_decoder_set_metadata_respond_application(of app block #2)... ");
724         if(!OggFLAC__stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id))
725                 return die_s_("returned false", decoder);
726         printf("OK\n");
727
728         num_expected_ = 0;
729         expected_metadata_sequence_[num_expected_++] = &application1_;
730         expected_metadata_sequence_[num_expected_++] = &application2_;
731
732         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
733                 return false;
734
735         /*
736          * respond all, ignore APPLICATION, respond APPLICATION id of app#1
737          */
738
739         printf("testing OggFLAC__stream_decoder_set_metadata_respond_all()... ");
740         if(!OggFLAC__stream_decoder_set_metadata_respond_all(decoder))
741                 return die_s_("returned false", decoder);
742         printf("OK\n");
743
744         printf("testing OggFLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
745         if(!OggFLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
746                 return die_s_("returned false", decoder);
747         printf("OK\n");
748
749         printf("testing OggFLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
750         if(!OggFLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
751                 return die_s_("returned false", decoder);
752         printf("OK\n");
753
754         num_expected_ = 0;
755         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
756         expected_metadata_sequence_[num_expected_++] = &padding_;
757         expected_metadata_sequence_[num_expected_++] = &seektable_;
758         expected_metadata_sequence_[num_expected_++] = &application1_;
759         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
760
761         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
762                 return false;
763
764         /*
765          * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
766          */
767
768         printf("testing OggFLAC__stream_decoder_set_metadata_ignore_all()... ");
769         if(!OggFLAC__stream_decoder_set_metadata_ignore_all(decoder))
770                 return die_s_("returned false", decoder);
771         printf("OK\n");
772
773         printf("testing OggFLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
774         if(!OggFLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION))
775                 return die_s_("returned false", decoder);
776         printf("OK\n");
777
778         printf("testing OggFLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
779         if(!OggFLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
780                 return die_s_("returned false", decoder);
781         printf("OK\n");
782
783         num_expected_ = 0;
784         expected_metadata_sequence_[num_expected_++] = &application2_;
785
786         if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
787                 return false;
788
789         /* done, now leave the sequence the way we found it... */
790         num_expected_ = 0;
791         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
792         expected_metadata_sequence_[num_expected_++] = &padding_;
793         expected_metadata_sequence_[num_expected_++] = &seektable_;
794         expected_metadata_sequence_[num_expected_++] = &application1_;
795         expected_metadata_sequence_[num_expected_++] = &application2_;
796         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
797
798         printf("testing OggFLAC__stream_decoder_delete()... ");
799         OggFLAC__stream_decoder_delete(decoder);
800         printf("OK\n");
801
802         fclose(decoder_client_data.file);
803
804         printf("\nPASSED!\n");
805
806         return true;
807 }
808
809 FLAC__bool test_decoders()
810 {
811         init_metadata_blocks_();
812         if(!generate_file_())
813                 return false;
814
815         if(!test_stream_decoder())
816                 return false;
817
818         (void) grabbag__file_remove_file(oggflacfilename_);
819         free_metadata_blocks_();
820
821         return true;
822 }