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" |
| 11 #include "../../../../third_party/base/numerics/safe_conversions_impl.h" |
9 #include "../../../include/fpdfapi/fpdf_module.h" | 12 #include "../../../include/fpdfapi/fpdf_module.h" |
10 #include "../../../include/fpdfapi/fpdf_page.h" | 13 #include "../../../include/fpdfapi/fpdf_page.h" |
11 #include "../../../include/fxcrt/fx_safe_types.h" | 14 #include "../../../include/fxcrt/fx_safe_types.h" |
12 #include "../../../third_party/base/numerics/safe_conversions_impl.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, |
19 PSOP_MUL, | 21 PSOP_MUL, |
20 PSOP_DIV, | 22 PSOP_DIV, |
21 PSOP_IDIV, | 23 PSOP_IDIV, |
22 PSOP_MOD, | 24 PSOP_MOD, |
(...skipping 694 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 (pFuncObj->GetType() == PDFOBJ_STREAM) { | 829 if (pFuncObj->GetType() == PDFOBJ_STREAM) { |
818 type = ((CPDF_Stream*)pFuncObj) | 830 type = ((CPDF_Stream*)pFuncObj) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 for (int i = 0; i < m_nOutputs; i++) { | 921 for (int i = 0; i < m_nOutputs; i++) { |
910 if (results[i] < m_pRanges[i * 2]) { | 922 if (results[i] < m_pRanges[i * 2]) { |
911 results[i] = m_pRanges[i * 2]; | 923 results[i] = m_pRanges[i * 2]; |
912 } else if (results[i] > m_pRanges[i * 2 + 1]) { | 924 } else if (results[i] > m_pRanges[i * 2 + 1]) { |
913 results[i] = m_pRanges[i * 2 + 1]; | 925 results[i] = m_pRanges[i * 2 + 1]; |
914 } | 926 } |
915 } | 927 } |
916 } | 928 } |
917 return TRUE; | 929 return TRUE; |
918 } | 930 } |
OLD | NEW |