Fix retained argument TODOs, part 6.

Update CPDF_Function, CPDF_GeneralState, CPDF_DocRenderData,
CPDF_RenderStatus, and CPDF_ViewerPreferences.

Change-Id: Ia75e99a4888281a9d903f910dc149fb25e327a66
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/98618
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index 89cb55a..ea1e7af 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -1126,7 +1126,7 @@
 
   RetainPtr<const CPDF_Object> pFuncObj = pArray->GetDirectObjectAt(3);
   if (pFuncObj && !pFuncObj->IsName()) {
-    auto pFunc = CPDF_Function::Load(pFuncObj.Get());
+    auto pFunc = CPDF_Function::Load(std::move(pFuncObj));
     if (pFunc && pFunc->CountOutputs() >= m_pBaseCS->CountComponents())
       m_pFunc = std::move(pFunc);
   }
@@ -1191,7 +1191,7 @@
     return 0;
 
   m_pBaseCS = Load(pDoc, pAltCS.Get(), pVisited);
-  m_pFunc = CPDF_Function::Load(pArray->GetDirectObjectAt(3).Get());
+  m_pFunc = CPDF_Function::Load(pArray->GetDirectObjectAt(3));
   if (!m_pBaseCS || !m_pFunc)
     return 0;
 
diff --git a/core/fpdfapi/page/cpdf_expintfunc.cpp b/core/fpdfapi/page/cpdf_expintfunc.cpp
index 93de2d5..53a99d9 100644
--- a/core/fpdfapi/page/cpdf_expintfunc.cpp
+++ b/core/fpdfapi/page/cpdf_expintfunc.cpp
@@ -21,8 +21,7 @@
 
 CPDF_ExpIntFunc::~CPDF_ExpIntFunc() = default;
 
-bool CPDF_ExpIntFunc::v_Init(const CPDF_Object* pObj,
-                             std::set<const CPDF_Object*>* pVisited) {
+bool CPDF_ExpIntFunc::v_Init(const CPDF_Object* pObj, VisitedSet* pVisited) {
   RetainPtr<const CPDF_Dictionary> pDict = pObj->GetDict();
   if (!pDict)
     return false;
diff --git a/core/fpdfapi/page/cpdf_expintfunc.h b/core/fpdfapi/page/cpdf_expintfunc.h
index 4dd2529..817fda9 100644
--- a/core/fpdfapi/page/cpdf_expintfunc.h
+++ b/core/fpdfapi/page/cpdf_expintfunc.h
@@ -22,8 +22,7 @@
   ~CPDF_ExpIntFunc() override;
 
   // CPDF_Function:
-  bool v_Init(const CPDF_Object* pObj,
-              std::set<const CPDF_Object*>* pVisited) override;
+  bool v_Init(const CPDF_Object* pObj, VisitedSet* pVisited) override;
   bool v_Call(pdfium::span<const float> inputs,
               pdfium::span<float> results) const override;
 
diff --git a/core/fpdfapi/page/cpdf_function.cpp b/core/fpdfapi/page/cpdf_function.cpp
index 03e9afc..182715a 100644
--- a/core/fpdfapi/page/cpdf_function.cpp
+++ b/core/fpdfapi/page/cpdf_function.cpp
@@ -6,6 +6,7 @@
 
 #include "core/fpdfapi/page/cpdf_function.h"
 
+#include <utility>
 #include <vector>
 
 #include "core/fpdfapi/page/cpdf_expintfunc.h"
@@ -40,21 +41,22 @@
 
 // static
 std::unique_ptr<CPDF_Function> CPDF_Function::Load(
-    const CPDF_Object* pFuncObj) {
-  std::set<const CPDF_Object*> visited;
-  return Load(pFuncObj, &visited);
+    RetainPtr<const CPDF_Object> pFuncObj) {
+  VisitedSet visited;
+  return Load(std::move(pFuncObj), &visited);
 }
 
 // static
 std::unique_ptr<CPDF_Function> CPDF_Function::Load(
-    const CPDF_Object* pFuncObj,
-    std::set<const CPDF_Object*>* pVisited) {
+    RetainPtr<const CPDF_Object> pFuncObj,
+    VisitedSet* pVisited) {
   if (!pFuncObj)
     return nullptr;
 
   if (pdfium::Contains(*pVisited, pFuncObj))
     return nullptr;
-  ScopedSetInsertion<const CPDF_Object*> insertion(pVisited, pFuncObj);
+
+  ScopedSetInsertion<VisitedSet::value_type> insertion(pVisited, pFuncObj);
 
   int iType = -1;
   if (const CPDF_Stream* pStream = pFuncObj->AsStream())
@@ -83,8 +85,7 @@
 
 CPDF_Function::~CPDF_Function() = default;
 
-bool CPDF_Function::Init(const CPDF_Object* pObj,
-                         std::set<const CPDF_Object*>* pVisited) {
+bool CPDF_Function::Init(const CPDF_Object* pObj, VisitedSet* pVisited) {
   const CPDF_Stream* pStream = pObj->AsStream();
   RetainPtr<const CPDF_Dictionary> pDict =
       pStream ? pStream->GetDict() : pdfium::WrapRetain(pObj->AsDictionary());
diff --git a/core/fpdfapi/page/cpdf_function.h b/core/fpdfapi/page/cpdf_function.h
index a0f3382..b9dde74 100644
--- a/core/fpdfapi/page/cpdf_function.h
+++ b/core/fpdfapi/page/cpdf_function.h
@@ -11,6 +11,7 @@
 #include <set>
 #include <vector>
 
+#include "core/fxcrt/retain_ptr.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/span.h"
 
@@ -30,7 +31,8 @@
     kType4PostScript = 4,
   };
 
-  static std::unique_ptr<CPDF_Function> Load(const CPDF_Object* pFuncObj);
+  static std::unique_ptr<CPDF_Function> Load(
+      RetainPtr<const CPDF_Object> pFuncObj);
 
   virtual ~CPDF_Function();
 
@@ -55,12 +57,12 @@
  protected:
   explicit CPDF_Function(Type type);
 
+  using VisitedSet = std::set<RetainPtr<const CPDF_Object>>;
   static std::unique_ptr<CPDF_Function> Load(
-      const CPDF_Object* pFuncObj,
-      std::set<const CPDF_Object*>* pVisited);
-  bool Init(const CPDF_Object* pObj, std::set<const CPDF_Object*>* pVisited);
-  virtual bool v_Init(const CPDF_Object* pObj,
-                      std::set<const CPDF_Object*>* pVisited) = 0;
+      RetainPtr<const CPDF_Object> pFuncObj,
+      VisitedSet* pVisited);
+  bool Init(const CPDF_Object* pObj, VisitedSet* pVisited);
+  virtual bool v_Init(const CPDF_Object* pObj, VisitedSet* pVisited) = 0;
   virtual bool v_Call(pdfium::span<const float> inputs,
                       pdfium::span<float> results) const = 0;
 
diff --git a/core/fpdfapi/page/cpdf_function_unittest.cpp b/core/fpdfapi/page/cpdf_function_unittest.cpp
index 26acf01..57f9237 100644
--- a/core/fpdfapi/page/cpdf_function_unittest.cpp
+++ b/core/fpdfapi/page/cpdf_function_unittest.cpp
@@ -13,23 +13,23 @@
 TEST(CPDFFunction, BadFunctionType) {
   auto pDict = pdfium::MakeRetain<CPDF_Dictionary>();
   pDict->SetNewFor<CPDF_Number>("FunctionType", -2);
-  EXPECT_FALSE(CPDF_Function::Load(pDict.Get()));
+  EXPECT_FALSE(CPDF_Function::Load(pDict));
 
   pDict->SetNewFor<CPDF_Number>("FunctionType", 5);
-  EXPECT_FALSE(CPDF_Function::Load(pDict.Get()));
+  EXPECT_FALSE(CPDF_Function::Load(pDict));
 }
 
 TEST(CPDFFunction, NoDomain) {
   auto pDict = pdfium::MakeRetain<CPDF_Dictionary>();
   pDict->SetNewFor<CPDF_Number>("FunctionType", 0);
-  EXPECT_FALSE(CPDF_Function::Load(pDict.Get()));
+  EXPECT_FALSE(CPDF_Function::Load(pDict));
 }
 
 TEST(CPDFFunction, EmptyDomain) {
   auto pDict = pdfium::MakeRetain<CPDF_Dictionary>();
   pDict->SetNewFor<CPDF_Number>("FunctionType", 0);
   pDict->SetNewFor<CPDF_Array>("Domain");
-  EXPECT_FALSE(CPDF_Function::Load(pDict.Get()));
+  EXPECT_FALSE(CPDF_Function::Load(pDict));
 }
 
 TEST(CPDFFunction, NoRange) {
@@ -39,5 +39,5 @@
   auto pArray = pDict->SetNewFor<CPDF_Array>("Domain");
   pArray->AppendNew<CPDF_Number>(0);
   pArray->AppendNew<CPDF_Number>(10);
-  EXPECT_FALSE(CPDF_Function::Load(pDict.Get()));
+  EXPECT_FALSE(CPDF_Function::Load(pDict));
 }
diff --git a/core/fpdfapi/page/cpdf_occontext.cpp b/core/fpdfapi/page/cpdf_occontext.cpp
index b8edb07..69e31f6 100644
--- a/core/fpdfapi/page/cpdf_occontext.cpp
+++ b/core/fpdfapi/page/cpdf_occontext.cpp
@@ -34,9 +34,8 @@
   return bsIntent == "All" || bsIntent == csElement;
 }
 
-// TODO(tsepez): return retained object.
-const CPDF_Dictionary* GetConfig(CPDF_Document* pDoc,
-                                 const CPDF_Dictionary* pOCGDict) {
+RetainPtr<const CPDF_Dictionary> GetConfig(CPDF_Document* pDoc,
+                                           const CPDF_Dictionary* pOCGDict) {
   DCHECK(pOCGDict);
   RetainPtr<const CPDF_Dictionary> pOCProperties =
       pDoc->GetRoot()->GetDictFor("OCProperties");
@@ -51,16 +50,17 @@
     return nullptr;
 
   RetainPtr<const CPDF_Dictionary> pConfig = pOCProperties->GetDictFor("D");
-  RetainPtr<const CPDF_Array> pConfigs = pOCProperties->GetArrayFor("Configs");
-  if (!pConfigs)
-    return pConfig.Get();
+  RetainPtr<const CPDF_Array> pConfigArray =
+      pOCProperties->GetArrayFor("Configs");
+  if (!pConfigArray)
+    return pConfig;
 
-  for (size_t i = 0; i < pConfigs->size(); i++) {
-    RetainPtr<const CPDF_Dictionary> pFind = pConfigs->GetDictAt(i);
+  for (size_t i = 0; i < pConfigArray->size(); i++) {
+    RetainPtr<const CPDF_Dictionary> pFind = pConfigArray->GetDictAt(i);
     if (pFind && HasIntent(pFind.Get(), "View", ""))
-      return pFind.Get();
+      return pFind;
   }
-  return pConfig.Get();
+  return pConfig;
 }
 
 ByteString GetUsageTypeString(CPDF_OCContext::UsageType eType) {
@@ -94,7 +94,8 @@
 bool CPDF_OCContext::LoadOCGStateFromConfig(
     const ByteString& csConfig,
     const CPDF_Dictionary* pOCGDict) const {
-  const CPDF_Dictionary* pConfig = GetConfig(m_pDocument.Get(), pOCGDict);
+  RetainPtr<const CPDF_Dictionary> pConfig =
+      GetConfig(m_pDocument.Get(), pOCGDict);
   if (!pConfig)
     return true;
 
diff --git a/core/fpdfapi/page/cpdf_psfunc.cpp b/core/fpdfapi/page/cpdf_psfunc.cpp
index bd91956..6fbb3ec 100644
--- a/core/fpdfapi/page/cpdf_psfunc.cpp
+++ b/core/fpdfapi/page/cpdf_psfunc.cpp
@@ -13,8 +13,7 @@
 
 CPDF_PSFunc::~CPDF_PSFunc() = default;
 
-bool CPDF_PSFunc::v_Init(const CPDF_Object* pObj,
-                         std::set<const CPDF_Object*>* pVisited) {
+bool CPDF_PSFunc::v_Init(const CPDF_Object* pObj, VisitedSet* pVisited) {
   auto pAcc =
       pdfium::MakeRetain<CPDF_StreamAcc>(pdfium::WrapRetain(pObj->AsStream()));
   pAcc->LoadAllDataFiltered();
diff --git a/core/fpdfapi/page/cpdf_psfunc.h b/core/fpdfapi/page/cpdf_psfunc.h
index 8fb454f..f4be494 100644
--- a/core/fpdfapi/page/cpdf_psfunc.h
+++ b/core/fpdfapi/page/cpdf_psfunc.h
@@ -20,8 +20,7 @@
   ~CPDF_PSFunc() override;
 
   // CPDF_Function:
-  bool v_Init(const CPDF_Object* pObj,
-              std::set<const CPDF_Object*>* pVisited) override;
+  bool v_Init(const CPDF_Object* pObj, VisitedSet* pVisited) override;
   bool v_Call(pdfium::span<const float> inputs,
               pdfium::span<float> results) const override;
 
diff --git a/core/fpdfapi/page/cpdf_sampledfunc.cpp b/core/fpdfapi/page/cpdf_sampledfunc.cpp
index 3f57286..c475925 100644
--- a/core/fpdfapi/page/cpdf_sampledfunc.cpp
+++ b/core/fpdfapi/page/cpdf_sampledfunc.cpp
@@ -42,8 +42,7 @@
 
 CPDF_SampledFunc::~CPDF_SampledFunc() = default;
 
-bool CPDF_SampledFunc::v_Init(const CPDF_Object* pObj,
-                              std::set<const CPDF_Object*>* pVisited) {
+bool CPDF_SampledFunc::v_Init(const CPDF_Object* pObj, VisitedSet* pVisited) {
   RetainPtr<const CPDF_Stream> pStream(pObj->AsStream());
   if (!pStream)
     return false;
diff --git a/core/fpdfapi/page/cpdf_sampledfunc.h b/core/fpdfapi/page/cpdf_sampledfunc.h
index f9d226b..026a881 100644
--- a/core/fpdfapi/page/cpdf_sampledfunc.h
+++ b/core/fpdfapi/page/cpdf_sampledfunc.h
@@ -32,8 +32,7 @@
   ~CPDF_SampledFunc() override;
 
   // CPDF_Function:
-  bool v_Init(const CPDF_Object* pObj,
-              std::set<const CPDF_Object*>* pVisited) override;
+  bool v_Init(const CPDF_Object* pObj, VisitedSet* pVisited) override;
   bool v_Call(pdfium::span<const float> inputs,
               pdfium::span<float> results) const override;
 
diff --git a/core/fpdfapi/page/cpdf_shadingpattern.cpp b/core/fpdfapi/page/cpdf_shadingpattern.cpp
index aa73f5d..db51f4c 100644
--- a/core/fpdfapi/page/cpdf_shadingpattern.cpp
+++ b/core/fpdfapi/page/cpdf_shadingpattern.cpp
@@ -64,12 +64,10 @@
     if (const CPDF_Array* pArray = pFunc->AsArray()) {
       m_pFunctions.resize(std::min<size_t>(pArray->size(), 4));
       for (size_t i = 0; i < m_pFunctions.size(); ++i) {
-        m_pFunctions[i] =
-            CPDF_Function::Load(pArray->GetDirectObjectAt(i).Get());
+        m_pFunctions[i] = CPDF_Function::Load(pArray->GetDirectObjectAt(i));
       }
     } else {
-      // TODO(tsepez): pass retained argumments to load.
-      m_pFunctions.push_back(CPDF_Function::Load(pFunc.Get()));
+      m_pFunctions.push_back(CPDF_Function::Load(std::move(pFunc)));
     }
   }
   RetainPtr<const CPDF_Object> pCSObj =
diff --git a/core/fpdfapi/page/cpdf_stitchfunc.cpp b/core/fpdfapi/page/cpdf_stitchfunc.cpp
index d28113e..b2ae07c 100644
--- a/core/fpdfapi/page/cpdf_stitchfunc.cpp
+++ b/core/fpdfapi/page/cpdf_stitchfunc.cpp
@@ -24,8 +24,7 @@
 
 CPDF_StitchFunc::~CPDF_StitchFunc() = default;
 
-bool CPDF_StitchFunc::v_Init(const CPDF_Object* pObj,
-                             std::set<const CPDF_Object*>* pVisited) {
+bool CPDF_StitchFunc::v_Init(const CPDF_Object* pObj, VisitedSet* pVisited) {
   if (m_nInputs != kRequiredNumInputs)
     return false;
 
@@ -72,8 +71,8 @@
       if (pSub == pObj)
         return false;
 
-      std::unique_ptr<CPDF_Function> pFunc(
-          CPDF_Function::Load(pSub.Get(), pVisited));
+      std::unique_ptr<CPDF_Function> pFunc =
+          CPDF_Function::Load(std::move(pSub), pVisited);
       if (!pFunc)
         return false;
 
diff --git a/core/fpdfapi/page/cpdf_stitchfunc.h b/core/fpdfapi/page/cpdf_stitchfunc.h
index c6f3e36..1933505 100644
--- a/core/fpdfapi/page/cpdf_stitchfunc.h
+++ b/core/fpdfapi/page/cpdf_stitchfunc.h
@@ -19,8 +19,7 @@
   ~CPDF_StitchFunc() override;
 
   // CPDF_Function:
-  bool v_Init(const CPDF_Object* pObj,
-              std::set<const CPDF_Object*>* pVisited) override;
+  bool v_Init(const CPDF_Object* pObj, VisitedSet* pVisited) override;
   bool v_Call(pdfium::span<const float> inputs,
               pdfium::span<float> results) const override;
 
diff --git a/core/fpdfapi/render/cpdf_docrenderdata.cpp b/core/fpdfapi/render/cpdf_docrenderdata.cpp
index 701dede..25d602c 100644
--- a/core/fpdfapi/render/cpdf_docrenderdata.cpp
+++ b/core/fpdfapi/render/cpdf_docrenderdata.cpp
@@ -54,7 +54,7 @@
 }
 
 RetainPtr<CPDF_TransferFunc> CPDF_DocRenderData::GetTransferFunc(
-    const CPDF_Object* pObj) {
+    RetainPtr<const CPDF_Object> pObj) {
   if (!pObj)
     return nullptr;
 
@@ -63,7 +63,7 @@
     return pdfium::WrapRetain(it->second.Get());
 
   auto pFunc = CreateTransferFunc(pObj);
-  m_TransferFuncMap[pdfium::WrapRetain(pObj)].Reset(pFunc.Get());
+  m_TransferFuncMap[pObj].Reset(pFunc.Get());
   return pFunc;
 }
 
@@ -76,7 +76,7 @@
 #endif
 
 RetainPtr<CPDF_TransferFunc> CPDF_DocRenderData::CreateTransferFunc(
-    const CPDF_Object* pObj) const {
+    RetainPtr<const CPDF_Object> pObj) const {
   std::unique_ptr<CPDF_Function> pFuncs[3];
   const CPDF_Array* pArray = pObj->AsArray();
   if (pArray) {
@@ -84,8 +84,7 @@
       return nullptr;
 
     for (uint32_t i = 0; i < 3; ++i) {
-      // TODO(tsepez): pass retained objects to Load().
-      pFuncs[2 - i] = CPDF_Function::Load(pArray->GetDirectObjectAt(i).Get());
+      pFuncs[2 - i] = CPDF_Function::Load(pArray->GetDirectObjectAt(i));
       if (!pFuncs[2 - i])
         return nullptr;
     }
diff --git a/core/fpdfapi/render/cpdf_docrenderdata.h b/core/fpdfapi/render/cpdf_docrenderdata.h
index c280fe7..416a889 100644
--- a/core/fpdfapi/render/cpdf_docrenderdata.h
+++ b/core/fpdfapi/render/cpdf_docrenderdata.h
@@ -40,7 +40,8 @@
   CPDF_DocRenderData& operator=(const CPDF_DocRenderData&) = delete;
 
   RetainPtr<CPDF_Type3Cache> GetCachedType3(CPDF_Type3Font* pFont);
-  RetainPtr<CPDF_TransferFunc> GetTransferFunc(const CPDF_Object* pObj);
+  RetainPtr<CPDF_TransferFunc> GetTransferFunc(
+      RetainPtr<const CPDF_Object> pObj);
 
 #if BUILDFLAG(IS_WIN)
   CFX_PSFontTracker* GetPSFontTracker();
@@ -49,7 +50,7 @@
  protected:
   // protected for use by test subclasses.
   RetainPtr<CPDF_TransferFunc> CreateTransferFunc(
-      const CPDF_Object* pObj) const;
+      RetainPtr<const CPDF_Object> pObj) const;
 
  private:
   // TODO(tsepez): investigate this map outliving its font keys.
diff --git a/core/fpdfapi/render/cpdf_docrenderdata_unittest.cpp b/core/fpdfapi/render/cpdf_docrenderdata_unittest.cpp
index abf7d22..4b774d9 100644
--- a/core/fpdfapi/render/cpdf_docrenderdata_unittest.cpp
+++ b/core/fpdfapi/render/cpdf_docrenderdata_unittest.cpp
@@ -161,8 +161,8 @@
   TestDocRenderData() : CPDF_DocRenderData() {}
 
   RetainPtr<CPDF_TransferFunc> CreateTransferFuncForTesting(
-      const CPDF_Object* pObj) const {
-    return CreateTransferFunc(pObj);
+      RetainPtr<const CPDF_Object> pObj) const {
+    return CreateTransferFunc(std::move(pObj));
   }
 };
 
@@ -170,7 +170,7 @@
   RetainPtr<CPDF_Dictionary> func_dict = CreateType2FunctionDict();
 
   TestDocRenderData render_data;
-  auto func = render_data.CreateTransferFuncForTesting(func_dict.Get());
+  auto func = render_data.CreateTransferFuncForTesting(func_dict);
   ASSERT_TRUE(func);
   EXPECT_FALSE(func->GetIdentity());
 
@@ -206,7 +206,7 @@
   func_array->Append(CreateType4FunctionStream());
 
   TestDocRenderData render_data;
-  auto func = render_data.CreateTransferFuncForTesting(func_array.Get());
+  auto func = render_data.CreateTransferFuncForTesting(func_array);
   ASSERT_TRUE(func);
   EXPECT_FALSE(func->GetIdentity());
 
@@ -240,7 +240,7 @@
     auto func_stream = CreateBadType4FunctionStream();
 
     TestDocRenderData render_data;
-    auto func = render_data.CreateTransferFuncForTesting(func_stream.Get());
+    auto func = render_data.CreateTransferFuncForTesting(func_stream);
     EXPECT_FALSE(func);
   }
 
@@ -248,7 +248,7 @@
     auto func_array = pdfium::MakeRetain<CPDF_Array>();
 
     TestDocRenderData render_data;
-    auto func = render_data.CreateTransferFuncForTesting(func_array.Get());
+    auto func = render_data.CreateTransferFuncForTesting(func_array);
     EXPECT_FALSE(func);
   }
 
@@ -259,7 +259,7 @@
     func_array->Append(CreateBadType4FunctionStream());
 
     TestDocRenderData render_data;
-    auto func = render_data.CreateTransferFuncForTesting(func_array.Get());
+    auto func = render_data.CreateTransferFuncForTesting(func_array);
     EXPECT_FALSE(func);
   }
 }
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index affd4eb..35955c3 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -456,10 +456,10 @@
 }
 
 RetainPtr<CPDF_TransferFunc> CPDF_RenderStatus::GetTransferFunc(
-    const CPDF_Object* pObj) const {
+    RetainPtr<const CPDF_Object> pObj) const {
   DCHECK(pObj);
   auto* pDocCache = CPDF_DocRenderData::FromDocument(m_pContext->GetDocument());
-  return pDocCache ? pDocCache->GetTransferFunc(pObj) : nullptr;
+  return pDocCache ? pDocCache->GetTransferFunc(std::move(pObj)) : nullptr;
 }
 
 FX_ARGB CPDF_RenderStatus::GetFillArgb(CPDF_PageObject* pObj) const {
@@ -1402,7 +1402,7 @@
   RetainPtr<const CPDF_Object> pFuncObj =
       pSMaskDict->GetDirectObjectFor(pdfium::transparency::kTR);
   if (pFuncObj && (pFuncObj->IsDictionary() || pFuncObj->IsStream()))
-    pFunc = CPDF_Function::Load(pFuncObj.Get());
+    pFunc = CPDF_Function::Load(std::move(pFuncObj));
 
   CFX_Matrix matrix = mtMatrix;
   matrix.Translate(-pClipRect->left, -pClipRect->top);
diff --git a/core/fpdfapi/render/cpdf_renderstatus.h b/core/fpdfapi/render/cpdf_renderstatus.h
index 6d0a180..bbc3505 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.h
+++ b/core/fpdfapi/render/cpdf_renderstatus.h
@@ -98,7 +98,7 @@
 #endif
 
   RetainPtr<CPDF_TransferFunc> GetTransferFunc(
-      const CPDF_Object* pObject) const;
+      RetainPtr<const CPDF_Object> pObject) const;
 
   FX_ARGB GetFillArgb(CPDF_PageObject* pObj) const;
   FX_ARGB GetFillArgbForType3(CPDF_PageObject* pObj) const;
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index 7721a5d..0d2faab 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -267,8 +267,7 @@
   return FX_GetCharsetFromCodePage(FX_GetACP());
 }
 
-// TODO(tsepez): return retained reference.
-CPDF_Dictionary* InitDict(CPDF_Document* pDocument) {
+RetainPtr<CPDF_Dictionary> InitDict(CPDF_Document* pDocument) {
   auto pFormDict = pDocument->NewIndirect<CPDF_Dictionary>();
   pDocument->GetMutableRoot()->SetNewFor<CPDF_Reference>(
       "AcroForm", pDocument, pFormDict->GetObjNum());
@@ -295,7 +294,7 @@
     csDA = "/" + PDF_NameEncode(csBaseName) + " 0 Tf ";
   csDA += "0 g";
   pFormDict->SetNewFor<CPDF_String>("DA", csDA, /*bHex=*/false);
-  return pFormDict.Get();
+  return pFormDict;
 }
 
 RetainPtr<CPDF_Font> GetNativeFont(const CPDF_Dictionary* pFormDict,
@@ -571,7 +570,7 @@
   RetainPtr<CPDF_Dictionary> pFormDict =
       pDocument->GetMutableRoot()->GetMutableDictFor("AcroForm");
   if (!pFormDict)
-    pFormDict.Reset(InitDict(pDocument));
+    pFormDict = InitDict(pDocument);
 
   FX_Charset charSet = GetNativeCharSet();
   ByteString csTemp;
diff --git a/core/fpdfdoc/cpdf_viewerpreferences.cpp b/core/fpdfdoc/cpdf_viewerpreferences.cpp
index fcb65f9..19d9687 100644
--- a/core/fpdfdoc/cpdf_viewerpreferences.cpp
+++ b/core/fpdfdoc/cpdf_viewerpreferences.cpp
@@ -17,34 +17,33 @@
 CPDF_ViewerPreferences::~CPDF_ViewerPreferences() = default;
 
 bool CPDF_ViewerPreferences::IsDirectionR2L() const {
-  const CPDF_Dictionary* pDict = GetViewerPreferences();
+  RetainPtr<const CPDF_Dictionary> pDict = GetViewerPreferences();
   return pDict && pDict->GetByteStringFor("Direction") == "R2L";
 }
 
 bool CPDF_ViewerPreferences::PrintScaling() const {
-  const CPDF_Dictionary* pDict = GetViewerPreferences();
+  RetainPtr<const CPDF_Dictionary> pDict = GetViewerPreferences();
   return !pDict || pDict->GetByteStringFor("PrintScaling") != "None";
 }
 
 int32_t CPDF_ViewerPreferences::NumCopies() const {
-  const CPDF_Dictionary* pDict = GetViewerPreferences();
+  RetainPtr<const CPDF_Dictionary> pDict = GetViewerPreferences();
   return pDict ? pDict->GetIntegerFor("NumCopies") : 1;
 }
 
-// TODO(tsepez): return retained references.
-const CPDF_Array* CPDF_ViewerPreferences::PrintPageRange() const {
-  const CPDF_Dictionary* pDict = GetViewerPreferences();
-  return pDict ? pDict->GetArrayFor("PrintPageRange").Get() : nullptr;
+RetainPtr<const CPDF_Array> CPDF_ViewerPreferences::PrintPageRange() const {
+  RetainPtr<const CPDF_Dictionary> pDict = GetViewerPreferences();
+  return pDict ? pDict->GetArrayFor("PrintPageRange") : nullptr;
 }
 
 ByteString CPDF_ViewerPreferences::Duplex() const {
-  const CPDF_Dictionary* pDict = GetViewerPreferences();
+  RetainPtr<const CPDF_Dictionary> pDict = GetViewerPreferences();
   return pDict ? pDict->GetByteStringFor("Duplex") : ByteString("None");
 }
 
 absl::optional<ByteString> CPDF_ViewerPreferences::GenericName(
     const ByteString& bsKey) const {
-  const CPDF_Dictionary* pDict = GetViewerPreferences();
+  RetainPtr<const CPDF_Dictionary> pDict = GetViewerPreferences();
   if (!pDict)
     return absl::nullopt;
 
@@ -55,8 +54,8 @@
   return pName->GetString();
 }
 
-// TODO(tsepez): return retained object.
-const CPDF_Dictionary* CPDF_ViewerPreferences::GetViewerPreferences() const {
+RetainPtr<const CPDF_Dictionary> CPDF_ViewerPreferences::GetViewerPreferences()
+    const {
   const CPDF_Dictionary* pDict = m_pDoc->GetRoot();
-  return pDict ? pDict->GetDictFor("ViewerPreferences").Get() : nullptr;
+  return pDict ? pDict->GetDictFor("ViewerPreferences") : nullptr;
 }
diff --git a/core/fpdfdoc/cpdf_viewerpreferences.h b/core/fpdfdoc/cpdf_viewerpreferences.h
index f5001c2..40c5d84 100644
--- a/core/fpdfdoc/cpdf_viewerpreferences.h
+++ b/core/fpdfdoc/cpdf_viewerpreferences.h
@@ -10,6 +10,7 @@
 #include <stdint.h>
 
 #include "core/fxcrt/bytestring.h"
+#include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -25,14 +26,14 @@
   bool IsDirectionR2L() const;
   bool PrintScaling() const;
   int32_t NumCopies() const;
-  const CPDF_Array* PrintPageRange() const;
+  RetainPtr<const CPDF_Array> PrintPageRange() const;
   ByteString Duplex() const;
 
   // Gets the entry for |bsKey|.
   absl::optional<ByteString> GenericName(const ByteString& bsKey) const;
 
  private:
-  const CPDF_Dictionary* GetViewerPreferences() const;
+  RetainPtr<const CPDF_Dictionary> GetViewerPreferences() const;
 
   UnownedPtr<const CPDF_Document> const m_pDoc;
 };
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index 2d5fe54..b9452b8 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -323,16 +323,14 @@
   return pFormControl ? pForm->GetWidget(pFormControl) : nullptr;
 }
 
-// TODO(tsepez): return retained references.
-const CPDF_Array* GetInkList(FPDF_ANNOTATION annot) {
+RetainPtr<const CPDF_Array> GetInkList(FPDF_ANNOTATION annot) {
   FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot);
   if (subtype != FPDF_ANNOT_INK)
     return nullptr;
 
   const CPDF_Dictionary* annot_dict = GetAnnotDictFromFPDFAnnotation(annot);
-  return annot_dict
-             ? annot_dict->GetArrayFor(pdfium::annotation::kInkList).Get()
-             : nullptr;
+  return annot_dict ? annot_dict->GetArrayFor(pdfium::annotation::kInkList)
+                    : nullptr;
 }
 
 }  // namespace
@@ -900,7 +898,7 @@
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV
 FPDFAnnot_GetInkListCount(FPDF_ANNOTATION annot) {
-  const CPDF_Array* ink_list = GetInkList(annot);
+  RetainPtr<const CPDF_Array> ink_list = GetInkList(annot);
   return ink_list ? fxcrt::CollectionSize<unsigned long>(*ink_list) : 0;
 }
 
@@ -909,7 +907,7 @@
                          unsigned long path_index,
                          FS_POINTF* buffer,
                          unsigned long length) {
-  const CPDF_Array* ink_list = GetInkList(annot);
+  RetainPtr<const CPDF_Array> ink_list = GetInkList(annot);
   if (!ink_list)
     return 0;
 
diff --git a/fpdfsdk/fpdf_thumbnail.cpp b/fpdfsdk/fpdf_thumbnail.cpp
index c09ac2d..71c5c26 100644
--- a/fpdfsdk/fpdf_thumbnail.cpp
+++ b/fpdfsdk/fpdf_thumbnail.cpp
@@ -17,7 +17,7 @@
 
 namespace {
 
-const CPDF_Stream* CPDFStreamForThumbnailFromPage(FPDF_PAGE page) {
+RetainPtr<const CPDF_Stream> CPDFStreamForThumbnailFromPage(FPDF_PAGE page) {
   const CPDF_Page* p_page = CPDFPageFromFPDFPage(page);
   if (!p_page)
     return nullptr;
@@ -26,8 +26,7 @@
   if (!page_dict->KeyExist("Type"))
     return nullptr;
 
-  // TODO(tsepez): return retained objects.
-  return page_dict->GetStreamFor("Thumb").Get();
+  return page_dict->GetStreamFor("Thumb");
 }
 
 }  // namespace
@@ -36,7 +35,8 @@
 FPDFPage_GetDecodedThumbnailData(FPDF_PAGE page,
                                  void* buffer,
                                  unsigned long buflen) {
-  const CPDF_Stream* thumb_stream = CPDFStreamForThumbnailFromPage(page);
+  RetainPtr<const CPDF_Stream> thumb_stream =
+      CPDFStreamForThumbnailFromPage(page);
   if (!thumb_stream)
     return 0u;
 
@@ -47,7 +47,8 @@
 FPDFPage_GetRawThumbnailData(FPDF_PAGE page,
                              void* buffer,
                              unsigned long buflen) {
-  const CPDF_Stream* thumb_stream = CPDFStreamForThumbnailFromPage(page);
+  RetainPtr<const CPDF_Stream> thumb_stream =
+      CPDFStreamForThumbnailFromPage(page);
   if (!thumb_stream)
     return 0u;
 
@@ -57,7 +58,7 @@
 FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
 FPDFPage_GetThumbnailAsBitmap(FPDF_PAGE page) {
   RetainPtr<const CPDF_Stream> thumb_stream =
-      pdfium::WrapRetain(CPDFStreamForThumbnailFromPage(page));
+      CPDFStreamForThumbnailFromPage(page);
   if (!thumb_stream)
     return nullptr;
 
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 8a57919..1627575 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -1003,7 +1003,7 @@
   if (!pDoc)
     return nullptr;
   CPDF_ViewerPreferences viewRef(pDoc);
-  return FPDFPageRangeFromCPDFArray(viewRef.PrintPageRange());
+  return FPDFPageRangeFromCPDFArray(viewRef.PrintPageRange().Get());
 }
 
 FPDF_EXPORT size_t FPDF_CALLCONV