mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 10:17:35 +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):
|
case (FlacMetadataBlockType::SEEKTABLE):
|
||||||
TRY(load_seektable(block));
|
TRY(load_seektable(block));
|
||||||
break;
|
break;
|
||||||
|
case FlacMetadataBlockType::PICTURE:
|
||||||
|
TRY(load_picture(block));
|
||||||
|
break;
|
||||||
case FlacMetadataBlockType::APPLICATION:
|
case FlacMetadataBlockType::APPLICATION:
|
||||||
// Note: Third-party library can encode specific data in this.
|
// Note: Third-party library can encode specific data in this.
|
||||||
dbgln("Unknown 'Application' metadata block encountered.");
|
dbgln("Unknown 'Application' metadata block encountered.");
|
||||||
|
@ -130,6 +133,43 @@ MaybeLoaderError FlacLoaderPlugin::parse_header()
|
||||||
return {};
|
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
|
// 11.13. METADATA_BLOCK_SEEKTABLE
|
||||||
MaybeLoaderError FlacLoaderPlugin::load_seektable(FlacRawMetadataBlock& block)
|
MaybeLoaderError FlacLoaderPlugin::load_seektable(FlacRawMetadataBlock& block)
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,6 +89,7 @@ private:
|
||||||
// decode a single rice partition that has its own rice parameter
|
// 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);
|
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_seektable(FlacRawMetadataBlock&);
|
||||||
|
MaybeLoaderError load_picture(FlacRawMetadataBlock&);
|
||||||
|
|
||||||
// Converters for special coding used in frame headers
|
// Converters for special coding used in frame headers
|
||||||
ALWAYS_INLINE ErrorOr<u32, LoaderError> convert_sample_count_code(u8 sample_count_code);
|
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/Span.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <AK/Try.h>
|
#include <AK/Try.h>
|
||||||
|
#include <LibAudio/GenericTypes.h>
|
||||||
#include <LibAudio/LoaderError.h>
|
#include <LibAudio/LoaderError.h>
|
||||||
#include <LibAudio/Sample.h>
|
#include <LibAudio/Sample.h>
|
||||||
#include <LibAudio/SampleFormats.h>
|
#include <LibAudio/SampleFormats.h>
|
||||||
|
@ -62,6 +63,8 @@ protected:
|
||||||
OwnPtr<Core::Stream::SeekableStream> m_stream;
|
OwnPtr<Core::Stream::SeekableStream> m_stream;
|
||||||
// The constructor might set this so that we can initialize the data stream later.
|
// The constructor might set this so that we can initialize the data stream later.
|
||||||
Optional<Bytes> m_backing_memory;
|
Optional<Bytes> m_backing_memory;
|
||||||
|
|
||||||
|
Vector<PictureData> m_pictures;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Loader : public RefCounted<Loader> {
|
class Loader : public RefCounted<Loader> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue