Fix a couple of Windows 2Gig file size issues.
[flac.git] / src / test_libFLAC++ / decoders.cpp
blobf5b1d0b9de71008dcf93dda12d68f48fb82b5f26
1 /* test_libFLAC++ - Unit tester for libFLAC++
2 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Josh Coalson
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.
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.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #if HAVE_CONFIG_H
20 # include <config.h>
21 #endif
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/metadata.h" // for ::FLAC__metadata_object_is_equal()
30 #include "FLAC++/decoder.h"
31 #include "share/grabbag.h"
32 #include "share/compat.h"
33 extern "C" {
34 #include "test_libs_common/file_utils_flac.h"
35 #include "test_libs_common/metadata_utils.h"
38 #ifdef _MSC_VER
39 // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
40 #pragma warning ( disable : 4800 )
41 #endif
43 typedef enum {
44 LAYER_STREAM = 0, /* FLAC__stream_decoder_init_stream() without seeking */
45 LAYER_SEEKABLE_STREAM, /* FLAC__stream_decoder_init_stream() with seeking */
46 LAYER_FILE, /* FLAC__stream_decoder_init_FILE() */
47 LAYER_FILENAME /* FLAC__stream_decoder_init_file() */
48 } Layer;
50 static const char * const LayerString[] = {
51 "Stream",
52 "Seekable Stream",
53 "FILE*",
54 "Filename"
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 FLAC__off_t flacfilesize_;
62 static const char *flacfilename(bool is_ogg)
64 return is_ogg? "metadata.oga" : "metadata.flac";
67 static bool die_(const char *msg)
69 printf("ERROR: %s\n", msg);
70 return false;
73 static FLAC__bool die_s_(const char *msg, const FLAC::Decoder::Stream *decoder)
75 FLAC::Decoder::Stream::State state = decoder->get_state();
77 if(msg)
78 printf("FAILED, %s", msg);
79 else
80 printf("FAILED");
82 printf(", state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
84 return false;
87 static void init_metadata_blocks_()
89 mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
92 static void free_metadata_blocks_()
94 mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
97 static bool generate_file_(FLAC__bool is_ogg)
99 printf("\n\ngenerating %sFLAC file for decoder tests...\n", is_ogg? "Ogg ":"");
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 */
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");
115 return true;
119 class DecoderCommon {
120 public:
121 Layer layer_;
122 unsigned current_metadata_number_;
123 bool ignore_errors_;
124 bool error_occurred_;
126 DecoderCommon(Layer layer): layer_(layer), current_metadata_number_(0), ignore_errors_(false), error_occurred_(false) { }
127 ::FLAC__StreamDecoderWriteStatus common_write_callback_(const ::FLAC__Frame *frame);
128 void common_metadata_callback_(const ::FLAC__StreamMetadata *metadata);
129 void common_error_callback_(::FLAC__StreamDecoderErrorStatus status);
132 ::FLAC__StreamDecoderWriteStatus DecoderCommon::common_write_callback_(const ::FLAC__Frame *frame)
134 if(error_occurred_)
135 return ::FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
138 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
139 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
141 printf("content... ");
142 fflush(stdout);
145 return ::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
148 void DecoderCommon::common_metadata_callback_(const ::FLAC__StreamMetadata *metadata)
150 if(error_occurred_)
151 return;
153 printf("%d... ", current_metadata_number_);
154 fflush(stdout);
156 if(current_metadata_number_ >= num_expected_) {
157 (void)die_("got more metadata blocks than expected");
158 error_occurred_ = true;
160 else {
161 if(!::FLAC__metadata_object_is_equal(expected_metadata_sequence_[current_metadata_number_], metadata)) {
162 (void)die_("metadata block mismatch");
163 error_occurred_ = true;
166 current_metadata_number_++;
169 void DecoderCommon::common_error_callback_(::FLAC__StreamDecoderErrorStatus status)
171 if(!ignore_errors_) {
172 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, ::FLAC__StreamDecoderErrorStatusString[status]);
173 error_occurred_ = true;
177 class StreamDecoder : public FLAC::Decoder::Stream, public DecoderCommon {
178 public:
179 FILE *file_;
181 StreamDecoder(Layer layer): FLAC::Decoder::Stream(), DecoderCommon(layer), file_(0) { }
182 ~StreamDecoder() { }
184 // from FLAC::Decoder::Stream
185 ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes);
186 ::FLAC__StreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset);
187 ::FLAC__StreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset);
188 ::FLAC__StreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length);
189 bool eof_callback();
190 ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
191 void metadata_callback(const ::FLAC__StreamMetadata *metadata);
192 void error_callback(::FLAC__StreamDecoderErrorStatus status);
194 bool test_respond(bool is_ogg);
197 ::FLAC__StreamDecoderReadStatus StreamDecoder::read_callback(FLAC__byte buffer[], size_t *bytes)
199 const size_t requested_bytes = *bytes;
201 if(error_occurred_)
202 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT;
204 if(feof(file_)) {
205 *bytes = 0;
206 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
208 else if(requested_bytes > 0) {
209 *bytes = ::fread(buffer, 1, requested_bytes, file_);
210 if(*bytes == 0) {
211 if(feof(file_))
212 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
213 else
214 return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
216 else {
217 return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
220 else
221 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
224 ::FLAC__StreamDecoderSeekStatus StreamDecoder::seek_callback(FLAC__uint64 absolute_byte_offset)
226 if(layer_ == LAYER_STREAM)
227 return ::FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
229 if(error_occurred_)
230 return ::FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
232 if(fseeko(file_, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) {
233 error_occurred_ = true;
234 return ::FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
237 return ::FLAC__STREAM_DECODER_SEEK_STATUS_OK;
240 ::FLAC__StreamDecoderTellStatus StreamDecoder::tell_callback(FLAC__uint64 *absolute_byte_offset)
242 if(layer_ == LAYER_STREAM)
243 return ::FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
245 if(error_occurred_)
246 return ::FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
248 FLAC__off_t offset = ftello(file_);
249 *absolute_byte_offset = (FLAC__uint64)offset;
251 if(offset < 0) {
252 error_occurred_ = true;
253 return ::FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
256 return ::FLAC__STREAM_DECODER_TELL_STATUS_OK;
259 ::FLAC__StreamDecoderLengthStatus StreamDecoder::length_callback(FLAC__uint64 *stream_length)
261 if(layer_ == LAYER_STREAM)
262 return ::FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
264 if(error_occurred_)
265 return ::FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
267 *stream_length = (FLAC__uint64)flacfilesize_;
268 return ::FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
271 bool StreamDecoder::eof_callback()
273 if(layer_ == LAYER_STREAM)
274 return false;
276 if(error_occurred_)
277 return true;
279 return (bool)feof(file_);
282 ::FLAC__StreamDecoderWriteStatus StreamDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[])
284 (void)buffer;
286 return common_write_callback_(frame);
289 void StreamDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
291 common_metadata_callback_(metadata);
294 void StreamDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
296 common_error_callback_(status);
299 bool StreamDecoder::test_respond(bool is_ogg)
301 ::FLAC__StreamDecoderInitStatus init_status;
303 if(!set_md5_checking(true)) {
304 printf("FAILED at set_md5_checking(), returned false\n");
305 return false;
308 printf("testing init%s()... ", is_ogg? "_ogg":"");
309 init_status = is_ogg? init_ogg() : init();
310 if(init_status != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
311 return die_s_(0, this);
312 printf("OK\n");
314 current_metadata_number_ = 0;
316 if(fseeko(file_, 0, SEEK_SET) < 0) {
317 printf("FAILED rewinding input, errno = %d\n", errno);
318 return false;
321 printf("testing process_until_end_of_stream()... ");
322 if(!process_until_end_of_stream()) {
323 State state = get_state();
324 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
325 return false;
327 printf("OK\n");
329 printf("testing finish()... ");
330 if(!finish()) {
331 State state = get_state();
332 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
333 return false;
335 printf("OK\n");
337 return true;
340 class FileDecoder : public FLAC::Decoder::File, public DecoderCommon {
341 public:
342 FileDecoder(Layer layer): FLAC::Decoder::File(), DecoderCommon(layer) { }
343 ~FileDecoder() { }
345 // from FLAC::Decoder::Stream
346 ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
347 void metadata_callback(const ::FLAC__StreamMetadata *metadata);
348 void error_callback(::FLAC__StreamDecoderErrorStatus status);
350 bool test_respond(bool is_ogg);
353 ::FLAC__StreamDecoderWriteStatus FileDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[])
355 (void)buffer;
356 return common_write_callback_(frame);
359 void FileDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
361 common_metadata_callback_(metadata);
364 void FileDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
366 common_error_callback_(status);
369 bool FileDecoder::test_respond(bool is_ogg)
371 ::FLAC__StreamDecoderInitStatus init_status;
373 if(!set_md5_checking(true)) {
374 printf("FAILED at set_md5_checking(), returned false\n");
375 return false;
378 switch(layer_) {
379 case LAYER_FILE:
381 printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
382 FILE *file = ::fopen(flacfilename(is_ogg), "rb");
383 if(0 == file) {
384 printf("ERROR (%s)\n", strerror(errno));
385 return false;
387 printf("OK\n");
389 printf("testing init%s()... ", is_ogg? "_ogg":"");
390 init_status = is_ogg? init_ogg(file) : init(file);
392 break;
393 case LAYER_FILENAME:
394 printf("testing init%s()... ", is_ogg? "_ogg":"");
395 init_status = is_ogg? init_ogg(flacfilename(is_ogg)) : init(flacfilename(is_ogg));
396 break;
397 default:
398 die_("internal error 001");
399 return false;
401 if(init_status != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
402 return die_s_(0, this);
403 printf("OK\n");
405 current_metadata_number_ = 0;
407 printf("testing process_until_end_of_stream()... ");
408 if(!process_until_end_of_stream()) {
409 State state = get_state();
410 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
411 return false;
413 printf("OK\n");
415 printf("testing finish()... ");
416 if(!finish()) {
417 State state = get_state();
418 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
419 return false;
421 printf("OK\n");
423 return true;
427 static FLAC::Decoder::Stream *new_by_layer(Layer layer)
429 if(layer < LAYER_FILE)
430 return new StreamDecoder(layer);
431 else
432 return new FileDecoder(layer);
435 static bool test_stream_decoder(Layer layer, bool is_ogg)
437 FLAC::Decoder::Stream *decoder;
438 ::FLAC__StreamDecoderInitStatus init_status;
439 bool expect;
441 printf("\n+++ libFLAC++ unit test: FLAC::Decoder::%s (layer: %s, format: %s)\n\n", layer<LAYER_FILE? "Stream":"File", LayerString[layer], is_ogg? "Ogg FLAC" : "FLAC");
444 // test new -> delete
446 printf("allocating decoder instance... ");
447 decoder = new_by_layer(layer);
448 if(0 == decoder) {
449 printf("FAILED, new returned NULL\n");
450 return false;
452 printf("OK\n");
454 printf("testing is_valid()... ");
455 if(!decoder->is_valid()) {
456 printf("FAILED, returned false\n");
457 return false;
459 printf("OK\n");
461 printf("freeing decoder instance... ");
462 delete decoder;
463 printf("OK\n");
466 // test new -> init -> delete
468 printf("allocating decoder instance... ");
469 decoder = new_by_layer(layer);
470 if(0 == decoder) {
471 printf("FAILED, new returned NULL\n");
472 return false;
474 printf("OK\n");
476 printf("testing is_valid()... ");
477 if(!decoder->is_valid()) {
478 printf("FAILED, returned false\n");
479 return false;
481 printf("OK\n");
483 printf("testing init%s()... ", is_ogg? "_ogg":"");
484 switch(layer) {
485 case LAYER_STREAM:
486 case LAYER_SEEKABLE_STREAM:
487 dynamic_cast<StreamDecoder*>(decoder)->file_ = stdin;
488 init_status = is_ogg? decoder->init_ogg() : decoder->init();
489 break;
490 case LAYER_FILE:
491 init_status = is_ogg?
492 dynamic_cast<FLAC::Decoder::File*>(decoder)->init_ogg(stdin) :
493 dynamic_cast<FLAC::Decoder::File*>(decoder)->init(stdin);
494 break;
495 case LAYER_FILENAME:
496 init_status = is_ogg?
497 dynamic_cast<FLAC::Decoder::File*>(decoder)->init_ogg(flacfilename(is_ogg)) :
498 dynamic_cast<FLAC::Decoder::File*>(decoder)->init(flacfilename(is_ogg));
499 break;
500 default:
501 die_("internal error 006");
502 return false;
504 if(init_status != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
505 return die_s_(0, decoder);
506 printf("OK\n");
508 printf("freeing decoder instance... ");
509 delete decoder;
510 printf("OK\n");
513 // test normal usage
515 num_expected_ = 0;
516 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
518 printf("allocating decoder instance... ");
519 decoder = new_by_layer(layer);
520 if(0 == decoder) {
521 printf("FAILED, new returned NULL\n");
522 return false;
524 printf("OK\n");
526 printf("testing is_valid()... ");
527 if(!decoder->is_valid()) {
528 printf("FAILED, returned false\n");
529 return false;
531 printf("OK\n");
533 if(is_ogg) {
534 printf("testing set_ogg_serial_number()... ");
535 if(!decoder->set_ogg_serial_number(file_utils__ogg_serial_number))
536 return die_s_("returned false", decoder);
537 printf("OK\n");
540 if(!decoder->set_md5_checking(true)) {
541 printf("FAILED at set_md5_checking(), returned false\n");
542 return false;
545 switch(layer) {
546 case LAYER_STREAM:
547 case LAYER_SEEKABLE_STREAM:
548 printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
549 dynamic_cast<StreamDecoder*>(decoder)->file_ = ::fopen(flacfilename(is_ogg), "rb");
550 if(0 == dynamic_cast<StreamDecoder*>(decoder)->file_) {
551 printf("ERROR (%s)\n", strerror(errno));
552 return false;
554 printf("OK\n");
556 printf("testing init%s()... ", is_ogg? "_ogg":"");
557 init_status = is_ogg? decoder->init_ogg() : decoder->init();
558 break;
559 case LAYER_FILE:
561 printf("opening FLAC file... ");
562 FILE *file = ::fopen(flacfilename(is_ogg), "rb");
563 if(0 == file) {
564 printf("ERROR (%s)\n", strerror(errno));
565 return false;
567 printf("OK\n");
569 printf("testing init%s()... ", is_ogg? "_ogg":"");
570 init_status = is_ogg?
571 dynamic_cast<FLAC::Decoder::File*>(decoder)->init_ogg(file) :
572 dynamic_cast<FLAC::Decoder::File*>(decoder)->init(file);
574 break;
575 case LAYER_FILENAME:
576 printf("testing init%s()... ", is_ogg? "_ogg":"");
577 init_status = is_ogg?
578 dynamic_cast<FLAC::Decoder::File*>(decoder)->init_ogg(flacfilename(is_ogg)) :
579 dynamic_cast<FLAC::Decoder::File*>(decoder)->init(flacfilename(is_ogg));
580 break;
581 default:
582 die_("internal error 009");
583 return false;
585 if(init_status != ::FLAC__STREAM_DECODER_INIT_STATUS_OK)
586 return die_s_(0, decoder);
587 printf("OK\n");
589 printf("testing get_state()... ");
590 FLAC::Decoder::Stream::State state = decoder->get_state();
591 printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
593 dynamic_cast<DecoderCommon*>(decoder)->current_metadata_number_ = 0;
594 dynamic_cast<DecoderCommon*>(decoder)->ignore_errors_ = false;
595 dynamic_cast<DecoderCommon*>(decoder)->error_occurred_ = false;
597 printf("testing get_md5_checking()... ");
598 if(!decoder->get_md5_checking()) {
599 printf("FAILED, returned false, expected true\n");
600 return false;
602 printf("OK\n");
604 printf("testing process_until_end_of_metadata()... ");
605 if(!decoder->process_until_end_of_metadata())
606 return die_s_("returned false", decoder);
607 printf("OK\n");
609 printf("testing process_single()... ");
610 if(!decoder->process_single())
611 return die_s_("returned false", decoder);
612 printf("OK\n");
614 printf("testing skip_single_frame()... ");
615 if(!decoder->skip_single_frame())
616 return die_s_("returned false", decoder);
617 printf("OK\n");
619 if(layer < LAYER_FILE) {
620 printf("testing flush()... ");
621 if(!decoder->flush())
622 return die_s_("returned false", decoder);
623 printf("OK\n");
625 dynamic_cast<DecoderCommon*>(decoder)->ignore_errors_ = true;
626 printf("testing process_single()... ");
627 if(!decoder->process_single())
628 return die_s_("returned false", decoder);
629 printf("OK\n");
630 dynamic_cast<DecoderCommon*>(decoder)->ignore_errors_ = false;
633 expect = (layer != LAYER_STREAM);
634 printf("testing seek_absolute()... ");
635 if(decoder->seek_absolute(0) != expect)
636 return die_s_(expect? "returned false" : "returned true", decoder);
637 printf("OK\n");
639 printf("testing process_until_end_of_stream()... ");
640 if(!decoder->process_until_end_of_stream())
641 return die_s_("returned false", decoder);
642 printf("OK\n");
644 expect = (layer != LAYER_STREAM);
645 printf("testing seek_absolute()... ");
646 if(decoder->seek_absolute(0) != expect)
647 return die_s_(expect? "returned false" : "returned true", decoder);
648 printf("OK\n");
650 printf("testing get_channels()... ");
652 unsigned channels = decoder->get_channels();
653 if(channels != streaminfo_.data.stream_info.channels) {
654 printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
655 return false;
658 printf("OK\n");
660 printf("testing get_bits_per_sample()... ");
662 unsigned bits_per_sample = decoder->get_bits_per_sample();
663 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
664 printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
665 return false;
668 printf("OK\n");
670 printf("testing get_sample_rate()... ");
672 unsigned sample_rate = decoder->get_sample_rate();
673 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
674 printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
675 return false;
678 printf("OK\n");
680 printf("testing get_blocksize()... ");
682 unsigned blocksize = decoder->get_blocksize();
683 /* value could be anything since we're at the last block, so accept any reasonable answer */
684 printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED");
685 if(blocksize == 0)
686 return false;
689 printf("testing get_channel_assignment()... ");
691 ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment();
692 printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]);
695 if(layer < LAYER_FILE) {
696 printf("testing reset()... ");
697 if(!decoder->reset())
698 return die_s_("returned false", decoder);
699 printf("OK\n");
701 if(layer == LAYER_STREAM) {
702 /* after a reset() we have to rewind the input ourselves */
703 printf("rewinding input... ");
704 if(fseeko(dynamic_cast<StreamDecoder*>(decoder)->file_, 0, SEEK_SET) < 0) {
705 printf("FAILED, errno = %d\n", errno);
706 return false;
708 printf("OK\n");
711 dynamic_cast<DecoderCommon*>(decoder)->current_metadata_number_ = 0;
713 printf("testing process_until_end_of_stream()... ");
714 if(!decoder->process_until_end_of_stream())
715 return die_s_("returned false", decoder);
716 printf("OK\n");
719 printf("testing finish()... ");
720 if(!decoder->finish()) {
721 state = decoder->get_state();
722 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring());
723 return false;
725 printf("OK\n");
728 * respond all
731 printf("testing set_metadata_respond_all()... ");
732 if(!decoder->set_metadata_respond_all()) {
733 printf("FAILED, returned false\n");
734 return false;
736 printf("OK\n");
738 num_expected_ = 0;
739 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
740 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
741 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
742 expected_metadata_sequence_[num_expected_++] = &padding_;
743 expected_metadata_sequence_[num_expected_++] = &seektable_;
744 expected_metadata_sequence_[num_expected_++] = &application1_;
745 expected_metadata_sequence_[num_expected_++] = &application2_;
746 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
747 expected_metadata_sequence_[num_expected_++] = &picture_;
748 expected_metadata_sequence_[num_expected_++] = &unknown_;
750 else {
751 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
752 expected_metadata_sequence_[num_expected_++] = &padding_;
753 expected_metadata_sequence_[num_expected_++] = &seektable_;
754 expected_metadata_sequence_[num_expected_++] = &application1_;
755 expected_metadata_sequence_[num_expected_++] = &application2_;
756 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
757 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
758 expected_metadata_sequence_[num_expected_++] = &picture_;
759 expected_metadata_sequence_[num_expected_++] = &unknown_;
762 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
763 return false;
766 * ignore all
769 printf("testing set_metadata_ignore_all()... ");
770 if(!decoder->set_metadata_ignore_all()) {
771 printf("FAILED, returned false\n");
772 return false;
774 printf("OK\n");
776 num_expected_ = 0;
778 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
779 return false;
782 * respond all, ignore VORBIS_COMMENT
785 printf("testing set_metadata_respond_all()... ");
786 if(!decoder->set_metadata_respond_all()) {
787 printf("FAILED, returned false\n");
788 return false;
790 printf("OK\n");
792 printf("testing set_metadata_ignore(VORBIS_COMMENT)... ");
793 if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
794 printf("FAILED, returned false\n");
795 return false;
797 printf("OK\n");
799 num_expected_ = 0;
800 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
801 expected_metadata_sequence_[num_expected_++] = &padding_;
802 expected_metadata_sequence_[num_expected_++] = &seektable_;
803 expected_metadata_sequence_[num_expected_++] = &application1_;
804 expected_metadata_sequence_[num_expected_++] = &application2_;
805 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
806 expected_metadata_sequence_[num_expected_++] = &picture_;
807 expected_metadata_sequence_[num_expected_++] = &unknown_;
809 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
810 return false;
813 * respond all, ignore APPLICATION
816 printf("testing set_metadata_respond_all()... ");
817 if(!decoder->set_metadata_respond_all()) {
818 printf("FAILED, returned false\n");
819 return false;
821 printf("OK\n");
823 printf("testing set_metadata_ignore(APPLICATION)... ");
824 if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
825 printf("FAILED, returned false\n");
826 return false;
828 printf("OK\n");
830 num_expected_ = 0;
831 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
832 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
833 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
834 expected_metadata_sequence_[num_expected_++] = &padding_;
835 expected_metadata_sequence_[num_expected_++] = &seektable_;
836 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
837 expected_metadata_sequence_[num_expected_++] = &picture_;
838 expected_metadata_sequence_[num_expected_++] = &unknown_;
840 else {
841 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
842 expected_metadata_sequence_[num_expected_++] = &padding_;
843 expected_metadata_sequence_[num_expected_++] = &seektable_;
844 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
845 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
846 expected_metadata_sequence_[num_expected_++] = &picture_;
847 expected_metadata_sequence_[num_expected_++] = &unknown_;
850 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
851 return false;
854 * respond all, ignore APPLICATION id of app#1
857 printf("testing set_metadata_respond_all()... ");
858 if(!decoder->set_metadata_respond_all()) {
859 printf("FAILED, returned false\n");
860 return false;
862 printf("OK\n");
864 printf("testing set_metadata_ignore_application(of app block #1)... ");
865 if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
866 printf("FAILED, returned false\n");
867 return false;
869 printf("OK\n");
871 num_expected_ = 0;
872 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
873 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
874 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
875 expected_metadata_sequence_[num_expected_++] = &padding_;
876 expected_metadata_sequence_[num_expected_++] = &seektable_;
877 expected_metadata_sequence_[num_expected_++] = &application2_;
878 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
879 expected_metadata_sequence_[num_expected_++] = &picture_;
880 expected_metadata_sequence_[num_expected_++] = &unknown_;
882 else {
883 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
884 expected_metadata_sequence_[num_expected_++] = &padding_;
885 expected_metadata_sequence_[num_expected_++] = &seektable_;
886 expected_metadata_sequence_[num_expected_++] = &application2_;
887 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
888 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
889 expected_metadata_sequence_[num_expected_++] = &picture_;
890 expected_metadata_sequence_[num_expected_++] = &unknown_;
893 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
894 return false;
897 * respond all, ignore APPLICATION id of app#1 & app#2
900 printf("testing set_metadata_respond_all()... ");
901 if(!decoder->set_metadata_respond_all()) {
902 printf("FAILED, returned false\n");
903 return false;
905 printf("OK\n");
907 printf("testing set_metadata_ignore_application(of app block #1)... ");
908 if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
909 printf("FAILED, returned false\n");
910 return false;
912 printf("OK\n");
914 printf("testing set_metadata_ignore_application(of app block #2)... ");
915 if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) {
916 printf("FAILED, returned false\n");
917 return false;
919 printf("OK\n");
921 num_expected_ = 0;
922 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
923 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
924 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
925 expected_metadata_sequence_[num_expected_++] = &padding_;
926 expected_metadata_sequence_[num_expected_++] = &seektable_;
927 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
928 expected_metadata_sequence_[num_expected_++] = &picture_;
929 expected_metadata_sequence_[num_expected_++] = &unknown_;
931 else {
932 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
933 expected_metadata_sequence_[num_expected_++] = &padding_;
934 expected_metadata_sequence_[num_expected_++] = &seektable_;
935 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
936 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
937 expected_metadata_sequence_[num_expected_++] = &picture_;
938 expected_metadata_sequence_[num_expected_++] = &unknown_;
941 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
942 return false;
945 * ignore all, respond VORBIS_COMMENT
948 printf("testing set_metadata_ignore_all()... ");
949 if(!decoder->set_metadata_ignore_all()) {
950 printf("FAILED, returned false\n");
951 return false;
953 printf("OK\n");
955 printf("testing set_metadata_respond(VORBIS_COMMENT)... ");
956 if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
957 printf("FAILED, returned false\n");
958 return false;
960 printf("OK\n");
962 num_expected_ = 0;
963 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
965 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
966 return false;
969 * ignore all, respond APPLICATION
972 printf("testing set_metadata_ignore_all()... ");
973 if(!decoder->set_metadata_ignore_all()) {
974 printf("FAILED, returned false\n");
975 return false;
977 printf("OK\n");
979 printf("testing set_metadata_respond(APPLICATION)... ");
980 if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
981 printf("FAILED, returned false\n");
982 return false;
984 printf("OK\n");
986 num_expected_ = 0;
987 expected_metadata_sequence_[num_expected_++] = &application1_;
988 expected_metadata_sequence_[num_expected_++] = &application2_;
990 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
991 return false;
994 * ignore all, respond APPLICATION id of app#1
997 printf("testing set_metadata_ignore_all()... ");
998 if(!decoder->set_metadata_ignore_all()) {
999 printf("FAILED, returned false\n");
1000 return false;
1002 printf("OK\n");
1004 printf("testing set_metadata_respond_application(of app block #1)... ");
1005 if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
1006 printf("FAILED, returned false\n");
1007 return false;
1009 printf("OK\n");
1011 num_expected_ = 0;
1012 expected_metadata_sequence_[num_expected_++] = &application1_;
1014 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
1015 return false;
1018 * ignore all, respond APPLICATION id of app#1 & app#2
1021 printf("testing set_metadata_ignore_all()... ");
1022 if(!decoder->set_metadata_ignore_all()) {
1023 printf("FAILED, returned false\n");
1024 return false;
1026 printf("OK\n");
1028 printf("testing set_metadata_respond_application(of app block #1)... ");
1029 if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
1030 printf("FAILED, returned false\n");
1031 return false;
1033 printf("OK\n");
1035 printf("testing set_metadata_respond_application(of app block #2)... ");
1036 if(!decoder->set_metadata_respond_application(application2_.data.application.id)) {
1037 printf("FAILED, returned false\n");
1038 return false;
1040 printf("OK\n");
1042 num_expected_ = 0;
1043 expected_metadata_sequence_[num_expected_++] = &application1_;
1044 expected_metadata_sequence_[num_expected_++] = &application2_;
1046 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
1047 return false;
1050 * respond all, ignore APPLICATION, respond APPLICATION id of app#1
1053 printf("testing set_metadata_respond_all()... ");
1054 if(!decoder->set_metadata_respond_all()) {
1055 printf("FAILED, returned false\n");
1056 return false;
1058 printf("OK\n");
1060 printf("testing set_metadata_ignore(APPLICATION)... ");
1061 if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
1062 printf("FAILED, returned false\n");
1063 return false;
1065 printf("OK\n");
1067 printf("testing set_metadata_respond_application(of app block #1)... ");
1068 if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
1069 printf("FAILED, returned false\n");
1070 return false;
1072 printf("OK\n");
1074 num_expected_ = 0;
1075 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
1076 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1077 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1078 expected_metadata_sequence_[num_expected_++] = &padding_;
1079 expected_metadata_sequence_[num_expected_++] = &seektable_;
1080 expected_metadata_sequence_[num_expected_++] = &application1_;
1081 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1082 expected_metadata_sequence_[num_expected_++] = &picture_;
1083 expected_metadata_sequence_[num_expected_++] = &unknown_;
1085 else {
1086 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
1087 expected_metadata_sequence_[num_expected_++] = &padding_;
1088 expected_metadata_sequence_[num_expected_++] = &seektable_;
1089 expected_metadata_sequence_[num_expected_++] = &application1_;
1090 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
1091 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
1092 expected_metadata_sequence_[num_expected_++] = &picture_;
1093 expected_metadata_sequence_[num_expected_++] = &unknown_;
1096 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
1097 return false;
1100 * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
1103 printf("testing set_metadata_ignore_all()... ");
1104 if(!decoder->set_metadata_ignore_all()) {
1105 printf("FAILED, returned false\n");
1106 return false;
1108 printf("OK\n");
1110 printf("testing set_metadata_respond(APPLICATION)... ");
1111 if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
1112 printf("FAILED, returned false\n");
1113 return false;
1115 printf("OK\n");
1117 printf("testing set_metadata_ignore_application(of app block #1)... ");
1118 if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
1119 printf("FAILED, returned false\n");
1120 return false;
1122 printf("OK\n");
1124 num_expected_ = 0;
1125 expected_metadata_sequence_[num_expected_++] = &application2_;
1127 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg)))
1128 return false;
1130 if(layer < LAYER_FILE) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */
1131 ::fclose(dynamic_cast<StreamDecoder*>(decoder)->file_);
1133 printf("freeing decoder instance... ");
1134 delete decoder;
1135 printf("OK\n");
1137 printf("\nPASSED!\n");
1139 return true;
1142 bool test_decoders()
1144 FLAC__bool is_ogg = false;
1146 while(1) {
1147 init_metadata_blocks_();
1149 if(!generate_file_(is_ogg))
1150 return false;
1152 if(!test_stream_decoder(LAYER_STREAM, is_ogg))
1153 return false;
1155 if(!test_stream_decoder(LAYER_SEEKABLE_STREAM, is_ogg))
1156 return false;
1158 if(!test_stream_decoder(LAYER_FILE, is_ogg))
1159 return false;
1161 if(!test_stream_decoder(LAYER_FILENAME, is_ogg))
1162 return false;
1164 (void) grabbag__file_remove_file(flacfilename(is_ogg));
1166 free_metadata_blocks_();
1168 if(!FLAC_API_SUPPORTS_OGG_FLAC || is_ogg)
1169 break;
1170 is_ogg = true;
1173 return true;