16
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
#include "file_utils.h"
22
#include "FLAC/assert.h"
23
#include "FLAC++/decoder.h"
24
#include "FLAC++/metadata.h"
25
#include "share/grabbag.h"
27
24
#include <stdlib.h> /* for malloc() */
28
25
#include <string.h> /* for memcpy()/memset() */
30
26
#if defined _MSC_VER || defined __MINGW32__
31
27
#include <sys/utime.h> /* for utime() */
32
28
#include <io.h> /* for chmod() */
29
#if _MSC_VER <= 1600 /* @@@ [2G limit] */
34
34
#include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
35
35
#include <utime.h> /* for utime() */
36
36
#include <unistd.h> /* for chown(), unlink() */
38
38
#include <sys/stat.h> /* for stat(), maybe chmod() */
39
#include "FLAC/assert.h"
40
#include "FLAC++/decoder.h"
41
#include "FLAC++/metadata.h"
42
#include "share/grabbag.h"
44
#include "test_libs_common/file_utils_flac.h"
40
47
/******************************************************************************
41
48
The general strategy of these tests (for interface levels 1 and 2) is
471
492
printf("ERROR: got error callback, status = %s (%u)\n", FLAC__StreamDecoderErrorStatusString[status], (unsigned)status);
474
static bool generate_file_()
495
static bool generate_file_(bool include_extras, bool is_ogg)
476
::FLAC__StreamMetadata streaminfo, vorbiscomment, padding;
477
::FLAC__StreamMetadata *metadata[1];
497
::FLAC__StreamMetadata streaminfo, vorbiscomment, *cuesheet, picture, padding;
498
::FLAC__StreamMetadata *metadata[4];
499
unsigned i = 0, n = 0;
479
printf("generating FLAC file for test\n");
501
printf("generating %sFLAC file for test\n", is_ogg? "Ogg " : "");
481
503
while(our_metadata_.num_blocks > 0)
482
504
delete_from_our_metadata_(0);
506
528
vorbiscomment.data.vorbis_comment.comments = 0;
532
if (0 == (cuesheet = ::FLAC__metadata_object_new(::FLAC__METADATA_TYPE_CUESHEET)))
533
return die_("priming our metadata");
534
cuesheet->is_last = false;
535
strcpy(cuesheet->data.cue_sheet.media_catalog_number, "bogo-MCN");
536
cuesheet->data.cue_sheet.lead_in = 123;
537
cuesheet->data.cue_sheet.is_cd = false;
538
if (!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, 0))
539
return die_("priming our metadata");
540
cuesheet->data.cue_sheet.tracks[0].number = 1;
541
if (!FLAC__metadata_object_cuesheet_track_insert_blank_index(cuesheet, 0, 0))
542
return die_("priming our metadata");
546
picture.is_last = false;
547
picture.type = ::FLAC__METADATA_TYPE_PICTURE;
550
FLAC__STREAM_METADATA_PICTURE_TYPE_LEN +
551
FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN + /* will add the length for the string later */
552
FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN + /* will add the length for the string later */
553
FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN +
554
FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN +
555
FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN +
556
FLAC__STREAM_METADATA_PICTURE_COLORS_LEN +
557
FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN /* will add the length for the data later */
560
picture.data.picture.type = ::FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER;
561
picture.data.picture.mime_type = strdup_or_die_("image/jpeg");
562
picture.length += strlen(picture.data.picture.mime_type);
563
picture.data.picture.description = (FLAC__byte*)strdup_or_die_("desc");
564
picture.length += strlen((const char *)picture.data.picture.description);
565
picture.data.picture.width = 300;
566
picture.data.picture.height = 300;
567
picture.data.picture.depth = 24;
568
picture.data.picture.colors = 0;
569
picture.data.picture.data = (FLAC__byte*)strdup_or_die_("SOMEJPEGDATA");
570
picture.data.picture.data_length = strlen((const char *)picture.data.picture.data);
571
picture.length += picture.data.picture.data_length;
509
574
padding.is_last = true;
510
575
padding.type = ::FLAC__METADATA_TYPE_PADDING;
511
576
padding.length = 1234;
513
metadata[0] = &padding;
578
metadata[n++] = &vorbiscomment;
580
metadata[n++] = cuesheet;
581
metadata[n++] = &picture;
583
metadata[n++] = &padding;
515
585
FLAC::Metadata::StreamInfo s(&streaminfo);
516
586
FLAC::Metadata::VorbisComment v(&vorbiscomment);
587
FLAC::Metadata::CueSheet c(cuesheet, /*copy=*/false);
588
FLAC::Metadata::Picture pi(&picture);
517
589
FLAC::Metadata::Padding p(&padding);
519
!insert_to_our_metadata_(&s, 0, /*copy=*/true) ||
520
!insert_to_our_metadata_(&v, 1, /*copy=*/true) ||
521
!insert_to_our_metadata_(&p, 2, /*copy=*/true)
591
!insert_to_our_metadata_(&s, i++, /*copy=*/true) ||
592
!insert_to_our_metadata_(&v, i++, /*copy=*/true) ||
593
(include_extras && !insert_to_our_metadata_(&c, i++, /*copy=*/true)) ||
594
(include_extras && !insert_to_our_metadata_(&pi, i++, /*copy=*/true)) ||
595
!insert_to_our_metadata_(&p, i++, /*copy=*/true)
523
597
return die_("priming our metadata");
525
if(!file_utils__generate_flacfile(flacfile_, 0, 512 * 1024, &streaminfo, metadata, 1))
599
if(!file_utils__generate_flacfile(is_ogg, flacfilename(is_ogg), 0, 512 * 1024, &streaminfo, metadata, n))
526
600
return die_("creating the encoded file");
528
602
free(vorbiscomment.data.vorbis_comment.vendor_string.entry);
603
free(picture.data.picture.mime_type);
604
free(picture.data.picture.description);
605
free(picture.data.picture.data);
533
static bool test_file_(const char *filename, bool ignore_metadata)
610
static bool test_file_(bool is_ogg, bool ignore_metadata)
612
const char *filename = flacfilename(is_ogg);
535
613
OurFileDecoder decoder(ignore_metadata);
537
FLAC__ASSERT(0 != filename);
539
615
mc_our_block_number_ = 0;
540
616
decoder.error_occurred_ = false;
654
if(!remove_file_(flacfile_))
730
printf("testing FLAC::Metadata::get_cuesheet(CueSheet *&)... ");
732
FLAC::Metadata::CueSheet *cuesheet = 0;
734
if(!FLAC::Metadata::get_cuesheet(flacfilename(/*is_ogg=*/false), cuesheet))
735
return die_("during FLAC::Metadata::get_cuesheet()");
737
/* check to see if some basic data matches (c.f. generate_file_()) */
738
if(cuesheet->get_lead_in() != 123)
739
return die_("mismatch in cuesheet->get_lead_in()");
747
printf("testing FLAC::Metadata::get_cuesheet(CueSheet &)... ");
749
FLAC::Metadata::CueSheet cuesheet;
751
if(!FLAC::Metadata::get_cuesheet(flacfilename(/*is_ogg=*/false), cuesheet))
752
return die_("during FLAC::Metadata::get_cuesheet()");
754
/* check to see if some basic data matches (c.f. generate_file_()) */
755
if(cuesheet.get_lead_in() != 123)
756
return die_("mismatch in cuesheet.get_lead_in()");
762
printf("testing FLAC::Metadata::get_picture(Picture *&)... ");
764
FLAC::Metadata::Picture *picture = 0;
766
if(!FLAC::Metadata::get_picture(flacfilename(/*is_ogg=*/false), picture, /*type=*/(::FLAC__StreamMetadata_Picture_Type)(-1), /*mime_type=*/0, /*description=*/0, /*max_width=*/(unsigned)(-1), /*max_height=*/(unsigned)(-1), /*max_depth=*/(unsigned)(-1), /*max_colors=*/(unsigned)(-1)))
767
return die_("during FLAC::Metadata::get_picture()");
769
/* check to see if some basic data matches (c.f. generate_file_()) */
770
if(picture->get_type () != ::FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER)
771
return die_("mismatch in picture->get_type ()");
779
printf("testing FLAC::Metadata::get_picture(Picture &)... ");
781
FLAC::Metadata::Picture picture;
783
if(!FLAC::Metadata::get_picture(flacfilename(/*is_ogg=*/false), picture, /*type=*/(::FLAC__StreamMetadata_Picture_Type)(-1), /*mime_type=*/0, /*description=*/0, /*max_width=*/(unsigned)(-1), /*max_height=*/(unsigned)(-1), /*max_depth=*/(unsigned)(-1), /*max_colors=*/(unsigned)(-1)))
784
return die_("during FLAC::Metadata::get_picture()");
786
/* check to see if some basic data matches (c.f. generate_file_()) */
787
if(picture.get_type () != ::FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER)
788
return die_("mismatch in picture->get_type ()");
793
if(!remove_file_(flacfilename(/*is_ogg=*/false)))
1336
1475
// initialize 'data' to avoid Valgrind errors
1337
1476
memset(data, 0, sizeof(data));
1339
printf("\n\n++++++ testing level 2 interface (%s-based)\n", filename_based? "filename":"callback");
1478
printf("\n\n++++++ testing level 2 interface (%s-based, %s FLAC)\n", filename_based? "filename":"callback", is_ogg? "Ogg":"native");
1341
1480
printf("generate read-only file\n");
1343
if(!generate_file_())
1482
if(!generate_file_(/*include_extras=*/false, is_ogg))
1346
if(!change_stats_(flacfile_, /*read_only=*/true))
1485
if(!change_stats_(flacfilename(is_ogg), /*read_only=*/true))
1349
1488
printf("create chain\n");
1354
1493
printf("read chain\n");
1356
if(!read_chain_(chain, flacfile_, filename_based))
1495
if(!read_chain_(chain, flacfilename(is_ogg), filename_based, is_ogg))
1357
1496
return die_c_("reading chain", chain.status());
1359
1498
printf("[S]VP\ttest initial metadata\n");
1361
1500
if(!compare_chain_(chain, 0, 0))
1363
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1502
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1366
1508
printf("switch file to read-write\n");
1368
if(!change_stats_(flacfile_, /*read-only=*/false))
1510
if(!change_stats_(flacfilename(is_ogg), /*read-only=*/false))
1371
1513
printf("create iterator\n");
1392
1534
return die_("copying object");
1395
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/true, filename_based, flacfile_))
1537
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/true, filename_based, flacfilename(is_ogg)))
1396
1538
return die_c_("during chain.write(false, true)", chain.status());
1397
1539
block = iterator.get_block();
1398
1540
if(!compare_chain_(chain, our_current_position, block))
1401
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1543
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1404
1546
printf("[S]VP\tnext\n");
1425
1567
if(!iterator.set_block(app))
1426
1568
return die_c_("iterator.set_block(app)", chain.status());
1428
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1570
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1429
1571
return die_c_("during chain.write(false, false)", chain.status());
1430
1572
block = iterator.get_block();
1431
1573
if(!compare_chain_(chain, our_current_position, block))
1434
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1576
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1437
1579
printf("SV[A]\tshrink APPLICATION, don't use padding\n");
1444
1586
if(!iterator.set_block(app))
1445
1587
return die_c_("iterator.set_block(app)", chain.status());
1447
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1589
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1448
1590
return die_c_("during chain.write(false, false)", chain.status());
1449
1591
block = iterator.get_block();
1450
1592
if(!compare_chain_(chain, our_current_position, block))
1453
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1595
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1456
1598
printf("SV[A]\tgrow APPLICATION, don't use padding\n");
1463
1605
if(!iterator.set_block(app))
1464
1606
return die_c_("iterator.set_block(app)", chain.status());
1466
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1608
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1467
1609
return die_c_("during chain.write(false, false)", chain.status());
1468
1610
block = iterator.get_block();
1469
1611
if(!compare_chain_(chain, our_current_position, block))
1472
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1614
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1475
1617
printf("SV[A]\tgrow APPLICATION, use padding, but last block is not padding\n");
1482
1624
if(!iterator.set_block(app))
1483
1625
return die_c_("iterator.set_block(app)", chain.status());
1485
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1627
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1486
1628
return die_c_("during chain.write(false, false)", chain.status());
1487
1629
block = iterator.get_block();
1488
1630
if(!compare_chain_(chain, our_current_position, block))
1491
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1633
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1494
1636
printf("SV[A]\tshrink APPLICATION, use padding, last block is not padding, but delta is too small for new PADDING block\n");
1501
1643
if(!iterator.set_block(app))
1502
1644
return die_c_("iterator.set_block(app)", chain.status());
1504
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1646
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1505
1647
return die_c_("during chain.write(true, false)", chain.status());
1506
1648
block = iterator.get_block();
1507
1649
if(!compare_chain_(chain, our_current_position, block))
1510
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1652
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1513
1655
printf("SV[A]\tshrink APPLICATION, use padding, last block is not padding, delta is enough for new PADDING block\n");
1525
1667
if(!iterator.set_block(app))
1526
1668
return die_c_("iterator.set_block(app)", chain.status());
1528
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1670
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1529
1671
return die_c_("during chain.write(true, false)", chain.status());
1530
1672
block = iterator.get_block();
1531
1673
if(!compare_chain_(chain, our_current_position, block))
1534
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1676
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1537
1679
printf("SV[A]P\tshrink APPLICATION, use padding, last block is padding\n");
1545
1687
if(!iterator.set_block(app))
1546
1688
return die_c_("iterator.set_block(app)", chain.status());
1548
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1690
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1549
1691
return die_c_("during chain.write(true, false)", chain.status());
1550
1692
block = iterator.get_block();
1551
1693
if(!compare_chain_(chain, our_current_position, block))
1554
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1696
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1557
1699
printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding, but delta is too small\n");
1564
1706
if(!iterator.set_block(app))
1565
1707
return die_c_("iterator.set_block(app)", chain.status());
1567
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1709
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1568
1710
return die_c_("during chain.write(true, false)", chain.status());
1569
1711
block = iterator.get_block();
1570
1712
if(!compare_chain_(chain, our_current_position, block))
1573
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1715
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1576
1718
printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding of exceeding size\n");
1584
1726
if(!iterator.set_block(app))
1585
1727
return die_c_("iterator.set_block(app)", chain.status());
1587
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1729
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1588
1730
return die_c_("during chain.write(true, false)", chain.status());
1589
1731
block = iterator.get_block();
1590
1732
if(!compare_chain_(chain, our_current_position, block))
1593
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1735
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1596
1738
printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding of exact size\n");
1604
1746
if(!iterator.set_block(app))
1605
1747
return die_c_("iterator.set_block(app)", chain.status());
1607
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1749
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1608
1750
return die_c_("during chain.write(true, false)", chain.status());
1609
1751
block = iterator.get_block();
1610
1752
if(!compare_chain_(chain, our_current_position, block))
1613
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1755
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1616
1758
printf("SV[A]\tprev\n");
1731
1873
delete_from_our_metadata_(4);
1732
1874
delete_from_our_metadata_(3);
1734
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1876
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1735
1877
return die_c_("during chain.write(true, false)", chain.status());
1736
1878
if(!compare_chain_(chain, 0, 0))
1738
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1880
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1741
1883
printf("SVPAP\tsort padding\n");
1743
1885
add_to_padding_length_(4, FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[2]->get_length());
1744
1886
delete_from_our_metadata_(2);
1746
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfile_))
1888
if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1747
1889
return die_c_("during chain.write(true, false)", chain.status());
1748
1890
if(!compare_chain_(chain, 0, 0))
1750
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
1892
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1753
1895
printf("create iterator\n");
1853
1995
printf("SV\tmerge padding\n");
1854
1996
chain.merge_padding();
1856
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
1998
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1857
1999
return die_c_("during chain.write(false, false)", chain.status());
1858
2000
if(!compare_chain_(chain, 0, 0))
1860
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
2002
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1863
2005
printf("SV\tsort padding\n");
1864
2006
chain.sort_padding();
1866
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfile_))
2008
if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
1867
2009
return die_c_("during chain.write(false, false)", chain.status());
1868
2010
if(!compare_chain_(chain, 0, 0))
1870
if(!test_file_(flacfile_, /*ignore_metadata=*/false))
2012
if(!test_file_(is_ogg, /*ignore_metadata=*/false))
1873
if(!remove_file_(flacfile_))
2016
if(!remove_file_(flacfilename(is_ogg)))
1879
static bool test_level_2_misc_()
2022
static bool test_level_2_misc_(bool is_ogg)
1881
2024
::FLAC__IOCallbacks callbacks;
2044
2187
if(!test_level_1_())
2047
if(!test_level_2_(/*filename_based=*/true)) /* filename-based */
2049
if(!test_level_2_(/*filename_based=*/false)) /* callback-based */
2051
if(!test_level_2_misc_())
2190
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/false)) /* filename-based */
2192
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/false)) /* callback-based */
2194
if(!test_level_2_misc_(/*is_ogg=*/false))
2197
if(FLAC_API_SUPPORTS_OGG_FLAC) {
2198
if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/true)) /* filename-based */
2200
if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/true)) /* callback-based */
2203
/* when ogg flac write is supported, will have to add this: */
2204
if(!test_level_2_misc_(/*is_ogg=*/true))