mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-02 22:24:26 +00:00
LibGfx/WebPWriter: Separate symbol generation from statistics collection
We now do this in two passes instead of in one. This is virtually free performance-wise, and allows nicer factoring. Perf numbers after this change (see previous commit for perf numbers before): Benchmark 1: image -o sunset-retro.webp sunset-retro.bmp Time (mean ± σ): 26.7 ms ± 0.8 ms Benchmark 1: animation -o 7z7c.webp 7z7c.gif Time (mean ± σ): 14.5 ms ± 0.6 ms Benchmark 1: animation -o wow.webp wow.gif Time (mean ± σ): 108.2 ms ± 2.2 ms
This commit is contained in:
parent
85739def89
commit
580134241e
|
@ -284,12 +284,6 @@ static ErrorOr<void> write_VP8L_coded_image(ImageKind image_kind, LittleEndianOu
|
|||
|
||||
Vector<Symbol> symbols;
|
||||
TRY(symbols.try_ensure_capacity(bitmap.size().area()));
|
||||
Array<Array<u16, 256>, 4> symbol_frequencies {};
|
||||
|
||||
static constexpr auto saturating_increment = [](u16& value) {
|
||||
if (value < UINT16_MAX)
|
||||
value++;
|
||||
};
|
||||
|
||||
auto emit_literal = [&](ARGB32 pixel) {
|
||||
Symbol symbol;
|
||||
|
@ -298,11 +292,6 @@ static ErrorOr<void> write_VP8L_coded_image(ImageKind image_kind, LittleEndianOu
|
|||
symbol.b = pixel;
|
||||
symbol.a = pixel >> 24;
|
||||
symbols.append(symbol);
|
||||
|
||||
saturating_increment(symbol_frequencies[0][symbol.green_or_length_or_index]);
|
||||
saturating_increment(symbol_frequencies[1][symbol.r]);
|
||||
saturating_increment(symbol_frequencies[2][symbol.b]);
|
||||
saturating_increment(symbol_frequencies[3][symbol.a]);
|
||||
};
|
||||
|
||||
for (ARGB32 const* it = bitmap.begin(), * end = bitmap.end(); it != end; ++it) {
|
||||
|
@ -313,6 +302,20 @@ static ErrorOr<void> write_VP8L_coded_image(ImageKind image_kind, LittleEndianOu
|
|||
// We do use huffman coding by writing a single prefix-code-group for the entire image.
|
||||
// FIXME: Consider using a meta-prefix image and using one prefix-code-group per tile.
|
||||
|
||||
Array<Array<u16, 256>, 4> symbol_frequencies {};
|
||||
|
||||
static constexpr auto saturating_increment = [](u16& value) {
|
||||
if (value < UINT16_MAX)
|
||||
value++;
|
||||
};
|
||||
|
||||
for (Symbol const& symbol : symbols) {
|
||||
saturating_increment(symbol_frequencies[0][symbol.green_or_length_or_index]);
|
||||
saturating_increment(symbol_frequencies[1][symbol.r]);
|
||||
saturating_increment(symbol_frequencies[2][symbol.b]);
|
||||
saturating_increment(symbol_frequencies[3][symbol.a]);
|
||||
}
|
||||
|
||||
Array<Array<u8, 256>, 4> code_lengths {};
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
// "Code [0..15] indicates literal code lengths." => the maximum bit length is 15.
|
||||
|
|
Loading…
Reference in a new issue