1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:18:11 +00:00

LibGfx/JPEG: Use a look-up table for cosine values

This solution is a middle ground between re-computing `cos` every time
and a much more mathematically complicated approach (as we have in the
decoder).

While still being far from optimal it already gives us a 10x
improvement, not that bad :^)

Co-authored-by: Tim Flynn <trflynn89@pm.me>
This commit is contained in:
Lucas CHOLLET 2023-06-23 19:01:03 -04:00 committed by Jelle Raaijmakers
parent 5056668ab2
commit cc1bd2d2d9

View file

@ -136,20 +136,35 @@ public:
return {};
}
static Array<double, 64> create_cosine_lookup_table()
{
static constexpr double pi_over_16 = AK::Pi<double> / 16;
Array<double, 64> table;
for (u8 u = 0; u < 8; ++u) {
for (u8 x = 0; x < 8; ++x)
table[u * 8 + x] = cos((2 * x + 1) * u * pi_over_16);
}
return table;
}
void fdct_and_quantization()
{
static auto cosine_table = create_cosine_lookup_table();
for (auto& macroblock : m_macroblocks) {
constexpr double pi_over_16 = AK::Pi<double> / 16;
constexpr double inverse_sqrt_2 = M_SQRT1_2;
auto const convert_one_component = [](i16 component[], QuantizationTable const& table) {
auto const convert_one_component = [&](i16 component[], QuantizationTable const& table) {
Array<i16, 64> result {};
auto const sum_xy = [&component](u8 u, u8 v) {
auto const sum_xy = [&](u8 u, u8 v) {
double sum {};
for (u8 x {}; x < 8; ++x) {
for (u8 y {}; y < 8; ++y)
sum += component[x * 8 + y] * cos((2 * x + 1) * u * pi_over_16) * cos((2 * y + 1) * v * pi_over_16);
sum += component[x * 8 + y] * cosine_table[u * 8 + x] * cosine_table[v * 8 + y];
}
return sum;
};