mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-25 17:39:27 +00:00
We still construct the code length codes manually, and now we also construct a PrefixCodeGroup manually that assigns 8 bits to all symbols (except for fully-opaque alpha channels, and for the unused distance codes, like before). But now we use the CanonicalCodes from that PrefixCodeGroup for writing. No behavior change at all, the output is bit-for-bit identical to before. But this is a step towards actually huffman-coding symbols. This is however a pretty big perf regression. For `image -o test.webp test.bmp` (where test.bmp is retro-sunset.png re-encoded as bmp), time goes from 23.7 ms to 33.2 ms. `animation -o wow.webp giphy.gif` goes from 85.5 ms to 127.7 ms. `animation -o wow.webp 7z7c.gif` goes from 12.6 ms to 16.5 ms.
43 lines
1.3 KiB
C++
43 lines
1.3 KiB
C++
/*
|
|
* Copyright (c) 2024, Nico Weber <thakis@chromium.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibGfx/ImageFormats/WebPSharedLossless.h>
|
|
|
|
namespace Gfx {
|
|
|
|
ErrorOr<CanonicalCode> CanonicalCode::from_bytes(ReadonlyBytes bytes)
|
|
{
|
|
auto non_zero_symbol_count = 0;
|
|
auto last_non_zero_symbol = -1;
|
|
for (size_t i = 0; i < bytes.size(); i++) {
|
|
if (bytes[i] != 0) {
|
|
non_zero_symbol_count++;
|
|
last_non_zero_symbol = i;
|
|
}
|
|
}
|
|
|
|
if (non_zero_symbol_count == 1)
|
|
return CanonicalCode(last_non_zero_symbol);
|
|
|
|
return CanonicalCode(TRY(Compress::CanonicalCode::from_bytes(bytes)));
|
|
}
|
|
|
|
ErrorOr<u32> CanonicalCode::read_symbol(LittleEndianInputBitStream& bit_stream) const
|
|
{
|
|
return TRY(m_code.visit(
|
|
[](u32 single_code) -> ErrorOr<u32> { return single_code; },
|
|
[&bit_stream](Compress::CanonicalCode const& code) { return code.read_symbol(bit_stream); }));
|
|
}
|
|
|
|
ErrorOr<void> CanonicalCode::write_symbol(LittleEndianOutputBitStream& bit_stream, u32 symbol) const
|
|
{
|
|
TRY(m_code.visit(
|
|
[&](u32 single_code) -> ErrorOr<void> { VERIFY(symbol == single_code); return {};},
|
|
[&](Compress::CanonicalCode const& code) { return code.write_symbol(bit_stream, symbol); }));
|
|
return {};
|
|
}
|
|
|
|
}
|