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

LibPDF: Do less work in SampledFunction::evaluate()'s inner loop

Instead of recomputing the left index and the float amount in that
interval for each coordinate all the time, do it once when we
preprocess the input coordinates.

One line less, faster, and arguably easier to read.

No behavior change.
This commit is contained in:
Nico Weber 2023-12-02 19:28:18 +09:00 committed by Andreas Kling
parent 54883b7d41
commit 1c88b82dfc

View file

@ -68,6 +68,7 @@ private:
ReadonlyBytes m_sample_data;
Vector<float> mutable m_inputs;
Vector<unsigned> mutable m_left_index;
Vector<float> mutable m_outputs;
};
@ -167,6 +168,7 @@ SampledFunction::create(Document* document, Vector<Bound> domain, Optional<Vecto
function->m_encode = move(encode);
function->m_decode = move(decode);
function->m_inputs.resize(function->m_domain.size());
function->m_left_index.resize(function->m_domain.size());
function->m_outputs.resize(function->m_range.size());
return function;
}
@ -189,8 +191,11 @@ PDFErrorOr<ReadonlySpan<float>> SampledFunction::evaluate(ReadonlySpan<float> xs
for (size_t i = 0; i < m_domain.size(); ++i) {
float x = clamp(xs[i], m_domain[i].lower, m_domain[i].upper);
float e = interpolate(x, m_domain[i].lower, m_domain[i].upper, m_encode[i].lower, m_encode[i].upper);
float ec = clamp(e, 0.0f, static_cast<float>(m_sizes[i] - 1));
m_inputs[i] = ec;
unsigned n = m_sizes[i] - 1;
float ec = clamp(e, 0.0f, static_cast<float>(n));
m_left_index[i] = min(ec, n - 1);
m_inputs[i] = ec - m_left_index[i];
}
for (size_t r = 0; r < m_range.size(); ++r) {
@ -207,20 +212,14 @@ PDFErrorOr<ReadonlySpan<float>> SampledFunction::evaluate(ReadonlySpan<float> xs
Vector<int> coordinates;
coordinates.resize(m_domain.size());
for (size_t mask = 0; mask < (1u << m_domain.size()); ++mask) {
for (size_t i = 0; i < m_domain.size(); ++i) {
unsigned n = m_sizes[i] - 1;
unsigned left_index = min(m_inputs[i], n - 1);
coordinates[i] = left_index + ((mask >> i) & 1u);
}
for (size_t i = 0; i < m_domain.size(); ++i)
coordinates[i] = m_left_index[i] + ((mask >> i) & 1u);
samples[mask] = sample(coordinates, r);
}
for (int i = static_cast<int>(m_domain.size() - 1); i >= 0; --i) {
unsigned n = m_sizes[i] - 1;
float ec = m_inputs[i];
unsigned e0 = min(static_cast<unsigned>(ec), n - 1);
for (size_t mask = 0; mask < (1u << i); ++mask)
samples[mask] = mix(samples[mask], samples[mask | (1 << i)], ec - e0);
samples[mask] = mix(samples[mask], samples[mask | (1 << i)], m_inputs[i]);
}
float result = interpolate(samples[0], 0.0f, 255.0f, m_decode[r].lower, m_decode[r].upper);