| OLD | NEW | 
|---|
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 
| 6 | 6 | 
| 7 #include <limits.h> | 7 #include <limits.h> | 
|  | 8 #include <vector> | 
| 8 | 9 | 
|  | 10 #include "../../../../third_party/base/nonstd_unique_ptr.h" | 
| 9 #include "../../../../third_party/base/numerics/safe_conversions_impl.h" | 11 #include "../../../../third_party/base/numerics/safe_conversions_impl.h" | 
| 10 #include "../../../include/fpdfapi/fpdf_module.h" | 12 #include "../../../include/fpdfapi/fpdf_module.h" | 
| 11 #include "../../../include/fpdfapi/fpdf_page.h" | 13 #include "../../../include/fpdfapi/fpdf_page.h" | 
| 12 #include "../../../include/fxcrt/fx_safe_types.h" | 14 #include "../../../include/fxcrt/fx_safe_types.h" | 
| 13 #include "pageint.h" | 15 #include "pageint.h" | 
| 14 | 16 | 
| 15 class CPDF_PSEngine; | 17 class CPDF_PSEngine; | 
| 16 typedef enum { | 18 typedef enum { | 
| 17   PSOP_ADD, | 19   PSOP_ADD, | 
| 18   PSOP_SUB, | 20   PSOP_SUB, | 
| (...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 717 | 719 | 
| 718 class CPDF_StitchFunc : public CPDF_Function { | 720 class CPDF_StitchFunc : public CPDF_Function { | 
| 719  public: | 721  public: | 
| 720   CPDF_StitchFunc(); | 722   CPDF_StitchFunc(); | 
| 721   ~CPDF_StitchFunc() override; | 723   ~CPDF_StitchFunc() override; | 
| 722 | 724 | 
| 723   // CPDF_Function | 725   // CPDF_Function | 
| 724   FX_BOOL v_Init(CPDF_Object* pObj) override; | 726   FX_BOOL v_Init(CPDF_Object* pObj) override; | 
| 725   FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; | 727   FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; | 
| 726 | 728 | 
| 727   int m_nSubs; | 729   std::vector<CPDF_Function*> m_pSubFunctions; | 
| 728   CPDF_Function** m_pSubFunctions; |  | 
| 729   FX_FLOAT* m_pBounds; | 730   FX_FLOAT* m_pBounds; | 
| 730   FX_FLOAT* m_pEncode; | 731   FX_FLOAT* m_pEncode; | 
|  | 732 | 
|  | 733   static const int kRequiredNumInputs = 1; | 
| 731 }; | 734 }; | 
| 732 | 735 | 
| 733 CPDF_StitchFunc::CPDF_StitchFunc() { | 736 CPDF_StitchFunc::CPDF_StitchFunc() { | 
| 734   m_nSubs = 0; |  | 
| 735   m_pSubFunctions = NULL; |  | 
| 736   m_pBounds = NULL; | 737   m_pBounds = NULL; | 
| 737   m_pEncode = NULL; | 738   m_pEncode = NULL; | 
| 738 } | 739 } | 
| 739 CPDF_StitchFunc::~CPDF_StitchFunc() { | 740 CPDF_StitchFunc::~CPDF_StitchFunc() { | 
| 740   for (int i = 0; i < m_nSubs; i++) | 741   for (auto& sub : m_pSubFunctions) { | 
| 741     delete m_pSubFunctions[i]; | 742     delete sub; | 
| 742   FX_Free(m_pSubFunctions); | 743   } | 
| 743   FX_Free(m_pBounds); | 744   FX_Free(m_pBounds); | 
| 744   FX_Free(m_pEncode); | 745   FX_Free(m_pEncode); | 
| 745 } | 746 } | 
| 746 FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) { | 747 FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) { | 
| 747   CPDF_Dictionary* pDict = pObj->GetDict(); | 748   CPDF_Dictionary* pDict = pObj->GetDict(); | 
| 748   if (pDict == NULL) { | 749   if (!pDict) { | 
|  | 750     return FALSE; | 
|  | 751   } | 
|  | 752   if (m_nInputs != kRequiredNumInputs) { | 
| 749     return FALSE; | 753     return FALSE; | 
| 750   } | 754   } | 
| 751   CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Functions")); | 755   CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Functions")); | 
| 752   if (pArray == NULL) { | 756   if (!pArray) { | 
| 753     return FALSE; | 757     return FALSE; | 
| 754   } | 758   } | 
| 755   m_nSubs = pArray->GetCount(); | 759   FX_DWORD nSubs = pArray->GetCount(); | 
| 756   if (m_nSubs == 0) { | 760   if (nSubs == 0) { | 
| 757     return FALSE; | 761     return FALSE; | 
| 758   } | 762   } | 
| 759   m_pSubFunctions = FX_Alloc(CPDF_Function*, m_nSubs); |  | 
| 760   m_nOutputs = 0; | 763   m_nOutputs = 0; | 
| 761   int i; | 764   for (FX_DWORD i = 0; i < nSubs; i++) { | 
| 762   for (i = 0; i < m_nSubs; i++) { |  | 
| 763     CPDF_Object* pSub = pArray->GetElementValue(i); | 765     CPDF_Object* pSub = pArray->GetElementValue(i); | 
| 764     if (pSub == pObj) { | 766     if (pSub == pObj) { | 
| 765       return FALSE; | 767       return FALSE; | 
| 766     } | 768     } | 
| 767     m_pSubFunctions[i] = CPDF_Function::Load(pSub); | 769     nonstd::unique_ptr<CPDF_Function> pFunc(CPDF_Function::Load(pSub)); | 
| 768     if (m_pSubFunctions[i] == NULL) { | 770     if (!pFunc) { | 
| 769       return FALSE; | 771       return FALSE; | 
| 770     } | 772     } | 
| 771     if (m_pSubFunctions[i]->CountOutputs() > m_nOutputs) { | 773     // Check that the input dimensionality is 1, and that all output | 
| 772       m_nOutputs = m_pSubFunctions[i]->CountOutputs(); | 774     // dimensionalities are the same. | 
|  | 775     if (pFunc->CountInputs() != kRequiredNumInputs) { | 
|  | 776       return FALSE; | 
| 773     } | 777     } | 
|  | 778     if (pFunc->CountOutputs() != m_nOutputs) { | 
|  | 779       if (m_nOutputs) | 
|  | 780         return FALSE; | 
|  | 781 | 
|  | 782       m_nOutputs = pFunc->CountOutputs(); | 
|  | 783     } | 
|  | 784 | 
|  | 785     m_pSubFunctions.push_back(pFunc.release()); | 
| 774   } | 786   } | 
| 775   m_pBounds = FX_Alloc(FX_FLOAT, m_nSubs + 1); | 787   m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); | 
| 776   m_pBounds[0] = m_pDomains[0]; | 788   m_pBounds[0] = m_pDomains[0]; | 
| 777   pArray = pDict->GetArray(FX_BSTRC("Bounds")); | 789   pArray = pDict->GetArray(FX_BSTRC("Bounds")); | 
| 778   if (pArray == NULL) { | 790   if (!pArray) { | 
| 779     return FALSE; | 791     return FALSE; | 
| 780   } | 792   } | 
| 781   for (i = 0; i < m_nSubs - 1; i++) { | 793   for (FX_DWORD i = 0; i < nSubs - 1; i++) { | 
| 782     m_pBounds[i + 1] = pArray->GetFloat(i); | 794     m_pBounds[i + 1] = pArray->GetFloat(i); | 
| 783   } | 795   } | 
| 784   m_pBounds[m_nSubs] = m_pDomains[1]; | 796   m_pBounds[nSubs] = m_pDomains[1]; | 
| 785   m_pEncode = FX_Alloc2D(FX_FLOAT, m_nSubs, 2); | 797   m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); | 
| 786   pArray = pDict->GetArray(FX_BSTRC("Encode")); | 798   pArray = pDict->GetArray(FX_BSTRC("Encode")); | 
| 787   if (pArray == NULL) { | 799   if (!pArray) { | 
| 788     return FALSE; | 800     return FALSE; | 
| 789   } | 801   } | 
| 790   for (i = 0; i < m_nSubs * 2; i++) { | 802   for (FX_DWORD i = 0; i < nSubs * 2; i++) { | 
| 791     m_pEncode[i] = pArray->GetFloat(i); | 803     m_pEncode[i] = pArray->GetFloat(i); | 
| 792   } | 804   } | 
| 793   return TRUE; | 805   return TRUE; | 
| 794 } | 806 } | 
| 795 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { | 807 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { | 
| 796   FX_FLOAT input = inputs[0]; | 808   FX_FLOAT input = inputs[0]; | 
| 797   int i; | 809   size_t i; | 
| 798   for (i = 0; i < m_nSubs - 1; i++) | 810   for (i = 0; i < m_pSubFunctions.size() - 1; i++) | 
| 799     if (input < m_pBounds[i + 1]) { | 811     if (input < m_pBounds[i + 1]) { | 
| 800       break; | 812       break; | 
| 801     } | 813     } | 
| 802   if (m_pSubFunctions[i] == NULL) { | 814   if (m_pSubFunctions[i] == NULL) { | 
| 803     return FALSE; | 815     return FALSE; | 
| 804   } | 816   } | 
| 805   input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], | 817   input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], | 
| 806                           m_pEncode[i * 2], m_pEncode[i * 2 + 1]); | 818                           m_pEncode[i * 2], m_pEncode[i * 2 + 1]); | 
| 807   int nresults; | 819   int nresults; | 
| 808   m_pSubFunctions[i]->Call(&input, m_nInputs, outputs, nresults); | 820   m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults); | 
| 809   return TRUE; | 821   return TRUE; | 
| 810 } | 822 } | 
| 811 CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) { | 823 CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) { | 
| 812   if (pFuncObj == NULL) { | 824   if (pFuncObj == NULL) { | 
| 813     return NULL; | 825     return NULL; | 
| 814   } | 826   } | 
| 815   CPDF_Function* pFunc = NULL; | 827   CPDF_Function* pFunc = NULL; | 
| 816   int type; | 828   int type; | 
| 817   if (CPDF_Stream* pStream = pFuncObj->AsStream()) { | 829   if (CPDF_Stream* pStream = pFuncObj->AsStream()) { | 
| 818     type = pStream->GetDict()->GetInteger(FX_BSTRC("FunctionType")); | 830     type = pStream->GetDict()->GetInteger(FX_BSTRC("FunctionType")); | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 904     for (int i = 0; i < m_nOutputs; i++) { | 916     for (int i = 0; i < m_nOutputs; i++) { | 
| 905       if (results[i] < m_pRanges[i * 2]) { | 917       if (results[i] < m_pRanges[i * 2]) { | 
| 906         results[i] = m_pRanges[i * 2]; | 918         results[i] = m_pRanges[i * 2]; | 
| 907       } else if (results[i] > m_pRanges[i * 2 + 1]) { | 919       } else if (results[i] > m_pRanges[i * 2 + 1]) { | 
| 908         results[i] = m_pRanges[i * 2 + 1]; | 920         results[i] = m_pRanges[i * 2 + 1]; | 
| 909       } | 921       } | 
| 910     } | 922     } | 
| 911   } | 923   } | 
| 912   return TRUE; | 924   return TRUE; | 
| 913 } | 925 } | 
| OLD | NEW | 
|---|