Integrate Github Actions
[flac.git] / src / test_libFLAC / decoders.c
blobe9d52e959a4276d6782ae7fe586fec312d4ac721
1 /* test_libFLAC - Unit tester for libFLAC
2 * Copyright (C) 2002-2009 Josh Coalson
3 * Copyright (C) 2011-2016 Xiph.Org Foundation
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #include <errno.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include "decoders.h"
29 #include "FLAC/assert.h"
30 #include "FLAC/stream_decoder.h"
31 #include "share/grabbag.h"
32 #include "share/compat.h"
33 #include "share/safe_str.h"
34 #include "test_libs_common/file_utils_flac.h"
35 #include "test_libs_common/metadata_utils.h"
37 typedef enum {
38 LAYER_STREAM = 0, /* FLAC__stream_decoder_init_[ogg_]stream() without seeking */
39 LAYER_SEEKABLE_STREAM, /* FLAC__stream_decoder_init_[ogg_]stream() with seeking */
40 LAYER_FILE, /* FLAC__stream_decoder_init_[ogg_]FILE() */
41 LAYER_FILENAME /* FLAC__stream_decoder_init_[ogg_]file() */
42 } Layer;
44 static const char * const LayerString[] = {
45 "Stream",
46 "Seekable Stream",
47 "FILE*",
48 "Filename"
51 typedef struct {
52 Layer layer;
53 FILE *file;
54 char filename[512];
55 uint32_t current_metadata_number;
56 FLAC__bool ignore_errors;
57 FLAC__bool error_occurred;
58 } StreamDecoderClientData;
60 static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, picture_, unknown_;
61 static FLAC__StreamMetadata *expected_metadata_sequence_[9];
62 static uint32_t num_expected_;
63 static FLAC__off_t flacfilesize_;
65 static const char *flacfilename(FLAC__bool is_ogg)
67 return is_ogg? "metadata.oga" : "metadata.flac";
70 static FLAC__bool die_(const char *msg)
72 printf("ERROR: %s\n", msg);
73 return false;
76 static FLAC__bool die_s_(const char *msg, const FLAC__StreamDecoder *decoder)
78 FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(decoder);
80 if(msg)
81 printf("FAILED, %s", msg);
82 else
83 printf("FAILED");
85 printf(", state = %u (%s)\n", (uint32_t)state, FLAC__StreamDecoderStateString[state]);
87 return false;
90 static void open_test_file(StreamDecoderClientData * pdcd, int is_ogg, const char * mode)
92 pdcd->file = flac_fopen(flacfilename(is_ogg), mode);
93 safe_strncpy(pdcd->filename, flacfilename(is_ogg), sizeof (pdcd->filename));
96 static void init_metadata_blocks_(void)
98 mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
101 static void free_metadata_blocks_(void)
103 mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
106 static FLAC__bool generate_file_(FLAC__bool is_ogg)
108 printf("\n\ngenerating %sFLAC file for decoder tests...\n", is_ogg? "Ogg ":"");
110 num_expected_ = 0;
111 expected_metadata_sequence_[num_expected_++] = &padding_;
112 expected_metadata_sequence_[num_expected_++] = &seektable_;
113 expected_metadata_sequence_[num_expected_++] = &application1_;
114 expected_metadata_sequence_[num_expected_++] = &application2_;
115 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
116 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
117 expected_metadata_sequence_[num_expected_++] = &picture_;
118 expected_metadata_sequence_[num_expected_++] = &unknown_;
119 /* WATCHOUT: for Ogg FLAC the encoder should move the VORBIS_COMMENT block to the front, right after STREAMINFO */
121 if(!file_utils__generate_flacfile(is_ogg, flacfilename(is_ogg), &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
122 return die_("creating the encoded file");
124 return true;
127 static FLAC__StreamDecoderReadStatus stream_decoder_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
129 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
130 const size_t requested_bytes = *bytes;
132 (void)decoder;
134 if(0 == dcd) {
135 printf("ERROR: client_data in read callback is NULL\n");
136 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
139 if(dcd->error_occurred)
140 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
142 if(feof(dcd->file)) {
143 *bytes = 0;
144 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
146 else if(requested_bytes > 0) {
147 *bytes = fread(buffer, 1, requested_bytes, dcd->file);
148 if(*bytes == 0) {
149 if(feof(dcd->file))
150 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
151 else
152 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
154 else {
155 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
158 else
159 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
162 static FLAC__StreamDecoderSeekStatus stream_decoder_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
164 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
166 (void)decoder;
168 if(0 == dcd) {
169 printf("ERROR: client_data in seek callback is NULL\n");
170 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
173 if(dcd->error_occurred)
174 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
176 if(fseeko(dcd->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) {
177 dcd->error_occurred = true;
178 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
181 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
184 static FLAC__StreamDecoderTellStatus stream_decoder_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
186 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
187 FLAC__off_t offset;
189 (void)decoder;
191 if(0 == dcd) {
192 printf("ERROR: client_data in tell callback is NULL\n");
193 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
196 if(dcd->error_occurred)
197 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
199 offset = ftello(dcd->file);
200 *absolute_byte_offset = (FLAC__uint64)offset;
202 if(offset < 0) {
203 dcd->error_occurred = true;
204 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
207 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
210 static FLAC__StreamDecoderLengthStatus stream_decoder_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
212 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
214 (void)decoder;
216 if(0 == dcd) {
217 printf("ERROR: client_data in length callback is NULL\n");
218 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
221 if(dcd->error_occurred)
222 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
224 *stream_length = (FLAC__uint64)flacfilesize_;
225 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
228 static FLAC__bool stream_decoder_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data)
230 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
232 (void)decoder;
234 if(0 == dcd) {
235 printf("ERROR: client_data in eof callback is NULL\n");
236 return true;
239 if(dcd->error_occurred)
240 return true;
242 return feof(dcd->file);
245 static FLAC__StreamDecoderWriteStatus stream_decoder_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
247 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
249 (void)decoder, (void)buffer;
251 if(0 == dcd) {
252 printf("ERROR: client_data in write callback is NULL\n");
253 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
256 if(dcd->error_occurred)
257 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
260 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
261 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
263 printf("content... ");
264 fflush(stdout);
267 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
270 static void stream_decoder_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
272 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
274 (void)decoder;
276 if(0 == dcd) {
277 printf("ERROR: client_data in metadata callback is NULL\n");
278 return;
281 if(dcd->error_occurred)
282 return;
284 if (metadata->type == FLAC__METADATA_TYPE_APPLICATION) {
285 printf ("%u ('%c%c%c%c')... ", dcd->current_metadata_number, metadata->data.application.id [0], metadata->data.application.id [1], metadata->data.application.id [2], metadata->data.application.id [3]);
287 else {
288 printf("%u... ", dcd->current_metadata_number);
290 fflush(stdout);
293 if(dcd->current_metadata_number >= num_expected_) {
294 (void)die_("got more metadata blocks than expected");
295 dcd->error_occurred = true;
297 else {
298 if(!mutils__compare_block(expected_metadata_sequence_[dcd->current_metadata_number], metadata)) {
299 (void)die_("metadata block mismatch");
300 dcd->error_occurred = true;
303 dcd->current_metadata_number++;
306 static void stream_decoder_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
308 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
310 (void)decoder;
312 if(0 == dcd) {
313 printf("ERROR: client_data in error callback is NULL\n");
314 return;
317 if(!dcd->ignore_errors) {
318 printf("ERROR: got error callback: err = %u (%s)\n", (uint32_t)status, FLAC__StreamDecoderErrorStatusString[status]);
319 dcd->error_occurred = true;
323 static FLAC__bool stream_decoder_test_respond_(FLAC__StreamDecoder *decoder, StreamDecoderClientData *dcd, FLAC__bool is_ogg)
325 FLAC__StreamDecoderInitStatus init_status;
327 if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
328 return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder);
330 /* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */
331 if(dcd->layer == LAYER_FILE) {
332 printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
333 open_test_file(dcd, is_ogg, "rb");
334 if(0 == dcd->file) {
335 printf("ERROR (%s)\n", strerror(errno));
336 return false;
338 printf("OK\n");
341 switch(dcd->layer) {
342 case LAYER_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_, /*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) :
346 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)
348 break;
349 case LAYER_SEEKABLE_STREAM:
350 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
351 init_status = is_ogg?
352 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) :
353 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);
354 break;
355 case LAYER_FILE:
356 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
357 init_status = is_ogg?
358 FLAC__stream_decoder_init_ogg_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
359 FLAC__stream_decoder_init_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
360 break;
361 case LAYER_FILENAME:
362 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
363 init_status = is_ogg?
364 FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
365 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
366 break;
367 default:
368 die_("internal error 000");
369 return false;
371 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
372 return die_s_(0, decoder);
373 printf("OK\n");
375 dcd->current_metadata_number = 0;
377 if(dcd->layer < LAYER_FILE && fseeko(dcd->file, 0, SEEK_SET) < 0) {
378 printf("FAILED rewinding input, errno = %d\n", errno);
379 return false;
382 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
383 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
384 return die_s_("returned false", decoder);
385 printf("OK\n");
387 printf("testing FLAC__stream_decoder_finish()... ");
388 if(!FLAC__stream_decoder_finish(decoder))
389 return die_s_("returned false", decoder);
390 printf("OK\n");
392 return true;
395 static FLAC__bool test_stream_decoder(Layer layer, FLAC__bool is_ogg)
397 FLAC__StreamDecoder *decoder;
398 FLAC__StreamDecoderInitStatus init_status;
399 FLAC__StreamDecoderState state;
400 StreamDecoderClientData decoder_client_data;
401 FLAC__bool expect;
403 decoder_client_data.layer = layer;
405 printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString[layer], is_ogg? "Ogg FLAC" : "FLAC");
407 printf("testing FLAC__stream_decoder_new()... ");
408 decoder = FLAC__stream_decoder_new();
409 if(0 == decoder) {
410 printf("FAILED, returned NULL\n");
411 return false;
413 printf("OK\n");
415 printf("testing FLAC__stream_decoder_delete()... ");
416 FLAC__stream_decoder_delete(decoder);
417 printf("OK\n");
419 printf("testing FLAC__stream_decoder_new()... ");
420 decoder = FLAC__stream_decoder_new();
421 if(0 == decoder) {
422 printf("FAILED, returned NULL\n");
423 return false;
425 printf("OK\n");
427 switch(layer) {
428 case LAYER_STREAM:
429 case LAYER_SEEKABLE_STREAM:
430 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
431 init_status = is_ogg?
432 FLAC__stream_decoder_init_ogg_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0) :
433 FLAC__stream_decoder_init_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0);
434 break;
435 case LAYER_FILE:
436 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
437 init_status = is_ogg?
438 FLAC__stream_decoder_init_ogg_FILE(decoder, stdin, 0, 0, 0, 0) :
439 FLAC__stream_decoder_init_FILE(decoder, stdin, 0, 0, 0, 0);
440 break;
441 case LAYER_FILENAME:
442 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
443 init_status = is_ogg?
444 FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0) :
445 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0);
446 break;
447 default:
448 die_("internal error 003");
449 return false;
451 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS)
452 return die_s_(0, decoder);
453 printf("OK\n");
455 printf("testing FLAC__stream_decoder_delete()... ");
456 FLAC__stream_decoder_delete(decoder);
457 printf("OK\n");
459 num_expected_ = 0;
460 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
462 printf("testing FLAC__stream_decoder_new()... ");
463 decoder = FLAC__stream_decoder_new();
464 if(0 == decoder) {
465 printf("FAILED, returned NULL\n");
466 return false;
468 printf("OK\n");
470 if(is_ogg) {
471 printf("testing FLAC__stream_decoder_set_ogg_serial_number()... ");
472 if(!FLAC__stream_decoder_set_ogg_serial_number(decoder, file_utils__ogg_serial_number))
473 return die_s_("returned false", decoder);
474 printf("OK\n");
477 printf("testing FLAC__stream_decoder_set_md5_checking()... ");
478 if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
479 return die_s_("returned false", decoder);
480 printf("OK\n");
482 if(layer < LAYER_FILENAME) {
483 printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
484 open_test_file(&decoder_client_data, is_ogg, "rb");
485 if(0 == decoder_client_data.file) {
486 printf("ERROR (%s)\n", strerror(errno));
487 return false;
489 printf("OK\n");
492 switch(layer) {
493 case LAYER_STREAM:
494 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
495 init_status = is_ogg?
496 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) :
497 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);
498 break;
499 case LAYER_SEEKABLE_STREAM:
500 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
501 init_status = is_ogg?
502 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) :
503 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);
504 break;
505 case LAYER_FILE:
506 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
507 init_status = is_ogg?
508 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) :
509 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);
510 break;
511 case LAYER_FILENAME:
512 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
513 init_status = is_ogg?
514 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) :
515 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
516 break;
517 default:
518 die_("internal error 009");
519 return false;
521 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
522 return die_s_(0, decoder);
523 printf("OK\n");
525 printf("testing FLAC__stream_decoder_get_state()... ");
526 state = FLAC__stream_decoder_get_state(decoder);
527 printf("returned state = %u (%s)... OK\n", state, FLAC__StreamDecoderStateString[state]);
529 decoder_client_data.current_metadata_number = 0;
530 decoder_client_data.ignore_errors = false;
531 decoder_client_data.error_occurred = false;
533 printf("testing FLAC__stream_decoder_get_md5_checking()... ");
534 if(!FLAC__stream_decoder_get_md5_checking(decoder)) {
535 printf("FAILED, returned false, expected true\n");
536 return false;
538 printf("OK\n");
540 printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... ");
541 if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
542 return die_s_("returned false", decoder);
543 printf("OK\n");
545 printf("testing FLAC__stream_decoder_process_single()... ");
546 if(!FLAC__stream_decoder_process_single(decoder))
547 return die_s_("returned false", decoder);
548 printf("OK\n");
550 printf("testing FLAC__stream_decoder_skip_single_frame()... ");
551 if(!FLAC__stream_decoder_skip_single_frame(decoder))
552 return die_s_("returned false", decoder);
553 printf("OK\n");
555 if(layer < LAYER_FILE) {
556 printf("testing FLAC__stream_decoder_flush()... ");
557 if(!FLAC__stream_decoder_flush(decoder))
558 return die_s_("returned false", decoder);
559 printf("OK\n");
561 decoder_client_data.ignore_errors = true;
562 printf("testing FLAC__stream_decoder_process_single()... ");
563 if(!FLAC__stream_decoder_process_single(decoder))
564 return die_s_("returned false", decoder);
565 printf("OK\n");
566 decoder_client_data.ignore_errors = false;
569 expect = (layer != LAYER_STREAM);
570 printf("testing FLAC__stream_decoder_seek_absolute()... ");
571 if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
572 return die_s_(expect? "returned false" : "returned true", decoder);
573 printf("OK\n");
575 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
576 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
577 return die_s_("returned false", decoder);
578 printf("OK\n");
580 expect = (layer != LAYER_STREAM);
581 printf("testing FLAC__stream_decoder_seek_absolute()... ");
582 if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
583 return die_s_(expect? "returned false" : "returned true", decoder);
584 printf("OK\n");
586 printf("testing FLAC__stream_decoder_get_channels()... ");
588 uint32_t channels = FLAC__stream_decoder_get_channels(decoder);
589 if(channels != streaminfo_.data.stream_info.channels) {
590 printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
591 return false;
594 printf("OK\n");
596 printf("testing FLAC__stream_decoder_get_bits_per_sample()... ");
598 uint32_t bits_per_sample = FLAC__stream_decoder_get_bits_per_sample(decoder);
599 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
600 printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
601 return false;
604 printf("OK\n");
606 printf("testing FLAC__stream_decoder_get_sample_rate()... ");
608 uint32_t sample_rate = FLAC__stream_decoder_get_sample_rate(decoder);
609 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
610 printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
611 return false;
614 printf("OK\n");
616 printf("testing FLAC__stream_decoder_get_blocksize()... ");
618 uint32_t blocksize = FLAC__stream_decoder_get_blocksize(decoder);
619 /* value could be anything since we're at the last block, so accept any reasonable answer */
620 printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED");
621 if(blocksize == 0)
622 return false;
625 printf("testing FLAC__stream_decoder_get_channel_assignment()... ");
627 FLAC__ChannelAssignment ca = FLAC__stream_decoder_get_channel_assignment(decoder);
628 printf("returned %u (%s)... OK\n", (uint32_t)ca, FLAC__ChannelAssignmentString[ca]);
631 if(layer < LAYER_FILE) {
632 printf("testing FLAC__stream_decoder_reset()... ");
633 if(!FLAC__stream_decoder_reset(decoder)) {
634 state = FLAC__stream_decoder_get_state(decoder);
635 printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]);
636 return false;
638 printf("OK\n");
640 if(layer == LAYER_STREAM) {
641 /* after a reset() we have to rewind the input ourselves */
642 printf("rewinding input... ");
643 if(fseeko(decoder_client_data.file, 0, SEEK_SET) < 0) {
644 printf("FAILED, errno = %d\n", errno);
645 return false;
647 printf("OK\n");
650 decoder_client_data.current_metadata_number = 0;
652 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
653 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
654 return die_s_("returned false", decoder);
655 printf("OK\n");
658 printf("testing FLAC__stream_decoder_finish()... ");
659 if(!FLAC__stream_decoder_finish(decoder))
660 return die_s_("returned false", decoder);
661 printf("OK\n");
664 * respond all
667 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
668 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
669 return die_s_("returned false", decoder);
670 printf("OK\n");
672 num_expected_ = 0;
673 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
674 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
675 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
676 expected_metadata_sequence_[num_expected_++] = &padding_;
677 expected_metadata_sequence_[num_expected_++] = &seektable_;
678 expected_metadata_sequence_[num_expected_++] = &application1_;
679 expected_metadata_sequence_[num_expected_++] = &application2_;
680 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
681 expected_metadata_sequence_[num_expected_++] = &picture_;
682 expected_metadata_sequence_[num_expected_++] = &unknown_;
684 else {
685 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
686 expected_metadata_sequence_[num_expected_++] = &padding_;
687 expected_metadata_sequence_[num_expected_++] = &seektable_;
688 expected_metadata_sequence_[num_expected_++] = &application1_;
689 expected_metadata_sequence_[num_expected_++] = &application2_;
690 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
691 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
692 expected_metadata_sequence_[num_expected_++] = &picture_;
693 expected_metadata_sequence_[num_expected_++] = &unknown_;
696 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
697 return false;
700 * ignore all
703 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
704 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
705 return die_s_("returned false", decoder);
706 printf("OK\n");
708 num_expected_ = 0;
710 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
711 return false;
714 * respond all, ignore VORBIS_COMMENT
717 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
718 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
719 return die_s_("returned false", decoder);
720 printf("OK\n");
722 printf("testing FLAC__stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... ");
723 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
724 return die_s_("returned false", decoder);
725 printf("OK\n");
727 num_expected_ = 0;
728 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
729 expected_metadata_sequence_[num_expected_++] = &padding_;
730 expected_metadata_sequence_[num_expected_++] = &seektable_;
731 expected_metadata_sequence_[num_expected_++] = &application1_;
732 expected_metadata_sequence_[num_expected_++] = &application2_;
733 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
734 expected_metadata_sequence_[num_expected_++] = &picture_;
735 expected_metadata_sequence_[num_expected_++] = &unknown_;
737 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
738 return false;
741 * respond all, ignore APPLICATION
744 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
745 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
746 return die_s_("returned false", decoder);
747 printf("OK\n");
749 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
750 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
751 return die_s_("returned false", decoder);
752 printf("OK\n");
754 num_expected_ = 0;
755 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
756 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
757 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
758 expected_metadata_sequence_[num_expected_++] = &padding_;
759 expected_metadata_sequence_[num_expected_++] = &seektable_;
760 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
761 expected_metadata_sequence_[num_expected_++] = &picture_;
762 expected_metadata_sequence_[num_expected_++] = &unknown_;
764 else {
765 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
766 expected_metadata_sequence_[num_expected_++] = &padding_;
767 expected_metadata_sequence_[num_expected_++] = &seektable_;
768 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
769 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
770 expected_metadata_sequence_[num_expected_++] = &picture_;
771 expected_metadata_sequence_[num_expected_++] = &unknown_;
774 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
775 return false;
778 * respond all, ignore APPLICATION id of app#1
781 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
782 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
783 return die_s_("returned false", decoder);
784 printf("OK\n");
786 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
787 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
788 return die_s_("returned false", decoder);
789 printf("OK\n");
791 num_expected_ = 0;
792 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
793 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
794 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
795 expected_metadata_sequence_[num_expected_++] = &padding_;
796 expected_metadata_sequence_[num_expected_++] = &seektable_;
797 expected_metadata_sequence_[num_expected_++] = &application2_;
798 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
799 expected_metadata_sequence_[num_expected_++] = &picture_;
800 expected_metadata_sequence_[num_expected_++] = &unknown_;
802 else {
803 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
804 expected_metadata_sequence_[num_expected_++] = &padding_;
805 expected_metadata_sequence_[num_expected_++] = &seektable_;
806 expected_metadata_sequence_[num_expected_++] = &application2_;
807 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
808 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
809 expected_metadata_sequence_[num_expected_++] = &picture_;
810 expected_metadata_sequence_[num_expected_++] = &unknown_;
813 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
814 return false;
817 * respond all, ignore APPLICATION id of app#1 & app#2
820 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
821 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
822 return die_s_("returned false", decoder);
823 printf("OK\n");
825 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
826 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
827 return die_s_("returned false", decoder);
828 printf("OK\n");
830 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... ");
831 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id))
832 return die_s_("returned false", decoder);
833 printf("OK\n");
835 num_expected_ = 0;
836 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
837 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
838 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
839 expected_metadata_sequence_[num_expected_++] = &padding_;
840 expected_metadata_sequence_[num_expected_++] = &seektable_;
841 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
842 expected_metadata_sequence_[num_expected_++] = &picture_;
843 expected_metadata_sequence_[num_expected_++] = &unknown_;
845 else {
846 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
847 expected_metadata_sequence_[num_expected_++] = &padding_;
848 expected_metadata_sequence_[num_expected_++] = &seektable_;
849 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
850 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
851 expected_metadata_sequence_[num_expected_++] = &picture_;
852 expected_metadata_sequence_[num_expected_++] = &unknown_;
855 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
856 return false;
859 * ignore all, respond VORBIS_COMMENT
862 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
863 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
864 return die_s_("returned false", decoder);
865 printf("OK\n");
867 printf("testing FLAC__stream_decoder_set_metadata_respond(VORBIS_COMMENT)... ");
868 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
869 return die_s_("returned false", decoder);
870 printf("OK\n");
872 num_expected_ = 0;
873 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
875 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
876 return false;
879 * ignore all, respond APPLICATION
882 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
883 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
884 return die_s_("returned false", decoder);
885 printf("OK\n");
887 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
888 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION))
889 return die_s_("returned false", decoder);
890 printf("OK\n");
892 num_expected_ = 0;
893 expected_metadata_sequence_[num_expected_++] = &application1_;
894 expected_metadata_sequence_[num_expected_++] = &application2_;
896 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
897 return false;
900 * ignore all, respond APPLICATION id of app#1
903 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
904 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
905 return die_s_("returned false", decoder);
906 printf("OK\n");
908 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
909 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
910 return die_s_("returned false", decoder);
911 printf("OK\n");
913 num_expected_ = 0;
914 expected_metadata_sequence_[num_expected_++] = &application1_;
916 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
917 return false;
920 * ignore all, respond APPLICATION id of app#1 & app#2
923 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
924 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
925 return die_s_("returned false", decoder);
926 printf("OK\n");
928 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
929 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
930 return die_s_("returned false", decoder);
931 printf("OK\n");
933 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #2)... ");
934 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id))
935 return die_s_("returned false", decoder);
936 printf("OK\n");
938 num_expected_ = 0;
939 expected_metadata_sequence_[num_expected_++] = &application1_;
940 expected_metadata_sequence_[num_expected_++] = &application2_;
942 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
943 return false;
946 * respond all, ignore APPLICATION, respond APPLICATION id of app#1
949 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
950 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
951 return die_s_("returned false", decoder);
952 printf("OK\n");
954 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
955 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
956 return die_s_("returned false", decoder);
957 printf("OK\n");
959 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
960 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
961 return die_s_("returned false", decoder);
962 printf("OK\n");
964 num_expected_ = 0;
965 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
966 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
967 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
968 expected_metadata_sequence_[num_expected_++] = &padding_;
969 expected_metadata_sequence_[num_expected_++] = &seektable_;
970 expected_metadata_sequence_[num_expected_++] = &application1_;
971 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
972 expected_metadata_sequence_[num_expected_++] = &picture_;
973 expected_metadata_sequence_[num_expected_++] = &unknown_;
975 else {
976 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
977 expected_metadata_sequence_[num_expected_++] = &padding_;
978 expected_metadata_sequence_[num_expected_++] = &seektable_;
979 expected_metadata_sequence_[num_expected_++] = &application1_;
980 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
981 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
982 expected_metadata_sequence_[num_expected_++] = &picture_;
983 expected_metadata_sequence_[num_expected_++] = &unknown_;
986 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
987 return false;
990 * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
993 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
994 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
995 return die_s_("returned false", decoder);
996 printf("OK\n");
998 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
999 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION))
1000 return die_s_("returned false", decoder);
1001 printf("OK\n");
1003 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
1004 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
1005 return die_s_("returned false", decoder);
1006 printf("OK\n");
1008 num_expected_ = 0;
1009 expected_metadata_sequence_[num_expected_++] = &application2_;
1011 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
1012 return false;
1014 if(layer < LAYER_FILE) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */
1015 fclose(decoder_client_data.file);
1017 printf("testing FLAC__stream_decoder_delete()... ");
1018 FLAC__stream_decoder_delete(decoder);
1019 printf("OK\n");
1021 printf("\nPASSED!\n");
1023 return true;
1026 FLAC__bool test_decoders(void)
1028 FLAC__bool is_ogg = false;
1030 while(1) {
1031 init_metadata_blocks_();
1033 if(!generate_file_(is_ogg))
1034 return false;
1036 if(!test_stream_decoder(LAYER_STREAM, is_ogg))
1037 return false;
1039 if(!test_stream_decoder(LAYER_SEEKABLE_STREAM, is_ogg))
1040 return false;
1042 if(!test_stream_decoder(LAYER_FILE, is_ogg))
1043 return false;
1045 if(!test_stream_decoder(LAYER_FILENAME, is_ogg))
1046 return false;
1048 (void) grabbag__file_remove_file(flacfilename(is_ogg));
1050 free_metadata_blocks_();
1052 if(!FLAC_API_SUPPORTS_OGG_FLAC || is_ogg)
1053 break;
1054 is_ogg = true;
1057 return true;