add support for new PICTURE metadata block

This commit is contained in:
Josh Coalson
2006-09-23 19:21:19 +00:00
parent aa1edebacd
commit e343ab2b87
26 changed files with 2036 additions and 147 deletions

View File

@@ -58,8 +58,8 @@ typedef struct {
FLAC__bool error_occurred;
} StreamDecoderClientData;
static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, unknown_;
static FLAC__StreamMetadata *expected_metadata_sequence_[8];
static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, picture_, unknown_;
static FLAC__StreamMetadata *expected_metadata_sequence_[9];
static unsigned num_expected_;
static const char *flacfilename_ = "metadata.flac";
static off_t flacfilesize_;
@@ -86,12 +86,12 @@ static FLAC__bool die_s_(const char *msg, const FLAC__StreamDecoder *decoder)
static void init_metadata_blocks_()
{
mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_);
mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
}
static void free_metadata_blocks_()
{
mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_);
mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
}
static FLAC__bool generate_file_()
@@ -105,6 +105,7 @@ static FLAC__bool generate_file_()
expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
expected_metadata_sequence_[num_expected_++] = &picture_;
expected_metadata_sequence_[num_expected_++] = &unknown_;
if(!file_utils__generate_flacfile(flacfilename_, &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
@@ -627,6 +628,7 @@ static FLAC__bool test_stream_decoder(Layer layer)
expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
expected_metadata_sequence_[num_expected_++] = &picture_;
expected_metadata_sequence_[num_expected_++] = &unknown_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
@@ -667,6 +669,7 @@ static FLAC__bool test_stream_decoder(Layer layer)
expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
expected_metadata_sequence_[num_expected_++] = &picture_;
expected_metadata_sequence_[num_expected_++] = &unknown_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
@@ -692,6 +695,7 @@ static FLAC__bool test_stream_decoder(Layer layer)
expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
expected_metadata_sequence_[num_expected_++] = &picture_;
expected_metadata_sequence_[num_expected_++] = &unknown_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
@@ -718,6 +722,7 @@ static FLAC__bool test_stream_decoder(Layer layer)
expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
expected_metadata_sequence_[num_expected_++] = &picture_;
expected_metadata_sequence_[num_expected_++] = &unknown_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
@@ -748,6 +753,7 @@ static FLAC__bool test_stream_decoder(Layer layer)
expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
expected_metadata_sequence_[num_expected_++] = &picture_;
expected_metadata_sequence_[num_expected_++] = &unknown_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
@@ -866,6 +872,7 @@ static FLAC__bool test_stream_decoder(Layer layer)
expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
expected_metadata_sequence_[num_expected_++] = &picture_;
expected_metadata_sequence_[num_expected_++] = &unknown_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data))

View File

@@ -45,8 +45,8 @@ static const char * const LayerString[] = {
"Filename"
};
static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, unknown_;
static FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_ };
static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, picture_, unknown_;
static FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_ };
static const unsigned num_metadata_ = sizeof(metadata_sequence_) / sizeof(metadata_sequence_[0]);
static const char *flacfilename_ = "metadata.flac";
@@ -76,12 +76,12 @@ static FLAC__bool die_s_(const char *msg, const FLAC__StreamEncoder *encoder)
static void init_metadata_blocks_()
{
mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_);
mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
}
static void free_metadata_blocks_()
{
mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_);
mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_);
}
static FLAC__StreamEncoderWriteStatus stream_encoder_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)

View File

@@ -100,6 +100,16 @@ static void *malloc_or_die_(size_t size)
return x;
}
static char *strdup_or_die_(const char *s)
{
char *x = strdup(s);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory copying string \"%s\"\n", s);
exit(1);
}
return x;
}
/* functions for working with our metadata copy */
static FLAC__bool replace_in_our_metadata_(FLAC__StreamMetadata *block, unsigned position, FLAC__bool copy)
@@ -485,10 +495,10 @@ static void decoder_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__St
printf("ERROR: got error callback, status = %s (%u)\n", FLAC__StreamDecoderErrorStatusString[status], (unsigned)status);
}
static FLAC__bool generate_file_(FLAC__bool include_cuesheet)
static FLAC__bool generate_file_(FLAC__bool include_extras)
{
FLAC__StreamMetadata streaminfo, vorbiscomment, *cuesheet, padding;
FLAC__StreamMetadata *metadata[3];
FLAC__StreamMetadata streaminfo, vorbiscomment, *cuesheet, picture, padding;
FLAC__StreamMetadata *metadata[4];
unsigned i = 0, n = 0;
printf("generating FLAC file for test\n");
@@ -535,19 +545,49 @@ static FLAC__bool generate_file_(FLAC__bool include_cuesheet)
return die_("priming our metadata");
}
{
picture.is_last = false;
picture.type = FLAC__METADATA_TYPE_PICTURE;
picture.length =
(
FLAC__STREAM_METADATA_PICTURE_TYPE_LEN +
FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN + /* will add the length for the string later */
FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN + /* will add the length for the string later */
FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN +
FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN +
FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN +
FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN /* will add the length for the data later */
) / 8
;
picture.data.picture.type = FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER;
picture.data.picture.mime_type = strdup_or_die_("image/jpeg");
picture.length += strlen(picture.data.picture.mime_type);
picture.data.picture.description = (FLAC__byte*)strdup_or_die_("desc");
picture.length += strlen((const char *)picture.data.picture.description);
picture.data.picture.width = 300;
picture.data.picture.height = 300;
picture.data.picture.depth = 24;
picture.data.picture.data = (FLAC__byte*)strdup_or_die_("SOMEJPEGDATA");
picture.data.picture.data_length = strlen((const char *)picture.data.picture.data);
picture.length += picture.data.picture.data_length;
}
padding.is_last = true;
padding.type = FLAC__METADATA_TYPE_PADDING;
padding.length = 1234;
metadata[n++] = &vorbiscomment;
if (include_cuesheet)
if(include_extras) {
metadata[n++] = cuesheet;
metadata[n++] = &picture;
}
metadata[n++] = &padding;
if(
!insert_to_our_metadata_(&streaminfo, i++, /*copy=*/true) ||
!insert_to_our_metadata_(&vorbiscomment, i++, /*copy=*/true) ||
(include_cuesheet && !insert_to_our_metadata_(cuesheet, i++, /*copy=*/false)) ||
(include_extras && !insert_to_our_metadata_(cuesheet, i++, /*copy=*/false)) ||
(include_extras && !insert_to_our_metadata_(&picture, i++, /*copy=*/true)) ||
!insert_to_our_metadata_(&padding, i++, /*copy=*/true)
)
return die_("priming our metadata");
@@ -627,10 +667,11 @@ static FLAC__bool test_level_0_()
FLAC__StreamMetadata streaminfo;
FLAC__StreamMetadata *tags = 0;
FLAC__StreamMetadata *cuesheet = 0;
FLAC__StreamMetadata *picture = 0;
printf("\n\n++++++ testing level 0 interface\n");
if(!generate_file_(/*include_cuesheet=*/true))
if(!generate_file_(/*include_extras=*/true))
return false;
if(!test_file_(flacfile_, decoder_metadata_callback_null_))
@@ -675,12 +716,25 @@ static FLAC__bool test_level_0_()
/* check to see if some basic data matches (c.f. generate_file_()) */
if(cuesheet->data.cue_sheet.lead_in != 123)
return die_("mismatch in cuesheet->data.vorbis_comment.num_comments");
return die_("mismatch in cuesheet->data.cue_sheet.lead_in");
printf("OK\n");
FLAC__metadata_object_delete(cuesheet);
printf("testing FLAC__metadata_get_picture()... ");
if(!FLAC__metadata_get_picture(flacfile_, &picture, /*type=*/(FLAC__StreamMetadata_Picture_Type)(-1), /*mime_type=*/0, /*description=*/0, /*max_width=*/(unsigned)(-1), /*max_height=*/(unsigned)(-1), /*max_depth=*/(unsigned)(-1)))
return die_("during FLAC__metadata_get_picture()");
/* check to see if some basic data matches (c.f. generate_file_()) */
if(picture->data.picture.type != FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER)
return die_("mismatch in picture->data.picture.type");
printf("OK\n");
FLAC__metadata_object_delete(picture);
if(!remove_file_(flacfile_))
return false;
@@ -703,7 +757,7 @@ static FLAC__bool test_level_1_()
printf("simple iterator on read-only file\n");
if(!generate_file_(/*include_cuesheet=*/false))
if(!generate_file_(/*include_extras=*/false))
return false;
if(!change_stats_(flacfile_, /*read_only=*/true))
@@ -1362,7 +1416,7 @@ static FLAC__bool test_level_2_(FLAC__bool filename_based)
printf("generate read-only file\n");
if(!generate_file_(/*include_cuesheet=*/false))
if(!generate_file_(/*include_extras=*/false))
return false;
if(!change_stats_(flacfile_, /*read_only=*/true))
@@ -1875,7 +1929,7 @@ static FLAC__bool test_level_2_misc_()
printf("generate file\n");
if(!generate_file_(/*include_cuesheet=*/false))
if(!generate_file_(/*include_extras=*/false))
return false;
printf("create chain\n");

View File

@@ -463,10 +463,43 @@ static void cs_delete_(FLAC__StreamMetadata *block, unsigned pos)
cs_calc_len_(block);
}
static void pi_set_mime_type(FLAC__StreamMetadata *block, const char *s)
{
if(block->data.picture.mime_type) {
block->length -= strlen(block->data.picture.mime_type);
free(block->data.picture.mime_type);
}
block->data.picture.mime_type = strdup(s);
FLAC__ASSERT(block->data.picture.mime_type);
block->length += strlen(block->data.picture.mime_type);
}
static void pi_set_description(FLAC__StreamMetadata *block, const FLAC__byte *s)
{
if(block->data.picture.description) {
block->length -= strlen((const char *)block->data.picture.description);
free(block->data.picture.description);
}
block->data.picture.description = (FLAC__byte*)strdup((const char *)s);
FLAC__ASSERT(block->data.picture.description);
block->length += strlen((const char *)block->data.picture.description);
}
static void pi_set_data(FLAC__StreamMetadata *block, const FLAC__byte *data, FLAC__uint32 len)
{
if(block->data.picture.data) {
block->length -= block->data.picture.data_length;
free(block->data.picture.data);
}
block->data.picture.data = (FLAC__byte*)strdup((const char *)data);
FLAC__ASSERT(block->data.picture.data);
block->data.picture.data_length = len;
block->length += len;
}
FLAC__bool test_metadata_object()
{
FLAC__StreamMetadata *block, *blockcopy, *vorbiscomment, *cuesheet;
FLAC__StreamMetadata *block, *blockcopy, *vorbiscomment, *cuesheet, *picture;
FLAC__StreamMetadata_SeekPoint seekpoint_array[14];
FLAC__StreamMetadata_VorbisComment_Entry entry;
FLAC__StreamMetadata_CueSheet_Index index;
@@ -1996,5 +2029,253 @@ FLAC__bool test_metadata_object()
printf("OK\n");
printf("testing PICTURE\n");
printf("testing FLAC__metadata_object_new()... ");
block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE);
if(0 == block) {
printf("FAILED, returned NULL\n");
return false;
}
expected_length = (
FLAC__STREAM_METADATA_PICTURE_TYPE_LEN +
FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN +
FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN +
FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN +
FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN +
FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN +
FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN
) / 8;
if(block->length != expected_length) {
printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length);
return false;
}
printf("OK\n");
printf("testing FLAC__metadata_object_clone()... ");
picture = FLAC__metadata_object_clone(block);
if(0 == picture) {
printf("FAILED, returned NULL\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
pi_set_mime_type(picture, "image/png\t");
printf("testing FLAC__metadata_object_picture_set_mime_type(copy)...");
if(!FLAC__metadata_object_picture_set_mime_type(block, "image/png\t", /*copy=*/true)) {
printf("FAILED, returned false\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_picture_is_legal()...");
{
const char *violation;
if(FLAC__metadata_object_picture_is_legal(block, &violation)) {
printf("FAILED, returned true when expecting false\n");
return false;
}
printf("returned false as expected, violation=\"%s\" OK\n", violation);
}
pi_set_mime_type(picture, "image/png");
printf("testing FLAC__metadata_object_picture_set_mime_type(copy)...");
if(!FLAC__metadata_object_picture_set_mime_type(block, "image/png", /*copy=*/true)) {
printf("FAILED, returned false\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_picture_is_legal()...");
{
const char *violation;
if(!FLAC__metadata_object_picture_is_legal(block, &violation)) {
printf("FAILED, returned false, violation=\"%s\"\n", violation);
return false;
}
printf("OK\n");
}
pi_set_description(picture, (const FLAC__byte *)"DESCRIPTION\xff");
printf("testing FLAC__metadata_object_picture_set_description(copy)...");
if(!FLAC__metadata_object_picture_set_description(block, (FLAC__byte *)"DESCRIPTION\xff", /*copy=*/true)) {
printf("FAILED, returned false\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_picture_is_legal()...");
{
const char *violation;
if(FLAC__metadata_object_picture_is_legal(block, &violation)) {
printf("FAILED, returned true when expecting false\n");
return false;
}
printf("returned false as expected, violation=\"%s\" OK\n", violation);
}
pi_set_description(picture, (const FLAC__byte *)"DESCRIPTION");
printf("testing FLAC__metadata_object_picture_set_description(copy)...");
if(!FLAC__metadata_object_picture_set_description(block, (FLAC__byte *)"DESCRIPTION", /*copy=*/true)) {
printf("FAILED, returned false\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_picture_is_legal()...");
{
const char *violation;
if(!FLAC__metadata_object_picture_is_legal(block, &violation)) {
printf("FAILED, returned false, violation=\"%s\"\n", violation);
return false;
}
printf("OK\n");
}
pi_set_data(picture, (const FLAC__byte*)"PNGDATA", strlen("PNGDATA"));
printf("testing FLAC__metadata_object_picture_set_data(copy)...");
if(!FLAC__metadata_object_picture_set_data(block, (FLAC__byte*)"PNGDATA", strlen("PNGDATA"), /*copy=*/true)) {
printf("FAILED, returned false\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_clone()... ");
blockcopy = FLAC__metadata_object_clone(block);
if(0 == blockcopy) {
printf("FAILED, returned NULL\n");
return false;
}
if(!mutils__compare_block(block, blockcopy))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_delete()... ");
FLAC__metadata_object_delete(blockcopy);
printf("OK\n");
pi_set_mime_type(picture, "image/png\t");
printf("testing FLAC__metadata_object_picture_set_mime_type(own)...");
if(!FLAC__metadata_object_picture_set_mime_type(block, strdup("image/png\t"), /*copy=*/false)) {
printf("FAILED, returned false\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_picture_is_legal()...");
{
const char *violation;
if(FLAC__metadata_object_picture_is_legal(block, &violation)) {
printf("FAILED, returned true when expecting false\n");
return false;
}
printf("returned false as expected, violation=\"%s\" OK\n", violation);
}
pi_set_mime_type(picture, "image/png");
printf("testing FLAC__metadata_object_picture_set_mime_type(own)...");
if(!FLAC__metadata_object_picture_set_mime_type(block, strdup("image/png"), /*copy=*/false)) {
printf("FAILED, returned false\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_picture_is_legal()...");
{
const char *violation;
if(!FLAC__metadata_object_picture_is_legal(block, &violation)) {
printf("FAILED, returned false, violation=\"%s\"\n", violation);
return false;
}
printf("OK\n");
}
pi_set_description(picture, (const FLAC__byte *)"DESCRIPTION\xff");
printf("testing FLAC__metadata_object_picture_set_description(own)...");
if(!FLAC__metadata_object_picture_set_description(block, (FLAC__byte *)strdup("DESCRIPTION\xff"), /*copy=*/false)) {
printf("FAILED, returned false\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_picture_is_legal()...");
{
const char *violation;
if(FLAC__metadata_object_picture_is_legal(block, &violation)) {
printf("FAILED, returned true when expecting false\n");
return false;
}
printf("returned false as expected, violation=\"%s\" OK\n", violation);
}
pi_set_description(picture, (const FLAC__byte *)"DESCRIPTION");
printf("testing FLAC__metadata_object_picture_set_description(own)...");
if(!FLAC__metadata_object_picture_set_description(block, (FLAC__byte *)strdup("DESCRIPTION"), /*copy=*/false)) {
printf("FAILED, returned false\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_picture_is_legal()...");
{
const char *violation;
if(!FLAC__metadata_object_picture_is_legal(block, &violation)) {
printf("FAILED, returned false, violation=\"%s\"\n", violation);
return false;
}
printf("OK\n");
}
pi_set_data(picture, (const FLAC__byte*)"PNGDATA", strlen("PNGDATA"));
printf("testing FLAC__metadata_object_picture_set_data(own)...");
if(!FLAC__metadata_object_picture_set_data(block, (FLAC__byte*)strdup("PNGDATA"), strlen("PNGDATA"), /*copy=*/false)) {
printf("FAILED, returned false\n");
return false;
}
if(!mutils__compare_block(picture, block))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_clone()... ");
blockcopy = FLAC__metadata_object_clone(block);
if(0 == blockcopy) {
printf("FAILED, returned NULL\n");
return false;
}
if(!mutils__compare_block(block, blockcopy))
return false;
printf("OK\n");
printf("testing FLAC__metadata_object_delete()... ");
FLAC__metadata_object_delete(blockcopy);
printf("OK\n");
printf("testing FLAC__metadata_object_delete()... ");
FLAC__metadata_object_delete(picture);
FLAC__metadata_object_delete(block);
printf("OK\n");
return true;
}