summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn23
-rw-r--r--core/fpdfapi/font/cpdf_type3font.cpp1
-rw-r--r--core/fpdfapi/font/fpdf_font.cpp1
-rw-r--r--core/fpdfapi/page/cpdf_allstates.cpp1
-rw-r--r--core/fpdfapi/page/cpdf_color.cpp1
-rw-r--r--core/fpdfapi/page/cpdf_colorspace.cpp57
-rw-r--r--core/fpdfapi/page/cpdf_colorspace.h10
-rw-r--r--core/fpdfapi/page/cpdf_countedobject.h4
-rw-r--r--core/fpdfapi/page/cpdf_devicecs.cpp (renamed from core/fpdfapi/page/fpdf_page_colors.cpp)28
-rw-r--r--core/fpdfapi/page/cpdf_devicecs.h38
-rw-r--r--core/fpdfapi/page/cpdf_devicecs_unittest.cpp2
-rw-r--r--core/fpdfapi/page/cpdf_docpagedata.cpp1
-rw-r--r--core/fpdfapi/page/cpdf_docpagedata.h3
-rw-r--r--core/fpdfapi/page/cpdf_expintfunc.cpp60
-rw-r--r--core/fpdfapi/page/cpdf_expintfunc.h27
-rw-r--r--core/fpdfapi/page/cpdf_form.cpp1
-rw-r--r--core/fpdfapi/page/cpdf_function.cpp153
-rw-r--r--core/fpdfapi/page/cpdf_function.h64
-rw-r--r--core/fpdfapi/page/cpdf_iccprofile.cpp40
-rw-r--r--core/fpdfapi/page/cpdf_iccprofile.h36
-rw-r--r--core/fpdfapi/page/cpdf_meshstream.cpp2
-rw-r--r--core/fpdfapi/page/cpdf_page.cpp1
-rw-r--r--core/fpdfapi/page/cpdf_pagemodule.h3
-rw-r--r--core/fpdfapi/page/cpdf_pageobjectholder.cpp1
-rw-r--r--core/fpdfapi/page/cpdf_pageobjectlist.cpp1
-rw-r--r--core/fpdfapi/page/cpdf_pattern.h2
-rw-r--r--core/fpdfapi/page/cpdf_patterncs.cpp62
-rw-r--r--core/fpdfapi/page/cpdf_patterncs.h29
-rw-r--r--core/fpdfapi/page/cpdf_psengine.cpp405
-rw-r--r--core/fpdfapi/page/cpdf_psfunc.cpp34
-rw-r--r--core/fpdfapi/page/cpdf_psfunc.h28
-rw-r--r--core/fpdfapi/page/cpdf_sampledfunc.cpp156
-rw-r--r--core/fpdfapi/page/cpdf_sampledfunc.h52
-rw-r--r--core/fpdfapi/page/cpdf_shadingpattern.cpp2
-rw-r--r--core/fpdfapi/page/cpdf_shadingpattern.h2
-rw-r--r--core/fpdfapi/page/cpdf_stitchfunc.cpp91
-rw-r--r--core/fpdfapi/page/cpdf_stitchfunc.h37
-rw-r--r--core/fpdfapi/page/cpdf_stitchfunc_embeddertest.cpp (renamed from core/fpdfapi/page/fpdf_page_func_embeddertest.cpp)0
-rw-r--r--core/fpdfapi/page/cpdf_streamcontentparser.cpp20
-rw-r--r--core/fpdfapi/page/cpdf_streamcontentparser.h3
-rw-r--r--core/fpdfapi/page/cpdf_streamcontentparser_unittest.cpp30
-rw-r--r--core/fpdfapi/page/fpdf_page_func.cpp851
-rw-r--r--core/fpdfapi/page/pageint.h213
-rw-r--r--core/fpdfapi/parser/cpdf_document.cpp2
-rw-r--r--core/fpdfapi/render/cpdf_docrenderdata.cpp2
-rw-r--r--core/fpdfapi/render/cpdf_renderstatus.cpp2
-rw-r--r--core/fxge/skia/fx_skia_device.cpp5
47 files changed, 1397 insertions, 1190 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 073fd57b15..2f8b8f1038 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -483,16 +483,24 @@ static_library("fpdfapi") {
"core/fpdfapi/page/cpdf_contentparser.cpp",
"core/fpdfapi/page/cpdf_contentparser.h",
"core/fpdfapi/page/cpdf_countedobject.h",
+ "core/fpdfapi/page/cpdf_devicecs.cpp",
+ "core/fpdfapi/page/cpdf_devicecs.h",
"core/fpdfapi/page/cpdf_docpagedata.cpp",
"core/fpdfapi/page/cpdf_docpagedata.h",
+ "core/fpdfapi/page/cpdf_expintfunc.cpp",
+ "core/fpdfapi/page/cpdf_expintfunc.h",
"core/fpdfapi/page/cpdf_form.cpp",
"core/fpdfapi/page/cpdf_form.h",
"core/fpdfapi/page/cpdf_formobject.cpp",
"core/fpdfapi/page/cpdf_formobject.h",
+ "core/fpdfapi/page/cpdf_function.cpp",
+ "core/fpdfapi/page/cpdf_function.h",
"core/fpdfapi/page/cpdf_generalstate.cpp",
"core/fpdfapi/page/cpdf_generalstate.h",
"core/fpdfapi/page/cpdf_graphicstates.cpp",
"core/fpdfapi/page/cpdf_graphicstates.h",
+ "core/fpdfapi/page/cpdf_iccprofile.cpp",
+ "core/fpdfapi/page/cpdf_iccprofile.h",
"core/fpdfapi/page/cpdf_image.cpp",
"core/fpdfapi/page/cpdf_image.h",
"core/fpdfapi/page/cpdf_imageobject.cpp",
@@ -515,10 +523,20 @@ static_library("fpdfapi") {
"core/fpdfapi/page/cpdf_pathobject.h",
"core/fpdfapi/page/cpdf_pattern.cpp",
"core/fpdfapi/page/cpdf_pattern.h",
+ "core/fpdfapi/page/cpdf_patterncs.cpp",
+ "core/fpdfapi/page/cpdf_patterncs.h",
+ "core/fpdfapi/page/cpdf_psengine.cpp",
+ "core/fpdfapi/page/cpdf_psengine.h",
+ "core/fpdfapi/page/cpdf_psfunc.cpp",
+ "core/fpdfapi/page/cpdf_psfunc.h",
+ "core/fpdfapi/page/cpdf_sampledfunc.cpp",
+ "core/fpdfapi/page/cpdf_sampledfunc.h",
"core/fpdfapi/page/cpdf_shadingobject.cpp",
"core/fpdfapi/page/cpdf_shadingobject.h",
"core/fpdfapi/page/cpdf_shadingpattern.cpp",
"core/fpdfapi/page/cpdf_shadingpattern.h",
+ "core/fpdfapi/page/cpdf_stitchfunc.cpp",
+ "core/fpdfapi/page/cpdf_stitchfunc.h",
"core/fpdfapi/page/cpdf_streamcontentparser.cpp",
"core/fpdfapi/page/cpdf_streamcontentparser.h",
"core/fpdfapi/page/cpdf_streamparser.cpp",
@@ -529,9 +547,6 @@ static_library("fpdfapi") {
"core/fpdfapi/page/cpdf_textstate.h",
"core/fpdfapi/page/cpdf_tilingpattern.cpp",
"core/fpdfapi/page/cpdf_tilingpattern.h",
- "core/fpdfapi/page/fpdf_page_colors.cpp",
- "core/fpdfapi/page/fpdf_page_func.cpp",
- "core/fpdfapi/page/pageint.h",
"core/fpdfapi/parser/cfdf_document.cpp",
"core/fpdfapi/parser/cfdf_document.h",
"core/fpdfapi/parser/cpdf_array.cpp",
@@ -1930,7 +1945,7 @@ test("pdfium_unittests") {
test("pdfium_embeddertests") {
sources = [
- "core/fpdfapi/page/fpdf_page_func_embeddertest.cpp",
+ "core/fpdfapi/page/cpdf_stitchfunc_embeddertest.cpp",
"core/fpdfapi/parser/cpdf_parser_embeddertest.cpp",
"core/fpdfapi/parser/cpdf_security_handler_embeddertest.cpp",
"core/fpdfapi/parser/fpdf_parser_decode_embeddertest.cpp",
diff --git a/core/fpdfapi/font/cpdf_type3font.cpp b/core/fpdfapi/font/cpdf_type3font.cpp
index b1ac99b0c3..b22551a26a 100644
--- a/core/fpdfapi/font/cpdf_type3font.cpp
+++ b/core/fpdfapi/font/cpdf_type3font.cpp
@@ -10,7 +10,6 @@
#include "core/fpdfapi/font/cpdf_type3char.h"
#include "core/fpdfapi/page/cpdf_form.h"
-#include "core/fpdfapi/page/pageint.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
diff --git a/core/fpdfapi/font/fpdf_font.cpp b/core/fpdfapi/font/fpdf_font.cpp
index 4702947fd3..ebdad49da7 100644
--- a/core/fpdfapi/font/fpdf_font.cpp
+++ b/core/fpdfapi/font/fpdf_font.cpp
@@ -12,7 +12,6 @@
#include "core/fpdfapi/cpdf_modulemgr.h"
#include "core/fpdfapi/page/cpdf_form.h"
#include "core/fpdfapi/page/cpdf_pagemodule.h"
-#include "core/fpdfapi/page/pageint.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
diff --git a/core/fpdfapi/page/cpdf_allstates.cpp b/core/fpdfapi/page/cpdf_allstates.cpp
index c67d3152c0..cedc8479bc 100644
--- a/core/fpdfapi/page/cpdf_allstates.cpp
+++ b/core/fpdfapi/page/cpdf_allstates.cpp
@@ -10,7 +10,6 @@
#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
#include "core/fpdfapi/page/cpdf_streamcontentparser.h"
-#include "core/fpdfapi/page/pageint.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fxge/cfx_graphstatedata.h"
diff --git a/core/fpdfapi/page/cpdf_color.cpp b/core/fpdfapi/page/cpdf_color.cpp
index 7e0675df15..e6665c83ac 100644
--- a/core/fpdfapi/page/cpdf_color.cpp
+++ b/core/fpdfapi/page/cpdf_color.cpp
@@ -7,7 +7,6 @@
#include "core/fpdfapi/page/cpdf_color.h"
#include "core/fpdfapi/page/cpdf_docpagedata.h"
-#include "core/fpdfapi/page/pageint.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fxcrt/fx_system.h"
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index 111d45f17e..345180f368 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -12,8 +12,13 @@
#include <utility>
#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "core/fpdfapi/page/cpdf_devicecs.h"
#include "core/fpdfapi/page/cpdf_docpagedata.h"
+#include "core/fpdfapi/page/cpdf_function.h"
+#include "core/fpdfapi/page/cpdf_iccprofile.h"
#include "core/fpdfapi/page/cpdf_pagemodule.h"
+#include "core/fpdfapi/page/cpdf_pattern.h"
+#include "core/fpdfapi/page/cpdf_patterncs.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
@@ -22,6 +27,7 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fpdfdoc/cpdf_action.h"
#include "core/fxcodec/fx_codec.h"
#include "core/fxcrt/cfx_maybe_owned.h"
#include "core/fxcrt/fx_memory.h"
@@ -1128,57 +1134,6 @@ void CPDF_IndexedCS::EnableStdConversion(bool bEnabled) {
m_pBaseCS->EnableStdConversion(bEnabled);
}
-CPDF_PatternCS::CPDF_PatternCS(CPDF_Document* pDoc)
- : CPDF_ColorSpace(pDoc, PDFCS_PATTERN, 1),
- m_pBaseCS(nullptr),
- m_pCountedBaseCS(nullptr) {}
-
-CPDF_PatternCS::~CPDF_PatternCS() {
- CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : nullptr;
- if (pCS && m_pDocument) {
- auto* pPageData = m_pDocument->GetPageData();
- if (pPageData)
- pPageData->ReleaseColorSpace(pCS->GetArray());
- }
-}
-
-bool CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
- CPDF_Object* pBaseCS = pArray->GetDirectObjectAt(1);
- if (pBaseCS == m_pArray)
- return false;
-
- CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
- m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, nullptr);
- if (!m_pBaseCS) {
- m_nComponents = 1;
- return true;
- }
-
- if (m_pBaseCS->GetFamily() == PDFCS_PATTERN)
- return false;
-
- m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
- m_nComponents = m_pBaseCS->CountComponents() + 1;
- return m_pBaseCS->CountComponents() <= MAX_PATTERN_COLORCOMPS;
-}
-
-bool CPDF_PatternCS::GetRGB(float* pBuf, float* R, float* G, float* B) const {
- if (m_pBaseCS) {
- ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN);
- PatternValue* pvalue = (PatternValue*)pBuf;
- if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B))
- return true;
- }
- *R = 0.75f;
- *G = 0.75f;
- *B = 0.75f;
- return false;
-}
-
-CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const {
- return m_pBaseCS;
-}
-
CPDF_SeparationCS::CPDF_SeparationCS(CPDF_Document* pDoc)
: CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1) {}
diff --git a/core/fpdfapi/page/cpdf_colorspace.h b/core/fpdfapi/page/cpdf_colorspace.h
index 9e1c4dea18..c8c2abf0da 100644
--- a/core/fpdfapi/page/cpdf_colorspace.h
+++ b/core/fpdfapi/page/cpdf_colorspace.h
@@ -9,6 +9,7 @@
#include <memory>
+#include "core/fpdfapi/page/cpdf_pattern.h"
#include "core/fxcrt/cfx_unowned_ptr.h"
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/fx_system.h"
@@ -29,6 +30,14 @@ class CPDF_Array;
class CPDF_Document;
class CPDF_Object;
+#define MAX_PATTERN_COLORCOMPS 16
+struct PatternValue {
+ CPDF_Pattern* m_pPattern;
+ CPDF_CountedPattern* m_pCountedPattern;
+ int m_nComps;
+ float m_Comps[MAX_PATTERN_COLORCOMPS];
+};
+
class CPDF_ColorSpace {
public:
static CPDF_ColorSpace* GetStockCS(int Family);
@@ -85,6 +94,7 @@ class CPDF_ColorSpace {
CFX_UnownedPtr<CPDF_Array> m_pArray;
uint32_t m_dwStdConversion;
};
+using CPDF_CountedColorSpace = CPDF_CountedObject<CPDF_ColorSpace>;
namespace std {
diff --git a/core/fpdfapi/page/cpdf_countedobject.h b/core/fpdfapi/page/cpdf_countedobject.h
index 64f936c52c..cb39616f2b 100644
--- a/core/fpdfapi/page/cpdf_countedobject.h
+++ b/core/fpdfapi/page/cpdf_countedobject.h
@@ -9,8 +9,6 @@
#include <memory>
-#include "core/fpdfapi/page/cpdf_colorspace.h"
-#include "core/fpdfapi/page/cpdf_pattern.h"
#include "core/fxcrt/fx_system.h"
template <class T>
@@ -44,7 +42,5 @@ class CPDF_CountedObject {
size_t m_nCount;
T* m_pObj;
};
-using CPDF_CountedColorSpace = CPDF_CountedObject<CPDF_ColorSpace>;
-using CPDF_CountedPattern = CPDF_CountedObject<CPDF_Pattern>;
#endif // CORE_FPDFAPI_PAGE_CPDF_COUNTEDOBJECT_H_
diff --git a/core/fpdfapi/page/fpdf_page_colors.cpp b/core/fpdfapi/page/cpdf_devicecs.cpp
index 1526b75041..d410b1fb4a 100644
--- a/core/fpdfapi/page/fpdf_page_colors.cpp
+++ b/core/fpdfapi/page/cpdf_devicecs.cpp
@@ -4,7 +4,7 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#include "core/fpdfapi/page/pageint.h"
+#include "core/fpdfapi/page/cpdf_devicecs.h"
#include <limits.h>
@@ -14,7 +14,6 @@
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
-#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fxcodec/fx_codec.h"
@@ -27,10 +26,6 @@ float NormalizeChannel(float fVal) {
return pdfium::clamp(fVal, 0.0f, 1.0f);
}
-bool DetectSRGB(const uint8_t* pData, uint32_t dwSize) {
- return dwSize == 3144 && memcmp(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0;
-}
-
} // namespace
uint32_t ComponentsForFamily(int family) {
@@ -218,24 +213,3 @@ void CPDF_DeviceCS::TranslateImageLine(uint8_t* pDestBuf,
break;
}
}
-
-CPDF_IccProfile::CPDF_IccProfile(CPDF_Stream* pStream,
- const uint8_t* pData,
- uint32_t dwSize)
- : m_bsRGB(DetectSRGB(pData, dwSize)), m_pStream(pStream) {
- if (m_bsRGB) {
- m_nSrcComponents = 3;
- return;
- }
- uint32_t nSrcComps = 0;
- auto* pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
- m_pTransform = pIccModule->CreateTransform_sRGB(pData, dwSize, nSrcComps);
- if (m_pTransform)
- m_nSrcComponents = nSrcComps;
-}
-
-CPDF_IccProfile::~CPDF_IccProfile() {
- if (m_pTransform) {
- CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform);
- }
-}
diff --git a/core/fpdfapi/page/cpdf_devicecs.h b/core/fpdfapi/page/cpdf_devicecs.h
new file mode 100644
index 0000000000..177f240fbc
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_devicecs.h
@@ -0,0 +1,38 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFAPI_PAGE_CPDF_DEVICECS_H_
+#define CORE_FPDFAPI_PAGE_CPDF_DEVICECS_H_
+
+#include "core/fpdfapi/page/cpdf_colorspace.h"
+
+class CPDF_DeviceCS : public CPDF_ColorSpace {
+ public:
+ explicit CPDF_DeviceCS(int family);
+ ~CPDF_DeviceCS() override;
+
+ // CPDF_ColorSpace:
+ bool GetRGB(float* pBuf, float* R, float* G, float* B) const override;
+ bool SetRGB(float* pBuf, float R, float G, float B) const override;
+ bool v_GetCMYK(float* pBuf,
+ float* c,
+ float* m,
+ float* y,
+ float* k) const override;
+ bool v_SetCMYK(float* pBuf,
+ float c,
+ float m,
+ float y,
+ float k) const override;
+ void TranslateImageLine(uint8_t* pDestBuf,
+ const uint8_t* pSrcBuf,
+ int pixels,
+ int image_width,
+ int image_height,
+ bool bTransMask) const override;
+};
+
+#endif // CORE_FPDFAPI_PAGE_CPDF_DEVICECS_H_
diff --git a/core/fpdfapi/page/cpdf_devicecs_unittest.cpp b/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
index 22a961a1c1..a171d01f59 100644
--- a/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
+++ b/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
@@ -4,7 +4,7 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-#include "core/fpdfapi/page/pageint.h"
+#include "core/fpdfapi/page/cpdf_devicecs.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(CPDF_DeviceCSTest, GetRGBFromGray) {
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index 435b0f2eec..d8b89b318b 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -15,6 +15,7 @@
#include "core/fpdfapi/cpdf_modulemgr.h"
#include "core/fpdfapi/font/cpdf_type1font.h"
#include "core/fpdfapi/font/font_int.h"
+#include "core/fpdfapi/page/cpdf_iccprofile.h"
#include "core/fpdfapi/page/cpdf_image.h"
#include "core/fpdfapi/page/cpdf_pagemodule.h"
#include "core/fpdfapi/page/cpdf_pattern.h"
diff --git a/core/fpdfapi/page/cpdf_docpagedata.h b/core/fpdfapi/page/cpdf_docpagedata.h
index 32d220b756..0fda16911d 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.h
+++ b/core/fpdfapi/page/cpdf_docpagedata.h
@@ -10,7 +10,7 @@
#include <map>
#include <set>
-#include "core/fpdfapi/page/cpdf_countedobject.h"
+#include "core/fpdfapi/page/cpdf_colorspace.h"
#include "core/fxcrt/cfx_unowned_ptr.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_string.h"
@@ -22,6 +22,7 @@ class CPDF_FontEncoding;
class CPDF_IccProfile;
class CPDF_Image;
class CPDF_Object;
+class CPDF_Pattern;
class CPDF_Stream;
class CPDF_StreamAcc;
diff --git a/core/fpdfapi/page/cpdf_expintfunc.cpp b/core/fpdfapi/page/cpdf_expintfunc.cpp
new file mode 100644
index 0000000000..5d1213131b
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_expintfunc.cpp
@@ -0,0 +1,60 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/page/cpdf_expintfunc.h"
+
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fxcrt/fx_memory.h"
+
+CPDF_ExpIntFunc::CPDF_ExpIntFunc()
+ : CPDF_Function(Type::kType2ExpotentialInterpolation),
+ m_pBeginValues(nullptr),
+ m_pEndValues(nullptr) {}
+
+CPDF_ExpIntFunc::~CPDF_ExpIntFunc() {
+ FX_Free(m_pBeginValues);
+ FX_Free(m_pEndValues);
+}
+
+bool CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) {
+ CPDF_Dictionary* pDict = pObj->GetDict();
+ if (!pDict)
+ return false;
+
+ CPDF_Array* pArray0 = pDict->GetArrayFor("C0");
+ if (m_nOutputs == 0) {
+ m_nOutputs = 1;
+ if (pArray0)
+ m_nOutputs = pArray0->GetCount();
+ }
+
+ CPDF_Array* pArray1 = pDict->GetArrayFor("C1");
+ m_pBeginValues = FX_Alloc2D(float, m_nOutputs, 2);
+ m_pEndValues = FX_Alloc2D(float, m_nOutputs, 2);
+ for (uint32_t i = 0; i < m_nOutputs; i++) {
+ m_pBeginValues[i] = pArray0 ? pArray0->GetFloatAt(i) : 0.0f;
+ m_pEndValues[i] = pArray1 ? pArray1->GetFloatAt(i) : 1.0f;
+ }
+
+ m_Exponent = pDict->GetFloatFor("N");
+ m_nOrigOutputs = m_nOutputs;
+ if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs)
+ return false;
+
+ m_nOutputs *= m_nInputs;
+ return true;
+}
+
+bool CPDF_ExpIntFunc::v_Call(float* inputs, float* results) const {
+ for (uint32_t i = 0; i < m_nInputs; i++)
+ for (uint32_t j = 0; j < m_nOrigOutputs; j++) {
+ results[i * m_nOrigOutputs + j] =
+ m_pBeginValues[j] + FXSYS_pow(inputs[i], m_Exponent) *
+ (m_pEndValues[j] - m_pBeginValues[j]);
+ }
+ return true;
+}
diff --git a/core/fpdfapi/page/cpdf_expintfunc.h b/core/fpdfapi/page/cpdf_expintfunc.h
new file mode 100644
index 0000000000..867d2fa265
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_expintfunc.h
@@ -0,0 +1,27 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFAPI_PAGE_CPDF_EXPINTFUNC_H_
+#define CORE_FPDFAPI_PAGE_CPDF_EXPINTFUNC_H_
+
+#include "core/fpdfapi/page/cpdf_function.h"
+
+class CPDF_ExpIntFunc : public CPDF_Function {
+ public:
+ CPDF_ExpIntFunc();
+ ~CPDF_ExpIntFunc() override;
+
+ // CPDF_Function
+ bool v_Init(CPDF_Object* pObj) override;
+ bool v_Call(float* inputs, float* results) const override;
+
+ uint32_t m_nOrigOutputs;
+ float m_Exponent;
+ float* m_pBeginValues;
+ float* m_pEndValues;
+};
+
+#endif // CORE_FPDFAPI_PAGE_CPDF_EXPINTFUNC_H_
diff --git a/core/fpdfapi/page/cpdf_form.cpp b/core/fpdfapi/page/cpdf_form.cpp
index 2245f934f6..c2170ac4e7 100644
--- a/core/fpdfapi/page/cpdf_form.cpp
+++ b/core/fpdfapi/page/cpdf_form.cpp
@@ -9,7 +9,6 @@
#include "core/fpdfapi/page/cpdf_contentparser.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
-#include "core/fpdfapi/page/pageint.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "third_party/base/ptr_util.h"
diff --git a/core/fpdfapi/page/cpdf_function.cpp b/core/fpdfapi/page/cpdf_function.cpp
new file mode 100644
index 0000000000..635c53a95f
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_function.cpp
@@ -0,0 +1,153 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/page/cpdf_function.h"
+
+#include "core/fpdfapi/page/cpdf_expintfunc.h"
+#include "core/fpdfapi/page/cpdf_psfunc.h"
+#include "core/fpdfapi/page/cpdf_sampledfunc.h"
+#include "core/fpdfapi/page/cpdf_stitchfunc.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "third_party/base/ptr_util.h"
+
+// static
+std::unique_ptr<CPDF_Function> CPDF_Function::Load(CPDF_Object* pFuncObj) {
+ std::unique_ptr<CPDF_Function> pFunc;
+ if (!pFuncObj)
+ return pFunc;
+
+ int iType = -1;
+ if (CPDF_Stream* pStream = pFuncObj->AsStream())
+ iType = pStream->GetDict()->GetIntegerFor("FunctionType");
+ else if (CPDF_Dictionary* pDict = pFuncObj->AsDictionary())
+ iType = pDict->GetIntegerFor("FunctionType");
+
+ Type type = IntegerToFunctionType(iType);
+ if (type == Type::kType0Sampled)
+ pFunc = pdfium::MakeUnique<CPDF_SampledFunc>();
+ else if (type == Type::kType2ExpotentialInterpolation)
+ pFunc = pdfium::MakeUnique<CPDF_ExpIntFunc>();
+ else if (type == Type::kType3Stitching)
+ pFunc = pdfium::MakeUnique<CPDF_StitchFunc>();
+ else if (type == Type::kType4PostScript)
+ pFunc = pdfium::MakeUnique<CPDF_PSFunc>();
+
+ if (!pFunc || !pFunc->Init(pFuncObj))
+ return nullptr;
+
+ return pFunc;
+}
+
+// static
+CPDF_Function::Type CPDF_Function::IntegerToFunctionType(int iType) {
+ switch (iType) {
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ return static_cast<Type>(iType);
+ default:
+ return Type::kTypeInvalid;
+ }
+}
+
+CPDF_Function::CPDF_Function(Type type)
+ : m_pDomains(nullptr), m_pRanges(nullptr), m_Type(type) {}
+
+CPDF_Function::~CPDF_Function() {
+ FX_Free(m_pDomains);
+ FX_Free(m_pRanges);
+}
+
+bool CPDF_Function::Init(CPDF_Object* pObj) {
+ CPDF_Stream* pStream = pObj->AsStream();
+ CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary();
+
+ CPDF_Array* pDomains = pDict->GetArrayFor("Domain");
+ if (!pDomains)
+ return false;
+
+ m_nInputs = pDomains->GetCount() / 2;
+ if (m_nInputs == 0)
+ return false;
+
+ m_pDomains = FX_Alloc2D(float, m_nInputs, 2);
+ for (uint32_t i = 0; i < m_nInputs * 2; i++) {
+ m_pDomains[i] = pDomains->GetFloatAt(i);
+ }
+ CPDF_Array* pRanges = pDict->GetArrayFor("Range");
+ m_nOutputs = 0;
+ if (pRanges) {
+ m_nOutputs = pRanges->GetCount() / 2;
+ m_pRanges = FX_Alloc2D(float, m_nOutputs, 2);
+ for (uint32_t i = 0; i < m_nOutputs * 2; i++)
+ m_pRanges[i] = pRanges->GetFloatAt(i);
+ }
+ uint32_t old_outputs = m_nOutputs;
+ if (!v_Init(pObj))
+ return false;
+ if (m_pRanges && m_nOutputs > old_outputs) {
+ m_pRanges = FX_Realloc(float, m_pRanges, m_nOutputs * 2);
+ if (m_pRanges) {
+ memset(m_pRanges + (old_outputs * 2), 0,
+ sizeof(float) * (m_nOutputs - old_outputs) * 2);
+ }
+ }
+ return true;
+}
+
+bool CPDF_Function::Call(float* inputs,
+ uint32_t ninputs,
+ float* results,
+ int* nresults) const {
+ if (m_nInputs != ninputs)
+ return false;
+
+ *nresults = m_nOutputs;
+ for (uint32_t i = 0; i < m_nInputs; i++) {
+ inputs[i] =
+ pdfium::clamp(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1]);
+ }
+ v_Call(inputs, results);
+ if (!m_pRanges)
+ return true;
+
+ for (uint32_t i = 0; i < m_nOutputs; i++) {
+ results[i] =
+ pdfium::clamp(results[i], m_pRanges[i * 2], m_pRanges[i * 2 + 1]);
+ }
+ return true;
+}
+
+// See PDF Reference 1.7, page 170.
+float CPDF_Function::Interpolate(float x,
+ float xmin,
+ float xmax,
+ float ymin,
+ float ymax) const {
+ float divisor = xmax - xmin;
+ return ymin + (divisor ? (x - xmin) * (ymax - ymin) / divisor : 0);
+}
+
+const CPDF_SampledFunc* CPDF_Function::ToSampledFunc() const {
+ return m_Type == Type::kType0Sampled
+ ? static_cast<const CPDF_SampledFunc*>(this)
+ : nullptr;
+}
+
+const CPDF_ExpIntFunc* CPDF_Function::ToExpIntFunc() const {
+ return m_Type == Type::kType2ExpotentialInterpolation
+ ? static_cast<const CPDF_ExpIntFunc*>(this)
+ : nullptr;
+}
+
+const CPDF_StitchFunc* CPDF_Function::ToStitchFunc() const {
+ return m_Type == Type::kType3Stitching
+ ? static_cast<const CPDF_StitchFunc*>(this)
+ : nullptr;
+}
diff --git a/core/fpdfapi/page/cpdf_function.h b/core/fpdfapi/page/cpdf_function.h
new file mode 100644
index 0000000000..ff7cf847d2
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_function.h
@@ -0,0 +1,64 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFAPI_PAGE_CPDF_FUNCTION_H_
+#define CORE_FPDFAPI_PAGE_CPDF_FUNCTION_H_
+
+#include <memory>
+
+class CPDF_ExpIntFunc;
+class CPDF_Object;
+class CPDF_SampledFunc;
+class CPDF_StitchFunc;
+
+class CPDF_Function {
+ public:
+ enum class Type {
+ kTypeInvalid = -1,
+ kType0Sampled = 0,
+ kType2ExpotentialInterpolation = 2,
+ kType3Stitching = 3,
+ kType4PostScript = 4,
+ };
+
+ static std::unique_ptr<CPDF_Function> Load(CPDF_Object* pFuncObj);
+ static Type IntegerToFunctionType(int iType);
+
+ virtual ~CPDF_Function();
+
+ bool Call(float* inputs,
+ uint32_t ninputs,
+ float* results,
+ int* nresults) const;
+ uint32_t CountInputs() const { return m_nInputs; }
+ uint32_t CountOutputs() const { return m_nOutputs; }
+ float GetDomain(int i) const { return m_pDomains[i]; }
+ float GetRange(int i) const { return m_pRanges[i]; }
+ float Interpolate(float x,
+ float xmin,
+ float xmax,
+ float ymin,
+ float ymax) const;
+
+ const CPDF_SampledFunc* ToSampledFunc() const;
+ const CPDF_ExpIntFunc* ToExpIntFunc() const;
+ const CPDF_StitchFunc* ToStitchFunc() const;
+
+ protected:
+ explicit CPDF_Function(Type type);
+
+ bool Init(CPDF_Object* pObj);
+ virtual bool v_Init(CPDF_Object* pObj) = 0;
+ virtual bool v_Call(float* inputs, float* results) const = 0;
+
+ uint32_t m_nInputs;
+ uint32_t m_nOutputs;
+ float* m_pDomains;
+ float* m_pRanges;
+ const Type m_Type;
+};
+
+#endif // CORE_FPDFAPI_PAGE_CPDF_FUNCTION_H_
diff --git a/core/fpdfapi/page/cpdf_iccprofile.cpp b/core/fpdfapi/page/cpdf_iccprofile.cpp
new file mode 100644
index 0000000000..afb505a7e6
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_iccprofile.cpp
@@ -0,0 +1,40 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/page/cpdf_iccprofile.h"
+
+#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fxcodec/codec/ccodec_iccmodule.h"
+
+namespace {
+
+bool DetectSRGB(const uint8_t* pData, uint32_t dwSize) {
+ return dwSize == 3144 && memcmp(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0;
+}
+
+} // namespace
+
+CPDF_IccProfile::CPDF_IccProfile(CPDF_Stream* pStream,
+ const uint8_t* pData,
+ uint32_t dwSize)
+ : m_bsRGB(DetectSRGB(pData, dwSize)), m_pStream(pStream) {
+ if (m_bsRGB) {
+ m_nSrcComponents = 3;
+ return;
+ }
+
+ uint32_t nSrcComps = 0;
+ auto* pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
+ m_pTransform = pIccModule->CreateTransform_sRGB(pData, dwSize, nSrcComps);
+ if (m_pTransform)
+ m_nSrcComponents = nSrcComps;
+}
+
+CPDF_IccProfile::~CPDF_IccProfile() {
+ if (m_pTransform)
+ CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform);
+}
diff --git a/core/fpdfapi/page/cpdf_iccprofile.h b/core/fpdfapi/page/cpdf_iccprofile.h
new file mode 100644
index 0000000000..05ac9bf1ba
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_iccprofile.h
@@ -0,0 +1,36 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFAPI_PAGE_CPDF_ICCPROFILE_H_
+#define CORE_FPDFAPI_PAGE_CPDF_ICCPROFILE_H_
+
+#include "core/fxcrt/cfx_retain_ptr.h"
+
+class CPDF_Stream;
+
+class CPDF_IccProfile : public CFX_Retainable {
+ public:
+ template <typename T, typename... Args>
+ friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+ CPDF_Stream* GetStream() const { return m_pStream; }
+ bool IsValid() const { return IsSRGB() || IsSupported(); }
+ bool IsSRGB() const { return m_bsRGB; }
+ bool IsSupported() const { return !!m_pTransform; }
+ void* transform() { return m_pTransform; }
+ uint32_t GetComponents() const { return m_nSrcComponents; }
+
+ private:
+ CPDF_IccProfile(CPDF_Stream* pStream, const uint8_t* pData, uint32_t dwSize);
+ ~CPDF_IccProfile() override;
+
+ const bool m_bsRGB;
+ CPDF_Stream* const m_pStream;
+ void* m_pTransform = nullptr;
+ uint32_t m_nSrcComponents = 0;
+};
+
+#endif // CORE_FPDFAPI_PAGE_CPDF_ICCPROFILE_H_
diff --git a/core/fpdfapi/page/cpdf_meshstream.cpp b/core/fpdfapi/page/cpdf_meshstream.cpp
index ac93513163..7a6228a25b 100644
--- a/core/fpdfapi/page/cpdf_meshstream.cpp
+++ b/core/fpdfapi/page/cpdf_meshstream.cpp
@@ -7,7 +7,7 @@
#include "core/fpdfapi/page/cpdf_meshstream.h"
#include "core/fpdfapi/page/cpdf_colorspace.h"
-#include "core/fpdfapi/page/pageint.h"
+#include "core/fpdfapi/page/cpdf_function.h"
#include "core/fpdfapi/parser/cpdf_array.h"
namespace {
diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp
index d528d3da0b..2f0c83556c 100644
--- a/core/fpdfapi/page/cpdf_page.cpp
+++ b/core/fpdfapi/page/cpdf_page.cpp
@@ -12,7 +12,6 @@
#include "core/fpdfapi/cpdf_pagerendercontext.h"
#include "core/fpdfapi/page/cpdf_contentparser.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
-#include "core/fpdfapi/page/pageint.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_object.h"
diff --git a/core/fpdfapi/page/cpdf_pagemodule.h b/core/fpdfapi/page/cpdf_pagemodule.h
index 4aa19da2bb..49d2769f88 100644
--- a/core/fpdfapi/page/cpdf_pagemodule.h
+++ b/core/fpdfapi/page/cpdf_pagemodule.h
@@ -9,7 +9,8 @@
#include "core/fpdfapi/font/font_int.h"
#include "core/fpdfapi/page/cpdf_colorspace.h"
-#include "core/fpdfapi/page/pageint.h"
+#include "core/fpdfapi/page/cpdf_devicecs.h"
+#include "core/fpdfapi/page/cpdf_patterncs.h"
class CPDF_Document;
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.cpp b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
index 1d2b51e959..53dfd75d5d 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.cpp
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
@@ -10,7 +10,6 @@
#include "core/fpdfapi/page/cpdf_contentparser.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
-#include "core/fpdfapi/page/pageint.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
CPDF_PageObjectHolder::CPDF_PageObjectHolder(CPDF_Document* pDoc,
diff --git a/core/fpdfapi/page/cpdf_pageobjectlist.cpp b/core/fpdfapi/page/cpdf_pageobjectlist.cpp
index 5c30fe9877..afd2c98536 100644
--- a/core/fpdfapi/page/cpdf_pageobjectlist.cpp
+++ b/core/fpdfapi/page/cpdf_pageobjectlist.cpp
@@ -6,7 +6,6 @@
#include "core/fpdfapi/page/cpdf_pageobjectlist.h"
-#include "core/fpdfapi/page/pageint.h"
#include "third_party/base/stl_util.h"
CPDF_PageObject* CPDF_PageObjectList::GetPageObjectByIndex(int index) {
diff --git a/core/fpdfapi/page/cpdf_pattern.h b/core/fpdfapi/page/cpdf_pattern.h
index dba301b922..504b5b0ffc 100644
--- a/core/fpdfapi/page/cpdf_pattern.h
+++ b/core/fpdfapi/page/cpdf_pattern.h
@@ -7,6 +7,7 @@
#ifndef CORE_FPDFAPI_PAGE_CPDF_PATTERN_H_
#define CORE_FPDFAPI_PAGE_CPDF_PATTERN_H_
+#include "core/fpdfapi/page/cpdf_countedobject.h"
#include "core/fxcrt/cfx_unowned_ptr.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_system.h"
@@ -44,5 +45,6 @@ class CPDF_Pattern {
CFX_Matrix m_Pattern2Form;
const CFX_Matrix m_ParentMatrix;
};
+using CPDF_CountedPattern = CPDF_CountedObject<CPDF_Pattern>;
#endif // CORE_FPDFAPI_PAGE_CPDF_PATTERN_H_
diff --git a/core/fpdfapi/page/cpdf_patterncs.cpp b/core/fpdfapi/page/cpdf_patterncs.cpp
new file mode 100644
index 0000000000..4951f61d54
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_patterncs.cpp
@@ -0,0 +1,62 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/page/cpdf_patterncs.h"
+
+#include "core/fpdfapi/page/cpdf_docpagedata.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+
+CPDF_PatternCS::CPDF_PatternCS(CPDF_Document* pDoc)
+ : CPDF_ColorSpace(pDoc, PDFCS_PATTERN, 1),
+ m_pBaseCS(nullptr),
+ m_pCountedBaseCS(nullptr) {}
+
+CPDF_PatternCS::~CPDF_PatternCS() {
+ CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : nullptr;
+ if (pCS && m_pDocument) {
+ auto* pPageData = m_pDocument->GetPageData();
+ if (pPageData)
+ pPageData->ReleaseColorSpace(pCS->GetArray());
+ }
+}
+
+bool CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
+ CPDF_Object* pBaseCS = pArray->GetDirectObjectAt(1);
+ if (pBaseCS == m_pArray)
+ return false;
+
+ CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
+ m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, nullptr);
+ if (!m_pBaseCS) {
+ m_nComponents = 1;
+ return true;
+ }
+
+ if (m_pBaseCS->GetFamily() == PDFCS_PATTERN)
+ return false;
+
+ m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
+ m_nComponents = m_pBaseCS->CountComponents() + 1;
+ return m_pBaseCS->CountComponents() <= MAX_PATTERN_COLORCOMPS;
+}
+
+bool CPDF_PatternCS::GetRGB(float* pBuf, float* R, float* G, float* B) const {
+ if (m_pBaseCS) {
+ ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN);
+ PatternValue* pvalue = (PatternValue*)pBuf;
+ if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B))
+ return true;
+ }
+ *R = 0.75f;
+ *G = 0.75f;
+ *B = 0.75f;
+ return false;
+}
+
+CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const {
+ return m_pBaseCS;
+}
diff --git a/core/fpdfapi/page/cpdf_patterncs.h b/core/fpdfapi/page/cpdf_patterncs.h
new file mode 100644
index 0000000000..d28fff19c9
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_patterncs.h
@@ -0,0 +1,29 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFAPI_PAGE_CPDF_PATTERNCS_H_
+#define CORE_FPDFAPI_PAGE_CPDF_PATTERNCS_H_
+
+#include "core/fpdfapi/page/cpdf_colorspace.h"
+
+class CPDF_Document;
+
+class CPDF_PatternCS : public CPDF_ColorSpace {
+ public:
+ explicit CPDF_PatternCS(CPDF_Document* pDoc);
+ ~CPDF_PatternCS() override;
+
+ // CPDF_ColorSpace:
+ bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
+ bool GetRGB(float* pBuf, float* R, float* G, float* B) const override;
+ CPDF_ColorSpace* GetBaseCS() const override;
+
+ private:
+ CPDF_ColorSpace* m_pBaseCS;
+ CPDF_CountedColorSpace* m_pCountedBaseCS;
+};
+
+#endif // CORE_FPDFAPI_PAGE_CPDF_PATTERNCS_H_
diff --git a/core/fpdfapi/page/cpdf_psengine.cpp b/core/fpdfapi/page/cpdf_psengine.cpp
new file mode 100644
index 0000000000..658d73cda3
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_psengine.cpp
@@ -0,0 +1,405 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/page/cpdf_psengine.h"
+
+#include <utility>
+
+#include "core/fpdfapi/parser/cpdf_simple_parser.h"
+#include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/fx_string.h"
+#include "third_party/base/logging.h"
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+struct PDF_PSOpName {
+ const char* name;
+ PDF_PSOP op;
+};
+
+const PDF_PSOpName kPsOpNames[] = {
+ {"add", PSOP_ADD}, {"sub", PSOP_SUB},
+ {"mul", PSOP_MUL}, {"div", PSOP_DIV},
+ {"idiv", PSOP_IDIV}, {"mod", PSOP_MOD},
+ {"neg", PSOP_NEG}, {"abs", PSOP_ABS},
+ {"ceiling", PSOP_CEILING}, {"floor", PSOP_FLOOR},
+ {"round", PSOP_ROUND}, {"truncate", PSOP_TRUNCATE},
+ {"sqrt", PSOP_SQRT}, {"sin", PSOP_SIN},
+ {"cos", PSOP_COS}, {"atan", PSOP_ATAN},
+ {"exp", PSOP_EXP}, {"ln", PSOP_LN},
+ {"log", PSOP_LOG}, {"cvi", PSOP_CVI},
+ {"cvr", PSOP_CVR}, {"eq", PSOP_EQ},
+ {"ne", PSOP_NE}, {"gt", PSOP_GT},
+ {"ge", PSOP_GE}, {"lt", PSOP_LT},
+ {"le", PSOP_LE}, {"and", PSOP_AND},
+ {"or", PSOP_OR}, {"xor", PSOP_XOR},
+ {"not", PSOP_NOT}, {"bitshift", PSOP_BITSHIFT},
+ {"true", PSOP_TRUE}, {"false", PSOP_FALSE},
+ {"if", PSOP_IF}, {"ifelse", PSOP_IFELSE},
+ {"pop", PSOP_POP}, {"exch", PSOP_EXCH},
+ {"dup", PSOP_DUP}, {"copy", PSOP_COPY},
+ {"index", PSOP_INDEX}, {"roll", PSOP_ROLL}};
+
+} // namespace
+
+class CPDF_PSOP {
+ public:
+ explicit CPDF_PSOP(PDF_PSOP op) : m_op(op), m_value(0) {
+ ASSERT(m_op != PSOP_CONST);
+ ASSERT(m_op != PSOP_PROC);
+ }
+ explicit CPDF_PSOP(float value) : m_op(PSOP_CONST), m_value(value) {}
+ CPDF_PSOP()
+ : m_op(PSOP_PROC),
+ m_value(0),
+ m_proc(pdfium::MakeUnique<CPDF_PSProc>()) {}
+
+ float GetFloatValue() const {
+ if (m_op == PSOP_CONST)
+ return m_value;
+
+ NOTREACHED();
+ return 0;
+ }
+ CPDF_PSProc* GetProc() const {
+ if (m_op == PSOP_PROC)
+ return m_proc.get();
+ NOTREACHED();
+ return nullptr;
+ }
+
+ PDF_PSOP GetOp() const { return m_op; }
+
+ private:
+ const PDF_PSOP m_op;
+ const float m_value;
+ std::unique_ptr<CPDF_PSProc> m_proc;
+};
+
+bool CPDF_PSEngine::Execute() {
+ return m_MainProc.Execute(this);
+}
+
+CPDF_PSProc::CPDF_PSProc() {}
+CPDF_PSProc::~CPDF_PSProc() {}
+
+bool CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) {
+ for (size_t i = 0; i < m_Operators.size(); ++i) {
+ const PDF_PSOP op = m_Operators[i]->GetOp();
+ if (op == PSOP_PROC)
+ continue;
+
+ if (op == PSOP_CONST) {
+ pEngine->Push(m_Operators[i]->GetFloatValue());
+ continue;
+ }
+
+ if (op == PSOP_IF) {
+ if (i == 0 || m_Operators[i - 1]->GetOp() != PSOP_PROC)
+ return false;
+
+ if (static_cast<int>(pEngine->Pop()))
+ m_Operators[i - 1]->GetProc()->Execute(pEngine);
+ } else if (op == PSOP_IFELSE) {
+ if (i < 2 || m_Operators[i - 1]->GetOp() != PSOP_PROC ||
+ m_Operators[i - 2]->GetOp() != PSOP_PROC) {
+ return false;
+ }
+ size_t offset = static_cast<int>(pEngine->Pop()) ? 2 : 1;
+ m_Operators[i - offset]->GetProc()->Execute(pEngine);
+ } else {
+ pEngine->DoOperator(op);
+ }
+ }
+ return true;
+}
+
+CPDF_PSEngine::CPDF_PSEngine() : m_StackCount(0) {}
+
+CPDF_PSEngine::~CPDF_PSEngine() {}
+
+void CPDF_PSEngine::Push(float v) {
+ if (m_StackCount < PSENGINE_STACKSIZE)
+ m_Stack[m_StackCount++] = v;
+}
+
+float CPDF_PSEngine::Pop() {
+ return m_StackCount > 0 ? m_Stack[--m_StackCount] : 0;
+}
+
+bool CPDF_PSEngine::Parse(const char* str, int size) {
+ CPDF_SimpleParser parser(reinterpret_cast<const uint8_t*>(str), size);
+ CFX_ByteStringC word = parser.GetWord();
+ return word == "{" ? m_MainProc.Parse(&parser, 0) : false;
+}
+
+bool CPDF_PSProc::Parse(CPDF_SimpleParser* parser, int depth) {
+ if (depth > kMaxDepth)
+ return false;
+
+ while (1) {
+ CFX_ByteStringC word = parser->GetWord();
+ if (word.IsEmpty())
+ return false;
+
+ if (word == "}")
+ return true;
+
+ if (word == "{") {
+ m_Operators.push_back(pdfium::MakeUnique<CPDF_PSOP>());
+ if (!m_Operators.back()->GetProc()->Parse(parser, depth + 1))
+ return false;
+ continue;
+ }
+
+ std::unique_ptr<CPDF_PSOP> op;
+ for (const PDF_PSOpName& op_name : kPsOpNames) {
+ if (word == CFX_ByteStringC(op_name.name)) {
+ op = pdfium::MakeUnique<CPDF_PSOP>(op_name.op);
+ break;
+ }
+ }
+ if (!op)
+ op = pdfium::MakeUnique<CPDF_PSOP>(FX_atof(word));
+ m_Operators.push_back(std::move(op));
+ }
+}
+
+bool CPDF_PSEngine::DoOperator(PDF_PSOP op) {
+ int i1;
+ int i2;
+ float d1;
+ float d2;
+ FX_SAFE_INT32 result;
+ switch (op) {
+ case PSOP_ADD:
+ d1 = Pop();
+ d2 = Pop();
+ Push(d1 + d2);
+ break;
+ case PSOP_SUB:
+ d2 = Pop();
+ d1 = Pop();
+ Push(d1 - d2);
+ break;
+ case PSOP_MUL:
+ d1 = Pop();
+ d2 = Pop();
+ Push(d1 * d2);
+ break;
+ case PSOP_DIV:
+ d2 = Pop();
+ d1 = Pop();
+ Push(d1 / d2);
+ break;
+ case PSOP_IDIV:
+ i2 = static_cast<int>(Pop());
+ i1 = static_cast<int>(Pop());
+ if (i2) {
+ result = i1;
+ result /= i2;
+ Push(result.ValueOrDefault(0));
+ } else {
+ Push(0);
+ }
+ break;
+ case PSOP_MOD:
+ i2 = static_cast<int>(Pop());
+ i1 = static_cast<int>(Pop());
+ if (i2) {
+ result = i1;
+ result %= i2;
+ Push(result.ValueOrDefault(0));
+ } else {
+ Push(0);
+ }
+ break;
+ case PSOP_NEG:
+ d1 = Pop();
+ Push(-d1);
+ break;
+ case PSOP_ABS:
+ d1 = Pop();
+ Push((float)fabs(d1));
+ break;
+ case PSOP_CEILING:
+ d1 = Pop();
+ Push((float)ceil(d1));
+ break;
+ case PSOP_FLOOR:
+ d1 = Pop();
+ Push((float)floor(d1));
+ break;
+ case PSOP_ROUND:
+ d1 = Pop();
+ Push(FXSYS_round(d1));
+ break;
+ case PSOP_TRUNCATE:
+ i1 = (int)Pop();
+ Push(i1);
+ break;
+ case PSOP_SQRT:
+ d1 = Pop();
+ Push((float)sqrt(d1));
+ break;
+ case PSOP_SIN:
+ d1 = Pop();
+ Push((float)sin(d1 * FX_PI / 180.0f));
+ break;
+ case PSOP_COS:
+ d1 = Pop();
+ Push((float)cos(d1 * FX_PI / 180.0f));
+ break;
+ case PSOP_ATAN:
+ d2 = Pop();
+ d1 = Pop();
+ d1 = (float)(atan2(d1, d2) * 180.0 / FX_PI);
+ if (d1 < 0) {
+ d1 += 360;
+ }
+ Push(d1);
+ break;
+ case PSOP_EXP:
+ d2 = Pop();
+ d1 = Pop();
+ Push((float)FXSYS_pow(d1, d2));
+ break;
+ case PSOP_LN:
+ d1 = Pop();
+ Push((float)log(d1));
+ break;
+ case PSOP_LOG:
+ d1 = Pop();
+ Push((float)log10(d1));
+ break;
+ case PSOP_CVI:
+ i1 = (int)Pop();
+ Push(i1);
+ break;
+ case PSOP_CVR:
+ break;
+ case PSOP_EQ:
+ d2 = Pop();
+ d1 = Pop();
+ Push((int)(d1 == d2));
+ break;
+ case PSOP_NE:
+ d2 = Pop();
+ d1 = Pop();
+ Push((int)(d1 != d2));
+ break;
+ case PSOP_GT:
+ d2 = Pop();
+ d1 = Pop();
+ Push((int)(d1 > d2));
+ break;
+ case PSOP_GE:
+ d2 = Pop();
+ d1 = Pop();
+ Push((int)(d1 >= d2));
+ break;
+ case PSOP_LT:
+ d2 = Pop();
+ d1 = Pop();
+ Push((int)(d1 < d2));
+ break;
+ case PSOP_LE:
+ d2 = Pop();
+ d1 = Pop();
+ Push((int)(d1 <= d2));
+ break;
+ case PSOP_AND:
+ i1 = (int)Pop();
+ i2 = (int)Pop();
+ Push(i1 & i2);
+ break;
+ case PSOP_OR:
+ i1 = (int)Pop();
+ i2 = (int)Pop();
+ Push(i1 | i2);
+ break;
+ case PSOP_XOR:
+ i1 = (int)Pop();
+ i2 = (int)Pop();
+ Push(i1 ^ i2);
+ break;
+ case PSOP_NOT:
+ i1 = (int)Pop();
+ Push((int)!i1);
+ break;
+ case PSOP_BITSHIFT: {
+ int shift = (int)Pop();
+ result = (int)Pop();
+ if (shift > 0) {
+ result <<= shift;
+ } else {
+ // Avoids unsafe negation of INT_MIN.
+ FX_SAFE_INT32 safe_shift = shift;
+ result >>= (-safe_shift).ValueOrDefault(0);
+ }
+ Push(result.ValueOrDefault(0));
+ break;
+ }
+ case PSOP_TRUE:
+ Push(1);
+ break;
+ case PSOP_FALSE:
+ Push(0);
+ break;
+ case PSOP_POP:
+ Pop();
+ break;
+ case PSOP_EXCH:
+ d2 = Pop();
+ d1 = Pop();
+ Push(d2);
+ Push(d1);
+ break;
+ case PSOP_DUP:
+ d1 = Pop();
+ Push(d1);
+ Push(d1);
+ break;
+ case PSOP_COPY: {
+ int n = static_cast<int>(Pop());
+ if (n < 0 || m_StackCount + n > PSENGINE_STACKSIZE ||
+ n > static_cast<int>(m_StackCount))
+ break;
+ for (int i = 0; i < n; i++)
+ m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n];
+ m_StackCount += n;
+ break;
+ }
+ case PSOP_INDEX: {
+ int n = static_cast<int>(Pop());
+ if (n < 0 || n >= static_cast<int>(m_StackCount))
+ break;
+ Push(m_Stack[m_StackCount - n - 1]);
+ break;
+ }
+ case PSOP_ROLL: {
+ int j = static_cast<int>(Pop());
+ int n = static_cast<int>(Pop());
+ if (j == 0 || n == 0 || m_StackCount == 0)
+ break;
+ if (n < 0 || n > static_cast<int>(m_StackCount))
+ break;
+
+ j %= n;
+ if (j > 0)
+ j -= n;
+ auto* begin_it = std::begin(m_Stack) + m_StackCount - n;
+ auto* middle_it = begin_it - j;
+ auto* end_it = std::begin(m_Stack) + m_StackCount;
+ std::rotate(begin_it, middle_it, end_it);
+ break;
+ }
+ default:
+ break;
+ }
+ return true;
+}
diff --git a/core/fpdfapi/page/cpdf_psfunc.cpp b/core/fpdfapi/page/cpdf_psfunc.cpp
new file mode 100644
index 0000000000..debbbd6e6d
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_psfunc.cpp
@@ -0,0 +1,34 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/page/cpdf_psfunc.h"
+
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
+#include "third_party/base/ptr_util.h"
+
+CPDF_PSFunc::CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {}
+
+CPDF_PSFunc::~CPDF_PSFunc() {}
+
+bool CPDF_PSFunc::v_Init(CPDF_Object* pObj) {
+ auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pObj->AsStream());
+ pAcc->LoadAllData(false);
+ return m_PS.Parse(reinterpret_cast<const char*>(pAcc->GetData()),
+ pAcc->GetSize());
+}
+
+bool CPDF_PSFunc::v_Call(float* inputs, float* results) const {
+ CPDF_PSEngine& PS = const_cast<CPDF_PSEngine&>(m_PS);
+ PS.Reset();
+ for (uint32_t i = 0; i < m_nInputs; i++)
+ PS.Push(inputs[i]);
+ PS.Execute();
+ if (PS.GetStackSize() < m_nOutputs)
+ return false;
+ for (uint32_t i = 0; i < m_nOutputs; i++)
+ results[m_nOutputs - i - 1] = PS.Pop();
+ return true;
+}
diff --git a/core/fpdfapi/page/cpdf_psfunc.h b/core/fpdfapi/page/cpdf_psfunc.h
new file mode 100644
index 0000000000..b8c18c9472
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_psfunc.h
@@ -0,0 +1,28 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFAPI_PAGE_CPDF_PSFUNC_H_
+#define CORE_FPDFAPI_PAGE_CPDF_PSFUNC_H_
+
+#include "core/fpdfapi/page/cpdf_function.h"
+#include "core/fpdfapi/page/cpdf_psengine.h"
+
+class CPDF_Object;
+
+class CPDF_PSFunc : public CPDF_Function {
+ public:
+ CPDF_PSFunc();
+ ~CPDF_PSFunc() override;
+
+ // CPDF_Function
+ bool v_Init(CPDF_Object* pObj) override;
+ bool v_Call(float* inputs, float* results) const override;
+
+ private:
+ CPDF_PSEngine m_PS;
+};
+
+#endif // CORE_FPDFAPI_PAGE_CPDF_PSFUNC_H_
diff --git a/core/fpdfapi/page/cpdf_sampledfunc.cpp b/core/fpdfapi/page/cpdf_sampledfunc.cpp
new file mode 100644
index 0000000000..37b9a4e468
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_sampledfunc.cpp
@@ -0,0 +1,156 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/page/cpdf_sampledfunc.h"
+
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fxcrt/fx_safe_types.h"
+
+namespace {
+
+// See PDF Reference 1.7, page 170, table 3.36.
+bool IsValidBitsPerSample(uint32_t x) {
+ switch (x) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 12:
+ case 16:
+ case 24:
+ case 32:
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // namespace
+
+CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {}
+
+CPDF_SampledFunc::~CPDF_SampledFunc() {}
+
+bool CPDF_SampledFunc::v_Init(CPDF_Object* pObj) {
+ CPDF_Stream* pStream = pObj->AsStream();
+ if (!pStream)
+ return false;
+
+ CPDF_Dictionary* pDict = pStream->GetDict();
+ CPDF_Array* pSize = pDict->GetArrayFor("Size");
+ CPDF_Array* pEncode = pDict->GetArrayFor("Encode");
+ CPDF_Array* pDecode = pDict->GetArrayFor("Decode");
+ m_nBitsPerSample = pDict->GetIntegerFor("BitsPerSample");
+ if (!IsValidBitsPerSample(m_nBitsPerSample))
+ return false;
+
+ m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample);
+ m_pSampleStream = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
+ m_pSampleStream->LoadAllData(false);
+ FX_SAFE_UINT32 nTotalSampleBits = 1;
+ m_EncodeInfo.resize(m_nInputs);
+ for (uint32_t i = 0; i < m_nInputs; i++) {
+ m_EncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0;
+ if (!pSize && i == 0)
+ m_EncodeInfo[i].sizes = pDict->GetIntegerFor("Size");
+ nTotalSampleBits *= m_EncodeInfo[i].sizes;
+ if (pEncode) {
+ m_EncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2);
+ m_EncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1);
+ } else {
+ m_EncodeInfo[i].encode_min = 0;
+ m_EncodeInfo[i].encode_max =
+ m_EncodeInfo[i].sizes == 1 ? 1 : (float)m_EncodeInfo[i].sizes - 1;
+ }
+ }
+ nTotalSampleBits *= m_nBitsPerSample;
+ nTotalSampleBits *= m_nOutputs;
+ FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits;
+ nTotalSampleBytes += 7;
+ nTotalSampleBytes /= 8;
+ if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 ||
+ nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) {
+ return false;
+ }
+ m_DecodeInfo.resize(m_nOutputs);
+ for (uint32_t i = 0; i < m_nOutputs; i++) {
+ if (pDecode) {
+ m_DecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i);
+ m_DecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1);
+ } else {
+ m_DecodeInfo[i].decode_min = m_pRanges[i * 2];
+ m_DecodeInfo[i].decode_max = m_pRanges[i * 2 + 1];
+ }
+ }
+ return true;
+}
+
+bool CPDF_SampledFunc::v_Call(float* inputs, float* results) const {
+ int pos = 0;
+ CFX_FixedBufGrow<float, 16> encoded_input_buf(m_nInputs);
+ float* encoded_input = encoded_input_buf;
+ CFX_FixedBufGrow<uint32_t, 32> int_buf(m_nInputs * 2);
+ uint32_t* index = int_buf;
+ uint32_t* blocksize = index + m_nInputs;
+ for (uint32_t i = 0; i < m_nInputs; i++) {
+ if (i == 0)
+ blocksize[i] = 1;
+ else
+ blocksize[i] = blocksize[i - 1] * m_EncodeInfo[i - 1].sizes;
+ encoded_input[i] =
+ Interpolate(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1],
+ m_EncodeInfo[i].encode_min, m_EncodeInfo[i].encode_max);
+ index[i] = pdfium::clamp(static_cast<uint32_t>(encoded_input[i]), 0U,
+ m_EncodeInfo[i].sizes - 1);
+ pos += index[i] * blocksize[i];
+ }
+ FX_SAFE_INT32 bits_to_output = m_nOutputs;
+ bits_to_output *= m_nBitsPerSample;
+ if (!bits_to_output.IsValid())
+ return false;
+
+ FX_SAFE_INT32 bitpos = pos;
+ bitpos *= bits_to_output.ValueOrDie();
+ if (!bitpos.IsValid())
+ return false;
+
+ FX_SAFE_INT32 range_check = bitpos;
+ range_check += bits_to_output.ValueOrDie();
+ if (!range_check.IsValid())
+ return false;
+
+ const uint8_t* pSampleData = m_pSampleStream->GetData();
+ if (!pSampleData)
+ return false;
+
+ for (uint32_t j = 0; j < m_nOutputs; j++, bitpos += m_nBitsPerSample) {
+ uint32_t sample =
+ GetBits32(pSampleData, bitpos.ValueOrDie(), m_nBitsPerSample);
+ float encoded = (float)sample;
+ for (uint32_t i = 0; i < m_nInputs; i++) {
+ if (index[i] == m_EncodeInfo[i].sizes - 1) {
+ if (index[i] == 0)
+ encoded = encoded_input[i] * (float)sample;
+ } else {
+ FX_SAFE_INT32 bitpos2 = blocksize[i];
+ bitpos2 += pos;
+ bitpos2 *= m_nOutputs;
+ bitpos2 += j;
+ bitpos2 *= m_nBitsPerSample;
+ if (!bitpos2.IsValid())
+ return false;
+ uint32_t sample1 =
+ GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample);
+ encoded +=
+ (encoded_input[i] - index[i]) * ((float)sample1 - (float)sample);
+ }
+ }
+ results[j] =
+ Interpolate(encoded, 0, (float)m_SampleMax, m_DecodeInfo[j].decode_min,
+ m_DecodeInfo[j].decode_max);
+ }
+ return true;
+}
diff --git a/core/fpdfapi/page/cpdf_sampledfunc.h b/core/fpdfapi/page/cpdf_sampledfunc.h
new file mode 100644
index 0000000000..59fe1ef141
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_sampledfunc.h
@@ -0,0 +1,52 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFAPI_PAGE_CPDF_SAMPLEDFUNC_H_
+#define CORE_FPDFAPI_PAGE_CPDF_SAMPLEDFUNC_H_
+
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_function.h"
+#include "core/fpdfapi/parser/cpdf_stream_acc.h"
+#include "core/fxcrt/cfx_retain_ptr.h"
+
+class CPDF_SampledFunc : public CPDF_Function {
+ public:
+ struct SampleEncodeInfo {
+ float encode_max;
+ float encode_min;
+ uint32_t sizes;
+ };
+
+ struct SampleDecodeInfo {
+ float decode_max;
+ float decode_min;
+ };
+
+ CPDF_SampledFunc();
+ ~CPDF_SampledFunc() override;
+
+ // CPDF_Function
+ bool v_Init(CPDF_Object* pObj) override;
+ bool v_Call(float* inputs, float* results) const override;
+
+ const std::vector<SampleEncodeInfo>& GetEncodeInfo() const {
+ return m_EncodeInfo;
+ }
+ uint32_t GetBitsPerSample() const { return m_nBitsPerSample; }
+ CFX_RetainPtr<CPDF_StreamAcc> GetSampleStream() const {
+ return m_pSampleStream;
+ }
+
+ private:
+ std::vector<SampleEncodeInfo> m_EncodeInfo;
+ std::vector<SampleDecodeInfo> m_DecodeInfo;
+ uint32_t m_nBitsPerSample;
+ uint32_t m_SampleMax;
+ CFX_RetainPtr<CPDF_StreamAcc> m_pSampleStream;
+};
+
+#endif // CORE_FPDFAPI_PAGE_CPDF_SAMPLEDFUNC_H_
diff --git a/core/fpdfapi/page/cpdf_shadingpattern.cpp b/core/fpdfapi/page/cpdf_shadingpattern.cpp
index 80eea63f9c..c21f51cb77 100644
--- a/core/fpdfapi/page/cpdf_shadingpattern.cpp
+++ b/core/fpdfapi/page/cpdf_shadingpattern.cpp
@@ -9,7 +9,7 @@
#include <algorithm>
#include "core/fpdfapi/page/cpdf_docpagedata.h"
-#include "core/fpdfapi/page/pageint.h"
+#include "core/fpdfapi/page/cpdf_function.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
diff --git a/core/fpdfapi/page/cpdf_shadingpattern.h b/core/fpdfapi/page/cpdf_shadingpattern.h
index c2d55cc3d5..068d772bc3 100644
--- a/core/fpdfapi/page/cpdf_shadingpattern.h
+++ b/core/fpdfapi/page/cpdf_shadingpattern.h
@@ -10,7 +10,7 @@
#include <memory>
#include <vector>
-#include "core/fpdfapi/page/cpdf_countedobject.h"
+#include "core/fpdfapi/page/cpdf_colorspace.h"
#include "core/fpdfapi/page/cpdf_pattern.h"
#include "core/fxcrt/cfx_unowned_ptr.h"
#include "core/fxcrt/fx_system.h"
diff --git a/core/fpdfapi/page/cpdf_stitchfunc.cpp b/core/fpdfapi/page/cpdf_stitchfunc.cpp
new file mode 100644
index 0000000000..336c74bf5c
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_stitchfunc.cpp
@@ -0,0 +1,91 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/page/cpdf_stitchfunc.h"
+
+#include <utility>
+
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fxcrt/fx_memory.h"
+
+CPDF_StitchFunc::CPDF_StitchFunc()
+ : CPDF_Function(Type::kType3Stitching),
+ m_pBounds(nullptr),
+ m_pEncode(nullptr) {}
+
+CPDF_StitchFunc::~CPDF_StitchFunc() {
+ FX_Free(m_pBounds);
+ FX_Free(m_pEncode);
+}
+
+bool CPDF_StitchFunc::v_Init(CPDF_Object* pObj) {
+ CPDF_Dictionary* pDict = pObj->GetDict();
+ if (!pDict) {
+ return false;
+ }
+ if (m_nInputs != kRequiredNumInputs) {
+ return false;
+ }
+ CPDF_Array* pArray = pDict->GetArrayFor("Functions");
+ if (!pArray) {
+ return false;
+ }
+ uint32_t nSubs = pArray->GetCount();
+ if (nSubs == 0)
+ return false;
+ m_nOutputs = 0;
+ for (uint32_t i = 0; i < nSubs; i++) {
+ CPDF_Object* pSub = pArray->GetDirectObjectAt(i);
+ if (pSub == pObj)
+ return false;
+ std::unique_ptr<CPDF_Function> pFunc(CPDF_Function::Load(pSub));
+ if (!pFunc)
+ return false;
+ // Check that the input dimensionality is 1, and that all output
+ // dimensionalities are the same.
+ if (pFunc->CountInputs() != kRequiredNumInputs)
+ return false;
+ if (pFunc->CountOutputs() != m_nOutputs) {
+ if (m_nOutputs)
+ return false;
+
+ m_nOutputs = pFunc->CountOutputs();
+ }
+
+ m_pSubFunctions.push_back(std::move(pFunc));
+ }
+ m_pBounds = FX_Alloc(float, nSubs + 1);
+ m_pBounds[0] = m_pDomains[0];
+ pArray = pDict->GetArrayFor("Bounds");
+ if (!pArray)
+ return false;
+ for (uint32_t i = 0; i < nSubs - 1; i++)
+ m_pBounds[i + 1] = pArray->GetFloatAt(i);
+ m_pBounds[nSubs] = m_pDomains[1];
+ m_pEncode = FX_Alloc2D(float, nSubs, 2);
+ pArray = pDict->GetArrayFor("Encode");
+ if (!pArray)
+ return false;
+
+ for (uint32_t i = 0; i < nSubs * 2; i++)
+ m_pEncode[i] = pArray->GetFloatAt(i);
+ return true;
+}
+
+bool CPDF_StitchFunc::v_Call(float* inputs, float* outputs) const {
+ float input = inputs[0];
+ size_t i;
+ for (i = 0; i < m_pSubFunctions.size() - 1; i++) {
+ if (input < m_pBounds[i + 1])
+ break;
+ }
+ input = Interpolate(input, m_pBounds[i], m_pBounds[i + 1], m_pEncode[i * 2],
+ m_pEncode[i * 2 + 1]);
+ int nresults;
+ m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, &nresults);
+ return true;
+}
diff --git a/core/fpdfapi/page/cpdf_stitchfunc.h b/core/fpdfapi/page/cpdf_stitchfunc.h
new file mode 100644
index 0000000000..69e5e41041
--- /dev/null
+++ b/core/fpdfapi/page/cpdf_stitchfunc.h
@@ -0,0 +1,37 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFAPI_PAGE_CPDF_STITCHFUNC_H_
+#define CORE_FPDFAPI_PAGE_CPDF_STITCHFUNC_H_
+
+#include <memory>
+#include <vector>
+
+#include "core/fpdfapi/page/cpdf_function.h"
+
+class CPDF_StitchFunc : public CPDF_Function {
+ public:
+ CPDF_StitchFunc();
+ ~CPDF_StitchFunc() override;
+
+ // CPDF_Function
+ bool v_Init(CPDF_Object* pObj) override;
+ bool v_Call(float* inputs, float* results) const override;
+
+ const std::vector<std::unique_ptr<CPDF_Function>>& GetSubFunctions() const {
+ return m_pSubFunctions;
+ }
+ float GetBound(size_t i) const { return m_pBounds[i]; }
+
+ private:
+ std::vector<std::unique_ptr<CPDF_Function>> m_pSubFunctions;
+ float* m_pBounds;
+ float* m_pEncode;
+
+ static const uint32_t kRequiredNumInputs = 1;
+};
+
+#endif // CORE_FPDFAPI_PAGE_CPDF_STITCHFUNC_H_
diff --git a/core/fpdfapi/page/fpdf_page_func_embeddertest.cpp b/core/fpdfapi/page/cpdf_stitchfunc_embeddertest.cpp
index 6a1b87b570..6a1b87b570 100644
--- a/core/fpdfapi/page/fpdf_page_func_embeddertest.cpp
+++ b/core/fpdfapi/page/cpdf_stitchfunc_embeddertest.cpp
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index e8594b927b..151b0e644e 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -25,7 +25,6 @@
#include "core/fpdfapi/page/cpdf_shadingpattern.h"
#include "core/fpdfapi/page/cpdf_streamparser.h"
#include "core/fpdfapi/page/cpdf_textobject.h"
-#include "core/fpdfapi/page/pageint.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
@@ -236,15 +235,6 @@ void ReplaceAbbr(CPDF_Object* pObj) {
} // namespace
-CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr) {
- return FindFullName(InlineKeyAbbr, FX_ArraySize(InlineKeyAbbr), abbr);
-}
-
-CFX_ByteStringC PDF_FindValueAbbreviationForTesting(
- const CFX_ByteStringC& abbr) {
- return FindFullName(InlineValueAbbr, FX_ArraySize(InlineValueAbbr), abbr);
-}
-
CPDF_StreamContentParser::CPDF_StreamContentParser(
CPDF_Document* pDocument,
CPDF_Dictionary* pPageResources,
@@ -1627,6 +1617,16 @@ void CPDF_StreamContentParser::ParsePathObject() {
}
}
+CFX_ByteStringC CPDF_StreamContentParser::FindKeyAbbreviationForTesting(
+ const CFX_ByteStringC& abbr) {
+ return FindFullName(InlineKeyAbbr, FX_ArraySize(InlineKeyAbbr), abbr);
+}
+
+CFX_ByteStringC CPDF_StreamContentParser::FindValueAbbreviationForTesting(
+ const CFX_ByteStringC& abbr) {
+ return FindFullName(InlineValueAbbr, FX_ArraySize(InlineValueAbbr), abbr);
+}
+
CPDF_StreamContentParser::ContentParam::ContentParam() {}
CPDF_StreamContentParser::ContentParam::~ContentParam() {}
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.h b/core/fpdfapi/page/cpdf_streamcontentparser.h
index 5436f8f8c6..41385558d3 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.h
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.h
@@ -51,6 +51,9 @@ class CPDF_StreamContentParser {
const float* GetType3Data() const { return m_Type3Data; }
CPDF_Font* FindFont(const CFX_ByteString& name);
+ CFX_ByteStringC FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr);
+ CFX_ByteStringC FindValueAbbreviationForTesting(const CFX_ByteStringC& abbr);
+
private:
struct ContentParam {
enum Type { OBJECT = 0, NUMBER, NAME };
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser_unittest.cpp b/core/fpdfapi/page/cpdf_streamcontentparser_unittest.cpp
index be2fcb09e4..ffc0d95107 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser_unittest.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser_unittest.cpp
@@ -2,33 +2,39 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "core/fpdfapi/page/pageint.h"
+#include "core/fpdfapi/page/cpdf_streamcontentparser.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(cpdf_streamcontentparser, PDF_FindKeyAbbreviation) {
+ CPDF_StreamContentParser parser(nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, 0);
+
EXPECT_EQ(CFX_ByteStringC("BitsPerComponent"),
- PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("BPC")));
+ parser.FindKeyAbbreviationForTesting(CFX_ByteStringC("BPC")));
EXPECT_EQ(CFX_ByteStringC("Width"),
- PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("W")));
+ parser.FindKeyAbbreviationForTesting(CFX_ByteStringC("W")));
EXPECT_EQ(CFX_ByteStringC(""),
- PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("")));
+ parser.FindKeyAbbreviationForTesting(CFX_ByteStringC("")));
EXPECT_EQ(CFX_ByteStringC(""),
- PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("NoInList")));
+ parser.FindKeyAbbreviationForTesting(CFX_ByteStringC("NoInList")));
// Prefix should not match.
EXPECT_EQ(CFX_ByteStringC(""),
- PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("WW")));
+ parser.FindKeyAbbreviationForTesting(CFX_ByteStringC("WW")));
}
TEST(cpdf_streamcontentparser, PDF_FindValueAbbreviation) {
+ CPDF_StreamContentParser parser(nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, 0);
+
EXPECT_EQ(CFX_ByteStringC("DeviceGray"),
- PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("G")));
+ parser.FindValueAbbreviationForTesting(CFX_ByteStringC("G")));
EXPECT_EQ(CFX_ByteStringC("DCTDecode"),
- PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("DCT")));
- EXPECT_EQ(CFX_ByteStringC(""),
- PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("")));
+ parser.FindValueAbbreviationForTesting(CFX_ByteStringC("DCT")));
EXPECT_EQ(CFX_ByteStringC(""),
- PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("NoInList")));
+ parser.FindValueAbbreviationForTesting(CFX_ByteStringC("")));
+ EXPECT_EQ(CFX_ByteStringC(""), parser.FindValueAbbreviationForTesting(
+ CFX_ByteStringC("NoInList")));
// Prefix should not match.
EXPECT_EQ(CFX_ByteStringC(""),
- PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("II")));
+ parser.FindValueAbbreviationForTesting(CFX_ByteStringC("II")));
}
diff --git a/core/fpdfapi/page/fpdf_page_func.cpp b/core/fpdfapi/page/fpdf_page_func.cpp
deleted file mode 100644
index 48cd41c090..0000000000
--- a/core/fpdfapi/page/fpdf_page_func.cpp
+++ /dev/null
@@ -1,851 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/page/pageint.h"
-
-#include <limits.h>
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "core/fpdfapi/page/cpdf_psengine.h"
-#include "core/fpdfapi/parser/cpdf_array.h"
-#include "core/fpdfapi/parser/cpdf_dictionary.h"
-#include "core/fpdfapi/parser/cpdf_simple_parser.h"
-#include "core/fpdfapi/parser/cpdf_stream.h"
-#include "core/fpdfapi/parser/cpdf_stream_acc.h"
-#include "core/fxcrt/fx_safe_types.h"
-#include "third_party/base/logging.h"
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
-
-namespace {
-
-struct PDF_PSOpName {
- const char* name;
- PDF_PSOP op;
-};
-
-const PDF_PSOpName kPsOpNames[] = {
- {"add", PSOP_ADD}, {"sub", PSOP_SUB},
- {"mul", PSOP_MUL}, {"div", PSOP_DIV},
- {"idiv", PSOP_IDIV}, {"mod", PSOP_MOD},
- {"neg", PSOP_NEG}, {"abs", PSOP_ABS},
- {"ceiling", PSOP_CEILING}, {"floor", PSOP_FLOOR},
- {"round", PSOP_ROUND}, {"truncate", PSOP_TRUNCATE},
- {"sqrt", PSOP_SQRT}, {"sin", PSOP_SIN},
- {"cos", PSOP_COS}, {"atan", PSOP_ATAN},
- {"exp", PSOP_EXP}, {"ln", PSOP_LN},
- {"log", PSOP_LOG}, {"cvi", PSOP_CVI},
- {"cvr", PSOP_CVR}, {"eq", PSOP_EQ},
- {"ne", PSOP_NE}, {"gt", PSOP_GT},
- {"ge", PSOP_GE}, {"lt", PSOP_LT},
- {"le", PSOP_LE}, {"and", PSOP_AND},
- {"or", PSOP_OR}, {"xor", PSOP_XOR},
- {"not", PSOP_NOT}, {"bitshift", PSOP_BITSHIFT},
- {"true", PSOP_TRUE}, {"false", PSOP_FALSE},
- {"if", PSOP_IF}, {"ifelse", PSOP_IFELSE},
- {"pop", PSOP_POP}, {"exch", PSOP_EXCH},
- {"dup", PSOP_DUP}, {"copy", PSOP_COPY},
- {"index", PSOP_INDEX}, {"roll", PSOP_ROLL}};
-
-// See PDF Reference 1.7, page 170, table 3.36.
-bool IsValidBitsPerSample(uint32_t x) {
- switch (x) {
- case 1:
- case 2:
- case 4:
- case 8:
- case 12:
- case 16:
- case 24:
- case 32:
- return true;
- default:
- return false;
- }
-}
-
-// See PDF Reference 1.7, page 170.
-float PDF_Interpolate(float x, float xmin, float xmax, float ymin, float ymax) {
- float divisor = xmax - xmin;
- return ymin + (divisor ? (x - xmin) * (ymax - ymin) / divisor : 0);
-}
-
-class CPDF_PSFunc : public CPDF_Function {
- public:
- CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {}
- ~CPDF_PSFunc() override {}
-
- // CPDF_Function
- bool v_Init(CPDF_Object* pObj) override;
- bool v_Call(float* inputs, float* results) const override;
-
- private:
- CPDF_PSEngine m_PS;
-};
-
-bool CPDF_PSFunc::v_Init(CPDF_Object* pObj) {
- auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pObj->AsStream());
- pAcc->LoadAllData(false);
- return m_PS.Parse(reinterpret_cast<const char*>(pAcc->GetData()),
- pAcc->GetSize());
-}
-
-bool CPDF_PSFunc::v_Call(float* inputs, float* results) const {
- CPDF_PSEngine& PS = const_cast<CPDF_PSEngine&>(m_PS);
- PS.Reset();
- for (uint32_t i = 0; i < m_nInputs; i++)
- PS.Push(inputs[i]);
- PS.Execute();
- if (PS.GetStackSize() < m_nOutputs)
- return false;
- for (uint32_t i = 0; i < m_nOutputs; i++)
- results[m_nOutputs - i - 1] = PS.Pop();
- return true;
-}
-
-} // namespace
-
-class CPDF_PSOP {
- public:
- explicit CPDF_PSOP(PDF_PSOP op) : m_op(op), m_value(0) {
- ASSERT(m_op != PSOP_CONST);
- ASSERT(m_op != PSOP_PROC);
- }
- explicit CPDF_PSOP(float value) : m_op(PSOP_CONST), m_value(value) {}
- CPDF_PSOP()
- : m_op(PSOP_PROC),
- m_value(0),
- m_proc(pdfium::MakeUnique<CPDF_PSProc>()) {}
-
- float GetFloatValue() const {
- if (m_op == PSOP_CONST)
- return m_value;
-
- NOTREACHED();
- return 0;
- }
- CPDF_PSProc* GetProc() const {
- if (m_op == PSOP_PROC)
- return m_proc.get();
- NOTREACHED();
- return nullptr;
- }
-
- PDF_PSOP GetOp() const { return m_op; }
-
- private:
- const PDF_PSOP m_op;
- const float m_value;
- std::unique_ptr<CPDF_PSProc> m_proc;
-};
-
-bool CPDF_PSEngine::Execute() {
- return m_MainProc.Execute(this);
-}
-
-CPDF_PSProc::CPDF_PSProc() {}
-CPDF_PSProc::~CPDF_PSProc() {}
-
-bool CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) {
- for (size_t i = 0; i < m_Operators.size(); ++i) {
- const PDF_PSOP op = m_Operators[i]->GetOp();
- if (op == PSOP_PROC)
- continue;
-
- if (op == PSOP_CONST) {
- pEngine->Push(m_Operators[i]->GetFloatValue());
- continue;
- }
-
- if (op == PSOP_IF) {
- if (i == 0 || m_Operators[i - 1]->GetOp() != PSOP_PROC)
- return false;
-
- if (static_cast<int>(pEngine->Pop()))
- m_Operators[i - 1]->GetProc()->Execute(pEngine);
- } else if (op == PSOP_IFELSE) {
- if (i < 2 || m_Operators[i - 1]->GetOp() != PSOP_PROC ||
- m_Operators[i - 2]->GetOp() != PSOP_PROC) {
- return false;
- }
- size_t offset = static_cast<int>(pEngine->Pop()) ? 2 : 1;
- m_Operators[i - offset]->GetProc()->Execute(pEngine);
- } else {
- pEngine->DoOperator(op);
- }
- }
- return true;
-}
-
-CPDF_PSEngine::CPDF_PSEngine() : m_StackCount(0) {}
-
-CPDF_PSEngine::~CPDF_PSEngine() {}
-
-void CPDF_PSEngine::Push(float v) {
- if (m_StackCount < PSENGINE_STACKSIZE)
- m_Stack[m_StackCount++] = v;
-}
-
-float CPDF_PSEngine::Pop() {
- return m_StackCount > 0 ? m_Stack[--m_StackCount] : 0;
-}
-
-bool CPDF_PSEngine::Parse(const char* str, int size) {
- CPDF_SimpleParser parser(reinterpret_cast<const uint8_t*>(str), size);
- CFX_ByteStringC word = parser.GetWord();
- return word == "{" ? m_MainProc.Parse(&parser, 0) : false;
-}
-
-bool CPDF_PSProc::Parse(CPDF_SimpleParser* parser, int depth) {
- if (depth > kMaxDepth)
- return false;
-
- while (1) {
- CFX_ByteStringC word = parser->GetWord();
- if (word.IsEmpty())
- return false;
-
- if (word == "}")
- return true;
-
- if (word == "{") {
- m_Operators.push_back(pdfium::MakeUnique<CPDF_PSOP>());
- if (!m_Operators.back()->GetProc()->Parse(parser, depth + 1))
- return false;
- continue;
- }
-
- std::unique_ptr<CPDF_PSOP> op;
- for (const PDF_PSOpName& op_name : kPsOpNames) {
- if (word == CFX_ByteStringC(op_name.name)) {
- op = pdfium::MakeUnique<CPDF_PSOP>(op_name.op);
- break;
- }
- }
- if (!op)
- op = pdfium::MakeUnique<CPDF_PSOP>(FX_atof(word));
- m_Operators.push_back(std::move(op));
- }
-}
-
-bool CPDF_PSEngine::DoOperator(PDF_PSOP op) {
- int i1;
- int i2;
- float d1;
- float d2;
- FX_SAFE_INT32 result;
- switch (op) {
- case PSOP_ADD:
- d1 = Pop();
- d2 = Pop();
- Push(d1 + d2);
- break;
- case PSOP_SUB:
- d2 = Pop();
- d1 = Pop();
- Push(d1 - d2);
- break;
- case PSOP_MUL:
- d1 = Pop();
- d2 = Pop();
- Push(d1 * d2);
- break;
- case PSOP_DIV:
- d2 = Pop();
- d1 = Pop();
- Push(d1 / d2);
- break;
- case PSOP_IDIV:
- i2 = static_cast<int>(Pop());
- i1 = static_cast<int>(Pop());
- if (i2) {
- result = i1;
- result /= i2;
- Push(result.ValueOrDefault(0));
- } else {
- Push(0);
- }
- break;
- case PSOP_MOD:
- i2 = static_cast<int>(Pop());
- i1 = static_cast<int>(Pop());
- if (i2) {
- result = i1;
- result %= i2;
- Push(result.ValueOrDefault(0));
- } else {
- Push(0);
- }
- break;
- case PSOP_NEG:
- d1 = Pop();
- Push(-d1);
- break;
- case PSOP_ABS:
- d1 = Pop();
- Push((float)fabs(d1));
- break;
- case PSOP_CEILING:
- d1 = Pop();
- Push((float)ceil(d1));
- break;
- case PSOP_FLOOR:
- d1 = Pop();
- Push((float)floor(d1));
- break;
- case PSOP_ROUND:
- d1 = Pop();
- Push(FXSYS_round(d1));
- break;
- case PSOP_TRUNCATE:
- i1 = (int)Pop();
- Push(i1);
- break;
- case PSOP_SQRT:
- d1 = Pop();
- Push((float)sqrt(d1));
- break;
- case PSOP_SIN:
- d1 = Pop();
- Push((float)sin(d1 * FX_PI / 180.0f));
- break;
- case PSOP_COS:
- d1 = Pop();
- Push((float)cos(d1 * FX_PI / 180.0f));
- break;
- case PSOP_ATAN:
- d2 = Pop();
- d1 = Pop();
- d1 = (float)(atan2(d1, d2) * 180.0 / FX_PI);
- if (d1 < 0) {
- d1 += 360;
- }
- Push(d1);
- break;
- case PSOP_EXP:
- d2 = Pop();
- d1 = Pop();
- Push((float)FXSYS_pow(d1, d2));
- break;
- case PSOP_LN:
- d1 = Pop();
- Push((float)log(d1));
- break;
- case PSOP_LOG:
- d1 = Pop();
- Push((float)log10(d1));
- break;
- case PSOP_CVI:
- i1 = (int)Pop();
- Push(i1);
- break;
- case PSOP_CVR:
- break;
- case PSOP_EQ:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 == d2));
- break;
- case PSOP_NE:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 != d2));
- break;
- case PSOP_GT:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 > d2));
- break;
- case PSOP_GE:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 >= d2));
- break;
- case PSOP_LT:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 < d2));
- break;
- case PSOP_LE:
- d2 = Pop();
- d1 = Pop();
- Push((int)(d1 <= d2));
- break;
- case PSOP_AND:
- i1 = (int)Pop();
- i2 = (int)Pop();
- Push(i1 & i2);
- break;
- case PSOP_OR:
- i1 = (int)Pop();
- i2 = (int)Pop();
- Push(i1 | i2);
- break;
- case PSOP_XOR:
- i1 = (int)Pop();
- i2 = (int)Pop();
- Push(i1 ^ i2);
- break;
- case PSOP_NOT:
- i1 = (int)Pop();
- Push((int)!i1);
- break;
- case PSOP_BITSHIFT: {
- int shift = (int)Pop();
- result = (int)Pop();
- if (shift > 0) {
- result <<= shift;
- } else {
- // Avoids unsafe negation of INT_MIN.
- FX_SAFE_INT32 safe_shift = shift;
- result >>= (-safe_shift).ValueOrDefault(0);
- }
- Push(result.ValueOrDefault(0));
- break;
- }
- case PSOP_TRUE:
- Push(1);
- break;
- case PSOP_FALSE:
- Push(0);
- break;
- case PSOP_POP:
- Pop();
- break;
- case PSOP_EXCH:
- d2 = Pop();
- d1 = Pop();
- Push(d2);
- Push(d1);
- break;
- case PSOP_DUP:
- d1 = Pop();
- Push(d1);
- Push(d1);
- break;
- case PSOP_COPY: {
- int n = static_cast<int>(Pop());
- if (n < 0 || m_StackCount + n > PSENGINE_STACKSIZE ||
- n > static_cast<int>(m_StackCount))
- break;
- for (int i = 0; i < n; i++)
- m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n];
- m_StackCount += n;
- break;
- }
- case PSOP_INDEX: {
- int n = static_cast<int>(Pop());
- if (n < 0 || n >= static_cast<int>(m_StackCount))
- break;
- Push(m_Stack[m_StackCount - n - 1]);
- break;
- }
- case PSOP_ROLL: {
- int j = static_cast<int>(Pop());
- int n = static_cast<int>(Pop());
- if (j == 0 || n == 0 || m_StackCount == 0)
- break;
- if (n < 0 || n > static_cast<int>(m_StackCount))
- break;
-
- j %= n;
- if (j > 0)
- j -= n;
- auto* begin_it = std::begin(m_Stack) + m_StackCount - n;
- auto* middle_it = begin_it - j;
- auto* end_it = std::begin(m_Stack) + m_StackCount;
- std::rotate(begin_it, middle_it, end_it);
- break;
- }
- default:
- break;
- }
- return true;
-}
-
-CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {}
-
-CPDF_SampledFunc::~CPDF_SampledFunc() {}
-
-bool CPDF_SampledFunc::v_Init(CPDF_Object* pObj) {
- CPDF_Stream* pStream = pObj->AsStream();
- if (!pStream)
- return false;
-
- CPDF_Dictionary* pDict = pStream->GetDict();
- CPDF_Array* pSize = pDict->GetArrayFor("Size");
- CPDF_Array* pEncode = pDict->GetArrayFor("Encode");
- CPDF_Array* pDecode = pDict->GetArrayFor("Decode");
- m_nBitsPerSample = pDict->GetIntegerFor("BitsPerSample");
- if (!IsValidBitsPerSample(m_nBitsPerSample))
- return false;
-
- m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample);
- m_pSampleStream = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
- m_pSampleStream->LoadAllData(false);
- FX_SAFE_UINT32 nTotalSampleBits = 1;
- m_EncodeInfo.resize(m_nInputs);
- for (uint32_t i = 0; i < m_nInputs; i++) {
- m_EncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0;
- if (!pSize && i == 0)
- m_EncodeInfo[i].sizes = pDict->GetIntegerFor("Size");
- nTotalSampleBits *= m_EncodeInfo[i].sizes;
- if (pEncode) {
- m_EncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2);
- m_EncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1);
- } else {
- m_EncodeInfo[i].encode_min = 0;
- m_EncodeInfo[i].encode_max =
- m_EncodeInfo[i].sizes == 1 ? 1 : (float)m_EncodeInfo[i].sizes - 1;
- }
- }
- nTotalSampleBits *= m_nBitsPerSample;
- nTotalSampleBits *= m_nOutputs;
- FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits;
- nTotalSampleBytes += 7;
- nTotalSampleBytes /= 8;
- if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 ||
- nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) {
- return false;
- }
- m_DecodeInfo.resize(m_nOutputs);
- for (uint32_t i = 0; i < m_nOutputs; i++) {
- if (pDecode) {
- m_DecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i);
- m_DecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1);
- } else {
- m_DecodeInfo[i].decode_min = m_pRanges[i * 2];
- m_DecodeInfo[i].decode_max = m_pRanges[i * 2 + 1];
- }
- }
- return true;
-}
-
-bool CPDF_SampledFunc::v_Call(float* inputs, float* results) const {
- int pos = 0;
- CFX_FixedBufGrow<float, 16> encoded_input_buf(m_nInputs);
- float* encoded_input = encoded_input_buf;
- CFX_FixedBufGrow<uint32_t, 32> int_buf(m_nInputs * 2);
- uint32_t* index = int_buf;
- uint32_t* blocksize = index + m_nInputs;
- for (uint32_t i = 0; i < m_nInputs; i++) {
- if (i == 0)
- blocksize[i] = 1;
- else
- blocksize[i] = blocksize[i - 1] * m_EncodeInfo[i - 1].sizes;
- encoded_input[i] =
- PDF_Interpolate(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1],
- m_EncodeInfo[i].encode_min, m_EncodeInfo[i].encode_max);
- index[i] = pdfium::clamp(static_cast<uint32_t>(encoded_input[i]), 0U,
- m_EncodeInfo[i].sizes - 1);
- pos += index[i] * blocksize[i];
- }
- FX_SAFE_INT32 bits_to_output = m_nOutputs;
- bits_to_output *= m_nBitsPerSample;
- if (!bits_to_output.IsValid())
- return false;
-
- FX_SAFE_INT32 bitpos = pos;
- bitpos *= bits_to_output.ValueOrDie();
- if (!bitpos.IsValid())
- return false;
-
- FX_SAFE_INT32 range_check = bitpos;
- range_check += bits_to_output.ValueOrDie();
- if (!range_check.IsValid())
- return false;
-
- const uint8_t* pSampleData = m_pSampleStream->GetData();
- if (!pSampleData)
- return false;
-
- for (uint32_t j = 0; j < m_nOutputs; j++, bitpos += m_nBitsPerSample) {
- uint32_t sample =
- GetBits32(pSampleData, bitpos.ValueOrDie(), m_nBitsPerSample);
- float encoded = (float)sample;
- for (uint32_t i = 0; i < m_nInputs; i++) {
- if (index[i] == m_EncodeInfo[i].sizes - 1) {
- if (index[i] == 0)
- encoded = encoded_input[i] * (float)sample;
- } else {
- FX_SAFE_INT32 bitpos2 = blocksize[i];
- bitpos2 += pos;
- bitpos2 *= m_nOutputs;
- bitpos2 += j;
- bitpos2 *= m_nBitsPerSample;
- if (!bitpos2.IsValid())
- return false;
- uint32_t sample1 =
- GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample);
- encoded +=
- (encoded_input[i] - index[i]) * ((float)sample1 - (float)sample);
- }
- }
- results[j] =
- PDF_Interpolate(encoded, 0, (float)m_SampleMax,
- m_DecodeInfo[j].decode_min, m_DecodeInfo[j].decode_max);
- }
- return true;
-}
-
-CPDF_ExpIntFunc::CPDF_ExpIntFunc()
- : CPDF_Function(Type::kType2ExpotentialInterpolation),
- m_pBeginValues(nullptr),
- m_pEndValues(nullptr) {}
-
-CPDF_ExpIntFunc::~CPDF_ExpIntFunc() {
- FX_Free(m_pBeginValues);
- FX_Free(m_pEndValues);
-}
-
-bool CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) {
- CPDF_Dictionary* pDict = pObj->GetDict();
- if (!pDict)
- return false;
-
- CPDF_Array* pArray0 = pDict->GetArrayFor("C0");
- if (m_nOutputs == 0) {
- m_nOutputs = 1;
- if (pArray0)
- m_nOutputs = pArray0->GetCount();
- }
-
- CPDF_Array* pArray1 = pDict->GetArrayFor("C1");
- m_pBeginValues = FX_Alloc2D(float, m_nOutputs, 2);
- m_pEndValues = FX_Alloc2D(float, m_nOutputs, 2);
- for (uint32_t i = 0; i < m_nOutputs; i++) {
- m_pBeginValues[i] = pArray0 ? pArray0->GetFloatAt(i) : 0.0f;
- m_pEndValues[i] = pArray1 ? pArray1->GetFloatAt(i) : 1.0f;
- }
-
- m_Exponent = pDict->GetFloatFor("N");
- m_nOrigOutputs = m_nOutputs;
- if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs)
- return false;
-
- m_nOutputs *= m_nInputs;
- return true;
-}
-
-bool CPDF_ExpIntFunc::v_Call(float* inputs, float* results) const {
- for (uint32_t i = 0; i < m_nInputs; i++)
- for (uint32_t j = 0; j < m_nOrigOutputs; j++) {
- results[i * m_nOrigOutputs + j] =
- m_pBeginValues[j] +
- FXSYS_pow(inputs[i], m_Exponent) *
- (m_pEndValues[j] - m_pBeginValues[j]);
- }
- return true;
-}
-
-CPDF_StitchFunc::CPDF_StitchFunc()
- : CPDF_Function(Type::kType3Stitching),
- m_pBounds(nullptr),
- m_pEncode(nullptr) {}
-
-CPDF_StitchFunc::~CPDF_StitchFunc() {
- FX_Free(m_pBounds);
- FX_Free(m_pEncode);
-}
-
-bool CPDF_StitchFunc::v_Init(CPDF_Object* pObj) {
- CPDF_Dictionary* pDict = pObj->GetDict();
- if (!pDict) {
- return false;
- }
- if (m_nInputs != kRequiredNumInputs) {
- return false;
- }
- CPDF_Array* pArray = pDict->GetArrayFor("Functions");
- if (!pArray) {
- return false;
- }
- uint32_t nSubs = pArray->GetCount();
- if (nSubs == 0)
- return false;
- m_nOutputs = 0;
- for (uint32_t i = 0; i < nSubs; i++) {
- CPDF_Object* pSub = pArray->GetDirectObjectAt(i);
- if (pSub == pObj)
- return false;
- std::unique_ptr<CPDF_Function> pFunc(CPDF_Function::Load(pSub));
- if (!pFunc)
- return false;
- // Check that the input dimensionality is 1, and that all output
- // dimensionalities are the same.
- if (pFunc->CountInputs() != kRequiredNumInputs)
- return false;
- if (pFunc->CountOutputs() != m_nOutputs) {
- if (m_nOutputs)
- return false;
-
- m_nOutputs = pFunc->CountOutputs();
- }
-
- m_pSubFunctions.push_back(std::move(pFunc));
- }
- m_pBounds = FX_Alloc(float, nSubs + 1);
- m_pBounds[0] = m_pDomains[0];
- pArray = pDict->GetArrayFor("Bounds");
- if (!pArray)
- return false;
- for (uint32_t i = 0; i < nSubs - 1; i++)
- m_pBounds[i + 1] = pArray->GetFloatAt(i);
- m_pBounds[nSubs] = m_pDomains[1];
- m_pEncode = FX_Alloc2D(float, nSubs, 2);
- pArray = pDict->GetArrayFor("Encode");
- if (!pArray)
- return false;
-
- for (uint32_t i = 0; i < nSubs * 2; i++)
- m_pEncode[i] = pArray->GetFloatAt(i);
- return true;
-}
-
-bool CPDF_StitchFunc::v_Call(float* inputs, float* outputs) const {
- float input = inputs[0];
- size_t i;
- for (i = 0; i < m_pSubFunctions.size() - 1; i++) {
- if (input < m_pBounds[i + 1])
- break;
- }
- input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1],
- m_pEncode[i * 2], m_pEncode[i * 2 + 1]);
- int nresults;
- m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, &nresults);
- return true;
-}
-
-// static
-std::unique_ptr<CPDF_Function> CPDF_Function::Load(CPDF_Object* pFuncObj) {
- std::unique_ptr<CPDF_Function> pFunc;
- if (!pFuncObj)
- return pFunc;
-
- int iType = -1;
- if (CPDF_Stream* pStream = pFuncObj->AsStream())
- iType = pStream->GetDict()->GetIntegerFor("FunctionType");
- else if (CPDF_Dictionary* pDict = pFuncObj->AsDictionary())
- iType = pDict->GetIntegerFor("FunctionType");
-
- Type type = IntegerToFunctionType(iType);
- if (type == Type::kType0Sampled)
- pFunc = pdfium::MakeUnique<CPDF_SampledFunc>();
- else if (type == Type::kType2ExpotentialInterpolation)
- pFunc = pdfium::MakeUnique<CPDF_ExpIntFunc>();
- else if (type == Type::kType3Stitching)
- pFunc = pdfium::MakeUnique<CPDF_StitchFunc>();
- else if (type == Type::kType4PostScript)
- pFunc = pdfium::MakeUnique<CPDF_PSFunc>();
-
- if (!pFunc || !pFunc->Init(pFuncObj))
- return nullptr;
-
- return pFunc;
-}
-
-// static
-CPDF_Function::Type CPDF_Function::IntegerToFunctionType(int iType) {
- switch (iType) {
- case 0:
- case 2:
- case 3:
- case 4:
- return static_cast<Type>(iType);
- default:
- return Type::kTypeInvalid;
- }
-}
-
-CPDF_Function::CPDF_Function(Type type)
- : m_pDomains(nullptr), m_pRanges(nullptr), m_Type(type) {}
-
-CPDF_Function::~CPDF_Function() {
- FX_Free(m_pDomains);
- FX_Free(m_pRanges);
-}
-
-bool CPDF_Function::Init(CPDF_Object* pObj) {
- CPDF_Stream* pStream = pObj->AsStream();
- CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary();
-
- CPDF_Array* pDomains = pDict->GetArrayFor("Domain");
- if (!pDomains)
- return false;
-
- m_nInputs = pDomains->GetCount() / 2;
- if (m_nInputs == 0)
- return false;
-
- m_pDomains = FX_Alloc2D(float, m_nInputs, 2);
- for (uint32_t i = 0; i < m_nInputs * 2; i++) {
- m_pDomains[i] = pDomains->GetFloatAt(i);
- }
- CPDF_Array* pRanges = pDict->GetArrayFor("Range");
- m_nOutputs = 0;
- if (pRanges) {
- m_nOutputs = pRanges->GetCount() / 2;
- m_pRanges = FX_Alloc2D(float, m_nOutputs, 2);
- for (uint32_t i = 0; i < m_nOutputs * 2; i++)
- m_pRanges[i] = pRanges->GetFloatAt(i);
- }
- uint32_t old_outputs = m_nOutputs;
- if (!v_Init(pObj))
- return false;
- if (m_pRanges && m_nOutputs > old_outputs) {
- m_pRanges = FX_Realloc(float, m_pRanges, m_nOutputs * 2);
- if (m_pRanges) {
- memset(m_pRanges + (old_outputs * 2), 0,
- sizeof(float) * (m_nOutputs - old_outputs) * 2);
- }
- }
- return true;
-}
-
-bool CPDF_Function::Call(float* inputs,
- uint32_t ninputs,
- float* results,
- int* nresults) const {
- if (m_nInputs != ninputs)
- return false;
-
- *nresults = m_nOutputs;
- for (uint32_t i = 0; i < m_nInputs; i++) {
- inputs[i] =
- pdfium::clamp(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1]);
- }
- v_Call(inputs, results);
- if (!m_pRanges)
- return true;
-
- for (uint32_t i = 0; i < m_nOutputs; i++) {
- results[i] =
- pdfium::clamp(results[i], m_pRanges[i * 2], m_pRanges[i * 2 + 1]);
- }
- return true;
-}
-
-const CPDF_SampledFunc* CPDF_Function::ToSampledFunc() const {
- return m_Type == Type::kType0Sampled
- ? static_cast<const CPDF_SampledFunc*>(this)
- : nullptr;
-}
-
-const CPDF_ExpIntFunc* CPDF_Function::ToExpIntFunc() const {
- return m_Type == Type::kType2ExpotentialInterpolation
- ? static_cast<const CPDF_ExpIntFunc*>(this)
- : nullptr;
-}
-
-const CPDF_StitchFunc* CPDF_Function::ToStitchFunc() const {
- return m_Type == Type::kType3Stitching
- ? static_cast<const CPDF_StitchFunc*>(this)
- : nullptr;
-}
diff --git a/core/fpdfapi/page/pageint.h b/core/fpdfapi/page/pageint.h
deleted file mode 100644
index 45ca671673..0000000000
--- a/core/fpdfapi/page/pageint.h
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFAPI_PAGE_PAGEINT_H_
-#define CORE_FPDFAPI_PAGE_PAGEINT_H_
-
-#include <memory>
-#include <vector>
-
-#include "core/fpdfapi/page/cpdf_colorspace.h"
-#include "core/fpdfapi/page/cpdf_countedobject.h"
-#include "core/fpdfapi/parser/cpdf_stream_acc.h"
-#include "core/fxcrt/cfx_retain_ptr.h"
-
-class CPDF_ExpIntFunc;
-class CPDF_Pattern;
-class CPDF_SampledFunc;
-class CPDF_StitchFunc;
-
-class CPDF_Function {
- public:
- enum class Type {
- kTypeInvalid = -1,
- kType0Sampled = 0,
- kType2ExpotentialInterpolation = 2,
- kType3Stitching = 3,
- kType4PostScript = 4,
- };
-
- static std::unique_ptr<CPDF_Function> Load(CPDF_Object* pFuncObj);
- static Type IntegerToFunctionType(int iType);
-
- virtual ~CPDF_Function();
-
- bool Call(float* inputs,
- uint32_t ninputs,
- float* results,
- int* nresults) const;
- uint32_t CountInputs() const { return m_nInputs; }
- uint32_t CountOutputs() const { return m_nOutputs; }
- float GetDomain(int i) const { return m_pDomains[i]; }
- float GetRange(int i) const { return m_pRanges[i]; }
-
- const CPDF_SampledFunc* ToSampledFunc() const;
- const CPDF_ExpIntFunc* ToExpIntFunc() const;
- const CPDF_StitchFunc* ToStitchFunc() const;
-
- protected:
- explicit CPDF_Function(Type type);
-
- bool Init(CPDF_Object* pObj);
- virtual bool v_Init(CPDF_Object* pObj) = 0;
- virtual bool v_Call(float* inputs, float* results) const = 0;
-
- uint32_t m_nInputs;
- uint32_t m_nOutputs;
- float* m_pDomains;
- float* m_pRanges;
- const Type m_Type;
-};
-
-class CPDF_ExpIntFunc : public CPDF_Function {
- public:
- CPDF_ExpIntFunc();
- ~CPDF_ExpIntFunc() override;
-
- // CPDF_Function
- bool v_Init(CPDF_Object* pObj) override;
- bool v_Call(float* inputs, float* results) const override;
-
- uint32_t m_nOrigOutputs;
- float m_Exponent;
- float* m_pBeginValues;
- float* m_pEndValues;
-};
-
-class CPDF_SampledFunc : public CPDF_Function {
- public:
- struct SampleEncodeInfo {
- float encode_max;
- float encode_min;
- uint32_t sizes;
- };
-
- struct SampleDecodeInfo {
- float decode_max;
- float decode_min;
- };
-
- CPDF_SampledFunc();
- ~CPDF_SampledFunc() override;
-
- // CPDF_Function
- bool v_Init(CPDF_Object* pObj) override;
- bool v_Call(float* inputs, float* results) const override;
-
- const std::vector<SampleEncodeInfo>& GetEncodeInfo() const {
- return m_EncodeInfo;
- }
- uint32_t GetBitsPerSample() const { return m_nBitsPerSample; }
- CFX_RetainPtr<CPDF_StreamAcc> GetSampleStream() const {
- return m_pSampleStream;
- }
-
- private:
- std::vector<SampleEncodeInfo> m_EncodeInfo;
- std::vector<SampleDecodeInfo> m_DecodeInfo;
- uint32_t m_nBitsPerSample;
- uint32_t m_SampleMax;
- CFX_RetainPtr<CPDF_StreamAcc> m_pSampleStream;
-};
-
-class CPDF_StitchFunc : public CPDF_Function {
- public:
- CPDF_StitchFunc();
- ~CPDF_StitchFunc() override;
-
- // CPDF_Function
- bool v_Init(CPDF_Object* pObj) override;
- bool v_Call(float* inputs, float* results) const override;
-
- const std::vector<std::unique_ptr<CPDF_Function>>& GetSubFunctions() const {
- return m_pSubFunctions;
- }
- float GetBound(size_t i) const { return m_pBounds[i]; }
-
- private:
- std::vector<std::unique_ptr<CPDF_Function>> m_pSubFunctions;
- float* m_pBounds;
- float* m_pEncode;
-
- static const uint32_t kRequiredNumInputs = 1;
-};
-
-class CPDF_IccProfile : public CFX_Retainable {
- public:
- template <typename T, typename... Args>
- friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
-
- CPDF_Stream* GetStream() const { return m_pStream; }
- bool IsValid() const { return IsSRGB() || IsSupported(); }
- bool IsSRGB() const { return m_bsRGB; }
- bool IsSupported() const { return !!m_pTransform; }
- void* transform() { return m_pTransform; }
- uint32_t GetComponents() const { return m_nSrcComponents; }
-
- private:
- CPDF_IccProfile(CPDF_Stream* pStream, const uint8_t* pData, uint32_t dwSize);
- ~CPDF_IccProfile() override;
-
- const bool m_bsRGB;
- CPDF_Stream* const m_pStream;
- void* m_pTransform = nullptr;
- uint32_t m_nSrcComponents = 0;
-};
-
-class CPDF_DeviceCS : public CPDF_ColorSpace {
- public:
- explicit CPDF_DeviceCS(int family);
- ~CPDF_DeviceCS() override;
-
- // CPDF_ColorSpace:
- bool GetRGB(float* pBuf, float* R, float* G, float* B) const override;
- bool SetRGB(float* pBuf, float R, float G, float B) const override;
- bool v_GetCMYK(float* pBuf,
- float* c,
- float* m,
- float* y,
- float* k) const override;
- bool v_SetCMYK(float* pBuf,
- float c,
- float m,
- float y,
- float k) const override;
- void TranslateImageLine(uint8_t* pDestBuf,
- const uint8_t* pSrcBuf,
- int pixels,
- int image_width,
- int image_height,
- bool bTransMask) const override;
-};
-
-class CPDF_PatternCS : public CPDF_ColorSpace {
- public:
- explicit CPDF_PatternCS(CPDF_Document* pDoc);
- ~CPDF_PatternCS() override;
-
- // CPDF_ColorSpace:
- bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
- bool GetRGB(float* pBuf, float* R, float* G, float* B) const override;
- CPDF_ColorSpace* GetBaseCS() const override;
-
- private:
- CPDF_ColorSpace* m_pBaseCS;
- CPDF_CountedColorSpace* m_pCountedBaseCS;
-};
-
-#define MAX_PATTERN_COLORCOMPS 16
-struct PatternValue {
- CPDF_Pattern* m_pPattern;
- CPDF_CountedPattern* m_pCountedPattern;
- int m_nComps;
- float m_Comps[MAX_PATTERN_COLORCOMPS];
-};
-
-CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr);
-CFX_ByteStringC PDF_FindValueAbbreviationForTesting(
- const CFX_ByteStringC& abbr);
-
-#endif // CORE_FPDFAPI_PAGE_PAGEINT_H_
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index 73d3081a9f..1fdd59e615 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -14,8 +14,8 @@
#include "core/fpdfapi/cpdf_modulemgr.h"
#include "core/fpdfapi/font/cpdf_fontencoding.h"
#include "core/fpdfapi/page/cpdf_docpagedata.h"
+#include "core/fpdfapi/page/cpdf_iccprofile.h"
#include "core/fpdfapi/page/cpdf_pagemodule.h"
-#include "core/fpdfapi/page/pageint.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_linearized_header.h"
diff --git a/core/fpdfapi/render/cpdf_docrenderdata.cpp b/core/fpdfapi/render/cpdf_docrenderdata.cpp
index d03824b59e..bf277f03f8 100644
--- a/core/fpdfapi/render/cpdf_docrenderdata.cpp
+++ b/core/fpdfapi/render/cpdf_docrenderdata.cpp
@@ -9,7 +9,7 @@
#include <memory>
#include "core/fpdfapi/font/cpdf_type3font.h"
-#include "core/fpdfapi/page/pageint.h"
+#include "core/fpdfapi/page/cpdf_function.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/render/cpdf_dibsource.h"
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 9170ae9daf..1d2218c166 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -17,6 +17,7 @@
#include "core/fpdfapi/page/cpdf_docpagedata.h"
#include "core/fpdfapi/page/cpdf_form.h"
#include "core/fpdfapi/page/cpdf_formobject.h"
+#include "core/fpdfapi/page/cpdf_function.h"
#include "core/fpdfapi/page/cpdf_graphicstates.h"
#include "core/fpdfapi/page/cpdf_image.h"
#include "core/fpdfapi/page/cpdf_imageobject.h"
@@ -28,7 +29,6 @@
#include "core/fpdfapi/page/cpdf_shadingpattern.h"
#include "core/fpdfapi/page/cpdf_textobject.h"
#include "core/fpdfapi/page/cpdf_tilingpattern.h"
-#include "core/fpdfapi/page/pageint.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index a1193fbe9b..7d91ab2b72 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -6,9 +6,12 @@
#include <utility>
#include <vector>
+#include "core/fpdfapi/page/cpdf_expintfunc.h"
+#include "core/fpdfapi/page/cpdf_function.h"
#include "core/fpdfapi/page/cpdf_meshstream.h"
+#include "core/fpdfapi/page/cpdf_sampledfunc.h"
#include "core/fpdfapi/page/cpdf_shadingpattern.h"
-#include "core/fpdfapi/page/pageint.h"
+#include "core/fpdfapi/page/cpdf_stitchfunc.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"