2023-03-06 14:42:04 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
// Copyright The Music Player Daemon Project
|
2019-08-13 12:22:11 +02:00
|
|
|
|
|
|
|
#include "Id3Picture.hxx"
|
|
|
|
#include "Handler.hxx"
|
2023-12-22 18:09:31 +01:00
|
|
|
#include "util/PackedBigEndian.hxx"
|
2019-08-13 12:22:11 +02:00
|
|
|
|
2020-03-13 01:08:53 +01:00
|
|
|
#include <cstdint>
|
2019-08-13 12:22:11 +02:00
|
|
|
#include <string>
|
|
|
|
|
2022-07-04 14:52:56 +02:00
|
|
|
static std::string_view
|
2022-05-24 13:51:18 +02:00
|
|
|
ReadString(std::span<const std::byte> &src) noexcept
|
2019-08-13 12:22:11 +02:00
|
|
|
{
|
2022-05-24 13:51:18 +02:00
|
|
|
if (src.size() < 4)
|
2022-07-04 14:52:56 +02:00
|
|
|
return {};
|
2019-08-13 12:22:11 +02:00
|
|
|
|
2022-05-24 13:51:18 +02:00
|
|
|
const size_t length = *(const PackedBE32 *)(const void *)src.data();
|
|
|
|
src = src.subspan(4);
|
2019-08-13 12:22:11 +02:00
|
|
|
|
2022-05-24 13:51:18 +02:00
|
|
|
if (src.size() < length)
|
2022-07-04 14:52:56 +02:00
|
|
|
return {};
|
2019-08-13 12:22:11 +02:00
|
|
|
|
2022-05-24 13:51:18 +02:00
|
|
|
const std::string_view result{(const char *)src.data(), length};
|
|
|
|
src = src.subspan(length);
|
2019-08-13 12:22:11 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-05-24 13:51:18 +02:00
|
|
|
ScanId3Apic(std::span<const std::byte> buffer, TagHandler &handler) noexcept
|
2019-08-13 12:22:11 +02:00
|
|
|
{
|
2022-05-24 13:51:18 +02:00
|
|
|
if (buffer.size() < 4)
|
2019-08-13 12:22:11 +02:00
|
|
|
return;
|
|
|
|
|
2022-05-24 13:51:18 +02:00
|
|
|
buffer = buffer.subspan(4); /* picture type */
|
2019-08-13 12:22:11 +02:00
|
|
|
|
|
|
|
const auto mime_type = ReadString(buffer);
|
2022-07-04 14:52:56 +02:00
|
|
|
if (mime_type.data() == nullptr)
|
2019-08-13 12:22:11 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* description */
|
2022-07-04 14:52:56 +02:00
|
|
|
if (ReadString(buffer).data() == nullptr)
|
2019-08-13 12:22:11 +02:00
|
|
|
return;
|
|
|
|
|
2022-05-24 13:51:18 +02:00
|
|
|
if (buffer.size() < 20)
|
2019-08-13 12:22:11 +02:00
|
|
|
return;
|
|
|
|
|
2022-05-24 13:51:18 +02:00
|
|
|
buffer = buffer.subspan(16);
|
2019-08-13 12:22:11 +02:00
|
|
|
|
2022-05-24 13:51:18 +02:00
|
|
|
const size_t image_size = *(const PackedBE32 *)(const void *)buffer.data();
|
|
|
|
buffer = buffer.subspan(4);
|
2019-08-13 12:22:11 +02:00
|
|
|
|
2022-05-24 13:51:18 +02:00
|
|
|
if (buffer.size() < image_size)
|
2019-08-13 12:22:11 +02:00
|
|
|
return;
|
|
|
|
|
2022-05-24 13:51:18 +02:00
|
|
|
const auto image = buffer.first(image_size);
|
2019-08-13 12:22:11 +02:00
|
|
|
|
2022-07-04 14:52:56 +02:00
|
|
|
// TODO: don't copy MIME type, pass std::string_view to TagHandler::OnPicture()
|
|
|
|
handler.OnPicture(std::string{mime_type}.c_str(),
|
2019-08-13 12:22:11 +02:00
|
|
|
image);
|
|
|
|
}
|