mirror of
https://github.com/taglib/taglib.git
synced 2026-08-14 06:17:00 -04:00
MP4: Allow extracting covr with wrong flags (#1383)
If the covr has invalid flags, detect the image format from the magic bytes and return the image anyways even if the type is unknown.
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "tbytevector.h"
|
||||
#include "tdebug.h"
|
||||
#include "tutils.h"
|
||||
|
||||
#include "id3v1genres.h"
|
||||
|
||||
@@ -40,6 +41,25 @@ namespace {
|
||||
|
||||
constexpr char freeFormPrefix[] = "----:com.apple.iTunes:";
|
||||
|
||||
MP4::CoverArt::Format detectImageFormat(const ByteVector &payload)
|
||||
{
|
||||
const unsigned int size = payload.size();
|
||||
if(size >= 2 &&
|
||||
static_cast<unsigned char>(payload[0]) == 0xff &&
|
||||
static_cast<unsigned char>(payload[1]) == 0xd8)
|
||||
return MP4::CoverArt::JPEG;
|
||||
if(size >= 8 && payload.startsWith("\x89PNG\x0d\x0a\x1a\x0a"))
|
||||
return MP4::CoverArt::PNG;
|
||||
if(size >= 6 && payload.startsWith("GIF8"))
|
||||
return MP4::CoverArt::GIF;
|
||||
if(size >= 14 &&
|
||||
static_cast<unsigned char>(payload[0]) == 'B' &&
|
||||
static_cast<unsigned char>(payload[1]) == 'M' &&
|
||||
payload.toUInt(6, false) == 0)
|
||||
return MP4::CoverArt::BMP;
|
||||
return MP4::CoverArt::Unknown;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class ItemFactory::ItemFactoryPrivate
|
||||
@@ -625,13 +645,21 @@ std::pair<String, Item> ItemFactory::parseCovr(
|
||||
debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\"");
|
||||
break;
|
||||
}
|
||||
const ByteVector payload = data.mid(pos + 16, length - 16);
|
||||
if(flags == TypeJPEG || flags == TypePNG || flags == TypeBMP ||
|
||||
flags == TypeGIF || flags == TypeImplicit) {
|
||||
value.append(MP4::CoverArt(static_cast<MP4::CoverArt::Format>(flags),
|
||||
data.mid(pos + 16, length - 16)));
|
||||
value.append(MP4::CoverArt(static_cast<MP4::CoverArt::Format>(flags), payload));
|
||||
}
|
||||
else {
|
||||
debug("MP4: Unknown covr format " + String::number(flags));
|
||||
// The flags field holds an unexpected type written by several buggy encoders/taggers
|
||||
// (e.g. files where flags == TypeUTF8 == 1 but the payload is a JPEG image).
|
||||
// Because 'covr' is semantically an image-only atom, try to recover the
|
||||
// real format by sniffing the payload's magic bytes rather than silently
|
||||
// discarding the artwork.
|
||||
const auto format = detectImageFormat(payload);
|
||||
debug(Utils::formatString(
|
||||
"MP4: Replacing unexpected covr flags %d by detected format %d", flags, format));
|
||||
value.append(MP4::CoverArt(format, payload));
|
||||
}
|
||||
pos += length;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user