Everywhere: Remove LibRIFF

This commit is contained in:
Jelle Raaijmakers 2025-07-02 12:34:34 +02:00 committed by Sam Atkins
commit 180bb0fc5d
Notes: github-actions[bot] 2025-07-02 11:02:33 +00:00
15 changed files with 2 additions and 388 deletions

View file

@ -8,7 +8,6 @@ add_subdirectory(LibIPC)
add_subdirectory(LibJS) add_subdirectory(LibJS)
add_subdirectory(LibRegex) add_subdirectory(LibRegex)
add_subdirectory(LibRequests) add_subdirectory(LibRequests)
add_subdirectory(LibRIFF)
add_subdirectory(LibSyntax) add_subdirectory(LibSyntax)
add_subdirectory(LibTest) add_subdirectory(LibTest)
add_subdirectory(LibTextCodec) add_subdirectory(LibTextCodec)

View file

@ -82,7 +82,7 @@ endif()
serenity_lib(LibGfx gfx) serenity_lib(LibGfx gfx)
target_link_libraries(LibGfx PRIVATE LibCompress LibCore LibCrypto LibFileSystem LibRIFF LibTextCodec LibIPC LibUnicode) target_link_libraries(LibGfx PRIVATE LibCompress LibCore LibCrypto LibFileSystem LibTextCodec LibIPC LibUnicode)
set(generated_sources TIFFMetadata.h TIFFTagHandler.cpp) set(generated_sources TIFFMetadata.h TIFFTagHandler.cpp)
list(TRANSFORM generated_sources PREPEND "ImageFormats/") list(TRANSFORM generated_sources PREPEND "ImageFormats/")

View file

@ -66,7 +66,6 @@ static ErrorOr<void> write_VP8L_header(Stream& stream, unsigned width, unsigned
return {}; return {};
} }
// FIXME: Consider using LibRIFF for RIFF writing details. (It currently has no writing support.)
static ErrorOr<void> align_to_two(Stream& stream, size_t number_of_bytes_written) static ErrorOr<void> align_to_two(Stream& stream, size_t number_of_bytes_written)
{ {
// https://developers.google.com/speed/webp/docs/riff_container // https://developers.google.com/speed/webp/docs/riff_container
@ -172,7 +171,6 @@ static ErrorOr<void> write_VP8X_chunk(Stream& stream, VP8XHeader const& header)
return {}; return {};
} }
// FIXME: Consider using LibRIFF for RIFF writing details. (It currently has no writing support.)
static ErrorOr<void> align_to_two(AllocatingMemoryStream& stream) static ErrorOr<void> align_to_two(AllocatingMemoryStream& stream)
{ {
return align_to_two(stream, stream.used_buffer_size()); return align_to_two(stream, stream.used_buffer_size());

View file

@ -17,7 +17,7 @@ set(SOURCES
) )
serenity_lib(LibMedia media) serenity_lib(LibMedia media)
target_link_libraries(LibMedia PRIVATE LibCore LibCrypto LibRIFF LibIPC LibGfx LibThreading LibUnicode) target_link_libraries(LibMedia PRIVATE LibCore LibCrypto LibIPC LibGfx LibThreading LibUnicode)
if (NOT ANDROID) if (NOT ANDROID)
target_sources(LibMedia PRIVATE target_sources(LibMedia PRIVATE

View file

@ -1,6 +0,0 @@
set(SOURCES
Decoding.cpp
Details.cpp
)
serenity_lib(LibRIFF riff)

View file

@ -1,71 +0,0 @@
/*
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Array.h>
#include <AK/Endian.h>
#include <AK/Format.h>
#include <AK/StringView.h>
#include <AK/Types.h>
namespace RIFF {
static constexpr size_t const chunk_id_size = 4;
// Also referred to as "FourCC" (four character code) in the context of some formats.
struct ChunkID {
constexpr ChunkID(char const name[4])
{
id_data[0] = static_cast<u8>(name[0]);
id_data[1] = static_cast<u8>(name[1]);
id_data[2] = static_cast<u8>(name[2]);
id_data[3] = static_cast<u8>(name[3]);
}
constexpr ChunkID(Array<u8, chunk_id_size> data)
: id_data(data)
{
}
constexpr ChunkID(ChunkID const&) = default;
constexpr ChunkID(ChunkID&&) = default;
constexpr ChunkID& operator=(ChunkID const&) = default;
static constexpr ChunkID from_number(u32 number)
{
return Array<u8, chunk_id_size> { {
static_cast<u8>((number >> 24) & 0xff),
static_cast<u8>((number >> 16) & 0xff),
static_cast<u8>((number >> 8) & 0xff),
static_cast<u8>(number & 0xff),
} };
}
static ErrorOr<ChunkID> read_from_stream(Stream& stream);
StringView as_ascii_string() const;
constexpr u32 as_number() const
{
return (id_data[0] << 24) | (id_data[1] << 16) | (id_data[2] << 8) | id_data[3];
}
bool operator==(ChunkID const&) const = default;
bool operator==(StringView) const;
Array<u8, chunk_id_size> id_data;
};
static_assert(AssertSize<ChunkID, chunk_id_size>());
}
template<>
struct AK::Formatter<RIFF::ChunkID> : StandardFormatter {
ErrorOr<void> format(FormatBuilder& builder, RIFF::ChunkID const& chunk_id)
{
TRY(builder.put_padding('\'', 1));
TRY(builder.put_literal(chunk_id.as_ascii_string()));
TRY(builder.put_padding('\'', 1));
return {};
}
};

View file

@ -1,28 +0,0 @@
/*
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
* Copyright (c) 2023, Nicolas Ramz <nicolas.ramz@gmail.com>
* Copyright (c) 2023, Nico Weber <thakis@chromium.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Stream.h>
#include <LibRIFF/ChunkID.h>
#include <LibRIFF/RIFF.h>
ErrorOr<RIFF::ChunkID> RIFF::ChunkID::read_from_stream(Stream& stream)
{
Array<u8, chunk_id_size> id;
TRY(stream.read_until_filled(id.span()));
return ChunkID { id };
}
ErrorOr<RIFF::OwnedList> RIFF::OwnedList::read_from_stream(Stream& stream)
{
auto type = TRY(stream.read_value<ChunkID>());
Vector<RIFF::OwnedChunk> chunks;
while (!stream.is_eof())
TRY(chunks.try_append(TRY(stream.read_value<RIFF::OwnedChunk>())));
return RIFF::OwnedList { .type = type, .chunks = move(chunks) };
}

View file

@ -1,125 +0,0 @@
/*
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "Details.h"
#include <AK/TypeCasts.h>
#include <LibRIFF/IFF.h>
#include <LibRIFF/RIFF.h>
namespace RIFF {
StringView ChunkID::as_ascii_string() const
{
return StringView { id_data.span() };
}
bool ChunkID::operator==(StringView other_string) const
{
return as_ascii_string() == other_string;
}
namespace Detail {
template<typename WordType>
auto ChunkHeader<WordType>::read_from_stream(Stream& stream) -> ErrorOr<ChunkHeader>
{
auto id = TRY(stream.read_value<RIFF::ChunkID>());
u32 size = TRY(stream.read_value<WordType>());
return ChunkHeader { id, size };
}
template<typename HeaderType>
auto FileHeader<HeaderType>::read_from_stream(Stream& stream) -> ErrorOr<FileHeader>
{
auto header = TRY(stream.read_value<HeaderType>());
auto subformat = TRY(stream.read_value<RIFF::ChunkID>());
return FileHeader { header, subformat };
}
template<typename HeaderType>
Chunk<HeaderType>::Chunk(HeaderType header, ReadonlyBytes data)
: m_header(header)
, m_data(data)
{
VERIFY(data.size() == header.size);
}
template<typename HeaderType>
FixedMemoryStream Chunk<HeaderType>::data_stream() const
{
return FixedMemoryStream { m_data };
}
template<typename HeaderType>
auto Chunk<HeaderType>::decode(ReadonlyBytes data) -> ErrorOr<Chunk>
{
auto data_stream = FixedMemoryStream { data };
auto header = TRY(HeaderType::read_from_stream(data_stream));
if (data.size() < sizeof(HeaderType) + header.size)
return Error::from_string_literal("Not enough data for IFF/RIFF chunk");
return Chunk { header, data.slice(sizeof(HeaderType), header.size) };
}
template<typename HeaderType>
auto Chunk<HeaderType>::decode_and_advance(ReadonlyBytes& data) -> ErrorOr<Chunk>
{
auto chunk = TRY(decode(data));
data = data.slice(sizeof(HeaderType) + chunk.size());
// add padding if needed
if (chunk.size() % 2 != 0) {
if (data.is_empty())
return Error::from_string_literal("Missing data for padding byte");
if (*data.data() != 0)
return Error::from_string_literal("Padding byte is not 0");
data = data.slice(1);
}
return chunk;
}
template<typename HeaderType>
OwnedChunk<HeaderType>::OwnedChunk(HeaderType header, Buffer backing_data)
: Chunk<HeaderType>(header, backing_data.span())
, m_backing_data(move(backing_data))
{
}
template<typename HeaderType>
auto OwnedChunk<HeaderType>::read_from_stream(Stream& stream) -> ErrorOr<OwnedChunk>
{
auto header = TRY(stream.read_value<HeaderType>());
auto data = TRY(Buffer::create_uninitialized(header.size));
TRY(stream.read_until_filled(data.span()));
// RIFF chunks may have trailing padding to align to x86 "words" (i.e. 2 bytes).
if (is<SeekableStream>(stream)) {
if (!stream.is_eof()) {
auto stream_position = TRY(static_cast<SeekableStream&>(stream).tell());
if (stream_position % 2 != 0)
TRY(static_cast<SeekableStream&>(stream).seek(1, SeekMode::FromCurrentPosition));
}
} else {
dbgln("RIFF Warning: Cannot align stream to 2-byte boundary, next chunk may be bogus!");
}
return OwnedChunk { header, data };
}
template class Chunk<IFF::ChunkHeader>;
template class Chunk<RIFF::ChunkHeader>;
template class OwnedChunk<IFF::ChunkHeader>;
template class OwnedChunk<RIFF::ChunkHeader>;
template struct ChunkHeader<IFF::WordType>;
template struct ChunkHeader<RIFF::WordType>;
template struct FileHeader<IFF::ChunkHeader>;
template struct FileHeader<RIFF::ChunkHeader>;
}
}

View file

@ -1,74 +0,0 @@
/*
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/ByteBuffer.h>
#include <AK/MemoryStream.h>
#include <LibRIFF/ChunkID.h>
// Despite the name, this header contains details for both RIFF and IFF
namespace RIFF::Detail {
// http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf page 11 (Chunks)
template<typename WordType>
struct ChunkHeader {
static ErrorOr<ChunkHeader> read_from_stream(Stream& stream);
RIFF::ChunkID id;
u32 size;
};
// Standard RIFF/IFF file formats use a global chunk with a chunk ID (magic bytes) such as "RIFF" or "FORM".
// A chunk ID right at the start of the global chunk specifies the subformat specific to the file type.
// Example for RIFF from WebP: https://developers.google.com/speed/webp/docs/riff_container#webp_file_header
template<typename HeaderType>
struct FileHeader {
HeaderType global_header;
RIFF::ChunkID subformat;
static ErrorOr<FileHeader> read_from_stream(Stream& stream);
constexpr ChunkID magic() const { return global_header.id; }
constexpr u32 file_size() const { return global_header.size; }
};
// An RIFF or IFF chunk.
template<typename HeaderType>
class Chunk {
public:
Chunk(HeaderType header, ReadonlyBytes data);
// Note that the resulting chunk will refer to the provided data.
static ErrorOr<Chunk> decode(ReadonlyBytes data);
static ErrorOr<Chunk> decode_and_advance(ReadonlyBytes& data);
RIFF::ChunkID id() const { return m_header.id; }
u32 size() const { return m_header.size; }
ReadonlyBytes data() const { return m_data; }
FixedMemoryStream data_stream() const;
u8 operator[](size_t index) const { return data()[index]; }
private:
HeaderType m_header;
ReadonlyBytes m_data;
};
// Owns the chunk data and can therefore be parsed from a stream.
template<typename HeaderType>
class OwnedChunk : public Chunk<HeaderType> {
public:
using Buffer = AK::Detail::ByteBuffer<0>;
OwnedChunk(HeaderType, Buffer);
static ErrorOr<OwnedChunk> read_from_stream(Stream& stream);
private:
Buffer m_backing_data;
};
}

View file

@ -1,24 +0,0 @@
/*
* Copyright (c) 2018-2023, the SerenityOS developers.
* Copyright (c) 2023, Nico Weber <thakis@chromium.org>
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Forward.h>
#include <LibRIFF/ChunkID.h>
#include <LibRIFF/Details.h>
// IFF chunks (as often used by Amiga, EA and more modern formats) use big-endian fields.
namespace IFF {
using WordType = BigEndian<u32>;
using ChunkHeader = RIFF::Detail::ChunkHeader<WordType>;
using FileHeader = RIFF::Detail::FileHeader<ChunkHeader>;
using Chunk = RIFF::Detail::Chunk<ChunkHeader>;
using OwnedChunk = RIFF::Detail::OwnedChunk<ChunkHeader>;
}

View file

@ -1,35 +0,0 @@
/*
* Copyright (c) 2018-2023, the SerenityOS developers.
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Forward.h>
#include <AK/Vector.h>
#include <LibRIFF/ChunkID.h>
#include <LibRIFF/Details.h>
// RIFF chunks (as often used by Microsoft's older formats) use little-endian fields.
namespace RIFF {
static constexpr StringView const riff_magic = "RIFF"sv;
static constexpr StringView const list_chunk_id = "LIST"sv;
using WordType = LittleEndian<u32>;
using ChunkHeader = RIFF::Detail::ChunkHeader<WordType>;
using FileHeader = RIFF::Detail::FileHeader<ChunkHeader>;
using Chunk = RIFF::Detail::Chunk<ChunkHeader>;
using OwnedChunk = RIFF::Detail::OwnedChunk<ChunkHeader>;
// http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf page 23 (LIST type)
struct OwnedList {
static ErrorOr<OwnedList> read_from_stream(Stream& stream);
ChunkID type;
Vector<OwnedChunk> chunks;
};
}

View file

@ -398,7 +398,6 @@ if (current_os != "mac") {
"//Userland/Libraries/LibJS", "//Userland/Libraries/LibJS",
"//Userland/Libraries/LibLine", "//Userland/Libraries/LibLine",
"//Userland/Libraries/LibMedia", "//Userland/Libraries/LibMedia",
"//Userland/Libraries/LibRIFF",
"//Userland/Libraries/LibRegex", "//Userland/Libraries/LibRegex",
"//Userland/Libraries/LibRequests", "//Userland/Libraries/LibRequests",
"//Userland/Libraries/LibSyntax", "//Userland/Libraries/LibSyntax",
@ -430,7 +429,6 @@ if (current_os != "mac") {
"$root_out_dir/lib/liblagom-media.dylib", "$root_out_dir/lib/liblagom-media.dylib",
"$root_out_dir/lib/liblagom-regex.dylib", "$root_out_dir/lib/liblagom-regex.dylib",
"$root_out_dir/lib/liblagom-requests.dylib", "$root_out_dir/lib/liblagom-requests.dylib",
"$root_out_dir/lib/liblagom-riff.dylib",
"$root_out_dir/lib/liblagom-syntax.dylib", "$root_out_dir/lib/liblagom-syntax.dylib",
"$root_out_dir/lib/liblagom-textcodec.dylib", "$root_out_dir/lib/liblagom-textcodec.dylib",
"$root_out_dir/lib/liblagom-threading.dylib", "$root_out_dir/lib/liblagom-threading.dylib",

View file

@ -95,7 +95,6 @@ shared_library("LibGfx") {
"//Userland/Libraries/LibCrypto", "//Userland/Libraries/LibCrypto",
"//Userland/Libraries/LibFileSystem", "//Userland/Libraries/LibFileSystem",
"//Userland/Libraries/LibIPC", "//Userland/Libraries/LibIPC",
"//Userland/Libraries/LibRIFF",
"//Userland/Libraries/LibTextCodec", "//Userland/Libraries/LibTextCodec",
"//Userland/Libraries/LibURL", "//Userland/Libraries/LibURL",
"//Userland/Libraries/LibUnicode", "//Userland/Libraries/LibUnicode",

View file

@ -41,7 +41,6 @@ shared_library("LibMedia") {
"//Userland/Libraries/LibCrypto", "//Userland/Libraries/LibCrypto",
"//Userland/Libraries/LibGfx", "//Userland/Libraries/LibGfx",
"//Userland/Libraries/LibIPC", "//Userland/Libraries/LibIPC",
"//Userland/Libraries/LibRIFF",
"//Userland/Libraries/LibThreading", "//Userland/Libraries/LibThreading",
"//Userland/Libraries/LibUnicode", "//Userland/Libraries/LibUnicode",
] ]

View file

@ -1,16 +0,0 @@
shared_library("LibRIFF") {
output_name = "riff"
include_dirs = [ "//Userland/Libraries" ]
sources = [
"ChunkID.h",
"Decoding.cpp",
"Details.cpp",
"Details.h",
"IFF.h",
"RIFF.h",
]
deps = [ "//AK" ]
}