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 == NULL) { |
Tom Sepez
2015/11/04 22:10:53
nit: !pDict
Oliver Chang
2015/11/04 22:18:58
Done.
| |
749 return FALSE; | 750 return FALSE; |
750 } | 751 } |
752 if (m_nInputs != kRequiredNumInputs) { | |
753 return FALSE; | |
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 == NULL) { |
Tom Sepez
2015/11/04 22:10:53
nit: !pArray
Oliver Chang
2015/11/04 22:18:58
Done.
| |
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 (int i = 0; i < nSubs; i++) { |
Tom Sepez
2015/11/04 22:10:53
nit: maybe this should be a FX_DWORD to match nSub
Oliver Chang
2015/11/04 22:18:58
good catch, done.
| |
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 } else { | |
Tom Sepez
2015/11/04 22:10:53
nit: else after return not needed.
Oliver Chang
2015/11/04 22:18:58
Done.
| |
782 m_nOutputs = pFunc->CountOutputs(); | |
783 } | |
784 } | |
785 | |
786 m_pSubFunctions.push_back(pFunc.release()); | |
774 } | 787 } |
775 m_pBounds = FX_Alloc(FX_FLOAT, m_nSubs + 1); | 788 m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); |
776 m_pBounds[0] = m_pDomains[0]; | 789 m_pBounds[0] = m_pDomains[0]; |
777 pArray = pDict->GetArray(FX_BSTRC("Bounds")); | 790 pArray = pDict->GetArray(FX_BSTRC("Bounds")); |
778 if (pArray == NULL) { | 791 if (!pArray) { |
779 return FALSE; | 792 return FALSE; |
780 } | 793 } |
781 for (i = 0; i < m_nSubs - 1; i++) { | 794 for (int i = 0; i < nSubs - 1; i++) { |
782 m_pBounds[i + 1] = pArray->GetFloat(i); | 795 m_pBounds[i + 1] = pArray->GetFloat(i); |
783 } | 796 } |
784 m_pBounds[m_nSubs] = m_pDomains[1]; | 797 m_pBounds[nSubs] = m_pDomains[1]; |
785 m_pEncode = FX_Alloc2D(FX_FLOAT, m_nSubs, 2); | 798 m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); |
786 pArray = pDict->GetArray(FX_BSTRC("Encode")); | 799 pArray = pDict->GetArray(FX_BSTRC("Encode")); |
787 if (pArray == NULL) { | 800 if (!pArray) { |
788 return FALSE; | 801 return FALSE; |
789 } | 802 } |
790 for (i = 0; i < m_nSubs * 2; i++) { | 803 for (int i = 0; i < nSubs * 2; i++) { |
791 m_pEncode[i] = pArray->GetFloat(i); | 804 m_pEncode[i] = pArray->GetFloat(i); |
792 } | 805 } |
793 return TRUE; | 806 return TRUE; |
794 } | 807 } |
795 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { | 808 FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { |
796 FX_FLOAT input = inputs[0]; | 809 FX_FLOAT input = inputs[0]; |
797 int i; | 810 int i; |
798 for (i = 0; i < m_nSubs - 1; i++) | 811 for (i = 0; i < m_pSubFunctions.size() - 1; i++) |
799 if (input < m_pBounds[i + 1]) { | 812 if (input < m_pBounds[i + 1]) { |
800 break; | 813 break; |
801 } | 814 } |
802 if (m_pSubFunctions[i] == NULL) { | 815 if (m_pSubFunctions[i] == NULL) { |
803 return FALSE; | 816 return FALSE; |
804 } | 817 } |
805 input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], | 818 input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], |
806 m_pEncode[i * 2], m_pEncode[i * 2 + 1]); | 819 m_pEncode[i * 2], m_pEncode[i * 2 + 1]); |
807 int nresults; | 820 int nresults; |
808 m_pSubFunctions[i]->Call(&input, m_nInputs, outputs, nresults); | 821 m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults); |
809 return TRUE; | 822 return TRUE; |
810 } | 823 } |
811 CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) { | 824 CPDF_Function* CPDF_Function::Load(CPDF_Object* pFuncObj) { |
812 if (pFuncObj == NULL) { | 825 if (pFuncObj == NULL) { |
813 return NULL; | 826 return NULL; |
814 } | 827 } |
815 CPDF_Function* pFunc = NULL; | 828 CPDF_Function* pFunc = NULL; |
816 int type; | 829 int type; |
817 if (CPDF_Stream* pStream = pFuncObj->AsStream()) { | 830 if (CPDF_Stream* pStream = pFuncObj->AsStream()) { |
818 type = pStream->GetDict()->GetInteger(FX_BSTRC("FunctionType")); | 831 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++) { | 917 for (int i = 0; i < m_nOutputs; i++) { |
905 if (results[i] < m_pRanges[i * 2]) { | 918 if (results[i] < m_pRanges[i * 2]) { |
906 results[i] = m_pRanges[i * 2]; | 919 results[i] = m_pRanges[i * 2]; |
907 } else if (results[i] > m_pRanges[i * 2 + 1]) { | 920 } else if (results[i] > m_pRanges[i * 2 + 1]) { |
908 results[i] = m_pRanges[i * 2 + 1]; | 921 results[i] = m_pRanges[i * 2 + 1]; |
909 } | 922 } |
910 } | 923 } |
911 } | 924 } |
912 return TRUE; | 925 return TRUE; |
913 } | 926 } |
OLD | NEW |