1// Copyright 2017 PDFium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7#include "core/fpdfapi/page/cpdf_stitchfunc.h" 8 9#include <utility> 10 11#include "core/fpdfapi/parser/cpdf_array.h" 12#include "core/fpdfapi/parser/cpdf_dictionary.h" 13#include "core/fxcrt/fx_memory.h" 14 15CPDF_StitchFunc::CPDF_StitchFunc() 16 : CPDF_Function(Type::kType3Stitching), 17 m_pBounds(nullptr), 18 m_pEncode(nullptr) {} 19 20CPDF_StitchFunc::~CPDF_StitchFunc() { 21 FX_Free(m_pBounds); 22 FX_Free(m_pEncode); 23} 24 25bool CPDF_StitchFunc::v_Init(CPDF_Object* pObj) { 26 CPDF_Dictionary* pDict = pObj->GetDict(); 27 if (!pDict) { 28 return false; 29 } 30 if (m_nInputs != kRequiredNumInputs) { 31 return false; 32 } 33 CPDF_Array* pArray = pDict->GetArrayFor("Functions"); 34 if (!pArray) { 35 return false; 36 } 37 uint32_t nSubs = pArray->GetCount(); 38 if (nSubs == 0) 39 return false; 40 m_nOutputs = 0; 41 for (uint32_t i = 0; i < nSubs; i++) { 42 CPDF_Object* pSub = pArray->GetDirectObjectAt(i); 43 if (pSub == pObj) 44 return false; 45 std::unique_ptr<CPDF_Function> pFunc(CPDF_Function::Load(pSub)); 46 if (!pFunc) 47 return false; 48 // Check that the input dimensionality is 1, and that all output 49 // dimensionalities are the same. 50 if (pFunc->CountInputs() != kRequiredNumInputs) 51 return false; 52 if (pFunc->CountOutputs() != m_nOutputs) { 53 if (m_nOutputs) 54 return false; 55 56 m_nOutputs = pFunc->CountOutputs(); 57 } 58 59 m_pSubFunctions.push_back(std::move(pFunc)); 60 } 61 m_pBounds = FX_Alloc(float, nSubs + 1); 62 m_pBounds[0] = m_pDomains[0]; 63 pArray = pDict->GetArrayFor("Bounds"); 64 if (!pArray) 65 return false; 66 for (uint32_t i = 0; i < nSubs - 1; i++) 67 m_pBounds[i + 1] = pArray->GetFloatAt(i); 68 m_pBounds[nSubs] = m_pDomains[1]; 69 m_pEncode = FX_Alloc2D(float, nSubs, 2); 70 pArray = pDict->GetArrayFor("Encode"); 71 if (!pArray) 72 return false; 73 74 for (uint32_t i = 0; i < nSubs * 2; i++) 75 m_pEncode[i] = pArray->GetFloatAt(i); 76 return true; 77} 78 79bool CPDF_StitchFunc::v_Call(float* inputs, float* outputs) const { 80 float input = inputs[0]; 81 size_t i; 82 for (i = 0; i < m_pSubFunctions.size() - 1; i++) { 83 if (input < m_pBounds[i + 1]) 84 break; 85 } 86 input = Interpolate(input, m_pBounds[i], m_pBounds[i + 1], m_pEncode[i * 2], 87 m_pEncode[i * 2 + 1]); 88 int nresults; 89 m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, &nresults); 90 return true; 91} 92