1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:47:45 +00:00

LibAudio: Parse the picture metadata block

This commit is contained in:
Lucas CHOLLET 2022-10-02 18:48:38 +02:00 committed by Andrew Kaster
parent db40a514f5
commit 2ddcfcb00f
4 changed files with 98 additions and 0 deletions

View file

@ -112,6 +112,9 @@ MaybeLoaderError FlacLoaderPlugin::parse_header()
case (FlacMetadataBlockType::SEEKTABLE):
TRY(load_seektable(block));
break;
case FlacMetadataBlockType::PICTURE:
TRY(load_picture(block));
break;
case FlacMetadataBlockType::APPLICATION:
// Note: Third-party library can encode specific data in this.
dbgln("Unknown 'Application' metadata block encountered.");
@ -130,6 +133,43 @@ MaybeLoaderError FlacLoaderPlugin::parse_header()
return {};
}
// 11.19. METADATA_BLOCK_PICTURE
MaybeLoaderError FlacLoaderPlugin::load_picture(FlacRawMetadataBlock& block)
{
auto memory_stream = LOADER_TRY(Core::Stream::MemoryStream::construct(block.data.bytes()));
auto picture_block_bytes = LOADER_TRY(BigEndianInputBitStream::construct(*memory_stream));
PictureData picture {};
picture.type = static_cast<ID3PictureType>(LOADER_TRY(picture_block_bytes->read_bits(32)));
auto const mime_string_length = LOADER_TRY(picture_block_bytes->read_bits(32));
// Note: We are seeking before reading the value to ensure that we stayed inside buffer's size.
auto offset_before_seeking = memory_stream->offset();
LOADER_TRY(memory_stream->seek(mime_string_length, Core::Stream::SeekMode::FromCurrentPosition));
picture.mime_string = { block.data.bytes().data() + offset_before_seeking, (size_t)mime_string_length };
auto const description_string_length = LOADER_TRY(picture_block_bytes->read_bits(32));
offset_before_seeking = memory_stream->offset();
LOADER_TRY(memory_stream->seek(description_string_length, Core::Stream::SeekMode::FromCurrentPosition));
picture.description_string = Vector<u32> { Span<u32> { reinterpret_cast<u32*>(block.data.bytes().data() + offset_before_seeking), (size_t)description_string_length } };
picture.width = LOADER_TRY(picture_block_bytes->read_bits(32));
picture.height = LOADER_TRY(picture_block_bytes->read_bits(32));
picture.color_depth = LOADER_TRY(picture_block_bytes->read_bits(32));
picture.colors = LOADER_TRY(picture_block_bytes->read_bits(32));
auto const picture_size = LOADER_TRY(picture_block_bytes->read_bits(32));
offset_before_seeking = memory_stream->offset();
LOADER_TRY(memory_stream->seek(picture_size, Core::Stream::SeekMode::FromCurrentPosition));
picture.data = Vector<u8> { Span<u8> { block.data.bytes().data() + offset_before_seeking, (size_t)picture_size } };
m_pictures.append(move(picture));
return {};
}
// 11.13. METADATA_BLOCK_SEEKTABLE
MaybeLoaderError FlacLoaderPlugin::load_seektable(FlacRawMetadataBlock& block)
{

View file

@ -89,6 +89,7 @@ private:
// decode a single rice partition that has its own rice parameter
ALWAYS_INLINE ErrorOr<Vector<i32>, LoaderError> decode_rice_partition(u8 partition_type, u32 partitions, u32 partition_index, FlacSubframeHeader& subframe, BigEndianInputBitStream& bit_input);
MaybeLoaderError load_seektable(FlacRawMetadataBlock&);
MaybeLoaderError load_picture(FlacRawMetadataBlock&);
// Converters for special coding used in frame headers
ALWAYS_INLINE ErrorOr<u32, LoaderError> convert_sample_count_code(u8 sample_count_code);

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2022, Lucas Chollet <lucas.chollet@free.fr>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/String.h>
#include <AK/Vector.h>
namespace Audio {
// 11.20. PICTURE_TYPE (in Flac specification)
enum class ID3PictureType : u32 {
Other = 0,
FileIcon = 1,
OtherFileIcon = 2,
FrontCover = 3,
BackCover = 4,
LeafletPage = 5,
Media = 6,
LeadArtist = 7,
Artist = 8,
Conductor = 9,
Band = 10,
Composer = 11,
Lyricist = 12,
RecordingLocation = 13,
DuringRecording = 14,
DuringPerformance = 15,
MovieScreenCapture = 16,
BrightColouredFish = 17,
Illustration = 18,
BandLogoType = 19,
PublisherLogoType = 20,
// others are reserved
};
// Note: This was first implemented for Flac but is compatible with ID3v2
struct PictureData {
ID3PictureType type {};
String mime_string {};
Vector<u32> description_string {};
u32 width {};
u32 height {};
u32 color_depth {};
u32 colors {};
Vector<u8> data;
};
}

View file

@ -15,6 +15,7 @@
#include <AK/Span.h>
#include <AK/StringView.h>
#include <AK/Try.h>
#include <LibAudio/GenericTypes.h>
#include <LibAudio/LoaderError.h>
#include <LibAudio/Sample.h>
#include <LibAudio/SampleFormats.h>
@ -62,6 +63,8 @@ protected:
OwnPtr<Core::Stream::SeekableStream> m_stream;
// The constructor might set this so that we can initialize the data stream later.
Optional<Bytes> m_backing_memory;
Vector<PictureData> m_pictures;
};
class Loader : public RefCounted<Loader> {