Use span<float> in CPDF_Function::v_Call().
Get some better bounds checking as a result.
-- Use Optional in place of out param.
-- Prefer std::fill(0.0f) over memset(0) for float arrays.
Change-Id: I982345a3099f7e9c06dd2c909e415a6c27007587
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/82550
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index c8ca89d..49c687a 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -1284,9 +1284,8 @@
// Using at least 16 elements due to the call m_pAltCS->GetRGB() below.
std::vector<float> results(std::max(m_pFunc->CountOutputs(), 16u));
- int nresults = 0;
- if (!m_pFunc->Call(pBuf.data(), 1, results.data(), &nresults) ||
- nresults == 0)
+ uint32_t nresults = m_pFunc->Call(pBuf.first(1), results).value_or(0);
+ if (nresults == 0)
return false;
if (m_pAltCS)
@@ -1352,12 +1351,12 @@
// Using at least 16 elements due to the call m_pAltCS->GetRGB() below.
std::vector<float> results(std::max(m_pFunc->CountOutputs(), 16u));
- int nresults = 0;
- if (!m_pFunc->Call(pBuf.data(), CountComponents(), results.data(),
- &nresults) ||
- nresults == 0) {
+ uint32_t nresults =
+ m_pFunc->Call(pBuf.first(CountComponents()), pdfium::make_span(results))
+ .value_or(0);
+
+ if (nresults == 0)
return false;
- }
return m_pAltCS->GetRGB(results, R, G, B);
}
diff --git a/core/fpdfapi/page/cpdf_expintfunc.cpp b/core/fpdfapi/page/cpdf_expintfunc.cpp
index 0e946f5..08afb91 100644
--- a/core/fpdfapi/page/cpdf_expintfunc.cpp
+++ b/core/fpdfapi/page/cpdf_expintfunc.cpp
@@ -53,7 +53,8 @@
return true;
}
-bool CPDF_ExpIntFunc::v_Call(const float* inputs, float* results) const {
+bool CPDF_ExpIntFunc::v_Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const {
for (uint32_t i = 0; i < m_nInputs; i++) {
for (uint32_t j = 0; j < m_nOrigOutputs; j++) {
results[i * m_nOrigOutputs + j] =
diff --git a/core/fpdfapi/page/cpdf_expintfunc.h b/core/fpdfapi/page/cpdf_expintfunc.h
index be29695..c31ad8b 100644
--- a/core/fpdfapi/page/cpdf_expintfunc.h
+++ b/core/fpdfapi/page/cpdf_expintfunc.h
@@ -17,10 +17,11 @@
CPDF_ExpIntFunc();
~CPDF_ExpIntFunc() override;
- // CPDF_Function
+ // CPDF_Function:
bool v_Init(const CPDF_Object* pObj,
std::set<const CPDF_Object*>* pVisited) override;
- bool v_Call(const float* inputs, float* results) const override;
+ bool v_Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const override;
uint32_t GetOrigOutputs() const { return m_nOrigOutputs; }
float GetExponent() const { return m_Exponent; }
diff --git a/core/fpdfapi/page/cpdf_function.cpp b/core/fpdfapi/page/cpdf_function.cpp
index a8c6463..feafc5c 100644
--- a/core/fpdfapi/page/cpdf_function.cpp
+++ b/core/fpdfapi/page/cpdf_function.cpp
@@ -126,30 +126,27 @@
return true;
}
-bool CPDF_Function::Call(const float* inputs,
- uint32_t ninputs,
- float* results,
- int* nresults) const {
- if (m_nInputs != ninputs)
- return false;
+Optional<uint32_t> CPDF_Function::Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const {
+ if (m_nInputs != inputs.size())
+ return pdfium::nullopt;
- *nresults = m_nOutputs;
std::vector<float> clamped_inputs(m_nInputs);
for (uint32_t i = 0; i < m_nInputs; i++) {
clamped_inputs[i] =
pdfium::clamp(inputs[i], m_Domains[i * 2], m_Domains[i * 2 + 1]);
}
- if (!v_Call(clamped_inputs.data(), results))
- return false;
+ if (!v_Call(clamped_inputs, results))
+ return pdfium::nullopt;
if (m_Ranges.empty())
- return true;
+ return m_nOutputs;
for (uint32_t i = 0; i < m_nOutputs; i++) {
results[i] =
pdfium::clamp(results[i], m_Ranges[i * 2], m_Ranges[i * 2 + 1]);
}
- return true;
+ return m_nOutputs;
}
// See PDF Reference 1.7, page 170.
diff --git a/core/fpdfapi/page/cpdf_function.h b/core/fpdfapi/page/cpdf_function.h
index 03c21aa..7b6fcc3 100644
--- a/core/fpdfapi/page/cpdf_function.h
+++ b/core/fpdfapi/page/cpdf_function.h
@@ -11,6 +11,9 @@
#include <set>
#include <vector>
+#include "third_party/base/optional.h"
+#include "third_party/base/span.h"
+
class CPDF_ExpIntFunc;
class CPDF_Object;
class CPDF_SampledFunc;
@@ -31,10 +34,8 @@
virtual ~CPDF_Function();
- bool Call(const float* inputs,
- uint32_t ninputs,
- float* results,
- int* nresults) const;
+ Optional<uint32_t> Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const;
uint32_t CountInputs() const { return m_nInputs; }
uint32_t CountOutputs() const { return m_nOutputs; }
float GetDomain(int i) const { return m_Domains[i]; }
@@ -60,7 +61,8 @@
bool Init(const CPDF_Object* pObj, std::set<const CPDF_Object*>* pVisited);
virtual bool v_Init(const CPDF_Object* pObj,
std::set<const CPDF_Object*>* pVisited) = 0;
- virtual bool v_Call(const float* inputs, float* results) const = 0;
+ virtual bool v_Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const = 0;
const Type m_Type;
uint32_t m_nInputs;
diff --git a/core/fpdfapi/page/cpdf_meshstream.cpp b/core/fpdfapi/page/cpdf_meshstream.cpp
index 7d7085f..60759f0 100644
--- a/core/fpdfapi/page/cpdf_meshstream.cpp
+++ b/core/fpdfapi/page/cpdf_meshstream.cpp
@@ -203,10 +203,9 @@
}
float result[kMaxComponents] = {};
- int nResults;
for (const auto& func : m_funcs) {
if (func && func->CountOutputs() <= kMaxComponents)
- func->Call(color_value, 1, result, &nResults);
+ func->Call(pdfium::make_span(color_value, 1), result);
}
m_pCS->GetRGB(result, &r, &g, &b);
diff --git a/core/fpdfapi/page/cpdf_psfunc.cpp b/core/fpdfapi/page/cpdf_psfunc.cpp
index f4d00dc..b365cee 100644
--- a/core/fpdfapi/page/cpdf_psfunc.cpp
+++ b/core/fpdfapi/page/cpdf_psfunc.cpp
@@ -20,7 +20,8 @@
return m_PS.Parse(pAcc->GetSpan());
}
-bool CPDF_PSFunc::v_Call(const float* inputs, float* results) const {
+bool CPDF_PSFunc::v_Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const {
m_PS.Reset();
for (uint32_t i = 0; i < m_nInputs; i++)
m_PS.Push(inputs[i]);
diff --git a/core/fpdfapi/page/cpdf_psfunc.h b/core/fpdfapi/page/cpdf_psfunc.h
index b81c2e7..8fb454f 100644
--- a/core/fpdfapi/page/cpdf_psfunc.h
+++ b/core/fpdfapi/page/cpdf_psfunc.h
@@ -19,10 +19,11 @@
CPDF_PSFunc();
~CPDF_PSFunc() override;
- // CPDF_Function
+ // CPDF_Function:
bool v_Init(const CPDF_Object* pObj,
std::set<const CPDF_Object*>* pVisited) override;
- bool v_Call(const float* inputs, float* results) const override;
+ bool v_Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const override;
private:
mutable CPDF_PSEngine m_PS; // Pre-initialized scratch space for v_Call().
diff --git a/core/fpdfapi/page/cpdf_sampledfunc.cpp b/core/fpdfapi/page/cpdf_sampledfunc.cpp
index 297ffd0..9cd764c 100644
--- a/core/fpdfapi/page/cpdf_sampledfunc.cpp
+++ b/core/fpdfapi/page/cpdf_sampledfunc.cpp
@@ -99,7 +99,8 @@
return true;
}
-bool CPDF_SampledFunc::v_Call(const float* inputs, float* results) const {
+bool CPDF_SampledFunc::v_Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const {
int pos = 0;
CFX_FixedBufGrow<float, 16> encoded_input_buf(m_nInputs);
float* encoded_input = encoded_input_buf;
diff --git a/core/fpdfapi/page/cpdf_sampledfunc.h b/core/fpdfapi/page/cpdf_sampledfunc.h
index fa129ac..f9d226b 100644
--- a/core/fpdfapi/page/cpdf_sampledfunc.h
+++ b/core/fpdfapi/page/cpdf_sampledfunc.h
@@ -31,10 +31,11 @@
CPDF_SampledFunc();
~CPDF_SampledFunc() override;
- // CPDF_Function
+ // CPDF_Function:
bool v_Init(const CPDF_Object* pObj,
std::set<const CPDF_Object*>* pVisited) override;
- bool v_Call(const float* inputs, float* results) const override;
+ bool v_Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const override;
const std::vector<SampleEncodeInfo>& GetEncodeInfo() const {
return m_EncodeInfo;
diff --git a/core/fpdfapi/page/cpdf_stitchfunc.cpp b/core/fpdfapi/page/cpdf_stitchfunc.cpp
index 4f55048..737ff5f 100644
--- a/core/fpdfapi/page/cpdf_stitchfunc.cpp
+++ b/core/fpdfapi/page/cpdf_stitchfunc.cpp
@@ -105,7 +105,8 @@
return true;
}
-bool CPDF_StitchFunc::v_Call(const float* inputs, float* results) const {
+bool CPDF_StitchFunc::v_Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const {
float input = inputs[0];
size_t i;
for (i = 0; i < m_pSubFunctions.size() - 1; i++) {
@@ -114,7 +115,7 @@
}
input = Interpolate(input, m_bounds[i], m_bounds[i + 1], m_encode[i * 2],
m_encode[i * 2 + 1]);
- int nresults;
- return m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, results,
- &nresults);
+ return m_pSubFunctions[i]
+ ->Call(pdfium::make_span(&input, 1), results)
+ .has_value();
}
diff --git a/core/fpdfapi/page/cpdf_stitchfunc.h b/core/fpdfapi/page/cpdf_stitchfunc.h
index 761c9ba..c6f3e36 100644
--- a/core/fpdfapi/page/cpdf_stitchfunc.h
+++ b/core/fpdfapi/page/cpdf_stitchfunc.h
@@ -18,10 +18,11 @@
CPDF_StitchFunc();
~CPDF_StitchFunc() override;
- // CPDF_Function
+ // CPDF_Function:
bool v_Init(const CPDF_Object* pObj,
std::set<const CPDF_Object*>* pVisited) override;
- bool v_Call(const float* inputs, float* results) const override;
+ bool v_Call(pdfium::span<const float> inputs,
+ pdfium::span<float> results) const override;
const std::vector<std::unique_ptr<CPDF_Function>>& GetSubFunctions() const {
return m_pSubFunctions;
diff --git a/core/fpdfapi/render/cpdf_docrenderdata.cpp b/core/fpdfapi/render/cpdf_docrenderdata.cpp
index 69af157..5e3e070 100644
--- a/core/fpdfapi/render/cpdf_docrenderdata.cpp
+++ b/core/fpdfapi/render/cpdf_docrenderdata.cpp
@@ -6,6 +6,7 @@
#include "core/fpdfapi/render/cpdf_docrenderdata.h"
+#include <algorithm>
#include <array>
#include <memory>
#include <utility>
@@ -79,9 +80,8 @@
return nullptr;
}
- int noutput;
float output[kMaxOutputs];
- memset(output, 0, sizeof(output));
+ std::fill(std::begin(output), std::end(output), 0.0f);
bool bIdentity = true;
std::vector<uint8_t, FxAllocAllocator<uint8_t>> samples_r(
@@ -100,7 +100,7 @@
samples[i][v] = v;
continue;
}
- pFuncs[i]->Call(&input, 1, output, &noutput);
+ pFuncs[i]->Call(pdfium::make_span(&input, 1), output);
size_t o = FXSYS_roundf(output[0] * 255);
if (o != v)
bIdentity = false;
@@ -109,7 +109,7 @@
continue;
}
if (pFuncs[0]->CountOutputs() <= kMaxOutputs)
- pFuncs[0]->Call(&input, 1, output, &noutput);
+ pFuncs[0]->Call(pdfium::make_span(&input, 1), output);
size_t o = FXSYS_roundf(output[0] * 255);
if (o != v)
bIdentity = false;
diff --git a/core/fpdfapi/render/cpdf_rendershading.cpp b/core/fpdfapi/render/cpdf_rendershading.cpp
index 8fb867b..bf012f5 100644
--- a/core/fpdfapi/render/cpdf_rendershading.cpp
+++ b/core/fpdfapi/render/cpdf_rendershading.cpp
@@ -69,13 +69,14 @@
float diff = t_max - t_min;
for (int i = 0; i < kShadingSteps; ++i) {
float input = diff * i / kShadingSteps + t_min;
- int offset = 0;
+ pdfium::span<float> result_span = pdfium::make_span(result_array);
for (const auto& func : funcs) {
- if (func) {
- int nresults = 0;
- if (func->Call(&input, 1, &result_array[offset], &nresults))
- offset += nresults;
- }
+ if (!func)
+ continue;
+ Optional<uint32_t> nresults =
+ func->Call(pdfium::make_span(&input, 1), result_span);
+ if (nresults.has_value())
+ result_span = result_span.subspan(nresults.value());
}
float R = 0.0f;
float G = 0.0f;
@@ -295,16 +296,15 @@
if (pos.x < xmin || pos.x > xmax || pos.y < ymin || pos.y > ymax)
continue;
- float input[] = {pos.x, pos.y};
- int offset = 0;
+ float input[2] = {pos.x, pos.y};
+ pdfium::span<float> result_span = pdfium::make_span(result_array);
for (const auto& func : funcs) {
- if (func) {
- int nresults;
- if (func->Call(input, 2, &result_array[offset], &nresults))
- offset += nresults;
- }
+ if (!func)
+ continue;
+ Optional<uint32_t> nresults = func->Call(input, result_span);
+ if (nresults.has_value())
+ result_span = result_span.subspan(nresults.value());
}
-
float R = 0.0f;
float G = 0.0f;
float B = 0.0f;
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index ea817a2..afecf66 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -1448,8 +1448,7 @@
std::vector<float> results(pFunc->CountOutputs());
for (size_t i = 0; i < transfers.size(); ++i) {
float input = i / 255.0f;
- int nresult;
- pFunc->Call(&input, 1, results.data(), &nresult);
+ pFunc->Call(pdfium::make_span(&input, 1), results);
transfers[i] = FXSYS_roundf(results[0] * 255);
}
} else {