mirror of
https://github.com/fmang/opustags.git
synced 2024-11-06 05:27:23 +01:00
Deduce the cover’s MIME type from its signature
This commit is contained in:
parent
558160d5c3
commit
46cc78bfff
22
src/opus.cc
22
src/opus.cc
@ -182,10 +182,30 @@ std::optional<ot::picture> ot::extract_cover(const ot::opus_tags& tags)
|
||||
return picture(decode_base64(cover_value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the MIME type of the given data block by checking the first bytes. Only the most common
|
||||
* image formats are currently supported. Using magic(5) would give better results but that level of
|
||||
* exhaustiveness is probably not necessary.
|
||||
*/
|
||||
static ot::byte_string_view detect_mime_type(ot::byte_string_view data)
|
||||
{
|
||||
static std::initializer_list<std::pair<ot::byte_string_view, ot::byte_string_view>> magic_numbers = {
|
||||
{ "\xff\xd8\xff"_bsv, "image/jpeg"_bsv },
|
||||
{ "\x89PNG"_bsv, "image/png"_bsv },
|
||||
{ "GIF8"_bsv, "image/gif"_bsv },
|
||||
};
|
||||
for (auto [magic, mime] : magic_numbers) {
|
||||
if (data.starts_with(magic))
|
||||
return mime;
|
||||
}
|
||||
fputs("warning: Could not identify the MIME type of the picture; defaulting to application/octet-stream.\n", stderr);
|
||||
return "application/octet-stream"_bsv;
|
||||
}
|
||||
|
||||
std::string ot::make_cover(ot::byte_string_view picture_data)
|
||||
{
|
||||
picture pic;
|
||||
pic.mime_type = "application/octet-stream"_bsv;
|
||||
pic.mime_type = detect_mime_type(picture_data);
|
||||
pic.picture_data = picture_data;
|
||||
return "METADATA_BLOCK_PICTURE=" + encode_base64(pic.serialize());
|
||||
}
|
||||
|
@ -169,16 +169,16 @@ static void make_cover()
|
||||
{
|
||||
ot::byte_string_view picture_block = ""_bsv
|
||||
"\x00\x00\x00\x03" // Picture type 3.
|
||||
"\x00\x00\x00\x18" "application/octet-stream" // MIME type.
|
||||
"\x00\x00\x00\x09" "image/png" // MIME type.
|
||||
"\x00\x00\x00\x00" "" // Description.
|
||||
"\x00\x00\x00\x00" // Width.
|
||||
"\x00\x00\x00\x00" // Height.
|
||||
"\x00\x00\x00\x00" // Color depth.
|
||||
"\x00\x00\x00\x00" // Palette size.
|
||||
"\x00\x00\x00\x0C" "Picture data";
|
||||
"\x00\x00\x00\x11" "\x89PNG Picture data";
|
||||
|
||||
std::string expected = "METADATA_BLOCK_PICTURE=" + ot::encode_base64(picture_block);
|
||||
is(ot::make_cover("Picture data"_bsv), expected, "build the picture tag");
|
||||
is(ot::make_cover("\x89PNG Picture data"_bsv), expected, "build the picture tag");
|
||||
}
|
||||
|
||||
int main()
|
||||
|
@ -333,7 +333,7 @@ unlink('out.opus');
|
||||
|
||||
is_deeply(opustags(qw(-D --set-cover pixel.png gobble.opus -o out.opus), ), ['', '', 0], 'set the cover');
|
||||
is_deeply(opustags(qw(--output-cover out.png out.opus), ), [<<'END_OUT', '', 0], 'extract the cover');
|
||||
METADATA_BLOCK_PICTURE=AAAAAwAAABhhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWJUE5HDQoaCgAAAA1JSERSAAAAAQAAAAEIAgAAAJB3U94AAAAMSURBVAjXY/j//z8ABf4C/tzMWecAAAAASUVORK5CYII=
|
||||
METADATA_BLOCK_PICTURE=AAAAAwAAAAlpbWFnZS9wbmcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWJUE5HDQoaCgAAAA1JSERSAAAAAQAAAAEIAgAAAJB3U94AAAAMSURBVAjXY/j//z8ABf4C/tzMWecAAAAASUVORK5CYII=
|
||||
END_OUT
|
||||
is(md5('out.png'), md5('pixel.png'), 'the extracted cover is identical to the one set');
|
||||
unlink('out.opus');
|
||||
|
Loading…
Reference in New Issue
Block a user