Fix retained argument TODOs, part 4.

Return retained arguments from CPDF_StreamAcc methods. Pass retained
arguments into CPDF_StructElement methods and the PDF_DataDecode()
function.

Change-Id: Ic86417ba3f6ea840ea4472f502670fe3083f4031
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/98611
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_stream_acc.cpp b/core/fpdfapi/parser/cpdf_stream_acc.cpp
index f0eeb83..f0bd7ae 100644
--- a/core/fpdfapi/parser/cpdf_stream_acc.cpp
+++ b/core/fpdfapi/parser/cpdf_stream_acc.cpp
@@ -71,9 +71,12 @@
   return m_pStream;
 }
 
-const CPDF_Dictionary* CPDF_StreamAcc::GetDict() const {
-  // TODO(tsepez): return retained references.
-  return m_pStream ? m_pStream->GetDict().Get() : nullptr;
+RetainPtr<const CPDF_Dictionary> CPDF_StreamAcc::GetDict() const {
+  return m_pStream ? m_pStream->GetDict() : nullptr;
+}
+
+RetainPtr<const CPDF_Dictionary> CPDF_StreamAcc::GetImageParam() const {
+  return m_pImageParam;
 }
 
 const uint8_t* CPDF_StreamAcc::GetData() const {
@@ -154,8 +157,8 @@
   std::unique_ptr<uint8_t, FxFreeDeleter> pDecodedData;
   uint32_t dwDecodedSize = 0;
 
-  absl::optional<std::vector<std::pair<ByteString, const CPDF_Object*>>>
-      decoder_array = GetDecoderArray(m_pStream->GetDict());
+  absl::optional<DecoderArray> decoder_array =
+      GetDecoderArray(m_pStream->GetDict());
   if (!decoder_array.has_value() || decoder_array.value().empty() ||
       !PDF_DataDecode(src_span, estimated_size, bImageAcc,
                       decoder_array.value(), &pDecodedData, &dwDecodedSize,
diff --git a/core/fpdfapi/parser/cpdf_stream_acc.h b/core/fpdfapi/parser/cpdf_stream_acc.h
index 2c6bfa1..2ac7c45 100644
--- a/core/fpdfapi/parser/cpdf_stream_acc.h
+++ b/core/fpdfapi/parser/cpdf_stream_acc.h
@@ -33,13 +33,13 @@
   void LoadAllDataRaw();
 
   RetainPtr<const CPDF_Stream> GetStream() const;
-  const CPDF_Dictionary* GetDict() const;
+  RetainPtr<const CPDF_Dictionary> GetDict() const;
+  RetainPtr<const CPDF_Dictionary> GetImageParam() const;
 
   uint32_t GetSize() const;
   pdfium::span<const uint8_t> GetSpan() const;
   ByteString ComputeDigest() const;
   ByteString GetImageDecoder() const { return m_ImageDecoder; }
-  const CPDF_Dictionary* GetImageParam() const { return m_pImageParam.Get(); }
   std::unique_ptr<uint8_t, FxFreeDeleter> DetachData();
 
  private:
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index 5e29b81..bbc07db 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -383,29 +383,27 @@
 
     RetainPtr<const CPDF_Array> pParamsArray = ToArray(pParams);
     for (size_t i = 0; i < pDecoders->size(); ++i) {
-      // TODO(tsepez): push retained arguments.
       decoder_array.push_back(
           {pDecoders->GetByteStringAt(i),
-           pParamsArray ? pParamsArray->GetDictAt(i).Get() : nullptr});
+           pParamsArray ? pParamsArray->GetDictAt(i) : nullptr});
     }
   } else {
     DCHECK(pFilter->IsName());
     decoder_array.push_back(
-        {pFilter->GetString(), pParams ? pParams->GetDict().Get() : nullptr});
+        {pFilter->GetString(), pParams ? pParams->GetDict() : nullptr});
   }
 
   return decoder_array;
 }
 
-bool PDF_DataDecode(
-    pdfium::span<const uint8_t> src_span,
-    uint32_t last_estimated_size,
-    bool bImageAcc,
-    const std::vector<std::pair<ByteString, const CPDF_Object*>>& decoder_array,
-    std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
-    uint32_t* dest_size,
-    ByteString* ImageEncoding,
-    RetainPtr<const CPDF_Dictionary>* pImageParams) {
+bool PDF_DataDecode(pdfium::span<const uint8_t> src_span,
+                    uint32_t last_estimated_size,
+                    bool bImageAcc,
+                    const DecoderArray& decoder_array,
+                    std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+                    uint32_t* dest_size,
+                    ByteString* ImageEncoding,
+                    RetainPtr<const CPDF_Dictionary>* pImageParams) {
   std::unique_ptr<uint8_t, FxFreeDeleter> result;
   // May be changed to point to |result| in the for-loop below. So put it below
   // |result| and let it get destroyed first.
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.h b/core/fpdfapi/parser/fpdf_parser_decode.h
index 7f68168..5ba2967 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.h
+++ b/core/fpdfapi/parser/fpdf_parser_decode.h
@@ -82,7 +82,8 @@
 // Returns an empty vector if there is no filter, or if the filter is an empty
 // array.
 // Otherwise, returns a vector of decoders.
-using DecoderArray = std::vector<std::pair<ByteString, const CPDF_Object*>>;
+using DecoderArray =
+    std::vector<std::pair<ByteString, RetainPtr<const CPDF_Object>>>;
 absl::optional<DecoderArray> GetDecoderArray(
     RetainPtr<const CPDF_Dictionary> pDict);
 
diff --git a/core/fpdfdoc/cpdf_structelement.cpp b/core/fpdfdoc/cpdf_structelement.cpp
index b03189a..211ec1c 100644
--- a/core/fpdfdoc/cpdf_structelement.cpp
+++ b/core/fpdfdoc/cpdf_structelement.cpp
@@ -44,7 +44,7 @@
     : m_pTree(pTree),
       m_pDict(std::move(pDict)),
       m_Type(GetStructElementType(m_pTree.Get(), m_pDict.Get())) {
-  LoadKids(m_pDict.Get());
+  LoadKids(m_pDict);
 }
 
 CPDF_StructElement::~CPDF_StructElement() {
@@ -92,7 +92,7 @@
   return bSave;
 }
 
-void CPDF_StructElement::LoadKids(const CPDF_Dictionary* pDict) {
+void CPDF_StructElement::LoadKids(RetainPtr<const CPDF_Dictionary> pDict) {
   RetainPtr<const CPDF_Object> pObj = pDict->GetObjectFor("Pg");
   const CPDF_Reference* pRef = ToReference(pObj.Get());
   const uint32_t PageObjNum = pRef ? pRef->GetRefObjNum() : 0;
@@ -104,22 +104,17 @@
   if (const CPDF_Array* pArray = pKids->AsArray()) {
     m_Kids.resize(pArray->size());
     for (size_t i = 0; i < pArray->size(); ++i) {
-      RetainPtr<const CPDF_Object> pKid = pArray->GetDirectObjectAt(i);
-
-      // TODO(tsepez): LoadKid() can take moved retained pKid
-      LoadKid(PageObjNum, pKid.Get(), &m_Kids[i]);
+      LoadKid(PageObjNum, pArray->GetDirectObjectAt(i), &m_Kids[i]);
     }
     return;
   }
 
   m_Kids.resize(1);
-
-  // TODO(tsepez): pass retained arguments.
-  LoadKid(PageObjNum, pKids.Get(), &m_Kids[0]);
+  LoadKid(PageObjNum, std::move(pKids), &m_Kids[0]);
 }
 
 void CPDF_StructElement::LoadKid(uint32_t PageObjNum,
-                                 const CPDF_Object* pKidObj,
+                                 RetainPtr<const CPDF_Object> pKidObj,
                                  Kid* pKid) {
   if (!pKidObj)
     return;
diff --git a/core/fpdfdoc/cpdf_structelement.h b/core/fpdfdoc/cpdf_structelement.h
index 7521e01..5ab976f 100644
--- a/core/fpdfdoc/cpdf_structelement.h
+++ b/core/fpdfdoc/cpdf_structelement.h
@@ -60,8 +60,10 @@
                      RetainPtr<const CPDF_Dictionary> pDict);
   ~CPDF_StructElement() override;
 
-  void LoadKids(const CPDF_Dictionary* pDict);
-  void LoadKid(uint32_t PageObjNum, const CPDF_Object* pKidObj, Kid* pKid);
+  void LoadKids(RetainPtr<const CPDF_Dictionary> pDict);
+  void LoadKid(uint32_t PageObjNum,
+               RetainPtr<const CPDF_Object> pKidObj,
+               Kid* pKid);
 
   UnownedPtr<const CPDF_StructTree> const m_pTree;
   RetainPtr<const CPDF_Dictionary> const m_pDict;