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:
parent
db40a514f5
commit
2ddcfcb00f
4 changed files with 98 additions and 0 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
54
Userland/Libraries/LibAudio/GenericTypes.h
Normal file
54
Userland/Libraries/LibAudio/GenericTypes.h
Normal 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;
|
||||
};
|
||||
|
||||
}
|
|
@ -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> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue