src/test_libFLAC/decoders.c : Minor improvement.
[flac.git] / src / test_libFLAC / decoders.c
blob100318e4f5e236d6b84c716d7b22ee3354004524
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/stream_decoder.h"
30 #include "share/grabbag.h"
31 #include "share/compat.h"
32 #include "share/safe_str.h"
33 #include "test_libs_common/file_utils_flac.h"
34 #include "test_libs_common/metadata_utils.h"
36 typedef enum {
37 LAYER_STREAM = 0, /* FLAC__stream_decoder_init_[ogg_]stream() without seeking */
38 LAYER_SEEKABLE_STREAM, /* FLAC__stream_decoder_init_[ogg_]stream() with seeking */
39 LAYER_FILE, /* FLAC__stream_decoder_init_[ogg_]FILE() */
40 LAYER_FILENAME /* FLAC__stream_decoder_init_[ogg_]file() */
41 } Layer;
43 static const char * const LayerString[] = {
44 "Stream",
45 "Seekable Stream",
46 "FILE*",
47 "Filename"
50 typedef struct {
51 Layer layer;
52 FILE *file;
53 char filename[512];
54 unsigned current_metadata_number;
55 FLAC__bool ignore_errors;
56 FLAC__bool error_occurred;
57 } StreamDecoderClientData;
59 static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, picture_, unknown_;
60 static FLAC__StreamMetadata *expected_metadata_sequence_[9];
61 static unsigned num_expected_;
62 static FLAC__off_t flacfilesize_;
64 static const char *flacfilename(FLAC__bool is_ogg)
66 return is_ogg? "metadata.oga" : "metadata.flac";
69 static FLAC__bool die_(const char *msg)
71 printf("ERROR: %s\n", msg);
72 return false;
75 static FLAC__bool die_s_(const char *msg, const FLAC__StreamDecoder *decoder)
77 FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(decoder);
79 if(msg)
80 printf("FAILED, %s", msg);
81 else
82 printf("FAILED");
84 printf(", state = %u (%s)\n", (unsigned)state, FLAC__StreamDecoderStateString[state]);
86 return false;
89 static void open_test_file(StreamDecoderClientData * pdcd, int is_ogg, const char * mode)
91 pdcd->file = fopen(flacfilename(is_ogg), mode);
92 safe_strncpy(pdcd->filename, flacfilename(is_ogg), sizeof (pdcd->filename));
95 static void init_metadata_blocks_(void)
97 mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
100 static void free_metadata_blocks_(void)
102 mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
105 static FLAC__bool generate_file_(FLAC__bool is_ogg)
107 printf("\n\ngenerating %sFLAC file for decoder tests...\n", is_ogg? "Ogg ":"");
109 num_expected_ = 0;
110 expected_metadata_sequence_[num_expected_++] = &padding_;
111 expected_metadata_sequence_[num_expected_++] = &seektable_;
112 expected_metadata_sequence_[num_expected_++] = &application1_;
113 expected_metadata_sequence_[num_expected_++] = &application2_;
114 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
115 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
116 expected_metadata_sequence_[num_expected_++] = &picture_;
117 expected_metadata_sequence_[num_expected_++] = &unknown_;
118 /* WATCHOUT: for Ogg FLAC the encoder should move the VORBIS_COMMENT block to the front, right after STREAMINFO */
120 if(!file_utils__generate_flacfile(is_ogg, flacfilename(is_ogg), &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
121 return die_("creating the encoded file");
123 return true;
126 static FLAC__StreamDecoderReadStatus stream_decoder_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
128 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
129 const size_t requested_bytes = *bytes;
131 (void)decoder;
133 if(0 == dcd) {
134 printf("ERROR: client_data in read callback is NULL\n");
135 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
138 if(dcd->error_occurred)
139 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
141 if(feof(dcd->file)) {
142 *bytes = 0;
143 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
145 else if(requested_bytes > 0) {
146 *bytes = fread(buffer, 1, requested_bytes, dcd->file);
147 if(*bytes == 0) {
148 if(feof(dcd->file))
149 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
150 else
151 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
153 else {
154 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
157 else
158 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
161 static FLAC__StreamDecoderSeekStatus stream_decoder_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
163 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
165 (void)decoder;
167 if(0 == dcd) {
168 printf("ERROR: client_data in seek callback is NULL\n");
169 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
172 if(dcd->error_occurred)
173 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
175 if(fseeko(dcd->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) {
176 dcd->error_occurred = true;
177 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
180 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
183 static FLAC__StreamDecoderTellStatus stream_decoder_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
185 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
186 FLAC__off_t offset;
188 (void)decoder;
190 if(0 == dcd) {
191 printf("ERROR: client_data in tell callback is NULL\n");
192 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
195 if(dcd->error_occurred)
196 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
198 offset = ftello(dcd->file);
199 *absolute_byte_offset = (FLAC__uint64)offset;
201 if(offset < 0) {
202 dcd->error_occurred = true;
203 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
206 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
209 static FLAC__StreamDecoderLengthStatus stream_decoder_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
211 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
213 (void)decoder;
215 if(0 == dcd) {
216 printf("ERROR: client_data in length callback is NULL\n");
217 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
220 if(dcd->error_occurred)
221 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
223 *stream_length = (FLAC__uint64)flacfilesize_;
224 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
227 static FLAC__bool stream_decoder_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data)
229 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
231 (void)decoder;
233 if(0 == dcd) {
234 printf("ERROR: client_data in eof callback is NULL\n");
235 return true;
238 if(dcd->error_occurred)
239 return true;
241 return feof(dcd->file);
244 static FLAC__StreamDecoderWriteStatus stream_decoder_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
246 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
248 (void)decoder, (void)buffer;
250 if(0 == dcd) {
251 printf("ERROR: client_data in write callback is NULL\n");
252 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
255 if(dcd->error_occurred)
256 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
259 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
260 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
262 printf("content... ");
263 fflush(stdout);
266 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
269 static void stream_decoder_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
271 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
273 (void)decoder;
275 if(0 == dcd) {
276 printf("ERROR: client_data in metadata callback is NULL\n");
277 return;
280 if(dcd->error_occurred)
281 return;
283 printf("%d... ", dcd->current_metadata_number);
284 fflush(stdout);
286 if(dcd->current_metadata_number >= num_expected_) {
287 (void)die_("got more metadata blocks than expected");
288 dcd->error_occurred = true;
290 else {
291 if(!mutils__compare_block(expected_metadata_sequence_[dcd->current_metadata_number], metadata)) {
292 (void)die_("metadata block mismatch");
293 dcd->error_occurred = true;
296 dcd->current_metadata_number++;
299 static void stream_decoder_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
301 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
303 (void)decoder;
305 if(0 == dcd) {
306 printf("ERROR: client_data in error callback is NULL\n");
307 return;
310 if(!dcd->ignore_errors) {
311 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, FLAC__StreamDecoderErrorStatusString[status]);
312 dcd->error_occurred = true;
316 static FLAC__bool stream_decoder_test_respond_(FLAC__StreamDecoder *decoder, StreamDecoderClientData *dcd, FLAC__bool is_ogg)
318 FLAC__StreamDecoderInitStatus init_status;
320 if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
321 return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder);
323 /* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */
324 if(dcd->layer == LAYER_FILE) {
325 printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
326 open_test_file(dcd, is_ogg, "rb");
327 if(0 == dcd->file) {
328 printf("ERROR (%s)\n", strerror(errno));
329 return false;
331 printf("OK\n");
334 switch(dcd->layer) {
335 case LAYER_STREAM:
336 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
337 init_status = is_ogg?
338 FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
339 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)
341 break;
342 case LAYER_SEEKABLE_STREAM:
343 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
344 init_status = is_ogg?
345 FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, 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) :
346 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);
347 break;
348 case LAYER_FILE:
349 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
350 init_status = is_ogg?
351 FLAC__stream_decoder_init_ogg_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
352 FLAC__stream_decoder_init_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
353 break;
354 case LAYER_FILENAME:
355 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
356 init_status = is_ogg?
357 FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
358 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
359 break;
360 default:
361 die_("internal error 000");
362 return false;
364 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
365 return die_s_(0, decoder);
366 printf("OK\n");
368 dcd->current_metadata_number = 0;
370 if(dcd->layer < LAYER_FILE && fseeko(dcd->file, 0, SEEK_SET) < 0) {
371 printf("FAILED rewinding input, errno = %d\n", errno);
372 return false;
375 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
376 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
377 return die_s_("returned false", decoder);
378 printf("OK\n");
380 printf("testing FLAC__stream_decoder_finish()... ");
381 if(!FLAC__stream_decoder_finish(decoder))
382 return die_s_("returned false", decoder);
383 printf("OK\n");
385 return true;
388 static FLAC__bool test_stream_decoder(Layer layer, FLAC__bool is_ogg)
390 FLAC__StreamDecoder *decoder;
391 FLAC__StreamDecoderInitStatus init_status;
392 FLAC__StreamDecoderState state;
393 StreamDecoderClientData decoder_client_data;
394 FLAC__bool expect;
396 decoder_client_data.layer = layer;
398 printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString[layer], is_ogg? "Ogg FLAC" : "FLAC");
400 printf("testing FLAC__stream_decoder_new()... ");
401 decoder = FLAC__stream_decoder_new();
402 if(0 == decoder) {
403 printf("FAILED, returned NULL\n");
404 return false;
406 printf("OK\n");
408 printf("testing FLAC__stream_decoder_delete()... ");
409 FLAC__stream_decoder_delete(decoder);
410 printf("OK\n");
412 printf("testing FLAC__stream_decoder_new()... ");
413 decoder = FLAC__stream_decoder_new();
414 if(0 == decoder) {
415 printf("FAILED, returned NULL\n");
416 return false;
418 printf("OK\n");
420 switch(layer) {
421 case LAYER_STREAM:
422 case LAYER_SEEKABLE_STREAM:
423 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
424 init_status = is_ogg?
425 FLAC__stream_decoder_init_ogg_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0) :
426 FLAC__stream_decoder_init_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0);
427 break;
428 case LAYER_FILE:
429 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
430 init_status = is_ogg?
431 FLAC__stream_decoder_init_ogg_FILE(decoder, stdin, 0, 0, 0, 0) :
432 FLAC__stream_decoder_init_FILE(decoder, stdin, 0, 0, 0, 0);
433 break;
434 case LAYER_FILENAME:
435 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
436 init_status = is_ogg?
437 FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0) :
438 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0);
439 break;
440 default:
441 die_("internal error 003");
442 return false;
444 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS)
445 return die_s_(0, decoder);
446 printf("OK\n");
448 printf("testing FLAC__stream_decoder_delete()... ");
449 FLAC__stream_decoder_delete(decoder);
450 printf("OK\n");
452 num_expected_ = 0;
453 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
455 printf("testing FLAC__stream_decoder_new()... ");
456 decoder = FLAC__stream_decoder_new();
457 if(0 == decoder) {
458 printf("FAILED, returned NULL\n");
459 return false;
461 printf("OK\n");
463 if(is_ogg) {
464 printf("testing FLAC__stream_decoder_set_ogg_serial_number()... ");
465 if(!FLAC__stream_decoder_set_ogg_serial_number(decoder, file_utils__ogg_serial_number))
466 return die_s_("returned false", decoder);
467 printf("OK\n");
470 printf("testing FLAC__stream_decoder_set_md5_checking()... ");
471 if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
472 return die_s_("returned false", decoder);
473 printf("OK\n");
475 if(layer < LAYER_FILENAME) {
476 printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
477 open_test_file(&decoder_client_data, is_ogg, "rb");
478 if(0 == decoder_client_data.file) {
479 printf("ERROR (%s)\n", strerror(errno));
480 return false;
482 printf("OK\n");
485 switch(layer) {
486 case LAYER_STREAM:
487 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
488 init_status = is_ogg?
489 FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
490 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);
491 break;
492 case LAYER_SEEKABLE_STREAM:
493 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
494 init_status = is_ogg?
495 FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
496 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);
497 break;
498 case LAYER_FILE:
499 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
500 init_status = is_ogg?
501 FLAC__stream_decoder_init_ogg_FILE(decoder, decoder_client_data.file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
502 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);
503 break;
504 case LAYER_FILENAME:
505 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
506 init_status = is_ogg?
507 FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
508 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
509 break;
510 default:
511 die_("internal error 009");
512 return false;
514 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
515 return die_s_(0, decoder);
516 printf("OK\n");
518 printf("testing FLAC__stream_decoder_get_state()... ");
519 state = FLAC__stream_decoder_get_state(decoder);
520 printf("returned state = %u (%s)... OK\n", state, FLAC__StreamDecoderStateString[state]);
522 decoder_client_data.current_metadata_number = 0;
523 decoder_client_data.ignore_errors = false;
524 decoder_client_data.error_occurred = false;
526 printf("testing FLAC__stream_decoder_get_md5_checking()... ");
527 if(!FLAC__stream_decoder_get_md5_checking(decoder)) {
528 printf("FAILED, returned false, expected true\n");
529 return false;
531 printf("OK\n");
533 printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... ");
534 if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
535 return die_s_("returned false", decoder);
536 printf("OK\n");
538 printf("testing FLAC__stream_decoder_process_single()... ");
539 if(!FLAC__stream_decoder_process_single(decoder))
540 return die_s_("returned false", decoder);
541 printf("OK\n");
543 printf("testing FLAC__stream_decoder_skip_single_frame()... ");
544 if(!FLAC__stream_decoder_skip_single_frame(decoder))
545 return die_s_("returned false", decoder);
546 printf("OK\n");
548 if(layer < LAYER_FILE) {
549 printf("testing FLAC__stream_decoder_flush()... ");
550 if(!FLAC__stream_decoder_flush(decoder))
551 return die_s_("returned false", decoder);
552 printf("OK\n");
554 decoder_client_data.ignore_errors = true;
555 printf("testing FLAC__stream_decoder_process_single()... ");
556 if(!FLAC__stream_decoder_process_single(decoder))
557 return die_s_("returned false", decoder);
558 printf("OK\n");
559 decoder_client_data.ignore_errors = false;
562 expect = (layer != LAYER_STREAM);
563 printf("testing FLAC__stream_decoder_seek_absolute()... ");
564 if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
565 return die_s_(expect? "returned false" : "returned true", decoder);
566 printf("OK\n");
568 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
569 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
570 return die_s_("returned false", decoder);
571 printf("OK\n");
573 expect = (layer != LAYER_STREAM);
574 printf("testing FLAC__stream_decoder_seek_absolute()... ");
575 if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
576 return die_s_(expect? "returned false" : "returned true", decoder);
577 printf("OK\n");
579 printf("testing FLAC__stream_decoder_get_channels()... ");
581 unsigned channels = FLAC__stream_decoder_get_channels(decoder);
582 if(channels != streaminfo_.data.stream_info.channels) {
583 printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
584 return false;
587 printf("OK\n");
589 printf("testing FLAC__stream_decoder_get_bits_per_sample()... ");
591 unsigned bits_per_sample = FLAC__stream_decoder_get_bits_per_sample(decoder);
592 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
593 printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
594 return false;
597 printf("OK\n");
599 printf("testing FLAC__stream_decoder_get_sample_rate()... ");
601 unsigned sample_rate = FLAC__stream_decoder_get_sample_rate(decoder);
602 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
603 printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
604 return false;
607 printf("OK\n");
609 printf("testing FLAC__stream_decoder_get_blocksize()... ");
611 unsigned blocksize = FLAC__stream_decoder_get_blocksize(decoder);
612 /* value could be anything since we're at the last block, so accept any reasonable answer */
613 printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED");
614 if(blocksize == 0)
615 return false;
618 printf("testing FLAC__stream_decoder_get_channel_assignment()... ");
620 FLAC__ChannelAssignment ca = FLAC__stream_decoder_get_channel_assignment(decoder);
621 printf("returned %u (%s)... OK\n", (unsigned)ca, FLAC__ChannelAssignmentString[ca]);
624 if(layer < LAYER_FILE) {
625 printf("testing FLAC__stream_decoder_reset()... ");
626 if(!FLAC__stream_decoder_reset(decoder)) {
627 state = FLAC__stream_decoder_get_state(decoder);
628 printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]);
629 return false;
631 printf("OK\n");
633 if(layer == LAYER_STREAM) {
634 /* after a reset() we have to rewind the input ourselves */
635 printf("rewinding input... ");
636 if(fseeko(decoder_client_data.file, 0, SEEK_SET) < 0) {
637 printf("FAILED, errno = %d\n", errno);
638 return false;
640 printf("OK\n");
643 decoder_client_data.current_metadata_number = 0;
645 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
646 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
647 return die_s_("returned false", decoder);
648 printf("OK\n");
651 printf("testing FLAC__stream_decoder_finish()... ");
652 if(!FLAC__stream_decoder_finish(decoder))
653 return die_s_("returned false", decoder);
654 printf("OK\n");
657 * respond all
660 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
661 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
662 return die_s_("returned false", decoder);
663 printf("OK\n");
665 num_expected_ = 0;
666 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
667 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
668 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
669 expected_metadata_sequence_[num_expected_++] = &padding_;
670 expected_metadata_sequence_[num_expected_++] = &seektable_;
671 expected_metadata_sequence_[num_expected_++] = &application1_;
672 expected_metadata_sequence_[num_expected_++] = &application2_;
673 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
674 expected_metadata_sequence_[num_expected_++] = &picture_;
675 expected_metadata_sequence_[num_expected_++] = &unknown_;
677 else {
678 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
679 expected_metadata_sequence_[num_expected_++] = &padding_;
680 expected_metadata_sequence_[num_expected_++] = &seektable_;
681 expected_metadata_sequence_[num_expected_++] = &application1_;
682 expected_metadata_sequence_[num_expected_++] = &application2_;
683 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
684 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
685 expected_metadata_sequence_[num_expected_++] = &picture_;
686 expected_metadata_sequence_[num_expected_++] = &unknown_;
689 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
690 return false;
693 * ignore all
696 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
697 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
698 return die_s_("returned false", decoder);
699 printf("OK\n");
701 num_expected_ = 0;
703 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
704 return false;
707 * respond all, ignore VORBIS_COMMENT
710 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
711 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
712 return die_s_("returned false", decoder);
713 printf("OK\n");
715 printf("testing FLAC__stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... ");
716 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
717 return die_s_("returned false", decoder);
718 printf("OK\n");
720 num_expected_ = 0;
721 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
722 expected_metadata_sequence_[num_expected_++] = &padding_;
723 expected_metadata_sequence_[num_expected_++] = &seektable_;
724 expected_metadata_sequence_[num_expected_++] = &application1_;
725 expected_metadata_sequence_[num_expected_++] = &application2_;
726 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
727 expected_metadata_sequence_[num_expected_++] = &picture_;
728 expected_metadata_sequence_[num_expected_++] = &unknown_;
730 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
731 return false;
734 * respond all, ignore APPLICATION
737 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
738 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
739 return die_s_("returned false", decoder);
740 printf("OK\n");
742 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
743 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
744 return die_s_("returned false", decoder);
745 printf("OK\n");
747 num_expected_ = 0;
748 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
749 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
750 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
751 expected_metadata_sequence_[num_expected_++] = &padding_;
752 expected_metadata_sequence_[num_expected_++] = &seektable_;
753 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
754 expected_metadata_sequence_[num_expected_++] = &picture_;
755 expected_metadata_sequence_[num_expected_++] = &unknown_;
757 else {
758 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
759 expected_metadata_sequence_[num_expected_++] = &padding_;
760 expected_metadata_sequence_[num_expected_++] = &seektable_;
761 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
762 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
763 expected_metadata_sequence_[num_expected_++] = &picture_;
764 expected_metadata_sequence_[num_expected_++] = &unknown_;
767 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
768 return false;
771 * respond all, ignore APPLICATION id of app#1
774 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
775 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
776 return die_s_("returned false", decoder);
777 printf("OK\n");
779 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
780 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
781 return die_s_("returned false", decoder);
782 printf("OK\n");
784 num_expected_ = 0;
785 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
786 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
787 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
788 expected_metadata_sequence_[num_expected_++] = &padding_;
789 expected_metadata_sequence_[num_expected_++] = &seektable_;
790 expected_metadata_sequence_[num_expected_++] = &application2_;
791 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
792 expected_metadata_sequence_[num_expected_++] = &picture_;
793 expected_metadata_sequence_[num_expected_++] = &unknown_;
795 else {
796 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
797 expected_metadata_sequence_[num_expected_++] = &padding_;
798 expected_metadata_sequence_[num_expected_++] = &seektable_;
799 expected_metadata_sequence_[num_expected_++] = &application2_;
800 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
801 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
802 expected_metadata_sequence_[num_expected_++] = &picture_;
803 expected_metadata_sequence_[num_expected_++] = &unknown_;
806 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
807 return false;
810 * respond all, ignore APPLICATION id of app#1 & app#2
813 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
814 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
815 return die_s_("returned false", decoder);
816 printf("OK\n");
818 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
819 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
820 return die_s_("returned false", decoder);
821 printf("OK\n");
823 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... ");
824 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id))
825 return die_s_("returned false", decoder);
826 printf("OK\n");
828 num_expected_ = 0;
829 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
830 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
831 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
832 expected_metadata_sequence_[num_expected_++] = &padding_;
833 expected_metadata_sequence_[num_expected_++] = &seektable_;
834 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
835 expected_metadata_sequence_[num_expected_++] = &picture_;
836 expected_metadata_sequence_[num_expected_++] = &unknown_;
838 else {
839 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
840 expected_metadata_sequence_[num_expected_++] = &padding_;
841 expected_metadata_sequence_[num_expected_++] = &seektable_;
842 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
843 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
844 expected_metadata_sequence_[num_expected_++] = &picture_;
845 expected_metadata_sequence_[num_expected_++] = &unknown_;
848 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
849 return false;
852 * ignore all, respond VORBIS_COMMENT
855 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
856 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
857 return die_s_("returned false", decoder);
858 printf("OK\n");
860 printf("testing FLAC__stream_decoder_set_metadata_respond(VORBIS_COMMENT)... ");
861 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
862 return die_s_("returned false", decoder);
863 printf("OK\n");
865 num_expected_ = 0;
866 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
868 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
869 return false;
872 * ignore all, respond APPLICATION
875 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
876 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
877 return die_s_("returned false", decoder);
878 printf("OK\n");
880 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
881 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION))
882 return die_s_("returned false", decoder);
883 printf("OK\n");
885 num_expected_ = 0;
886 expected_metadata_sequence_[num_expected_++] = &application1_;
887 expected_metadata_sequence_[num_expected_++] = &application2_;
889 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
890 return false;
893 * ignore all, respond APPLICATION id of app#1
896 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
897 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
898 return die_s_("returned false", decoder);
899 printf("OK\n");
901 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
902 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
903 return die_s_("returned false", decoder);
904 printf("OK\n");
906 num_expected_ = 0;
907 expected_metadata_sequence_[num_expected_++] = &application1_;
909 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
910 return false;
913 * ignore all, respond APPLICATION id of app#1 & app#2
916 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
917 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
918 return die_s_("returned false", decoder);
919 printf("OK\n");
921 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
922 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
923 return die_s_("returned false", decoder);
924 printf("OK\n");
926 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #2)... ");
927 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id))
928 return die_s_("returned false", decoder);
929 printf("OK\n");
931 num_expected_ = 0;
932 expected_metadata_sequence_[num_expected_++] = &application1_;
933 expected_metadata_sequence_[num_expected_++] = &application2_;
935 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
936 return false;
939 * respond all, ignore APPLICATION, respond APPLICATION id of app#1
942 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
943 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
944 return die_s_("returned false", decoder);
945 printf("OK\n");
947 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
948 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
949 return die_s_("returned false", decoder);
950 printf("OK\n");
952 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
953 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
954 return die_s_("returned false", decoder);
955 printf("OK\n");
957 num_expected_ = 0;
958 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
959 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
960 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
961 expected_metadata_sequence_[num_expected_++] = &padding_;
962 expected_metadata_sequence_[num_expected_++] = &seektable_;
963 expected_metadata_sequence_[num_expected_++] = &application1_;
964 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
965 expected_metadata_sequence_[num_expected_++] = &picture_;
966 expected_metadata_sequence_[num_expected_++] = &unknown_;
968 else {
969 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
970 expected_metadata_sequence_[num_expected_++] = &padding_;
971 expected_metadata_sequence_[num_expected_++] = &seektable_;
972 expected_metadata_sequence_[num_expected_++] = &application1_;
973 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
974 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
975 expected_metadata_sequence_[num_expected_++] = &picture_;
976 expected_metadata_sequence_[num_expected_++] = &unknown_;
979 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
980 return false;
983 * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
986 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
987 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
988 return die_s_("returned false", decoder);
989 printf("OK\n");
991 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
992 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION))
993 return die_s_("returned false", decoder);
994 printf("OK\n");
996 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
997 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
998 return die_s_("returned false", decoder);
999 printf("OK\n");
1001 num_expected_ = 0;
1002 expected_metadata_sequence_[num_expected_++] = &application2_;
1004 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
1005 return false;
1007 if(layer < LAYER_FILE) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */
1008 fclose(decoder_client_data.file);
1010 printf("testing FLAC__stream_decoder_delete()... ");
1011 FLAC__stream_decoder_delete(decoder);
1012 printf("OK\n");
1014 printf("\nPASSED!\n");
1016 return true;
1019 FLAC__bool test_decoders(void)
1021 FLAC__bool is_ogg = false;
1023 while(1) {
1024 init_metadata_blocks_();
1026 if(!generate_file_(is_ogg))
1027 return false;
1029 if(!test_stream_decoder(LAYER_STREAM, is_ogg))
1030 return false;
1032 if(!test_stream_decoder(LAYER_SEEKABLE_STREAM, is_ogg))
1033 return false;
1035 if(!test_stream_decoder(LAYER_FILE, is_ogg))
1036 return false;
1038 if(!test_stream_decoder(LAYER_FILENAME, is_ogg))
1039 return false;
1041 (void) grabbag__file_remove_file(flacfilename(is_ogg));
1043 free_metadata_blocks_();
1045 if(!FLAC_API_SUPPORTS_OGG_FLAC || is_ogg)
1046 break;
1047 is_ogg = true;
1050 return true;