31 RetainPtr<
const CPDF_Dictionary> pDict = pObj->GetDict();
35 RetainPtr<
const CPDF_Array> pFunctionsArray = pDict->GetArrayFor(
"Functions");
39 RetainPtr<
const CPDF_Array> pBoundsArray = pDict->GetArrayFor(
"Bounds");
43 RetainPtr<
const CPDF_Array> pEncodeArray = pDict->GetArrayFor(
"Encode");
47 const uint32_t nSubs =
fxcrt::CollectionSize<uint32_t>(*pFunctionsArray);
54 if (pBoundsArray->size() < nSubs - 1)
57 FX_SAFE_UINT32 nExpectedEncodeSize = nSubs;
58 nExpectedEncodeSize *= 2;
59 if (!nExpectedEncodeSize.IsValid())
62 if (pEncodeArray->size() < nExpectedEncodeSize.ValueOrDie())
68 absl::optional<uint32_t> nOutputs;
69 for (uint32_t i = 0; i < nSubs; ++i) {
74 std::unique_ptr<CPDF_Function> pFunc =
75 CPDF_Function::Load(std::move(pSub), pVisited);
81 if (pFunc->CountInputs() != kRequiredNumInputs)
84 uint32_t nFuncOutputs = pFunc->CountOutputs();
85 if (nFuncOutputs == 0)
88 if (nOutputs.has_value()) {
89 if (nOutputs != nFuncOutputs)
92 nOutputs = nFuncOutputs;
94 m_pSubFunctions.push_back(std::move(pFunc));
96 m_nOutputs = nOutputs.value();
99 m_bounds.reserve(nSubs + 1);
100 m_bounds.push_back(m_Domains[0]);
101 for (uint32_t i = 0; i < nSubs - 1; i++)
102 m_bounds.push_back(pBoundsArray->GetFloatAt(i));
103 m_bounds.push_back(m_Domains[1]);
105 m_encode = ReadArrayElementsToVector(pEncodeArray.Get(), nSubs * 2);
109bool CPDF_StitchFunc::
v_Call(pdfium::span<
const float> inputs,
110 pdfium::span<
float> results)
const {
111 float input = inputs[0];
113 for (i = 0; i + 1 < m_pSubFunctions.size(); i++) {
114 if (input < m_bounds[i + 1])
117 input = Interpolate(input, m_bounds[i], m_bounds[i + 1], m_encode[i * 2],
118 m_encode[i * 2 + 1]);
119 return m_pSubFunctions[i]
120 ->Call(pdfium::span_from_ref(input), results)