Fix a couple of Windows 2Gig file size issues.
[flac.git] / src / test_libFLAC / decoders.c
blobc9d2cdf32a8d31cb55bcd942e812317a5b6888a0
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 "test_libs_common/file_utils_flac.h"
33 #include "test_libs_common/metadata_utils.h"
35 typedef enum {
36 LAYER_STREAM = 0, /* FLAC__stream_decoder_init_[ogg_]stream() without seeking */
37 LAYER_SEEKABLE_STREAM, /* FLAC__stream_decoder_init_[ogg_]stream() with seeking */
38 LAYER_FILE, /* FLAC__stream_decoder_init_[ogg_]FILE() */
39 LAYER_FILENAME /* FLAC__stream_decoder_init_[ogg_]file() */
40 } Layer;
42 static const char * const LayerString[] = {
43 "Stream",
44 "Seekable Stream",
45 "FILE*",
46 "Filename"
49 typedef struct {
50 Layer layer;
51 FILE *file;
52 unsigned current_metadata_number;
53 FLAC__bool ignore_errors;
54 FLAC__bool error_occurred;
55 } StreamDecoderClientData;
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(FLAC__bool is_ogg)
64 return is_ogg? "metadata.oga" : "metadata.flac";
67 static FLAC__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__StreamDecoder *decoder)
75 FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(decoder);
77 if(msg)
78 printf("FAILED, %s", msg);
79 else
80 printf("FAILED");
82 printf(", state = %u (%s)\n", (unsigned)state, FLAC__StreamDecoderStateString[state]);
84 return false;
87 static void init_metadata_blocks_(void)
89 mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
92 static void free_metadata_blocks_(void)
94 mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
97 static FLAC__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;
118 static FLAC__StreamDecoderReadStatus stream_decoder_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
120 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
121 const size_t requested_bytes = *bytes;
123 (void)decoder;
125 if(0 == dcd) {
126 printf("ERROR: client_data in read callback is NULL\n");
127 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
130 if(dcd->error_occurred)
131 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
133 if(feof(dcd->file)) {
134 *bytes = 0;
135 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
137 else if(requested_bytes > 0) {
138 *bytes = fread(buffer, 1, requested_bytes, dcd->file);
139 if(*bytes == 0) {
140 if(feof(dcd->file))
141 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
142 else
143 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
145 else {
146 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
149 else
150 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
153 static FLAC__StreamDecoderSeekStatus stream_decoder_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
155 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
157 (void)decoder;
159 if(0 == dcd) {
160 printf("ERROR: client_data in seek callback is NULL\n");
161 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
164 if(dcd->error_occurred)
165 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
167 if(fseeko(dcd->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) {
168 dcd->error_occurred = true;
169 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
172 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
175 static FLAC__StreamDecoderTellStatus stream_decoder_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
177 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
178 FLAC__off_t offset;
180 (void)decoder;
182 if(0 == dcd) {
183 printf("ERROR: client_data in tell callback is NULL\n");
184 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
187 if(dcd->error_occurred)
188 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
190 offset = ftello(dcd->file);
191 *absolute_byte_offset = (FLAC__uint64)offset;
193 if(offset < 0) {
194 dcd->error_occurred = true;
195 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
198 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
201 static FLAC__StreamDecoderLengthStatus stream_decoder_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
203 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
205 (void)decoder;
207 if(0 == dcd) {
208 printf("ERROR: client_data in length callback is NULL\n");
209 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
212 if(dcd->error_occurred)
213 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
215 *stream_length = (FLAC__uint64)flacfilesize_;
216 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
219 static FLAC__bool stream_decoder_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data)
221 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
223 (void)decoder;
225 if(0 == dcd) {
226 printf("ERROR: client_data in eof callback is NULL\n");
227 return true;
230 if(dcd->error_occurred)
231 return true;
233 return feof(dcd->file);
236 static FLAC__StreamDecoderWriteStatus stream_decoder_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
238 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
240 (void)decoder, (void)buffer;
242 if(0 == dcd) {
243 printf("ERROR: client_data in write callback is NULL\n");
244 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
247 if(dcd->error_occurred)
248 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
251 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
252 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
254 printf("content... ");
255 fflush(stdout);
258 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
261 static void stream_decoder_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
263 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
265 (void)decoder;
267 if(0 == dcd) {
268 printf("ERROR: client_data in metadata callback is NULL\n");
269 return;
272 if(dcd->error_occurred)
273 return;
275 printf("%d... ", dcd->current_metadata_number);
276 fflush(stdout);
278 if(dcd->current_metadata_number >= num_expected_) {
279 (void)die_("got more metadata blocks than expected");
280 dcd->error_occurred = true;
282 else {
283 if(!mutils__compare_block(expected_metadata_sequence_[dcd->current_metadata_number], metadata)) {
284 (void)die_("metadata block mismatch");
285 dcd->error_occurred = true;
288 dcd->current_metadata_number++;
291 static void stream_decoder_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
293 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data;
295 (void)decoder;
297 if(0 == dcd) {
298 printf("ERROR: client_data in error callback is NULL\n");
299 return;
302 if(!dcd->ignore_errors) {
303 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, FLAC__StreamDecoderErrorStatusString[status]);
304 dcd->error_occurred = true;
308 static FLAC__bool stream_decoder_test_respond_(FLAC__StreamDecoder *decoder, StreamDecoderClientData *dcd, FLAC__bool is_ogg)
310 FLAC__StreamDecoderInitStatus init_status;
312 if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
313 return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder);
315 /* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */
316 if(dcd->layer == LAYER_FILE) {
317 printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
318 dcd->file = fopen(flacfilename(is_ogg), "rb");
319 if(0 == dcd->file) {
320 printf("ERROR (%s)\n", strerror(errno));
321 return false;
323 printf("OK\n");
326 switch(dcd->layer) {
327 case LAYER_STREAM:
328 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
329 init_status = is_ogg?
330 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) :
331 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)
333 break;
334 case LAYER_SEEKABLE_STREAM:
335 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
336 init_status = is_ogg?
337 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) :
338 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);
339 break;
340 case LAYER_FILE:
341 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
342 init_status = is_ogg?
343 FLAC__stream_decoder_init_ogg_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
344 FLAC__stream_decoder_init_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
345 break;
346 case LAYER_FILENAME:
347 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
348 init_status = is_ogg?
349 FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
350 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
351 break;
352 default:
353 die_("internal error 000");
354 return false;
356 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
357 return die_s_(0, decoder);
358 printf("OK\n");
360 dcd->current_metadata_number = 0;
362 if(dcd->layer < LAYER_FILE && fseeko(dcd->file, 0, SEEK_SET) < 0) {
363 printf("FAILED rewinding input, errno = %d\n", errno);
364 return false;
367 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
368 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
369 return die_s_("returned false", decoder);
370 printf("OK\n");
372 printf("testing FLAC__stream_decoder_finish()... ");
373 if(!FLAC__stream_decoder_finish(decoder))
374 return die_s_("returned false", decoder);
375 printf("OK\n");
377 return true;
380 static FLAC__bool test_stream_decoder(Layer layer, FLAC__bool is_ogg)
382 FLAC__StreamDecoder *decoder;
383 FLAC__StreamDecoderInitStatus init_status;
384 FLAC__StreamDecoderState state;
385 StreamDecoderClientData decoder_client_data;
386 FLAC__bool expect;
388 decoder_client_data.layer = layer;
390 printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString[layer], is_ogg? "Ogg FLAC" : "FLAC");
392 printf("testing FLAC__stream_decoder_new()... ");
393 decoder = FLAC__stream_decoder_new();
394 if(0 == decoder) {
395 printf("FAILED, returned NULL\n");
396 return false;
398 printf("OK\n");
400 printf("testing FLAC__stream_decoder_delete()... ");
401 FLAC__stream_decoder_delete(decoder);
402 printf("OK\n");
404 printf("testing FLAC__stream_decoder_new()... ");
405 decoder = FLAC__stream_decoder_new();
406 if(0 == decoder) {
407 printf("FAILED, returned NULL\n");
408 return false;
410 printf("OK\n");
412 switch(layer) {
413 case LAYER_STREAM:
414 case LAYER_SEEKABLE_STREAM:
415 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
416 init_status = is_ogg?
417 FLAC__stream_decoder_init_ogg_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0) :
418 FLAC__stream_decoder_init_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0);
419 break;
420 case LAYER_FILE:
421 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
422 init_status = is_ogg?
423 FLAC__stream_decoder_init_ogg_FILE(decoder, stdin, 0, 0, 0, 0) :
424 FLAC__stream_decoder_init_FILE(decoder, stdin, 0, 0, 0, 0);
425 break;
426 case LAYER_FILENAME:
427 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
428 init_status = is_ogg?
429 FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0) :
430 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0);
431 break;
432 default:
433 die_("internal error 003");
434 return false;
436 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS)
437 return die_s_(0, decoder);
438 printf("OK\n");
440 printf("testing FLAC__stream_decoder_delete()... ");
441 FLAC__stream_decoder_delete(decoder);
442 printf("OK\n");
444 num_expected_ = 0;
445 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
447 printf("testing FLAC__stream_decoder_new()... ");
448 decoder = FLAC__stream_decoder_new();
449 if(0 == decoder) {
450 printf("FAILED, returned NULL\n");
451 return false;
453 printf("OK\n");
455 if(is_ogg) {
456 printf("testing FLAC__stream_decoder_set_ogg_serial_number()... ");
457 if(!FLAC__stream_decoder_set_ogg_serial_number(decoder, file_utils__ogg_serial_number))
458 return die_s_("returned false", decoder);
459 printf("OK\n");
462 printf("testing FLAC__stream_decoder_set_md5_checking()... ");
463 if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
464 return die_s_("returned false", decoder);
465 printf("OK\n");
467 if(layer < LAYER_FILENAME) {
468 printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
469 decoder_client_data.file = fopen(flacfilename(is_ogg), "rb");
470 if(0 == decoder_client_data.file) {
471 printf("ERROR (%s)\n", strerror(errno));
472 return false;
474 printf("OK\n");
477 switch(layer) {
478 case LAYER_STREAM:
479 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
480 init_status = is_ogg?
481 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) :
482 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);
483 break;
484 case LAYER_SEEKABLE_STREAM:
485 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
486 init_status = is_ogg?
487 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) :
488 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);
489 break;
490 case LAYER_FILE:
491 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
492 init_status = is_ogg?
493 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) :
494 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);
495 break;
496 case LAYER_FILENAME:
497 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
498 init_status = is_ogg?
499 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) :
500 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
501 break;
502 default:
503 die_("internal error 009");
504 return false;
506 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
507 return die_s_(0, decoder);
508 printf("OK\n");
510 printf("testing FLAC__stream_decoder_get_state()... ");
511 state = FLAC__stream_decoder_get_state(decoder);
512 printf("returned state = %u (%s)... OK\n", state, FLAC__StreamDecoderStateString[state]);
514 decoder_client_data.current_metadata_number = 0;
515 decoder_client_data.ignore_errors = false;
516 decoder_client_data.error_occurred = false;
518 printf("testing FLAC__stream_decoder_get_md5_checking()... ");
519 if(!FLAC__stream_decoder_get_md5_checking(decoder)) {
520 printf("FAILED, returned false, expected true\n");
521 return false;
523 printf("OK\n");
525 printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... ");
526 if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
527 return die_s_("returned false", decoder);
528 printf("OK\n");
530 printf("testing FLAC__stream_decoder_process_single()... ");
531 if(!FLAC__stream_decoder_process_single(decoder))
532 return die_s_("returned false", decoder);
533 printf("OK\n");
535 printf("testing FLAC__stream_decoder_skip_single_frame()... ");
536 if(!FLAC__stream_decoder_skip_single_frame(decoder))
537 return die_s_("returned false", decoder);
538 printf("OK\n");
540 if(layer < LAYER_FILE) {
541 printf("testing FLAC__stream_decoder_flush()... ");
542 if(!FLAC__stream_decoder_flush(decoder))
543 return die_s_("returned false", decoder);
544 printf("OK\n");
546 decoder_client_data.ignore_errors = true;
547 printf("testing FLAC__stream_decoder_process_single()... ");
548 if(!FLAC__stream_decoder_process_single(decoder))
549 return die_s_("returned false", decoder);
550 printf("OK\n");
551 decoder_client_data.ignore_errors = false;
554 expect = (layer != LAYER_STREAM);
555 printf("testing FLAC__stream_decoder_seek_absolute()... ");
556 if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
557 return die_s_(expect? "returned false" : "returned true", decoder);
558 printf("OK\n");
560 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
561 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
562 return die_s_("returned false", decoder);
563 printf("OK\n");
565 expect = (layer != LAYER_STREAM);
566 printf("testing FLAC__stream_decoder_seek_absolute()... ");
567 if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
568 return die_s_(expect? "returned false" : "returned true", decoder);
569 printf("OK\n");
571 printf("testing FLAC__stream_decoder_get_channels()... ");
573 unsigned channels = FLAC__stream_decoder_get_channels(decoder);
574 if(channels != streaminfo_.data.stream_info.channels) {
575 printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
576 return false;
579 printf("OK\n");
581 printf("testing FLAC__stream_decoder_get_bits_per_sample()... ");
583 unsigned bits_per_sample = FLAC__stream_decoder_get_bits_per_sample(decoder);
584 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
585 printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
586 return false;
589 printf("OK\n");
591 printf("testing FLAC__stream_decoder_get_sample_rate()... ");
593 unsigned sample_rate = FLAC__stream_decoder_get_sample_rate(decoder);
594 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
595 printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
596 return false;
599 printf("OK\n");
601 printf("testing FLAC__stream_decoder_get_blocksize()... ");
603 unsigned blocksize = FLAC__stream_decoder_get_blocksize(decoder);
604 /* value could be anything since we're at the last block, so accept any reasonable answer */
605 printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED");
606 if(blocksize == 0)
607 return false;
610 printf("testing FLAC__stream_decoder_get_channel_assignment()... ");
612 FLAC__ChannelAssignment ca = FLAC__stream_decoder_get_channel_assignment(decoder);
613 printf("returned %u (%s)... OK\n", (unsigned)ca, FLAC__ChannelAssignmentString[ca]);
616 if(layer < LAYER_FILE) {
617 printf("testing FLAC__stream_decoder_reset()... ");
618 if(!FLAC__stream_decoder_reset(decoder)) {
619 state = FLAC__stream_decoder_get_state(decoder);
620 printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]);
621 return false;
623 printf("OK\n");
625 if(layer == LAYER_STREAM) {
626 /* after a reset() we have to rewind the input ourselves */
627 printf("rewinding input... ");
628 if(fseeko(decoder_client_data.file, 0, SEEK_SET) < 0) {
629 printf("FAILED, errno = %d\n", errno);
630 return false;
632 printf("OK\n");
635 decoder_client_data.current_metadata_number = 0;
637 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
638 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
639 return die_s_("returned false", decoder);
640 printf("OK\n");
643 printf("testing FLAC__stream_decoder_finish()... ");
644 if(!FLAC__stream_decoder_finish(decoder))
645 return die_s_("returned false", decoder);
646 printf("OK\n");
649 * respond all
652 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
653 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
654 return die_s_("returned false", decoder);
655 printf("OK\n");
657 num_expected_ = 0;
658 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
659 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
660 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
661 expected_metadata_sequence_[num_expected_++] = &padding_;
662 expected_metadata_sequence_[num_expected_++] = &seektable_;
663 expected_metadata_sequence_[num_expected_++] = &application1_;
664 expected_metadata_sequence_[num_expected_++] = &application2_;
665 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
666 expected_metadata_sequence_[num_expected_++] = &picture_;
667 expected_metadata_sequence_[num_expected_++] = &unknown_;
669 else {
670 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
671 expected_metadata_sequence_[num_expected_++] = &padding_;
672 expected_metadata_sequence_[num_expected_++] = &seektable_;
673 expected_metadata_sequence_[num_expected_++] = &application1_;
674 expected_metadata_sequence_[num_expected_++] = &application2_;
675 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
676 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
677 expected_metadata_sequence_[num_expected_++] = &picture_;
678 expected_metadata_sequence_[num_expected_++] = &unknown_;
681 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
682 return false;
685 * ignore all
688 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
689 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
690 return die_s_("returned false", decoder);
691 printf("OK\n");
693 num_expected_ = 0;
695 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
696 return false;
699 * respond all, ignore VORBIS_COMMENT
702 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
703 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
704 return die_s_("returned false", decoder);
705 printf("OK\n");
707 printf("testing FLAC__stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... ");
708 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
709 return die_s_("returned false", decoder);
710 printf("OK\n");
712 num_expected_ = 0;
713 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
714 expected_metadata_sequence_[num_expected_++] = &padding_;
715 expected_metadata_sequence_[num_expected_++] = &seektable_;
716 expected_metadata_sequence_[num_expected_++] = &application1_;
717 expected_metadata_sequence_[num_expected_++] = &application2_;
718 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
719 expected_metadata_sequence_[num_expected_++] = &picture_;
720 expected_metadata_sequence_[num_expected_++] = &unknown_;
722 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
723 return false;
726 * respond all, ignore APPLICATION
729 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
730 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
731 return die_s_("returned false", decoder);
732 printf("OK\n");
734 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
735 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
736 return die_s_("returned false", decoder);
737 printf("OK\n");
739 num_expected_ = 0;
740 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
741 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
742 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
743 expected_metadata_sequence_[num_expected_++] = &padding_;
744 expected_metadata_sequence_[num_expected_++] = &seektable_;
745 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
746 expected_metadata_sequence_[num_expected_++] = &picture_;
747 expected_metadata_sequence_[num_expected_++] = &unknown_;
749 else {
750 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
751 expected_metadata_sequence_[num_expected_++] = &padding_;
752 expected_metadata_sequence_[num_expected_++] = &seektable_;
753 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
754 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
755 expected_metadata_sequence_[num_expected_++] = &picture_;
756 expected_metadata_sequence_[num_expected_++] = &unknown_;
759 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
760 return false;
763 * respond all, ignore APPLICATION id of app#1
766 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
767 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
768 return die_s_("returned false", decoder);
769 printf("OK\n");
771 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
772 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
773 return die_s_("returned false", decoder);
774 printf("OK\n");
776 num_expected_ = 0;
777 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
778 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
779 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
780 expected_metadata_sequence_[num_expected_++] = &padding_;
781 expected_metadata_sequence_[num_expected_++] = &seektable_;
782 expected_metadata_sequence_[num_expected_++] = &application2_;
783 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
784 expected_metadata_sequence_[num_expected_++] = &picture_;
785 expected_metadata_sequence_[num_expected_++] = &unknown_;
787 else {
788 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
789 expected_metadata_sequence_[num_expected_++] = &padding_;
790 expected_metadata_sequence_[num_expected_++] = &seektable_;
791 expected_metadata_sequence_[num_expected_++] = &application2_;
792 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
793 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
794 expected_metadata_sequence_[num_expected_++] = &picture_;
795 expected_metadata_sequence_[num_expected_++] = &unknown_;
798 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
799 return false;
802 * respond all, ignore APPLICATION id of app#1 & app#2
805 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
806 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
807 return die_s_("returned false", decoder);
808 printf("OK\n");
810 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
811 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
812 return die_s_("returned false", decoder);
813 printf("OK\n");
815 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... ");
816 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id))
817 return die_s_("returned false", decoder);
818 printf("OK\n");
820 num_expected_ = 0;
821 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
822 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
823 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
824 expected_metadata_sequence_[num_expected_++] = &padding_;
825 expected_metadata_sequence_[num_expected_++] = &seektable_;
826 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
827 expected_metadata_sequence_[num_expected_++] = &picture_;
828 expected_metadata_sequence_[num_expected_++] = &unknown_;
830 else {
831 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
832 expected_metadata_sequence_[num_expected_++] = &padding_;
833 expected_metadata_sequence_[num_expected_++] = &seektable_;
834 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
835 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
836 expected_metadata_sequence_[num_expected_++] = &picture_;
837 expected_metadata_sequence_[num_expected_++] = &unknown_;
840 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
841 return false;
844 * ignore all, respond VORBIS_COMMENT
847 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
848 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
849 return die_s_("returned false", decoder);
850 printf("OK\n");
852 printf("testing FLAC__stream_decoder_set_metadata_respond(VORBIS_COMMENT)... ");
853 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT))
854 return die_s_("returned false", decoder);
855 printf("OK\n");
857 num_expected_ = 0;
858 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
860 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
861 return false;
864 * ignore all, respond APPLICATION
867 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
868 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
869 return die_s_("returned false", decoder);
870 printf("OK\n");
872 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
873 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION))
874 return die_s_("returned false", decoder);
875 printf("OK\n");
877 num_expected_ = 0;
878 expected_metadata_sequence_[num_expected_++] = &application1_;
879 expected_metadata_sequence_[num_expected_++] = &application2_;
881 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
882 return false;
885 * ignore all, respond APPLICATION id of app#1
888 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
889 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
890 return die_s_("returned false", decoder);
891 printf("OK\n");
893 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
894 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
895 return die_s_("returned false", decoder);
896 printf("OK\n");
898 num_expected_ = 0;
899 expected_metadata_sequence_[num_expected_++] = &application1_;
901 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
902 return false;
905 * ignore all, respond APPLICATION id of app#1 & app#2
908 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
909 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
910 return die_s_("returned false", decoder);
911 printf("OK\n");
913 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
914 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
915 return die_s_("returned false", decoder);
916 printf("OK\n");
918 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #2)... ");
919 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id))
920 return die_s_("returned false", decoder);
921 printf("OK\n");
923 num_expected_ = 0;
924 expected_metadata_sequence_[num_expected_++] = &application1_;
925 expected_metadata_sequence_[num_expected_++] = &application2_;
927 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
928 return false;
931 * respond all, ignore APPLICATION, respond APPLICATION id of app#1
934 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
935 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
936 return die_s_("returned false", decoder);
937 printf("OK\n");
939 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
940 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION))
941 return die_s_("returned false", decoder);
942 printf("OK\n");
944 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
945 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id))
946 return die_s_("returned false", decoder);
947 printf("OK\n");
949 num_expected_ = 0;
950 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
951 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
952 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
953 expected_metadata_sequence_[num_expected_++] = &padding_;
954 expected_metadata_sequence_[num_expected_++] = &seektable_;
955 expected_metadata_sequence_[num_expected_++] = &application1_;
956 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
957 expected_metadata_sequence_[num_expected_++] = &picture_;
958 expected_metadata_sequence_[num_expected_++] = &unknown_;
960 else {
961 expected_metadata_sequence_[num_expected_++] = &streaminfo_;
962 expected_metadata_sequence_[num_expected_++] = &padding_;
963 expected_metadata_sequence_[num_expected_++] = &seektable_;
964 expected_metadata_sequence_[num_expected_++] = &application1_;
965 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
966 expected_metadata_sequence_[num_expected_++] = &cuesheet_;
967 expected_metadata_sequence_[num_expected_++] = &picture_;
968 expected_metadata_sequence_[num_expected_++] = &unknown_;
971 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
972 return false;
975 * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
978 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
979 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder))
980 return die_s_("returned false", decoder);
981 printf("OK\n");
983 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
984 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION))
985 return die_s_("returned false", decoder);
986 printf("OK\n");
988 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
989 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id))
990 return die_s_("returned false", decoder);
991 printf("OK\n");
993 num_expected_ = 0;
994 expected_metadata_sequence_[num_expected_++] = &application2_;
996 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg))
997 return false;
999 if(layer < LAYER_FILE) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */
1000 fclose(decoder_client_data.file);
1002 printf("testing FLAC__stream_decoder_delete()... ");
1003 FLAC__stream_decoder_delete(decoder);
1004 printf("OK\n");
1006 printf("\nPASSED!\n");
1008 return true;
1011 FLAC__bool test_decoders(void)
1013 FLAC__bool is_ogg = false;
1015 while(1) {
1016 init_metadata_blocks_();
1018 if(!generate_file_(is_ogg))
1019 return false;
1021 if(!test_stream_decoder(LAYER_STREAM, is_ogg))
1022 return false;
1024 if(!test_stream_decoder(LAYER_SEEKABLE_STREAM, is_ogg))
1025 return false;
1027 if(!test_stream_decoder(LAYER_FILE, is_ogg))
1028 return false;
1030 if(!test_stream_decoder(LAYER_FILENAME, is_ogg))
1031 return false;
1033 (void) grabbag__file_remove_file(flacfilename(is_ogg));
1035 free_metadata_blocks_();
1037 if(!FLAC_API_SUPPORTS_OGG_FLAC || is_ogg)
1038 break;
1039 is_ogg = true;
1042 return true;