Break apart the pageint.h file.

This CL separates pageint.h and the supporting cpp files into indivudal
class files.

Change-Id: Idcadce41976a8cd5f0d916e6a5ebbc283fd36527
Reviewed-on: https://pdfium-review.googlesource.com/5930
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 073fd57..2f8b8f1 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -483,16 +483,24 @@
     "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 @@
     "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 @@
     "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_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 b1ac99b..b22551a 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 4702947..ebdad49 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 c67d315..cedc847 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 7e0675d..e6665c8 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 111d45f..345180f 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 @@
     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 9e1c4de..c8c2abf 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_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 @@
   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 64f936c..cb39616 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 @@
   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
similarity index 86%
rename from core/fpdfapi/page/fpdf_page_colors.cpp
rename to core/fpdfapi/page/cpdf_devicecs.cpp
index 1526b75..d410b1f 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 @@
   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 @@
       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 0000000..177f240
--- /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 22a961a..a171d01 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 435b0f2..d8b89b3 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 32d220b..0fda169 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_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 0000000..5d12131
--- /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 0000000..867d2fa
--- /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 2245f93..c2170ac 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 0000000..635c53a
--- /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 0000000..ff7cf84
--- /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 0000000..afb505a
--- /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 0000000..05ac9bf
--- /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 ac93513..7a6228a 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 d528d3d..2f0c835 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 4aa19da..49d2769 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 1d2b51e..53dfd75 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 5c30fe9..afd2c98 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 dba301b..504b5b0 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 @@
   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 0000000..4951f61
--- /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 0000000..d28fff1
--- /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 0000000..658d73c
--- /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 0000000..debbbd6
--- /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 0000000..b8c18c9
--- /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 0000000..37b9a4e
--- /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 0000000..59fe1ef
--- /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 80eea63..c21f51c 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 c2d55cc..068d772 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 0000000..336c74b
--- /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 0000000..69e5e41
--- /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
similarity index 100%
rename from core/fpdfapi/page/fpdf_page_func_embeddertest.cpp
rename to core/fpdfapi/page/cpdf_stitchfunc_embeddertest.cpp
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index e8594b9..151b0e6 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 @@
 
 }  // 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 @@
   }
 }
 
+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 5436f8f..4138555 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.h
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.h
@@ -51,6 +51,9 @@
   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 be2fcb0..ffc0d95 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")));
+            parser.FindValueAbbreviationForTesting(CFX_ByteStringC("DCT")));
   EXPECT_EQ(CFX_ByteStringC(""),
-            PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("")));
-  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 48cd41c..0000000
--- 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 45ca671..0000000
--- 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 73d3081..1fdd59e 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 d03824b..bf277f0 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 9170ae9..1d2218c 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 a1193fb..7d91ab2 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"