Refcount all the IFX_ stream classes all the time.

We can remove a lot of "bOwnsStream" logic in the process.
Always pass these by const reference, in case the called method
wants to hang on to the stream (one exception is where we stick
a raw pointer into a void* slot in a context from another layer).

Review-Url: https://codereview.chromium.org/2451493002
diff --git a/core/fpdfapi/edit/cpdf_creator.h b/core/fpdfapi/edit/cpdf_creator.h
index c04db6e..aeb7d66 100644
--- a/core/fpdfapi/edit/cpdf_creator.h
+++ b/core/fpdfapi/edit/cpdf_creator.h
@@ -9,6 +9,7 @@
 
 #include <memory>
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_basic.h"
 
 class CPDF_Array;
@@ -32,7 +33,7 @@
   ~CPDF_Creator();
 
   void RemoveSecurity();
-  bool Create(IFX_WriteStream* pFile, uint32_t flags = 0);
+  bool Create(const CFX_RetainPtr<IFX_WriteStream>& pFile, uint32_t flags = 0);
   int32_t Continue(IFX_Pause* pPause = nullptr);
   bool SetFileVersion(int32_t fileVersion = 17);
 
diff --git a/core/fpdfapi/edit/fpdf_edit_create.cpp b/core/fpdfapi/edit/fpdf_edit_create.cpp
index b8757ae..62314f4 100644
--- a/core/fpdfapi/edit/fpdf_edit_create.cpp
+++ b/core/fpdfapi/edit/fpdf_edit_create.cpp
@@ -1479,7 +1479,8 @@
       InitOldObjNumOffsets();
       m_iStage = 20;
     } else {
-      IFX_SeekableReadStream* pSrcFile = m_pParser->GetFileAccess();
+      CFX_RetainPtr<IFX_SeekableReadStream> pSrcFile =
+          m_pParser->GetFileAccess();
       m_Offset = pSrcFile->GetSize();
       m_Pos = (void*)(uintptr_t)m_Offset;
       m_iStage = 15;
@@ -1487,8 +1488,9 @@
   }
   if (m_iStage == 15) {
     if ((m_dwFlags & FPDFCREATE_NO_ORIGINAL) == 0 && m_Pos) {
-      IFX_SeekableReadStream* pSrcFile = m_pParser->GetFileAccess();
-      uint8_t buffer[4096];
+      CFX_RetainPtr<IFX_SeekableReadStream> pSrcFile =
+          m_pParser->GetFileAccess();
+      uint8_t buffer[4096];  // TODO(tsepez): don't stack allocate.
       uint32_t src_size = (uint32_t)(uintptr_t)m_Pos;
       while (src_size) {
         uint32_t block_size = src_size > 4096 ? 4096 : src_size;
@@ -1904,7 +1906,8 @@
   m_pIDArray.reset();
 }
 
-bool CPDF_Creator::Create(IFX_WriteStream* pFile, uint32_t flags) {
+bool CPDF_Creator::Create(const CFX_RetainPtr<IFX_WriteStream>& pFile,
+                          uint32_t flags) {
   m_File.AttachFile(pFile);
   return Create(flags);
 }
diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp
index 5d1d51d..a17222e 100644
--- a/core/fpdfapi/page/cpdf_image.cpp
+++ b/core/fpdfapi/page/cpdf_image.cpp
@@ -116,7 +116,8 @@
   return pDict;
 }
 
-void CPDF_Image::SetJpegImage(IFX_SeekableReadStream* pFile) {
+void CPDF_Image::SetJpegImage(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFile) {
   uint32_t size = pdfium::base::checked_cast<uint32_t>(pFile->GetSize());
   if (!size)
     return;
diff --git a/core/fpdfapi/page/cpdf_image.h b/core/fpdfapi/page/cpdf_image.h
index 38c7e3e..1b0d74f 100644
--- a/core/fpdfapi/page/cpdf_image.h
+++ b/core/fpdfapi/page/cpdf_image.h
@@ -51,7 +51,7 @@
                                bool bLoadMask = false) const;
 
   void SetImage(const CFX_DIBitmap* pDIBitmap);
-  void SetJpegImage(IFX_SeekableReadStream* pFile);
+  void SetJpegImage(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile);
 
   void ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pDIBitmap);
 
diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp
index a6045e7..6575552 100644
--- a/core/fpdfapi/parser/cfdf_document.cpp
+++ b/core/fpdfapi/parser/cfdf_document.cpp
@@ -15,15 +15,9 @@
 #include "third_party/base/ptr_util.h"
 
 CFDF_Document::CFDF_Document()
-    : CPDF_IndirectObjectHolder(),
-      m_pRootDict(nullptr),
-      m_pFile(nullptr),
-      m_bOwnFile(false) {}
+    : CPDF_IndirectObjectHolder(), m_pRootDict(nullptr) {}
 
-CFDF_Document::~CFDF_Document() {
-  if (m_bOwnFile && m_pFile)
-    m_pFile->Release();
-}
+CFDF_Document::~CFDF_Document() {}
 
 std::unique_ptr<CFDF_Document> CFDF_Document::CreateNewDoc() {
   auto pDoc = pdfium::MakeUnique<CFDF_Document>();
@@ -33,25 +27,23 @@
 }
 
 std::unique_ptr<CFDF_Document> CFDF_Document::ParseFile(
-    IFX_SeekableReadStream* pFile,
-    bool bOwnFile) {
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFile) {
   if (!pFile)
     return nullptr;
 
   auto pDoc = pdfium::MakeUnique<CFDF_Document>();
-  pDoc->ParseStream(pFile, bOwnFile);
+  pDoc->ParseStream(pFile);
   return pDoc->m_pRootDict ? std::move(pDoc) : nullptr;
 }
 
-std::unique_ptr<CFDF_Document> CFDF_Document::ParseMemory(const uint8_t* pData,
+std::unique_ptr<CFDF_Document> CFDF_Document::ParseMemory(uint8_t* pData,
                                                           uint32_t size) {
-  return CFDF_Document::ParseFile(
-      IFX_MemoryStream::Create((uint8_t*)pData, size), true);
+  return CFDF_Document::ParseFile(IFX_MemoryStream::Create(pData, size));
 }
 
-void CFDF_Document::ParseStream(IFX_SeekableReadStream* pFile, bool bOwnFile) {
+void CFDF_Document::ParseStream(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFile) {
   m_pFile = pFile;
-  m_bOwnFile = bOwnFile;
   CPDF_SyntaxParser parser;
   parser.InitParser(m_pFile, 0);
   while (1) {
diff --git a/core/fpdfapi/parser/cfdf_document.h b/core/fpdfapi/parser/cfdf_document.h
index 1b47368..f83adc1 100644
--- a/core/fpdfapi/parser/cfdf_document.h
+++ b/core/fpdfapi/parser/cfdf_document.h
@@ -18,9 +18,9 @@
 class CFDF_Document : public CPDF_IndirectObjectHolder {
  public:
   static std::unique_ptr<CFDF_Document> CreateNewDoc();
-  static std::unique_ptr<CFDF_Document> ParseFile(IFX_SeekableReadStream* pFile,
-                                                  bool bOwnFile = false);
-  static std::unique_ptr<CFDF_Document> ParseMemory(const uint8_t* pData,
+  static std::unique_ptr<CFDF_Document> ParseFile(
+      const CFX_RetainPtr<IFX_SeekableReadStream>& pFile);
+  static std::unique_ptr<CFDF_Document> ParseMemory(uint8_t* pData,
                                                     uint32_t size);
 
   CFDF_Document();
@@ -30,11 +30,10 @@
   CPDF_Dictionary* GetRoot() const { return m_pRootDict; }
 
  protected:
-  void ParseStream(IFX_SeekableReadStream* pFile, bool bOwnFile);
+  void ParseStream(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile);
 
   CPDF_Dictionary* m_pRootDict;
-  IFX_SeekableReadStream* m_pFile;
-  bool m_bOwnFile;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFile;
 };
 
 #endif  // CORE_FPDFAPI_PARSER_CFDF_DOCUMENT_H_
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index 2487484..76ea73d 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -33,9 +33,10 @@
 // static
 int CPDF_DataAvail::s_CurrentDataAvailRecursionDepth = 0;
 
-CPDF_DataAvail::CPDF_DataAvail(FileAvail* pFileAvail,
-                               IFX_SeekableReadStream* pFileRead,
-                               bool bSupportHintTable)
+CPDF_DataAvail::CPDF_DataAvail(
+    FileAvail* pFileAvail,
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
+    bool bSupportHintTable)
     : m_pFileAvail(pFileAvail), m_pFileRead(pFileRead) {
   m_Pos = 0;
   m_dwFileLen = 0;
@@ -72,7 +73,6 @@
   m_pPageDict = nullptr;
   m_pPageResource = nullptr;
   m_docStatus = PDF_DATAAVAIL_HEADER;
-  m_parser.m_bOwnFileRead = false;
   m_bTotalLoadPageTree = false;
   m_bCurPageDictLoadOK = false;
   m_bLinearedDataOK = false;
@@ -320,7 +320,6 @@
 
 bool CPDF_DataAvail::LoadAllXref(DownloadHints* pHints) {
   m_parser.m_pSyntax->InitParser(m_pFileRead, (uint32_t)m_dwHeaderOffset);
-  m_parser.m_bOwnFileRead = false;
   if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) &&
       !m_parser.LoadAllCrossRefV5(m_dwLastXRefOffset)) {
     m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
@@ -718,15 +717,16 @@
   if (m_pLinearized)
     return true;
 
-  ScopedFileStream file(IFX_MemoryStream::Create(pData, (size_t)dwLen, false));
-  int32_t offset = GetHeaderOffset(file.get());
+  CFX_RetainPtr<IFX_MemoryStream> file =
+      IFX_MemoryStream::Create(pData, (size_t)dwLen, false);
+  int32_t offset = GetHeaderOffset(file);
   if (offset == -1) {
     m_docStatus = PDF_DATAAVAIL_ERROR;
     return false;
   }
 
   m_dwHeaderOffset = offset;
-  m_syntaxParser.InitParser(file.get(), offset);
+  m_syntaxParser.InitParser(file, offset);
   m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9);
 
   bool bNumber;
@@ -753,9 +753,9 @@
     uint8_t buffer[1024];
     m_pFileRead->ReadBlock(buffer, req_pos, dwSize);
 
-    ScopedFileStream file(
-        IFX_MemoryStream::Create(buffer, (size_t)dwSize, false));
-    m_syntaxParser.InitParser(file.get(), 0);
+    CFX_RetainPtr<IFX_MemoryStream> file =
+        IFX_MemoryStream::Create(buffer, (size_t)dwSize, false);
+    m_syntaxParser.InitParser(file, 0);
     m_syntaxParser.RestorePos(dwSize - 1);
 
     if (m_syntaxParser.SearchWord("startxref", true, false, dwSize)) {
@@ -801,8 +801,9 @@
 
     m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize);
 
-    ScopedFileStream file(IFX_MemoryStream::Create(pBuf, (size_t)iSize, false));
-    m_parser.m_pSyntax->InitParser(file.get(), 0);
+    CFX_RetainPtr<IFX_MemoryStream> file =
+        IFX_MemoryStream::Create(pBuf, (size_t)iSize, false);
+    m_parser.m_pSyntax->InitParser(file, 0);
 
     bool bNumber;
     CFX_ByteString objnum = m_parser.m_pSyntax->GetNextWord(&bNumber);
@@ -1047,8 +1048,9 @@
     if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize))
       return false;
 
-    ScopedFileStream file(IFX_MemoryStream::Create(pBuf, (size_t)iSize, false));
-    m_syntaxParser.InitParser(file.get(), 0);
+    CFX_RetainPtr<IFX_MemoryStream> file =
+        IFX_MemoryStream::Create(pBuf, (size_t)iSize, false);
+    m_syntaxParser.InitParser(file, 0);
 
     std::unique_ptr<CPDF_Object> pTrailer(
         m_syntaxParser.GetObject(nullptr, 0, 0, true));
diff --git a/core/fpdfapi/parser/cpdf_data_avail.h b/core/fpdfapi/parser/cpdf_data_avail.h
index e81d705..1ced2a2 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.h
+++ b/core/fpdfapi/parser/cpdf_data_avail.h
@@ -95,7 +95,7 @@
   };
 
   CPDF_DataAvail(FileAvail* pFileAvail,
-                 IFX_SeekableReadStream* pFileRead,
+                 const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
                  bool bSupportHintTable);
   ~CPDF_DataAvail();
 
@@ -107,7 +107,9 @@
   DocLinearizationStatus IsLinearizedPDF();
   bool IsLinearized();
   void GetLinearizedMainXRefInfo(FX_FILESIZE* pPos, uint32_t* pSize);
-  IFX_SeekableReadStream* GetFileRead() const { return m_pFileRead; }
+  CFX_RetainPtr<IFX_SeekableReadStream> GetFileRead() const {
+    return m_pFileRead;
+  }
   int GetPageCount() const;
   CPDF_Dictionary* GetPage(int index);
 
@@ -195,7 +197,7 @@
   bool ValidateForm();
 
   FileAvail* const m_pFileAvail;
-  IFX_SeekableReadStream* const m_pFileRead;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFileRead;
   CPDF_Parser m_parser;
   CPDF_SyntaxParser m_syntaxParser;
   std::unique_ptr<CPDF_Object> m_pRoot;
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 1fae0d6..47c5c4e 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -52,7 +52,6 @@
 CPDF_Parser::CPDF_Parser()
     : m_pDocument(nullptr),
       m_bHasParsed(false),
-      m_bOwnFileRead(true),
       m_bXRefStream(false),
       m_bVersionUpdated(false),
       m_FileVersion(0),
@@ -64,11 +63,6 @@
 CPDF_Parser::~CPDF_Parser() {
   ReleaseEncryptHandler();
   SetEncryptDictionary(nullptr);
-
-  if (m_bOwnFileRead && m_pSyntax->m_pFileAccess) {
-    m_pSyntax->m_pFileAccess->Release();
-    m_pSyntax->m_pFileAccess = nullptr;
-  }
 }
 
 uint32_t CPDF_Parser::GetLastObjNum() const {
@@ -109,7 +103,7 @@
   return m_pSyntax->m_pCryptoHandler.get();
 }
 
-IFX_SeekableReadStream* CPDF_Parser::GetFileAccess() const {
+CFX_RetainPtr<IFX_SeekableReadStream> CPDF_Parser::GetFileAccess() const {
   return m_pSyntax->m_pFileAccess;
 }
 
@@ -129,31 +123,30 @@
     m_ObjectInfo[objnum - 1].pos = 0;
 }
 
-CPDF_Parser::Error CPDF_Parser::StartParse(IFX_SeekableReadStream* pFileAccess,
-                                           CPDF_Document* pDocument) {
+CPDF_Parser::Error CPDF_Parser::StartParse(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess,
+    CPDF_Document* pDocument) {
   ASSERT(!m_bHasParsed);
   m_bHasParsed = true;
-
   m_bXRefStream = false;
   m_LastXRefOffset = 0;
-  m_bOwnFileRead = true;
 
   int32_t offset = GetHeaderOffset(pFileAccess);
-  if (offset == -1) {
-    if (pFileAccess)
-      pFileAccess->Release();
+  if (offset == -1)
     return FORMAT_ERROR;
-  }
+
   m_pSyntax->InitParser(pFileAccess, offset);
 
   uint8_t ch;
   if (!m_pSyntax->GetCharAt(5, ch))
     return FORMAT_ERROR;
+
   if (std::isdigit(ch))
     m_FileVersion = FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch)) * 10;
 
   if (!m_pSyntax->GetCharAt(7, ch))
     return FORMAT_ERROR;
+
   if (std::isdigit(ch))
     m_FileVersion += FXSYS_toDecimalDigit(static_cast<FX_WCHAR>(ch));
 
@@ -1124,10 +1117,10 @@
   if (!pObjStream)
     return nullptr;
 
-  ScopedFileStream file(IFX_MemoryStream::Create(
-      (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), false));
+  CFX_RetainPtr<IFX_MemoryStream> file = IFX_MemoryStream::Create(
+      (uint8_t*)pObjStream->GetData(), (size_t)pObjStream->GetSize(), false);
   CPDF_SyntaxParser syntax;
-  syntax.InitParser(file.get(), 0);
+  syntax.InitParser(file, 0);
   const int32_t offset = GetStreamFirst(pObjStream);
 
   // Read object numbers from |pObjStream| into a cache.
@@ -1203,11 +1196,11 @@
     int32_t offset = GetStreamFirst(pObjStream);
     const uint8_t* pData = pObjStream->GetData();
     uint32_t totalsize = pObjStream->GetSize();
-    ScopedFileStream file(
-        IFX_MemoryStream::Create((uint8_t*)pData, (size_t)totalsize, false));
-
+    CFX_RetainPtr<IFX_MemoryStream> file =
+        IFX_MemoryStream::Create((uint8_t*)pData, (size_t)totalsize, false);
     CPDF_SyntaxParser syntax;
-    syntax.InitParser(file.get(), 0);
+    syntax.InitParser(file, 0);
+
     for (int i = GetStreamNCount(pObjStream); i > 0; --i) {
       uint32_t thisnum = syntax.GetDirectNum();
       uint32_t thisoff = syntax.GetDirectNum();
@@ -1420,8 +1413,9 @@
   return dwPermission;
 }
 
-bool CPDF_Parser::IsLinearizedFile(IFX_SeekableReadStream* pFileAccess,
-                                   uint32_t offset) {
+bool CPDF_Parser::IsLinearizedFile(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess,
+    uint32_t offset) {
   m_pSyntax->InitParser(pFileAccess, offset);
   m_pSyntax->RestorePos(m_pSyntax->m_HeaderOffset + 9);
 
@@ -1454,13 +1448,11 @@
 }
 
 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse(
-    IFX_SeekableReadStream* pFileAccess,
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess,
     CPDF_Document* pDocument) {
   ASSERT(!m_bHasParsed);
-
   m_bXRefStream = false;
   m_LastXRefOffset = 0;
-  m_bOwnFileRead = true;
 
   int32_t offset = GetHeaderOffset(pFileAccess);
   if (offset == -1)
@@ -1474,7 +1466,6 @@
   m_pDocument = pDocument;
 
   FX_FILESIZE dwFirstXRefOffset = m_pSyntax->SavePos();
-
   bool bXRefRebuilt = false;
   bool bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, false);
   if (!bLoadV4 && !LoadCrossRefV5(&dwFirstXRefOffset, true)) {
diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h
index 5e2cdea..f8ff7a1 100644
--- a/core/fpdfapi/parser/cpdf_parser.h
+++ b/core/fpdfapi/parser/cpdf_parser.h
@@ -43,8 +43,9 @@
   CPDF_Parser();
   ~CPDF_Parser();
 
-  Error StartParse(IFX_SeekableReadStream* pFile, CPDF_Document* pDocument);
-  Error StartLinearizedParse(IFX_SeekableReadStream* pFile,
+  Error StartParse(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
+                   CPDF_Document* pDocument);
+  Error StartLinearizedParse(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
                              CPDF_Document* pDocument);
 
   void SetPassword(const FX_CHAR* password) { m_Password = password; }
@@ -71,7 +72,7 @@
   bool IsVersionUpdated() const { return m_bVersionUpdated; }
   bool IsObjectFreeOrNull(uint32_t objnum) const;
   CPDF_CryptoHandler* GetCryptoHandler();
-  IFX_SeekableReadStream* GetFileAccess() const;
+  CFX_RetainPtr<IFX_SeekableReadStream> GetFileAccess() const;
 
   FX_FILESIZE GetObjectOffset(uint32_t objnum) const;
   FX_FILESIZE GetObjectSize(uint32_t objnum) const;
@@ -140,7 +141,9 @@
   bool LoadLinearizedAllCrossRefV5(FX_FILESIZE pos);
   Error LoadLinearizedMainXRefTable();
   CPDF_StreamAcc* GetObjectStream(uint32_t number);
-  bool IsLinearizedFile(IFX_SeekableReadStream* pFileAccess, uint32_t offset);
+  bool IsLinearizedFile(
+      const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess,
+      uint32_t offset);
   void SetEncryptDictionary(CPDF_Dictionary* pDict);
   void ShrinkObjectMap(uint32_t size);
   // A simple check whether the cross reference table matches with
@@ -149,7 +152,6 @@
 
   CPDF_Document* m_pDocument;  // not owned
   bool m_bHasParsed;
-  bool m_bOwnFileRead;
   bool m_bXRefStream;
   bool m_bVersionUpdated;
   int m_FileVersion;
diff --git a/core/fpdfapi/parser/cpdf_parser_unittest.cpp b/core/fpdfapi/parser/cpdf_parser_unittest.cpp
index 61496a1..3518f7d 100644
--- a/core/fpdfapi/parser/cpdf_parser_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_parser_unittest.cpp
@@ -7,6 +7,7 @@
 
 #include "core/fpdfapi/parser/cpdf_parser.h"
 #include "core/fpdfapi/parser/cpdf_syntax_parser.h"
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_ext.h"
 #include "core/fxcrt/fx_stream.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -15,11 +16,12 @@
 // Provide a way to read test data from a buffer instead of a file.
 class CFX_TestBufferRead : public IFX_SeekableReadStream {
  public:
-  CFX_TestBufferRead(const unsigned char* buffer_in, size_t buf_size)
-      : buffer_(buffer_in), total_size_(buf_size) {}
-
-  // IFX_ReadStream:
-  void Release() override { delete this; }
+  static CFX_RetainPtr<CFX_TestBufferRead> Create(
+      const unsigned char* buffer_in,
+      size_t buf_size) {
+    return CFX_RetainPtr<CFX_TestBufferRead>(
+        new CFX_TestBufferRead(buffer_in, buf_size));
+  }
 
   // IFX_SeekableReadStream:
   bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
@@ -33,6 +35,9 @@
   FX_FILESIZE GetSize() override { return (FX_FILESIZE)total_size_; };
 
  protected:
+  CFX_TestBufferRead(const unsigned char* buffer_in, size_t buf_size)
+      : buffer_(buffer_in), total_size_(buf_size) {}
+
   const unsigned char* buffer_;
   size_t total_size_;
 };
@@ -45,7 +50,7 @@
 
   // Setup reading from a file and initial states.
   bool InitTestFromFile(const FX_CHAR* path) {
-    IFX_SeekableReadStream* pFileAccess =
+    CFX_RetainPtr<IFX_SeekableReadStream> pFileAccess =
         IFX_SeekableReadStream::CreateFromFilename(path);
     if (!pFileAccess)
       return false;
@@ -57,7 +62,8 @@
 
   // Setup reading from a buffer and initial states.
   bool InitTestFromBuffer(const unsigned char* buffer, size_t len) {
-    CFX_TestBufferRead* buffer_reader = new CFX_TestBufferRead(buffer, len);
+    CFX_RetainPtr<CFX_TestBufferRead> buffer_reader =
+        CFX_TestBufferRead::Create(buffer, len);
 
     // For the test file, the header is set at the beginning.
     m_pSyntax->InitParser(buffer_reader, 0);
diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp
index de69bfa..4f76ec1 100644
--- a/core/fpdfapi/parser/cpdf_stream.cpp
+++ b/core/fpdfapi/parser/cpdf_stream.cpp
@@ -62,8 +62,9 @@
     m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize));
 }
 
-void CPDF_Stream::InitStreamFromFile(IFX_SeekableReadStream* pFile,
-                                     std::unique_ptr<CPDF_Dictionary> pDict) {
+void CPDF_Stream::InitStreamFromFile(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
+    std::unique_ptr<CPDF_Dictionary> pDict) {
   m_pDict = std::move(pDict);
   m_bMemoryBased = false;
   m_pDataBuf.reset();
diff --git a/core/fpdfapi/parser/cpdf_stream.h b/core/fpdfapi/parser/cpdf_stream.h
index fb2b67c..cd4113b 100644
--- a/core/fpdfapi/parser/cpdf_stream.h
+++ b/core/fpdfapi/parser/cpdf_stream.h
@@ -43,7 +43,7 @@
   void InitStream(const uint8_t* pData,
                   uint32_t size,
                   std::unique_ptr<CPDF_Dictionary> pDict);
-  void InitStreamFromFile(IFX_SeekableReadStream* pFile,
+  void InitStreamFromFile(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
                           std::unique_ptr<CPDF_Dictionary> pDict);
 
   bool ReadRawData(FX_FILESIZE start_pos,
@@ -62,7 +62,7 @@
   uint32_t m_dwSize = 0;
   std::unique_ptr<CPDF_Dictionary> m_pDict;
   std::unique_ptr<uint8_t, FxFreeDeleter> m_pDataBuf;
-  IFX_SeekableReadStream* m_pFile = nullptr;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFile;
 };
 
 inline CPDF_Stream* ToStream(CPDF_Object* obj) {
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
index 9beae0b..2a20e43 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp
@@ -756,8 +756,9 @@
   return pStream;
 }
 
-void CPDF_SyntaxParser::InitParser(IFX_SeekableReadStream* pFileAccess,
-                                   uint32_t HeaderOffset) {
+void CPDF_SyntaxParser::InitParser(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess,
+    uint32_t HeaderOffset) {
   FX_Free(m_pFileBuf);
 
   m_pFileBuf = FX_Alloc(uint8_t, m_BufSize);
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.h b/core/fpdfapi/parser/cpdf_syntax_parser.h
index 1e8f736..8dd9103 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser.h
+++ b/core/fpdfapi/parser/cpdf_syntax_parser.h
@@ -26,7 +26,9 @@
   explicit CPDF_SyntaxParser(const CFX_WeakPtr<CFX_ByteStringPool>& pPool);
   ~CPDF_SyntaxParser();
 
-  void InitParser(IFX_SeekableReadStream* pFileAccess, uint32_t HeaderOffset);
+  void InitParser(const CFX_RetainPtr<IFX_SeekableReadStream>& pFileAccess,
+                  uint32_t HeaderOffset);
+
   FX_FILESIZE SavePos() const { return m_Pos; }
   void RestorePos(FX_FILESIZE pos) { m_Pos = pos; }
 
@@ -87,7 +89,7 @@
 
   FX_FILESIZE m_Pos;
   uint32_t m_MetadataObjnum;
-  IFX_SeekableReadStream* m_pFileAccess;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFileAccess;
   FX_FILESIZE m_HeaderOffset;
   FX_FILESIZE m_FileLen;
   uint8_t* m_pFileBuf;
diff --git a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
index f94b431..faaa83d 100644
--- a/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp
@@ -16,10 +16,8 @@
   {
     // Empty string.
     uint8_t data[] = "";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 0, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 0, false), 0);
     EXPECT_EQ("", parser.ReadHexString());
     EXPECT_EQ(0, parser.SavePos());
   }
@@ -27,10 +25,8 @@
   {
     // Blank string.
     uint8_t data[] = "  ";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 2, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 2, false), 0);
     EXPECT_EQ("", parser.ReadHexString());
     EXPECT_EQ(2, parser.SavePos());
   }
@@ -38,10 +34,8 @@
   {
     // Skips unknown characters.
     uint8_t data[] = "z12b";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 4, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0);
     EXPECT_EQ("\x12\xb0", parser.ReadHexString());
     EXPECT_EQ(4, parser.SavePos());
   }
@@ -49,10 +43,8 @@
   {
     // Skips unknown characters.
     uint8_t data[] = "*<&*#$^&@1";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 10, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 10, false), 0);
     EXPECT_EQ("\x10", parser.ReadHexString());
     EXPECT_EQ(10, parser.SavePos());
   }
@@ -60,10 +52,8 @@
   {
     // Skips unknown characters.
     uint8_t data[] = "\x80zab";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 4, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0);
     EXPECT_EQ("\xab", parser.ReadHexString());
     EXPECT_EQ(4, parser.SavePos());
   }
@@ -71,10 +61,8 @@
   {
     // Skips unknown characters.
     uint8_t data[] = "\xffzab";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 4, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0);
     EXPECT_EQ("\xab", parser.ReadHexString());
     EXPECT_EQ(4, parser.SavePos());
   }
@@ -82,10 +70,8 @@
   {
     // Regular conversion.
     uint8_t data[] = "1A2b>abcd";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 9, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 9, false), 0);
     EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
     EXPECT_EQ(5, parser.SavePos());
   }
@@ -93,10 +79,8 @@
   {
     // Position out of bounds.
     uint8_t data[] = "12ab>";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 5, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 5, false), 0);
     parser.RestorePos(5);
     EXPECT_EQ("", parser.ReadHexString());
 
@@ -117,10 +101,8 @@
   {
     // Missing ending >.
     uint8_t data[] = "1A2b";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 4, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 4, false), 0);
     EXPECT_EQ("\x1a\x2b", parser.ReadHexString());
     EXPECT_EQ(4, parser.SavePos());
   }
@@ -128,10 +110,8 @@
   {
     // Missing ending >.
     uint8_t data[] = "12abz";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 5, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 5, false), 0);
     EXPECT_EQ("\x12\xab", parser.ReadHexString());
     EXPECT_EQ(5, parser.SavePos());
   }
@@ -139,10 +119,8 @@
   {
     // Uneven number of bytes.
     uint8_t data[] = "1A2>asdf";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 8, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 8, false), 0);
     EXPECT_EQ("\x1a\x20", parser.ReadHexString());
     EXPECT_EQ(4, parser.SavePos());
   }
@@ -150,10 +128,8 @@
   {
     // Uneven number of bytes.
     uint8_t data[] = "1A2zasdf";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 8, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 8, false), 0);
     EXPECT_EQ("\x1a\x2a\xdf", parser.ReadHexString());
     EXPECT_EQ(8, parser.SavePos());
   }
@@ -161,10 +137,8 @@
   {
     // Just ending character.
     uint8_t data[] = ">";
-    ScopedFileStream stream(IFX_MemoryStream::Create(data, 1, false));
-
     CPDF_SyntaxParser parser;
-    parser.InitParser(stream.get(), 0);
+    parser.InitParser(IFX_MemoryStream::Create(data, 1, false), 0);
     EXPECT_EQ("", parser.ReadHexString());
     EXPECT_EQ(1, parser.SavePos());
   }
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp
index ef37d8f..9583ea7 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_utility.cpp
@@ -69,7 +69,7 @@
     'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
     'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W'};
 
-int32_t GetHeaderOffset(IFX_SeekableReadStream* pFile) {
+int32_t GetHeaderOffset(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile) {
   const size_t kBufSize = 4;
   uint8_t buf[kBufSize];
   for (int32_t offset = 0; offset <= 1024; ++offset) {
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.h b/core/fpdfapi/parser/fpdf_parser_utility.h
index 589171f..29f54ee 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility.h
+++ b/core/fpdfapi/parser/fpdf_parser_utility.h
@@ -7,6 +7,7 @@
 #ifndef CORE_FPDFAPI_PARSER_FPDF_PARSER_UTILITY_H_
 #define CORE_FPDFAPI_PARSER_FPDF_PARSER_UTILITY_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
 
@@ -33,7 +34,7 @@
   return c == '\r' || c == '\n';
 }
 
-int32_t GetHeaderOffset(IFX_SeekableReadStream* pFile);
+int32_t GetHeaderOffset(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile);
 int32_t GetDirectInteger(CPDF_Dictionary* pDict, const CFX_ByteString& key);
 
 #endif  // CORE_FPDFAPI_PARSER_FPDF_PARSER_UTILITY_H_
diff --git a/core/fxcodec/codec/ccodec_progressivedecoder.h b/core/fxcodec/codec/ccodec_progressivedecoder.h
index de7542e..614146f 100644
--- a/core/fxcodec/codec/ccodec_progressivedecoder.h
+++ b/core/fxcodec/codec/ccodec_progressivedecoder.h
@@ -10,6 +10,7 @@
 #include <vector>
 
 #include "core/fxcodec/fx_codec_def.h"
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxge/fx_dib.h"
 
@@ -45,10 +46,11 @@
   explicit CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr);
   ~CCodec_ProgressiveDecoder();
 
-  FXCODEC_STATUS LoadImageInfo(IFX_SeekableReadStream* pFile,
-                               FXCODEC_IMAGE_TYPE imageType,
-                               CFX_DIBAttribute* pAttribute,
-                               bool bSkipImageTypeCheck);
+  FXCODEC_STATUS LoadImageInfo(
+      const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
+      FXCODEC_IMAGE_TYPE imageType,
+      CFX_DIBAttribute* pAttribute,
+      bool bSkipImageTypeCheck);
 
   FXCODEC_IMAGE_TYPE GetType() const { return m_imagType; }
   int32_t GetWidth() const { return m_SrcWidth; }
@@ -125,7 +127,7 @@
     std::vector<uint8_t> m_pWeightTables;
   };
 
-  IFX_SeekableReadStream* m_pFile;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFile;
   CCodec_ModuleMgr* m_pCodecMgr;
   FXJPEG_Context* m_pJpegContext;
   FXPNG_Context* m_pPngContext;
diff --git a/core/fxcodec/codec/ccodec_tiffmodule.h b/core/fxcodec/codec/ccodec_tiffmodule.h
index 37d4082..dd2cbd7 100644
--- a/core/fxcodec/codec/ccodec_tiffmodule.h
+++ b/core/fxcodec/codec/ccodec_tiffmodule.h
@@ -7,6 +7,7 @@
 #ifndef CORE_FXCODEC_CODEC_CCODEC_TIFFMODULE_H_
 #define CORE_FXCODEC_CODEC_CCODEC_TIFFMODULE_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_system.h"
 
 class CCodec_TiffContext;
@@ -18,7 +19,8 @@
  public:
   ~CCodec_TiffModule() {}
 
-  CCodec_TiffContext* CreateDecoder(IFX_SeekableReadStream* file_ptr);
+  CCodec_TiffContext* CreateDecoder(
+      const CFX_RetainPtr<IFX_SeekableReadStream>& file_ptr);
 
   bool LoadFrameInfo(CCodec_TiffContext* ctx,
                      int32_t frame,
diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp
index 8d29a7b..386b66a 100644
--- a/core/fxcodec/codec/fx_codec_progress.cpp
+++ b/core/fxcodec/codec/fx_codec_progress.cpp
@@ -1295,7 +1295,7 @@
 }
 
 FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo(
-    IFX_SeekableReadStream* pFile,
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
     FXCODEC_IMAGE_TYPE imageType,
     CFX_DIBAttribute* pAttribute,
     bool bSkipImageTypeCheck) {
diff --git a/core/fxcodec/codec/fx_codec_tiff.cpp b/core/fxcodec/codec/fx_codec_tiff.cpp
index 8046f1c..be9c7d4 100644
--- a/core/fxcodec/codec/fx_codec_tiff.cpp
+++ b/core/fxcodec/codec/fx_codec_tiff.cpp
@@ -8,8 +8,10 @@
 
 #include "core/fxcodec/codec/codec_int.h"
 #include "core/fxcodec/fx_codec.h"
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxge/fx_dib.h"
+#include "third_party/base/ptr_util.h"
 
 extern "C" {
 #include "third_party/libtiff/tiffiop.h"
@@ -20,7 +22,7 @@
   CCodec_TiffContext();
   ~CCodec_TiffContext();
 
-  bool InitDecoder(IFX_SeekableReadStream* file_ptr);
+  bool InitDecoder(const CFX_RetainPtr<IFX_SeekableReadStream>& file_ptr);
   bool LoadFrameInfo(int32_t frame,
                      int32_t* width,
                      int32_t* height,
@@ -29,7 +31,7 @@
                      CFX_DIBAttribute* pAttribute);
   bool Decode(CFX_DIBitmap* pDIBitmap);
 
-  IFX_SeekableReadStream* io_in() const { return m_io_in; }
+  CFX_RetainPtr<IFX_SeekableReadStream> io_in() const { return m_io_in; }
   uint32_t offset() const { return m_offset; }
   void set_offset(uint32_t offset) { m_offset = offset; }
 
@@ -52,7 +54,7 @@
                       uint16_t bps,
                       uint16_t spp);
 
-  IFX_SeekableReadStream* m_io_in;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_io_in;
   uint32_t m_offset;
   TIFF* m_tif_ctx;
 };
@@ -215,7 +217,8 @@
     TIFFClose(m_tif_ctx);
 }
 
-bool CCodec_TiffContext::InitDecoder(IFX_SeekableReadStream* file_ptr) {
+bool CCodec_TiffContext::InitDecoder(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& file_ptr) {
   m_io_in = file_ptr;
   m_tif_ctx = tiff_open(this, "r");
   return !!m_tif_ctx;
@@ -462,13 +465,12 @@
 }
 
 CCodec_TiffContext* CCodec_TiffModule::CreateDecoder(
-    IFX_SeekableReadStream* file_ptr) {
-  CCodec_TiffContext* pDecoder = new CCodec_TiffContext;
-  if (!pDecoder->InitDecoder(file_ptr)) {
-    delete pDecoder;
+    const CFX_RetainPtr<IFX_SeekableReadStream>& file_ptr) {
+  auto pDecoder = pdfium::MakeUnique<CCodec_TiffContext>();
+  if (!pDecoder->InitDecoder(file_ptr))
     return nullptr;
-  }
-  return pDecoder;
+
+  return pDecoder.release();
 }
 
 bool CCodec_TiffModule::LoadFrameInfo(CCodec_TiffContext* ctx,
diff --git a/core/fxcrt/fx_basic.h b/core/fxcrt/fx_basic.h
index 9034398..2f581b0 100644
--- a/core/fxcrt/fx_basic.h
+++ b/core/fxcrt/fx_basic.h
@@ -10,6 +10,7 @@
 #include <algorithm>
 #include <memory>
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_memory.h"
 #include "core/fxcrt/fx_stream.h"
 #include "core/fxcrt/fx_string.h"
@@ -119,16 +120,14 @@
   int32_t AppendByte(uint8_t byte);
   int32_t AppendDWord(uint32_t i);
   int32_t AppendString(const CFX_ByteStringC& lpsz);
-
-  // |pFile| must outlive the CFX_FileBufferArchive.
-  void AttachFile(IFX_WriteStream* pFile);
+  void AttachFile(const CFX_RetainPtr<IFX_WriteStream>& pFile);
 
  private:
   static const size_t kBufSize = 32768;
 
   size_t m_Length;
   std::unique_ptr<uint8_t, FxFreeDeleter> m_pBuffer;
-  IFX_WriteStream* m_pFile;
+  CFX_RetainPtr<IFX_WriteStream> m_pFile;
 };
 
 class CFX_CharMap {
diff --git a/core/fxcrt/fx_basic_buffer.cpp b/core/fxcrt/fx_basic_buffer.cpp
index 8466e88..e6d0552 100644
--- a/core/fxcrt/fx_basic_buffer.cpp
+++ b/core/fxcrt/fx_basic_buffer.cpp
@@ -234,7 +234,7 @@
 void CFX_FileBufferArchive::Clear() {
   m_Length = 0;
   m_pBuffer.reset();
-  m_pFile = nullptr;
+  m_pFile.Reset();
 }
 
 bool CFX_FileBufferArchive::Flush() {
@@ -285,7 +285,8 @@
   return AppendBlock(lpsz.raw_str(), lpsz.GetLength());
 }
 
-void CFX_FileBufferArchive::AttachFile(IFX_WriteStream* pFile) {
+void CFX_FileBufferArchive::AttachFile(
+    const CFX_RetainPtr<IFX_WriteStream>& pFile) {
   ASSERT(pFile);
   m_pFile = pFile;
 }
diff --git a/core/fxcrt/fx_ext.h b/core/fxcrt/fx_ext.h
index 7d8529e..737ea84 100644
--- a/core/fxcrt/fx_ext.h
+++ b/core/fxcrt/fx_ext.h
@@ -15,12 +15,6 @@
 
 #define FX_INVALID_OFFSET static_cast<uint32_t>(-1)
 
-// TODO(thestig) Using unique_ptr with ReleaseDeleter is still not ideal.
-// Come up or wait for something better. This appears in this file rather
-// than fx_stream.h due to include ordering restrictions.
-using ScopedFileStream =
-    std::unique_ptr<IFX_SeekableStream, ReleaseDeleter<IFX_SeekableStream>>;
-
 FX_FLOAT FXSYS_tan(FX_FLOAT a);
 FX_FLOAT FXSYS_logb(FX_FLOAT b, FX_FLOAT x);
 FX_FLOAT FXSYS_strtof(const FX_CHAR* pcsStr,
diff --git a/core/fxcrt/fx_extension.cpp b/core/fxcrt/fx_extension.cpp
index 1bb9a3a..cbbb86f 100644
--- a/core/fxcrt/fx_extension.cpp
+++ b/core/fxcrt/fx_extension.cpp
@@ -32,7 +32,7 @@
   void Release() override;
   IFX_FileAccess* Retain() override;
   void GetPath(CFX_WideString& wsPath) override;
-  IFX_SeekableStream* CreateFileStream(uint32_t dwModes) override;
+  CFX_RetainPtr<IFX_SeekableStream> CreateFileStream(uint32_t dwModes) override;
 
   bool Init(const CFX_WideStringC& wsPath);
 
@@ -59,7 +59,8 @@
   wsPath = m_path;
 }
 
-IFX_SeekableStream* CFX_CRTFileAccess::CreateFileStream(uint32_t dwModes) {
+CFX_RetainPtr<IFX_SeekableStream> CFX_CRTFileAccess::CreateFileStream(
+    uint32_t dwModes) {
   return IFX_SeekableStream::CreateFromFilename(m_path.c_str(), dwModes);
 }
 
@@ -77,8 +78,6 @@
   ~CFX_CRTFileStream() override;
 
   // IFX_SeekableStream:
-  IFX_SeekableStream* Retain() override;
-  void Release() override;
   FX_FILESIZE GetSize() override;
   bool IsEOF() override;
   FX_FILESIZE GetPosition() override;
@@ -89,23 +88,12 @@
 
  private:
   std::unique_ptr<IFXCRT_FileAccess> m_pFile;
-  uint32_t m_dwCount;
 };
 
 CFX_CRTFileStream::CFX_CRTFileStream(std::unique_ptr<IFXCRT_FileAccess> pFA)
-    : m_pFile(std::move(pFA)), m_dwCount(1) {}
+    : m_pFile(std::move(pFA)) {}
 
 CFX_CRTFileStream::~CFX_CRTFileStream() {}
-IFX_SeekableStream* CFX_CRTFileStream::Retain() {
-  m_dwCount++;
-  return this;
-}
-
-void CFX_CRTFileStream::Release() {
-  uint32_t nCount = --m_dwCount;
-  if (!nCount)
-    delete this;
-}
 
 FX_FILESIZE CFX_CRTFileStream::GetSize() {
   return m_pFile->GetSize();
@@ -150,8 +138,6 @@
   ~CFX_MemoryStream() override;
 
   // IFX_MemoryStream
-  IFX_SeekableStream* Retain() override;
-  void Release() override;
   FX_FILESIZE GetSize() override;
   bool IsEOF() override;
   FX_FILESIZE GetPosition() override;
@@ -168,19 +154,18 @@
   void DetachBuffer() override;
 
  private:
+  bool ExpandBlocks(size_t size);
+
   CFX_ArrayTemplate<uint8_t*> m_Blocks;
-  uint32_t m_dwCount;
   size_t m_nTotalSize;
   size_t m_nCurSize;
   size_t m_nCurPos;
   size_t m_nGrowSize;
   uint32_t m_dwFlags;
-  bool ExpandBlocks(size_t size);
 };
 
 CFX_MemoryStream::CFX_MemoryStream(bool bConsecutive)
-    : m_dwCount(1),
-      m_nTotalSize(0),
+    : m_nTotalSize(0),
       m_nCurSize(0),
       m_nCurPos(0),
       m_nGrowSize(FX_MEMSTREAM_BlockSize) {
@@ -191,8 +176,7 @@
 CFX_MemoryStream::CFX_MemoryStream(uint8_t* pBuffer,
                                    size_t nSize,
                                    bool bTakeOver)
-    : m_dwCount(1),
-      m_nTotalSize(nSize),
+    : m_nTotalSize(nSize),
       m_nCurSize(nSize),
       m_nCurPos(0),
       m_nGrowSize(FX_MEMSTREAM_BlockSize) {
@@ -210,19 +194,6 @@
   m_Blocks.RemoveAll();
 }
 
-IFX_SeekableStream* CFX_MemoryStream::Retain() {
-  m_dwCount++;
-  return this;
-}
-
-void CFX_MemoryStream::Release() {
-  uint32_t nCount = --m_dwCount;
-  if (nCount) {
-    return;
-  }
-  delete this;
-}
-
 FX_FILESIZE CFX_MemoryStream::GetSize() {
   return (FX_FILESIZE)m_nCurSize;
 }
@@ -419,41 +390,44 @@
 #endif  // PDF_ENABLE_XFA
 
 // static
-IFX_SeekableStream* IFX_SeekableStream::CreateFromFilename(
+CFX_RetainPtr<IFX_SeekableStream> IFX_SeekableStream::CreateFromFilename(
     const FX_CHAR* filename,
     uint32_t dwModes) {
   std::unique_ptr<IFXCRT_FileAccess> pFA(IFXCRT_FileAccess::Create());
   if (!pFA->Open(filename, dwModes))
     return nullptr;
-  return new CFX_CRTFileStream(std::move(pFA));
+  return CFX_RetainPtr<IFX_SeekableStream>(
+      new CFX_CRTFileStream(std::move(pFA)));
 }
 
 // static
-IFX_SeekableStream* IFX_SeekableStream::CreateFromFilename(
+CFX_RetainPtr<IFX_SeekableStream> IFX_SeekableStream::CreateFromFilename(
     const FX_WCHAR* filename,
     uint32_t dwModes) {
   std::unique_ptr<IFXCRT_FileAccess> pFA(IFXCRT_FileAccess::Create());
   if (!pFA->Open(filename, dwModes))
     return nullptr;
-  return new CFX_CRTFileStream(std::move(pFA));
+  return CFX_RetainPtr<IFX_SeekableStream>(
+      new CFX_CRTFileStream(std::move(pFA)));
 }
 
 // static
-IFX_SeekableReadStream* IFX_SeekableReadStream::CreateFromFilename(
-    const FX_CHAR* filename) {
+CFX_RetainPtr<IFX_SeekableReadStream>
+IFX_SeekableReadStream::CreateFromFilename(const FX_CHAR* filename) {
   return IFX_SeekableStream::CreateFromFilename(filename, FX_FILEMODE_ReadOnly);
 }
 
 // static
-IFX_MemoryStream* IFX_MemoryStream::Create(uint8_t* pBuffer,
-                                           size_t dwSize,
-                                           bool bTakeOver) {
-  return new CFX_MemoryStream(pBuffer, dwSize, bTakeOver);
+CFX_RetainPtr<IFX_MemoryStream> IFX_MemoryStream::Create(uint8_t* pBuffer,
+                                                         size_t dwSize,
+                                                         bool bTakeOver) {
+  return CFX_RetainPtr<IFX_MemoryStream>(
+      new CFX_MemoryStream(pBuffer, dwSize, bTakeOver));
 }
 
 // static
-IFX_MemoryStream* IFX_MemoryStream::Create(bool bConsecutive) {
-  return new CFX_MemoryStream(bConsecutive);
+CFX_RetainPtr<IFX_MemoryStream> IFX_MemoryStream::Create(bool bConsecutive) {
+  return CFX_RetainPtr<IFX_MemoryStream>(new CFX_MemoryStream(bConsecutive));
 }
 
 FX_FLOAT FXSYS_tan(FX_FLOAT a) {
diff --git a/core/fxcrt/fx_stream.h b/core/fxcrt/fx_stream.h
index 711b664..b998761 100644
--- a/core/fxcrt/fx_stream.h
+++ b/core/fxcrt/fx_stream.h
@@ -7,6 +7,7 @@
 #ifndef CORE_FXCRT_FX_STREAM_H_
 #define CORE_FXCRT_FX_STREAM_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
 
@@ -48,18 +49,13 @@
 #define FX_FILEMODE_ReadOnly 1
 #define FX_FILEMODE_Truncate 2
 
-class IFX_WriteStream {
+class IFX_WriteStream : virtual public CFX_Retainable {
  public:
-  virtual ~IFX_WriteStream() {}
-  virtual void Release() = 0;
   virtual bool WriteBlock(const void* pData, size_t size) = 0;
 };
 
-class IFX_ReadStream {
+class IFX_ReadStream : virtual public CFX_Retainable {
  public:
-  virtual ~IFX_ReadStream() {}
-
-  virtual void Release() = 0;
   virtual bool IsEOF() = 0;
   virtual FX_FILESIZE GetPosition() = 0;
   virtual size_t ReadBlock(void* buffer, size_t size) = 0;
@@ -69,6 +65,7 @@
  public:
   // IFX_WriteStream:
   bool WriteBlock(const void* pData, size_t size) override;
+
   virtual FX_FILESIZE GetSize() = 0;
   virtual bool Flush() = 0;
   virtual bool WriteBlock(const void* pData,
@@ -78,10 +75,10 @@
 
 class IFX_SeekableReadStream : public IFX_ReadStream {
  public:
-  static IFX_SeekableReadStream* CreateFromFilename(const FX_CHAR* filename);
+  static CFX_RetainPtr<IFX_SeekableReadStream> CreateFromFilename(
+      const FX_CHAR* filename);
 
   // IFX_ReadStream:
-  void Release() override = 0;
   bool IsEOF() override;
   FX_FILESIZE GetPosition() override;
   size_t ReadBlock(void* buffer, size_t size) override;
@@ -93,15 +90,15 @@
 class IFX_SeekableStream : public IFX_SeekableReadStream,
                            public IFX_SeekableWriteStream {
  public:
-  static IFX_SeekableStream* CreateFromFilename(const FX_CHAR* filename,
-                                                uint32_t dwModes);
-  static IFX_SeekableStream* CreateFromFilename(const FX_WCHAR* filename,
-                                                uint32_t dwModes);
+  static CFX_RetainPtr<IFX_SeekableStream> CreateFromFilename(
+      const FX_CHAR* filename,
+      uint32_t dwModes);
 
-  virtual IFX_SeekableStream* Retain() = 0;
+  static CFX_RetainPtr<IFX_SeekableStream> CreateFromFilename(
+      const FX_WCHAR* filename,
+      uint32_t dwModes);
 
   // IFX_SeekableReadStream:
-  void Release() override = 0;
   bool IsEOF() override = 0;
   FX_FILESIZE GetPosition() override = 0;
   size_t ReadBlock(void* buffer, size_t size) override = 0;
@@ -118,10 +115,10 @@
 
 class IFX_MemoryStream : public IFX_SeekableStream {
  public:
-  static IFX_MemoryStream* Create(uint8_t* pBuffer,
-                                  size_t nSize,
-                                  bool bTakeOver = false);
-  static IFX_MemoryStream* Create(bool bConsecutive = false);
+  static CFX_RetainPtr<IFX_MemoryStream> Create(uint8_t* pBuffer,
+                                                size_t nSize,
+                                                bool bTakeOver = false);
+  static CFX_RetainPtr<IFX_MemoryStream> Create(bool bConsecutive = false);
 
   virtual bool IsConsecutive() const = 0;
   virtual void EstimateSize(size_t nInitSize, size_t nGrowSize) = 0;
@@ -135,7 +132,6 @@
 class IFX_BufferedReadStream : public IFX_ReadStream {
  public:
   // IFX_ReadStream:
-  void Release() override = 0;
   bool IsEOF() override = 0;
   FX_FILESIZE GetPosition() override = 0;
   size_t ReadBlock(void* buffer, size_t size) override = 0;
@@ -155,7 +151,8 @@
   virtual void Release() = 0;
   virtual IFX_FileAccess* Retain() = 0;
   virtual void GetPath(CFX_WideString& wsPath) = 0;
-  virtual IFX_SeekableStream* CreateFileStream(uint32_t dwModes) = 0;
+  virtual CFX_RetainPtr<IFX_SeekableStream> CreateFileStream(
+      uint32_t dwModes) = 0;
 };
 #endif  // PDF_ENABLE_XFA
 
diff --git a/core/fxcrt/fx_xml.h b/core/fxcrt/fx_xml.h
index 03337d0..7f42a7f 100644
--- a/core/fxcrt/fx_xml.h
+++ b/core/fxcrt/fx_xml.h
@@ -58,12 +58,13 @@
                              size_t size,
                              bool bSaveSpaceChars = false,
                              FX_FILESIZE* pParsedSize = nullptr);
-  static CXML_Element* Parse(IFX_SeekableReadStream* pFile,
+  static CXML_Element* Parse(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
                              bool bSaveSpaceChars = false,
                              FX_FILESIZE* pParsedSize = nullptr);
-  static CXML_Element* Parse(IFX_BufferedReadStream* pBuffer,
-                             bool bSaveSpaceChars = false,
-                             FX_FILESIZE* pParsedSize = nullptr);
+  static CXML_Element* Parse(
+      const CFX_RetainPtr<IFX_BufferedReadStream>& pBuffer,
+      bool bSaveSpaceChars = false,
+      FX_FILESIZE* pParsedSize = nullptr);
 
   CXML_Element(const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagName);
   explicit CXML_Element(const CFX_ByteStringC& qTagName);
diff --git a/core/fxcrt/fx_xml_parser.cpp b/core/fxcrt/fx_xml_parser.cpp
index 803ba59..ab30926 100644
--- a/core/fxcrt/fx_xml_parser.cpp
+++ b/core/fxcrt/fx_xml_parser.cpp
@@ -74,7 +74,6 @@
   ~CXML_DataBufAcc() override;
 
   // IFX_BufferedReadStream
-  void Release() override;
   bool IsEOF() override;
   FX_FILESIZE GetPosition() override;
   size_t ReadBlock(void* buffer, size_t size) override;
@@ -94,10 +93,6 @@
 
 CXML_DataBufAcc::~CXML_DataBufAcc() {}
 
-void CXML_DataBufAcc::Release() {
-  delete this;
-}
-
 bool CXML_DataBufAcc::IsEOF() {
   return m_dwCurPos >= m_dwSize;
 }
@@ -135,11 +130,11 @@
 
 class CXML_DataStmAcc : public IFX_BufferedReadStream {
  public:
-  explicit CXML_DataStmAcc(IFX_SeekableReadStream* pFileRead);
+  explicit CXML_DataStmAcc(
+      const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead);
   ~CXML_DataStmAcc() override;
 
   // IFX_BufferedReadStream
-  void Release() override;
   bool IsEOF() override;
   FX_FILESIZE GetPosition() override;
   size_t ReadBlock(void* buffer, size_t size) override;
@@ -149,13 +144,14 @@
   FX_FILESIZE GetBlockOffset() override;
 
  private:
-  IFX_SeekableReadStream* m_pFileRead;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFileRead;
   uint8_t* m_pBuffer;
   FX_FILESIZE m_nStart;
   size_t m_dwSize;
 };
 
-CXML_DataStmAcc::CXML_DataStmAcc(IFX_SeekableReadStream* pFileRead)
+CXML_DataStmAcc::CXML_DataStmAcc(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead)
     : m_pFileRead(pFileRead), m_pBuffer(nullptr), m_nStart(0), m_dwSize(0) {
   ASSERT(m_pFileRead);
 }
@@ -164,10 +160,6 @@
   FX_Free(m_pBuffer);
 }
 
-void CXML_DataStmAcc::Release() {
-  delete this;
-}
-
 bool CXML_DataStmAcc::IsEOF() {
   return m_nStart + (FX_FILESIZE)m_dwSize >= m_pFileRead->GetSize();
 }
@@ -213,41 +205,34 @@
 }  // namespace
 
 CXML_Parser::CXML_Parser()
-    : m_pDataAcc(nullptr),
-      m_bOwnedStream(false),
-      m_nOffset(0),
+    : m_nOffset(0),
       m_bSaveSpaceChars(false),
       m_pBuffer(nullptr),
       m_dwBufferSize(0),
       m_nBufferOffset(0),
       m_dwIndex(0) {}
 
-CXML_Parser::~CXML_Parser() {
-  if (m_bOwnedStream) {
-    m_pDataAcc->Release();
-  }
-}
+CXML_Parser::~CXML_Parser() {}
 
 bool CXML_Parser::Init(uint8_t* pBuffer, size_t size) {
-  m_pDataAcc = new CXML_DataBufAcc(pBuffer, size);
-  return Init(true);
+  m_pDataAcc.Reset(new CXML_DataBufAcc(pBuffer, size));
+  return Init();
 }
 
-bool CXML_Parser::Init(IFX_SeekableReadStream* pFileRead) {
-  m_pDataAcc = new CXML_DataStmAcc(pFileRead);
-  return Init(true);
+bool CXML_Parser::Init(const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead) {
+  m_pDataAcc.Reset(new CXML_DataStmAcc(pFileRead));
+  return Init();
 }
 
-bool CXML_Parser::Init(IFX_BufferedReadStream* pBuffer) {
+bool CXML_Parser::Init(const CFX_RetainPtr<IFX_BufferedReadStream>& pBuffer) {
   if (!pBuffer)
     return false;
 
   m_pDataAcc = pBuffer;
-  return Init(false);
+  return Init();
 }
 
-bool CXML_Parser::Init(bool bOwndedStream) {
-  m_bOwnedStream = bOwndedStream;
+bool CXML_Parser::Init() {
   m_nOffset = 0;
   return ReadNextBlock();
 }
@@ -701,24 +686,29 @@
   }
   return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize);
 }
-CXML_Element* CXML_Element::Parse(IFX_SeekableReadStream* pFile,
-                                  bool bSaveSpaceChars,
-                                  FX_FILESIZE* pParsedSize) {
+
+CXML_Element* CXML_Element::Parse(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
+    bool bSaveSpaceChars,
+    FX_FILESIZE* pParsedSize) {
   CXML_Parser parser;
-  if (!parser.Init(pFile)) {
+  if (!parser.Init(pFile))
     return nullptr;
-  }
+
   return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize);
 }
-CXML_Element* CXML_Element::Parse(IFX_BufferedReadStream* pBuffer,
-                                  bool bSaveSpaceChars,
-                                  FX_FILESIZE* pParsedSize) {
+
+CXML_Element* CXML_Element::Parse(
+    const CFX_RetainPtr<IFX_BufferedReadStream>& pBuffer,
+    bool bSaveSpaceChars,
+    FX_FILESIZE* pParsedSize) {
   CXML_Parser parser;
-  if (!parser.Init(pBuffer)) {
+  if (!parser.Init(pBuffer))
     return nullptr;
-  }
+
   return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize);
 }
+
 CXML_Element::CXML_Element() : m_QSpaceName(), m_TagName(), m_AttrMap() {}
 CXML_Element::CXML_Element(const CFX_ByteStringC& qSpace,
                            const CFX_ByteStringC& tagName)
diff --git a/core/fxcrt/xml_int.h b/core/fxcrt/xml_int.h
index f5beaef..e617a77 100644
--- a/core/fxcrt/xml_int.h
+++ b/core/fxcrt/xml_int.h
@@ -20,9 +20,9 @@
   ~CXML_Parser();
 
   bool Init(uint8_t* pBuffer, size_t size);
-  bool Init(IFX_SeekableReadStream* pFileRead);
-  bool Init(IFX_BufferedReadStream* pBuffer);
-  bool Init(bool bOwndedStream);
+  bool Init(const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead);
+  bool Init(const CFX_RetainPtr<IFX_BufferedReadStream>& pBuffer);
+  bool Init();
   bool ReadNextBlock();
   bool IsEOF();
   bool HaveAvailData();
@@ -41,8 +41,7 @@
                             CXML_Element* pElement);
   void InsertCDATASegment(CFX_UTF8Decoder& decoder, CXML_Element* pElement);
 
-  IFX_BufferedReadStream* m_pDataAcc;
-  bool m_bOwnedStream;
+  CFX_RetainPtr<IFX_BufferedReadStream> m_pDataAcc;
   FX_FILESIZE m_nOffset;
   bool m_bSaveSpaceChars;
   const uint8_t* m_pBuffer;
diff --git a/core/fxge/android/cfpf_skiafilefont.h b/core/fxge/android/cfpf_skiafilefont.h
index b6657bf..2c9fc90 100644
--- a/core/fxge/android/cfpf_skiafilefont.h
+++ b/core/fxge/android/cfpf_skiafilefont.h
@@ -7,6 +7,7 @@
 #ifndef CORE_FXGE_ANDROID_CFPF_SKIAFILEFONT_H_
 #define CORE_FXGE_ANDROID_CFPF_SKIAFILEFONT_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxge/android/cfpf_skiafontdescriptor.h"
 
 class IFX_SeekableReadStream;
@@ -15,11 +16,12 @@
 
 class CFPF_SkiaFileFont : public CFPF_SkiaFontDescriptor {
  public:
-  CFPF_SkiaFileFont() : m_pFile(nullptr) {}
+  CFPF_SkiaFileFont() {}
 
   // CFPF_SkiaFontDescriptor
   int32_t GetType() const override { return FPF_SKIAFONTTYPE_File; }
-  IFX_SeekableReadStream* m_pFile;
+
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFile;
 };
 
 #endif  // CORE_FXGE_ANDROID_CFPF_SKIAFILEFONT_H_
diff --git a/core/fxge/android/cfpf_skiafontmgr.cpp b/core/fxge/android/cfpf_skiafontmgr.cpp
index 6463e8b..e3511be 100644
--- a/core/fxge/android/cfpf_skiafontmgr.cpp
+++ b/core/fxge/android/cfpf_skiafontmgr.cpp
@@ -28,14 +28,17 @@
                                          unsigned long offset,
                                          unsigned char* buffer,
                                          unsigned long count) {
+  if (count == 0)
+    return 0;
+
   IFX_SeekableReadStream* pFileRead =
-      (IFX_SeekableReadStream*)stream->descriptor.pointer;
+      static_cast<IFX_SeekableReadStream*>(stream->descriptor.pointer);
   if (!pFileRead)
     return 0;
-  if (count > 0) {
-    if (!pFileRead->ReadBlock(buffer, (FX_FILESIZE)offset, (size_t)count))
-      return 0;
-  }
+
+  if (!pFileRead->ReadBlock(buffer, (FX_FILESIZE)offset, (size_t)count))
+    return 0;
+
   return count;
 }
 
@@ -358,8 +361,9 @@
   return nullptr;
 }
 
-FXFT_Face CFPF_SkiaFontMgr::GetFontFace(IFX_SeekableReadStream* pFileRead,
-                                        int32_t iFaceIndex) {
+FXFT_Face CFPF_SkiaFontMgr::GetFontFace(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
+    int32_t iFaceIndex) {
   if (!pFileRead)
     return nullptr;
   if (pFileRead->GetSize() == 0)
@@ -369,7 +373,7 @@
   FXFT_StreamRec streamRec;
   FXSYS_memset(&streamRec, 0, sizeof(FXFT_StreamRec));
   streamRec.size = pFileRead->GetSize();
-  streamRec.descriptor.pointer = pFileRead;
+  streamRec.descriptor.pointer = static_cast<void*>(pFileRead.Get());
   streamRec.read = FPF_SkiaStream_Read;
   streamRec.close = FPF_SkiaStream_Close;
   FXFT_Open_Args args;
diff --git a/core/fxge/android/cfpf_skiafontmgr.h b/core/fxge/android/cfpf_skiafontmgr.h
index 7d89c6e..4d0ea0e 100644
--- a/core/fxge/android/cfpf_skiafontmgr.h
+++ b/core/fxge/android/cfpf_skiafontmgr.h
@@ -31,7 +31,7 @@
                             uint32_t dwMatch = 0);
 
   bool InitFTLibrary();
-  FXFT_Face GetFontFace(IFX_SeekableReadStream* pFileRead,
+  FXFT_Face GetFontFace(const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
                         int32_t iFaceIndex = 0);
   FXFT_Face GetFontFace(const CFX_ByteStringC& bsFile, int32_t iFaceIndex = 0);
   FXFT_Face GetFontFace(const uint8_t* pBuffer,
diff --git a/core/fxge/fx_font.h b/core/fxge/fx_font.h
index 6bb4bde..96396af 100644
--- a/core/fxge/fx_font.h
+++ b/core/fxge/fx_font.h
@@ -111,7 +111,7 @@
   CFX_SubstFont* GetSubstFont() const { return m_pSubstFont.get(); }
 
 #ifdef PDF_ENABLE_XFA
-  bool LoadFile(IFX_SeekableReadStream* pFile,
+  bool LoadFile(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
                 int nFaceIndex = 0,
                 int* pFaceCount = nullptr);
 
diff --git a/core/fxge/ge/cfx_font.cpp b/core/fxge/ge/cfx_font.cpp
index b857090..7be300f 100644
--- a/core/fxge/ge/cfx_font.cpp
+++ b/core/fxge/ge/cfx_font.cpp
@@ -47,21 +47,27 @@
 
   IFX_SeekableReadStream* pFile =
       static_cast<IFX_SeekableReadStream*>(stream->descriptor.pointer);
-  return pFile->ReadBlock(buffer, offset, count) ? count : 0;
+  if (!pFile)
+    return 0;
+
+  if (!pFile->ReadBlock(buffer, offset, count))
+    return 0;
+
+  return count;
 }
 
 void FTStreamClose(FXFT_Stream stream) {}
 
 bool LoadFileImp(FXFT_Library library,
                  FXFT_Face* Face,
-                 IFX_SeekableReadStream* pFile,
+                 const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
                  int32_t faceIndex,
                  std::unique_ptr<FXFT_StreamRec>* stream) {
-  std::unique_ptr<FXFT_StreamRec> stream1(new FXFT_StreamRec());
+  auto stream1 = pdfium::MakeUnique<FXFT_StreamRec>();
   stream1->base = nullptr;
   stream1->size = static_cast<unsigned long>(pFile->GetSize());
   stream1->pos = 0;
-  stream1->descriptor.pointer = pFile;
+  stream1->descriptor.pointer = static_cast<void*>(pFile.Get());
   stream1->close = FTStreamClose;
   stream1->read = FTStreamRead;
   FXFT_Open_Args args;
@@ -338,15 +344,15 @@
 }
 
 #ifdef PDF_ENABLE_XFA
-bool CFX_Font::LoadFile(IFX_SeekableReadStream* pFile,
+bool CFX_Font::LoadFile(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
                         int nFaceIndex,
                         int* pFaceCount) {
   m_bEmbedded = false;
 
   CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
   pFontMgr->InitFTLibrary();
-  FXFT_Library library = pFontMgr->GetFTLibrary();
 
+  FXFT_Library library = pFontMgr->GetFTLibrary();
   std::unique_ptr<FXFT_StreamRec> stream;
   if (!LoadFileImp(library, &m_Face, pFile, nFaceIndex, &stream))
     return false;
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.cpp b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
index ee7758c..b91c978 100644
--- a/fpdfsdk/cpdfsdk_formfillenvironment.cpp
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
@@ -462,8 +462,8 @@
   return nullptr;
 }
 
-IFX_SeekableReadStream* CPDFSDK_FormFillEnvironment::DownloadFromURL(
-    const FX_WCHAR* url) {
+CFX_RetainPtr<IFX_SeekableReadStream>
+CPDFSDK_FormFillEnvironment::DownloadFromURL(const FX_WCHAR* url) {
   if (!m_pInfo || !m_pInfo->FFI_DownloadFromURL)
     return nullptr;
 
@@ -472,7 +472,6 @@
       (FPDF_WIDESTRING)bstrURL.GetBuffer(bstrURL.GetLength());
 
   FPDF_LPFILEHANDLER fileHandler = m_pInfo->FFI_DownloadFromURL(m_pInfo, wsURL);
-
   return MakeSeekableStream(fileHandler);
 }
 
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.h b/fpdfsdk/cpdfsdk_formfillenvironment.h
index b4e11ca..8c2a8a3 100644
--- a/fpdfsdk/cpdfsdk_formfillenvironment.h
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.h
@@ -149,7 +149,7 @@
   FPDF_FILEHANDLER* OpenFile(int fileType,
                              FPDF_WIDESTRING wsURL,
                              const char* mode);
-  IFX_SeekableReadStream* DownloadFromURL(const FX_WCHAR* url);
+  CFX_RetainPtr<IFX_SeekableReadStream> DownloadFromURL(const FX_WCHAR* url);
   CFX_WideString PostRequestURL(const FX_WCHAR* wsURL,
                                 const FX_WCHAR* wsData,
                                 const FX_WCHAR* wsContentType,
diff --git a/fpdfsdk/fpdf_dataavail.cpp b/fpdfsdk/fpdf_dataavail.cpp
index a3accba..b1bc1e3 100644
--- a/fpdfsdk/fpdf_dataavail.cpp
+++ b/fpdfsdk/fpdf_dataavail.cpp
@@ -11,6 +11,7 @@
 
 #include "core/fpdfapi/parser/cpdf_data_avail.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "fpdfsdk/fsdk_define.h"
 #include "public/fpdf_formfill.h"
 #include "third_party/base/ptr_util.h"
@@ -43,7 +44,7 @@
 
 class CFPDF_FileAvailWrap : public CPDF_DataAvail::FileAvail {
  public:
-  CFPDF_FileAvailWrap() { m_pfileAvail = nullptr; }
+  CFPDF_FileAvailWrap() : m_pfileAvail(nullptr) {}
   ~CFPDF_FileAvailWrap() override {}
 
   void Set(FX_FILEAVAIL* pfileAvail) { m_pfileAvail = pfileAvail; }
@@ -59,7 +60,9 @@
 
 class CFPDF_FileAccessWrap : public IFX_SeekableReadStream {
  public:
-  CFPDF_FileAccessWrap() { m_pFileAccess = nullptr; }
+  static CFX_RetainPtr<CFPDF_FileAccessWrap> Create() {
+    return CFX_RetainPtr<CFPDF_FileAccessWrap>(new CFPDF_FileAccessWrap());
+  }
   ~CFPDF_FileAccessWrap() override {}
 
   void Set(FPDF_FILEACCESS* pFile) { m_pFileAccess = pFile; }
@@ -72,9 +75,9 @@
                                        (uint8_t*)buffer, size);
   }
 
-  void Release() override {}
-
  private:
+  CFPDF_FileAccessWrap() : m_pFileAccess(nullptr) {}
+
   FPDF_FILEACCESS* m_pFileAccess;
 };
 
@@ -97,12 +100,14 @@
 
 class CFPDF_DataAvail {
  public:
-  CFPDF_DataAvail() {}
+  CFPDF_DataAvail()
+      : m_FileAvail(new CFPDF_FileAvailWrap),
+        m_FileRead(CFPDF_FileAccessWrap::Create()) {}
   ~CFPDF_DataAvail() {}
 
   std::unique_ptr<CPDF_DataAvail> m_pDataAvail;
-  CFPDF_FileAvailWrap m_FileAvail;
-  CFPDF_FileAccessWrap m_FileRead;
+  std::unique_ptr<CFPDF_FileAvailWrap> m_FileAvail;
+  CFX_RetainPtr<CFPDF_FileAccessWrap> m_FileRead;
 };
 
 CFPDF_DataAvail* CFPDFDataAvailFromFPDFAvail(FPDF_AVAIL avail) {
@@ -114,10 +119,10 @@
 DLLEXPORT FPDF_AVAIL STDCALL FPDFAvail_Create(FX_FILEAVAIL* file_avail,
                                               FPDF_FILEACCESS* file) {
   CFPDF_DataAvail* pAvail = new CFPDF_DataAvail;
-  pAvail->m_FileAvail.Set(file_avail);
-  pAvail->m_FileRead.Set(file);
+  pAvail->m_FileAvail->Set(file_avail);
+  pAvail->m_FileRead->Set(file);
   pAvail->m_pDataAvail = pdfium::MakeUnique<CPDF_DataAvail>(
-      &pAvail->m_FileAvail, &pAvail->m_FileRead, true);
+      pAvail->m_FileAvail.get(), pAvail->m_FileRead, true);
   return pAvail;
 }
 
diff --git a/fpdfsdk/fpdfeditimg.cpp b/fpdfsdk/fpdfeditimg.cpp
index 2c869ac..531a9ab 100644
--- a/fpdfsdk/fpdfeditimg.cpp
+++ b/fpdfsdk/fpdfeditimg.cpp
@@ -32,7 +32,8 @@
   if (!image_object || !fileAccess || !pages)
     return false;
 
-  IFX_SeekableReadStream* pFile = MakeSeekableReadStream(fileAccess);
+  CFX_RetainPtr<IFX_SeekableReadStream> pFile =
+      MakeSeekableReadStream(fileAccess);
   CPDF_ImageObject* pImgObj = reinterpret_cast<CPDF_ImageObject*>(image_object);
   for (int index = 0; index < nCount; index++) {
     CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
diff --git a/fpdfsdk/fpdfsave.cpp b/fpdfsdk/fpdfsave.cpp
index c65ff88..0cfcd4a 100644
--- a/fpdfsdk/fpdfsave.cpp
+++ b/fpdfsdk/fpdfsave.cpp
@@ -39,21 +39,23 @@
 
 class CFX_IFileWrite final : public IFX_WriteStream {
  public:
-  CFX_IFileWrite();
+  static CFX_RetainPtr<CFX_IFileWrite> Create();
   bool Init(FPDF_FILEWRITE* pFileWriteStruct);
   bool WriteBlock(const void* pData, size_t size) override;
-  void Release() override;
 
  protected:
+  CFX_IFileWrite();
   ~CFX_IFileWrite() override {}
 
   FPDF_FILEWRITE* m_pFileWriteStruct;
 };
 
-CFX_IFileWrite::CFX_IFileWrite() {
-  m_pFileWriteStruct = nullptr;
+CFX_RetainPtr<CFX_IFileWrite> CFX_IFileWrite::Create() {
+  return CFX_RetainPtr<CFX_IFileWrite>(new CFX_IFileWrite());
 }
 
+CFX_IFileWrite::CFX_IFileWrite() : m_pFileWriteStruct(nullptr) {}
+
 bool CFX_IFileWrite::Init(FPDF_FILEWRITE* pFileWriteStruct) {
   if (!pFileWriteStruct)
     return false;
@@ -70,15 +72,12 @@
   return true;
 }
 
-void CFX_IFileWrite::Release() {
-  delete this;
-}
-
 namespace {
 
 #ifdef PDF_ENABLE_XFA
-bool SaveXFADocumentData(CPDFXFA_Context* pContext,
-                         std::vector<ScopedFileStream>* fileList) {
+bool SaveXFADocumentData(
+    CPDFXFA_Context* pContext,
+    std::vector<CFX_RetainPtr<IFX_SeekableStream>>* fileList) {
   if (!pContext)
     return false;
 
@@ -136,8 +135,9 @@
     streamAcc.LoadAllData(pTemplateStream);
     uint8_t* pData = (uint8_t*)streamAcc.GetData();
     uint32_t dwSize2 = streamAcc.GetSize();
-    ScopedFileStream pTemplate(IFX_MemoryStream::Create(pData, dwSize2));
-    pChecksum->UpdateChecksum(pTemplate.get());
+    CFX_RetainPtr<IFX_SeekableStream> pTemplate =
+        IFX_MemoryStream::Create(pData, dwSize2);
+    pChecksum->UpdateChecksum(pTemplate);
   }
   CPDF_Stream* pFormStream = nullptr;
   CPDF_Stream* pDataSetsStream = nullptr;
@@ -169,23 +169,23 @@
   }
   // L"datasets"
   {
-    ScopedFileStream pDsfileWrite(IFX_MemoryStream::Create());
-    if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets,
-                                           pDsfileWrite.get(), nullptr) &&
+    CFX_RetainPtr<IFX_SeekableStream> pDsfileWrite = IFX_MemoryStream::Create();
+    if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets, pDsfileWrite,
+                                           nullptr) &&
         pDsfileWrite->GetSize() > 0) {
       // Datasets
-      pChecksum->UpdateChecksum(pDsfileWrite.get());
+      pChecksum->UpdateChecksum(pDsfileWrite);
       pChecksum->FinishChecksum();
       auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>(
           pPDFDocument->GetByteStringPool());
       if (iDataSetsIndex != -1) {
         if (pDataSetsStream) {
-          pDataSetsStream->InitStreamFromFile(pDsfileWrite.get(),
+          pDataSetsStream->InitStreamFromFile(pDsfileWrite,
                                               std::move(pDataDict));
         }
       } else {
         CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
-        pData->InitStreamFromFile(pDsfileWrite.get(), std::move(pDataDict));
+        pData->InitStreamFromFile(pDsfileWrite, std::move(pDataDict));
         iLast = pArray->GetCount() - 2;
         pArray->InsertNewAt<CPDF_String>(iLast, "datasets", false);
         pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
@@ -196,20 +196,18 @@
   }
   // L"form"
   {
-    ScopedFileStream pfileWrite(IFX_MemoryStream::Create());
-    if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite.get(),
+    CFX_RetainPtr<IFX_SeekableStream> pfileWrite = IFX_MemoryStream::Create();
+    if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite,
                                            pChecksum.get()) &&
         pfileWrite->GetSize() > 0) {
       auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>(
           pPDFDocument->GetByteStringPool());
       if (iFormIndex != -1) {
-        if (pFormStream) {
-          pFormStream->InitStreamFromFile(pfileWrite.get(),
-                                          std::move(pDataDict));
-        }
+        if (pFormStream)
+          pFormStream->InitStreamFromFile(pfileWrite, std::move(pDataDict));
       } else {
         CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
-        pData->InitStreamFromFile(pfileWrite.get(), std::move(pDataDict));
+        pData->InitStreamFromFile(pfileWrite, std::move(pDataDict));
         iLast = pArray->GetCount() - 2;
         pArray->InsertNewAt<CPDF_String>(iLast, "form", false);
         pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
@@ -246,8 +244,9 @@
   return true;
 }
 
-bool SendPreSaveToXFADoc(CPDFXFA_Context* pContext,
-                         std::vector<ScopedFileStream>* fileList) {
+bool SendPreSaveToXFADoc(
+    CPDFXFA_Context* pContext,
+    std::vector<CFX_RetainPtr<IFX_SeekableStream>>* fileList) {
   if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
       pContext->GetDocType() != DOCTYPE_STATIC_XFA)
     return true;
@@ -280,7 +279,7 @@
 
 #ifdef PDF_ENABLE_XFA
   CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
-  std::vector<ScopedFileStream> fileList;
+  std::vector<CFX_RetainPtr<IFX_SeekableStream>> fileList;
   SendPreSaveToXFADoc(pContext, &fileList);
 #endif  // PDF_ENABLE_XFA
 
@@ -295,13 +294,12 @@
     FileMaker.RemoveSecurity();
   }
 
-  CFX_IFileWrite* pStreamWrite = new CFX_IFileWrite;
+  CFX_RetainPtr<CFX_IFileWrite> pStreamWrite = CFX_IFileWrite::Create();
   pStreamWrite->Init(pFileWrite);
   bool bRet = FileMaker.Create(pStreamWrite, flags);
 #ifdef PDF_ENABLE_XFA
   SendPostSaveToXFADoc(pContext);
 #endif  // PDF_ENABLE_XFA
-  pStreamWrite->Release();
   return bRet;
 }
 
diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp
index fb87c83..b49be38 100644
--- a/fpdfsdk/fpdfview.cpp
+++ b/fpdfsdk/fpdfview.cpp
@@ -119,15 +119,17 @@
 
 class CPDF_CustomAccess final : public IFX_SeekableReadStream {
  public:
-  explicit CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess);
-  ~CPDF_CustomAccess() override {}
+  static CFX_RetainPtr<CPDF_CustomAccess> Create(FPDF_FILEACCESS* pFileAccess) {
+    return CFX_RetainPtr<CPDF_CustomAccess>(new CPDF_CustomAccess(pFileAccess));
+  }
 
   // IFX_SeekableReadStream
   FX_FILESIZE GetSize() override;
-  void Release() override;
   bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
 
  private:
+  explicit CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess);
+
   FPDF_FILEACCESS m_FileAccess;
 };
 
@@ -138,10 +140,6 @@
   return m_FileAccess.m_FileLen;
 }
 
-void CPDF_CustomAccess::Release() {
-  delete this;
-}
-
 bool CPDF_CustomAccess::ReadBlock(void* buffer,
                                   FX_FILESIZE offset,
                                   size_t size) {
@@ -161,12 +159,12 @@
 #ifdef PDF_ENABLE_XFA
 class CFPDF_FileStream : public IFX_SeekableStream {
  public:
-  explicit CFPDF_FileStream(FPDF_FILEHANDLER* pFS);
-  ~CFPDF_FileStream() override {}
+  static CFX_RetainPtr<CFPDF_FileStream> Create(FPDF_FILEHANDLER* pFS) {
+    return CFX_RetainPtr<CFPDF_FileStream>(new CFPDF_FileStream(pFS));
+  }
+  ~CFPDF_FileStream() override;
 
   // IFX_SeekableStream:
-  IFX_SeekableStream* Retain() override;
-  void Release() override;
   FX_FILESIZE GetSize() override;
   bool IsEOF() override;
   FX_FILESIZE GetPosition() override;
@@ -178,6 +176,8 @@
   void SetPosition(FX_FILESIZE pos) { m_nCurPos = pos; }
 
  protected:
+  explicit CFPDF_FileStream(FPDF_FILEHANDLER* pFS);
+
   FPDF_FILEHANDLER* m_pFS;
   FX_FILESIZE m_nCurPos;
 };
@@ -187,14 +187,9 @@
   m_nCurPos = 0;
 }
 
-IFX_SeekableStream* CFPDF_FileStream::Retain() {
-  return this;
-}
-
-void CFPDF_FileStream::Release() {
+CFPDF_FileStream::~CFPDF_FileStream() {
   if (m_pFS && m_pFS->Release)
     m_pFS->Release(m_pFS->clientData);
-  delete this;
 }
 
 FX_FILESIZE CFPDF_FileStream::GetSize() {
@@ -310,13 +305,15 @@
   return static_cast<CFX_DIBitmap*>(bitmap);
 }
 
-IFX_SeekableReadStream* MakeSeekableReadStream(FPDF_FILEACCESS* pFileAccess) {
-  return new CPDF_CustomAccess(pFileAccess);
+CFX_RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream(
+    FPDF_FILEACCESS* pFileAccess) {
+  return CPDF_CustomAccess::Create(pFileAccess);
 }
 
 #ifdef PDF_ENABLE_XFA
-IFX_SeekableStream* MakeSeekableStream(FPDF_FILEHANDLER* pFilehandler) {
-  return new CFPDF_FileStream(pFilehandler);
+CFX_RetainPtr<IFX_SeekableStream> MakeSeekableStream(
+    FPDF_FILEHANDLER* pFilehandler) {
+  return CFPDF_FileStream::Create(pFilehandler);
 }
 #endif  // PDF_ENABLE_XFA
 
@@ -447,7 +444,7 @@
                                                   FPDF_BYTESTRING password) {
   // NOTE: the creation of the file needs to be by the embedder on the
   // other side of this API.
-  IFX_SeekableReadStream* pFileAccess =
+  CFX_RetainPtr<IFX_SeekableReadStream> pFileAccess =
       IFX_SeekableReadStream::CreateFromFilename((const FX_CHAR*)file_path);
   if (!pFileAccess)
     return nullptr;
@@ -500,25 +497,26 @@
 
 class CMemFile final : public IFX_SeekableReadStream {
  public:
-  CMemFile(uint8_t* pBuf, FX_FILESIZE size) : m_pBuf(pBuf), m_size(size) {}
+  static CFX_RetainPtr<CMemFile> Create(uint8_t* pBuf, FX_FILESIZE size) {
+    return CFX_RetainPtr<CMemFile>(new CMemFile(pBuf, size));
+  }
 
-  void Release() override { delete this; }
   FX_FILESIZE GetSize() override { return m_size; }
   bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
-    if (offset < 0) {
+    if (offset < 0)
       return false;
-    }
+
     FX_SAFE_FILESIZE newPos = pdfium::base::checked_cast<FX_FILESIZE>(size);
     newPos += offset;
-    if (!newPos.IsValid() || newPos.ValueOrDie() > m_size) {
+    if (!newPos.IsValid() || newPos.ValueOrDie() > m_size)
       return false;
-    }
+
     FXSYS_memcpy(buffer, m_pBuf + offset, size);
     return true;
   }
 
  private:
-  ~CMemFile() override {}
+  CMemFile(uint8_t* pBuf, FX_FILESIZE size) : m_pBuf(pBuf), m_size(size) {}
 
   uint8_t* const m_pBuf;
   const FX_FILESIZE m_size;
@@ -527,12 +525,11 @@
 DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadMemDocument(const void* data_buf,
                                                      int size,
                                                      FPDF_BYTESTRING password) {
-  CMemFile* pMemFile = new CMemFile((uint8_t*)data_buf, size);
-  std::unique_ptr<CPDF_Parser> pParser(new CPDF_Parser);
+  CFX_RetainPtr<CMemFile> pMemFile = CMemFile::Create((uint8_t*)data_buf, size);
+  auto pParser = pdfium::MakeUnique<CPDF_Parser>();
   pParser->SetPassword(password);
 
-  std::unique_ptr<CPDF_Document> pDocument(
-      new CPDF_Document(std::move(pParser)));
+  auto pDocument = pdfium::MakeUnique<CPDF_Document>(std::move(pParser));
   CPDF_Parser::Error error =
       pDocument->GetParser()->StartParse(pMemFile, pDocument.get());
   if (error != CPDF_Parser::SUCCESS) {
@@ -546,12 +543,12 @@
 DLLEXPORT FPDF_DOCUMENT STDCALL
 FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAccess,
                         FPDF_BYTESTRING password) {
-  CPDF_CustomAccess* pFile = new CPDF_CustomAccess(pFileAccess);
-  std::unique_ptr<CPDF_Parser> pParser(new CPDF_Parser);
+  CFX_RetainPtr<CPDF_CustomAccess> pFile =
+      CPDF_CustomAccess::Create(pFileAccess);
+  auto pParser = pdfium::MakeUnique<CPDF_Parser>();
   pParser->SetPassword(password);
 
-  std::unique_ptr<CPDF_Document> pDocument(
-      new CPDF_Document(std::move(pParser)));
+  auto pDocument = pdfium::MakeUnique<CPDF_Document>(std::move(pParser));
   CPDF_Parser::Error error =
       pDocument->GetParser()->StartParse(pFile, pDocument.get());
   if (error != CPDF_Parser::SUCCESS) {
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
index 7945786..1995882 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -328,7 +328,7 @@
   return wsAnswer;
 }
 
-IFX_SeekableReadStream* CPDFXFA_Context::DownloadURL(
+CFX_RetainPtr<IFX_SeekableReadStream> CPDFXFA_Context::DownloadURL(
     const CFX_WideString& wsURL) {
   return m_pFormFillEnv ? m_pFormFillEnv->DownloadFromURL(wsURL.c_str())
                         : nullptr;
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.h b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
index 2cd2b43..8b9daea 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
@@ -67,7 +67,8 @@
                           const CFX_WideString& wsTitle,
                           const CFX_WideString& wsDefaultAnswer,
                           bool bMark) override;
-  IFX_SeekableReadStream* DownloadURL(const CFX_WideString& wsURL) override;
+  CFX_RetainPtr<IFX_SeekableReadStream> DownloadURL(
+      const CFX_WideString& wsURL) override;
   bool PostRequestURL(const CFX_WideString& wsURL,
                       const CFX_WideString& wsData,
                       const CFX_WideString& wsContentType,
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
index 6e199e2..2b3368b 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp
@@ -11,6 +11,7 @@
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
 #include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_interform.h"
 #include "fpdfsdk/cpdfsdk_pageview.h"
@@ -437,15 +438,15 @@
   if (!pFileHandler)
     return;
 
-  std::unique_ptr<IFX_SeekableStream, ReleaseDeleter<IFX_SeekableStream>>
-      fileWrite(MakeSeekableStream(pFileHandler));
+  CFX_RetainPtr<IFX_SeekableStream> fileWrite =
+      MakeSeekableStream(pFileHandler);
   CFX_ByteString content;
   if (fileType == FXFA_SAVEAS_XML) {
     content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
     fileWrite->WriteBlock(content.c_str(), fileWrite->GetSize(),
                           content.GetLength());
-    m_pContext->GetXFADocView()->GetDoc()->SavePackage(
-        XFA_HASHCODE_Data, fileWrite.get(), nullptr);
+    m_pContext->GetXFADocView()->GetDoc()->SavePackage(XFA_HASHCODE_Data,
+                                                       fileWrite, nullptr);
   } else if (fileType == FXFA_SAVEAS_XDP) {
     if (!m_pContext->GetPDFDoc())
       return;
@@ -475,13 +476,13 @@
       if (!pStream)
         continue;
       if (pPrePDFObj->GetString() == "form") {
-        m_pContext->GetXFADocView()->GetDoc()->SavePackage(
-            XFA_HASHCODE_Form, fileWrite.get(), nullptr);
+        m_pContext->GetXFADocView()->GetDoc()->SavePackage(XFA_HASHCODE_Form,
+                                                           fileWrite, nullptr);
         continue;
       }
       if (pPrePDFObj->GetString() == "datasets") {
         m_pContext->GetXFADocView()->GetDoc()->SavePackage(
-            XFA_HASHCODE_Datasets, fileWrite.get(), nullptr);
+            XFA_HASHCODE_Datasets, fileWrite, nullptr);
         continue;
       }
       if (i == size - 1) {
@@ -699,7 +700,7 @@
   return ret;
 }
 
-IFX_SeekableReadStream* CPDFXFA_DocEnvironment::OpenLinkedFile(
+CFX_RetainPtr<IFX_SeekableReadStream> CPDFXFA_DocEnvironment::OpenLinkedFile(
     CXFA_FFDoc* hDoc,
     const CFX_WideString& wsLink) {
   CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
@@ -729,13 +730,13 @@
   if (!pFormFillEnv)
     return false;
 
-  std::unique_ptr<IFX_SeekableStream, ReleaseDeleter<IFX_SeekableStream>>
-      fileStream(MakeSeekableStream(pFileHandler));
+  CFX_RetainPtr<IFX_SeekableStream> fileStream =
+      MakeSeekableStream(pFileHandler);
 
   if (fileType == FXFA_SAVEAS_XML) {
     const char kContent[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
     fileStream->WriteBlock(kContent, 0, strlen(kContent));
-    m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Data, fileStream.get(),
+    m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Data, fileStream,
                                          nullptr);
     return true;
   }
@@ -797,11 +798,11 @@
     if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM))
       continue;
     if (pPrePDFObj->GetString() == "form") {
-      m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Form, fileStream.get(),
+      m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Form, fileStream,
                                            nullptr);
     } else if (pPrePDFObj->GetString() == "datasets") {
-      m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Datasets,
-                                           fileStream.get(), nullptr);
+      m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Datasets, fileStream,
+                                           nullptr);
     } else {
       // PDF,creator.
     }
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
index a7d41a8..d7cb169 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h
@@ -7,6 +7,7 @@
 #ifndef FPDFSDK_FPDFXFA_CPDFXFA_DOCENVIRONMENT_H_
 #define FPDFSDK_FPDFXFA_CPDFXFA_DOCENVIRONMENT_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "public/fpdfview.h"
 #include "xfa/fxfa/fxfa.h"
 
@@ -85,8 +86,9 @@
                          const CFX_ByteStringC& szPropName,
                          CFXJSE_Value* pValue) override;
 
-  IFX_SeekableReadStream* OpenLinkedFile(CXFA_FFDoc* hDoc,
-                                         const CFX_WideString& wsLink) override;
+  CFX_RetainPtr<IFX_SeekableReadStream> OpenLinkedFile(
+      CXFA_FFDoc* hDoc,
+      const CFX_WideString& wsLink) override;
 
  private:
   bool OnBeforeNotifySubmit();
diff --git a/fpdfsdk/fsdk_define.h b/fpdfsdk/fsdk_define.h
index a3f5a30..9a11596 100644
--- a/fpdfsdk/fsdk_define.h
+++ b/fpdfsdk/fsdk_define.h
@@ -27,12 +27,14 @@
 
 // Layering prevents fxcrt from knowing about FPDF_FILEACCESS, so this can't
 // be a static method of IFX_SeekableReadStream.
-IFX_SeekableReadStream* MakeSeekableReadStream(FPDF_FILEACCESS* pFileAccess);
+CFX_RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream(
+    FPDF_FILEACCESS* pFileAccess);
 
 #ifdef PDF_ENABLE_XFA
 // Layering prevents fxcrt from knowing about FPDF_FILEHANDLER, so this can't
 // be a static method of IFX_SeekableStream.
-IFX_SeekableStream* MakeSeekableStream(FPDF_FILEHANDLER* pFileHandler);
+CFX_RetainPtr<IFX_SeekableStream> MakeSeekableStream(
+    FPDF_FILEHANDLER* pFileHandler);
 #endif  // PDF_ENABLE_XFA
 
 // Object types for public FPDF_ types; these correspond to next layer down
diff --git a/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc b/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc
index 63d0e3c..94decbf 100644
--- a/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc
+++ b/testing/libfuzzer/pdf_cfx_saxreader_fuzzer.cc
@@ -16,17 +16,14 @@
   if (!stream)
     return 0;
 
-  std::unique_ptr<IFX_SeekableReadStream,
-                  ReleaseDeleter<IFX_SeekableReadStream>>
-      fileRead(stream->MakeSeekableReadStream());
+  CFX_RetainPtr<IFX_SeekableReadStream> fileRead =
+      stream->MakeSeekableReadStream();
   if (!fileRead)
     return 0;
 
   CFX_SAXReader reader;
-  if (reader.StartParse(fileRead.get(), 0, -1, CFX_SaxParseMode_NotSkipSpace) <
-      0) {
+  if (reader.StartParse(fileRead, 0, -1, CFX_SaxParseMode_NotSkipSpace) < 0)
     return 0;
-  }
 
   while (1) {
     int32_t ret = reader.ContinueParse(nullptr);
diff --git a/testing/libfuzzer/xfa_codec_fuzzer.h b/testing/libfuzzer/xfa_codec_fuzzer.h
index 4281db0..8608993 100644
--- a/testing/libfuzzer/xfa_codec_fuzzer.h
+++ b/testing/libfuzzer/xfa_codec_fuzzer.h
@@ -17,10 +17,8 @@
     std::unique_ptr<CCodec_ModuleMgr> mgr(new CCodec_ModuleMgr());
     std::unique_ptr<CCodec_ProgressiveDecoder> decoder(
         mgr->CreateProgressiveDecoder());
-    Reader source(data, size);
-
-    FXCODEC_STATUS status =
-        decoder->LoadImageInfo(&source, type, nullptr, true);
+    CFX_RetainPtr<Reader> source(new Reader(data, size));
+    FXCODEC_STATUS status = decoder->LoadImageInfo(source, type, nullptr, true);
     if (status != FXCODEC_STATUS_FRAME_READY)
       return 0;
 
@@ -46,8 +44,6 @@
     Reader(const uint8_t* data, size_t size) : m_data(data), m_size(size) {}
     ~Reader() {}
 
-    void Release() override {}
-
     bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
       if (offset < 0 || static_cast<size_t>(offset) >= m_size)
         return false;
diff --git a/xfa/fde/xml/cfx_saxreader.cpp b/xfa/fde/xml/cfx_saxreader.cpp
index b4d48d2..458bed5 100644
--- a/xfa/fde/xml/cfx_saxreader.cpp
+++ b/xfa/fde/xml/cfx_saxreader.cpp
@@ -63,32 +63,34 @@
 }  // namespace
 
 CFX_SAXFile::CFX_SAXFile()
-    : m_pFile(nullptr),
-      m_dwStart(0),
+    : m_dwStart(0),
       m_dwEnd(0),
       m_dwCur(0),
       m_pBuf(nullptr),
       m_dwBufSize(0),
       m_dwBufIndex(0) {}
-bool CFX_SAXFile::StartFile(IFX_SeekableReadStream* pFile,
+
+CFX_SAXFile::~CFX_SAXFile() {}
+
+bool CFX_SAXFile::StartFile(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
                             uint32_t dwStart,
                             uint32_t dwLen) {
   ASSERT(!m_pFile && pFile);
   uint32_t dwSize = pFile->GetSize();
-  if (dwStart >= dwSize) {
+  if (dwStart >= dwSize)
     return false;
-  }
-  if (dwLen == static_cast<uint32_t>(-1) || dwStart + dwLen > dwSize) {
+
+  if (dwLen == static_cast<uint32_t>(-1) || dwStart + dwLen > dwSize)
     dwLen = dwSize - dwStart;
-  }
-  if (dwLen == 0) {
+
+  if (dwLen == 0)
     return false;
-  }
+
   m_dwBufSize = std::min(dwLen, kSaxFileBufSize);
   m_pBuf = FX_Alloc(uint8_t, m_dwBufSize);
-  if (!pFile->ReadBlock(m_pBuf, dwStart, m_dwBufSize)) {
+  if (!pFile->ReadBlock(m_pBuf, dwStart, m_dwBufSize))
     return false;
-  }
+
   m_dwStart = dwStart;
   m_dwEnd = dwStart + dwLen;
   m_dwCur = dwStart;
@@ -214,15 +216,16 @@
   return (m_dwParseMode & CFX_SaxParseMode_NotSkipSpace) == 0 && ch < 0x21;
 }
 
-int32_t CFX_SAXReader::StartParse(IFX_SeekableReadStream* pFile,
-                                  uint32_t dwStart,
-                                  uint32_t dwLen,
-                                  uint32_t dwParseMode) {
+int32_t CFX_SAXReader::StartParse(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
+    uint32_t dwStart,
+    uint32_t dwLen,
+    uint32_t dwParseMode) {
   m_iState = -1;
   Reset();
-  if (!m_File.StartFile(pFile, dwStart, dwLen)) {
+  if (!m_File.StartFile(pFile, dwStart, dwLen))
     return -1;
-  }
+
   m_iState = 0;
   m_eMode = CFX_SaxMode::Text;
   m_ePrevMode = CFX_SaxMode::Text;
diff --git a/xfa/fde/xml/cfx_saxreader.h b/xfa/fde/xml/cfx_saxreader.h
index 667813c..8e06d9b 100644
--- a/xfa/fde/xml/cfx_saxreader.h
+++ b/xfa/fde/xml/cfx_saxreader.h
@@ -38,12 +38,15 @@
 class CFX_SAXFile {
  public:
   CFX_SAXFile();
-  bool StartFile(IFX_SeekableReadStream* pFile,
+  ~CFX_SAXFile();
+
+  bool StartFile(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
                  uint32_t dwStart,
                  uint32_t dwLen);
   bool ReadNextBlock();
   void Reset();
-  IFX_SeekableReadStream* m_pFile;
+
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFile;
   uint32_t m_dwStart;
   uint32_t m_dwEnd;
   uint32_t m_dwCur;
@@ -72,7 +75,7 @@
   CFX_SAXReader();
   ~CFX_SAXReader();
 
-  int32_t StartParse(IFX_SeekableReadStream* pFile,
+  int32_t StartParse(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile,
                      uint32_t dwStart = 0,
                      uint32_t dwLen = -1,
                      uint32_t dwParseMode = 0);
diff --git a/xfa/fgas/crt/fgas_stream.cpp b/xfa/fgas/crt/fgas_stream.cpp
index 18d8e0b..3ccb652 100644
--- a/xfa/fgas/crt/fgas_stream.cpp
+++ b/xfa/fgas/crt/fgas_stream.cpp
@@ -14,6 +14,7 @@
 #include <algorithm>
 #include <memory>
 
+#include "third_party/base/ptr_util.h"
 #include "xfa/fgas/crt/fgas_codepage.h"
 
 namespace {
@@ -100,7 +101,8 @@
   CFGAS_FileReadStreamImp();
   ~CFGAS_FileReadStreamImp() override {}
 
-  bool LoadFileRead(IFX_SeekableReadStream* pFileRead, uint32_t dwAccess);
+  bool LoadFileRead(const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
+                    uint32_t dwAccess);
 
   // IFGAS_StreamImp:
   int32_t GetLength() const override;
@@ -119,7 +121,7 @@
   bool SetLength(int32_t iLength) override { return false; }
 
  protected:
-  IFX_SeekableReadStream* m_pFileRead;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFileRead;
   int32_t m_iPosition;
   int32_t m_iLength;
 };
@@ -129,10 +131,9 @@
   CFGAS_BufferReadStreamImp();
   ~CFGAS_BufferReadStreamImp() override;
 
-  bool LoadBufferRead(IFX_BufferedReadStream* pBufferRead,
+  bool LoadBufferRead(const CFX_RetainPtr<IFX_BufferedReadStream>& pBufferRead,
                       int32_t iFileSize,
-                      uint32_t dwAccess,
-                      bool bReleaseBufferRead);
+                      uint32_t dwAccess);
 
   // IFGAS_StreamImp:
   int32_t GetLength() const override;
@@ -151,8 +152,7 @@
   bool SetLength(int32_t iLength) override { return false; }
 
  private:
-  IFX_BufferedReadStream* m_pBufferRead;
-  bool m_bReleaseBufferRead;
+  CFX_RetainPtr<IFX_BufferedReadStream> m_pBufferRead;
   int32_t m_iPosition;
   int32_t m_iBufferSize;
 };
@@ -162,7 +162,8 @@
   CFGAS_FileWriteStreamImp();
   ~CFGAS_FileWriteStreamImp() override {}
 
-  bool LoadFileWrite(IFX_SeekableWriteStream* pFileWrite, uint32_t dwAccess);
+  bool LoadFileWrite(const CFX_RetainPtr<IFX_SeekableWriteStream>& pFileWrite,
+                     uint32_t dwAccess);
 
   // IFGAS_StreamImp:
   int32_t GetLength() const override;
@@ -179,7 +180,7 @@
   bool SetLength(int32_t iLength) override { return false; }
 
  protected:
-  IFX_SeekableWriteStream* m_pFileWrite;
+  CFX_RetainPtr<IFX_SeekableWriteStream> m_pFileWrite;
   int32_t m_iPosition;
 };
 
@@ -198,12 +199,13 @@
 
   bool LoadFile(const FX_WCHAR* pszSrcFileName, uint32_t dwAccess);
   bool LoadBuffer(uint8_t* pData, int32_t iTotalSize, uint32_t dwAccess);
-  bool LoadFileRead(IFX_SeekableReadStream* pFileRead, uint32_t dwAccess);
-  bool LoadFileWrite(IFX_SeekableWriteStream* pFileWrite, uint32_t dwAccess);
-  bool LoadBufferRead(IFX_BufferedReadStream* pBufferRead,
+  bool LoadFileRead(const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
+                    uint32_t dwAccess);
+  bool LoadFileWrite(const CFX_RetainPtr<IFX_SeekableWriteStream>& pFileWrite,
+                     uint32_t dwAccess);
+  bool LoadBufferRead(const CFX_RetainPtr<IFX_BufferedReadStream>& pBufferRead,
                       int32_t iFileSize,
-                      uint32_t dwAccess,
-                      bool bReleaseBufferRead);
+                      uint32_t dwAccess);
 
   // IFGAS_Stream
   void Release() override;
@@ -277,15 +279,17 @@
 
 class CFGAS_FileRead : public IFX_SeekableReadStream {
  public:
-  CFGAS_FileRead(IFGAS_Stream* pStream, bool bReleaseStream);
+  static CFX_RetainPtr<CFGAS_FileRead> Create(IFGAS_Stream* pStream,
+                                              bool bReleaseStream);
   ~CFGAS_FileRead() override;
 
   // IFX_SeekableReadStream
-  void Release() override;
   FX_FILESIZE GetSize() override;
   bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
 
  protected:
+  CFGAS_FileRead(IFGAS_Stream* pStream, bool bReleaseStream);
+
   bool m_bReleaseStream;
   IFGAS_Stream* m_pStream;
 };
@@ -322,8 +326,9 @@
 }  // namespace
 
 // static
-IFGAS_Stream* IFGAS_Stream::CreateStream(IFX_SeekableReadStream* pFileRead,
-                                         uint32_t dwAccess) {
+IFGAS_Stream* IFGAS_Stream::CreateStream(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
+    uint32_t dwAccess) {
   CFGAS_Stream* pSR = new CFGAS_Stream;
   if (!pSR->LoadFileRead(pFileRead, dwAccess)) {
     pSR->Release();
@@ -336,8 +341,9 @@
 }
 
 // static
-IFGAS_Stream* IFGAS_Stream::CreateStream(IFX_SeekableWriteStream* pFileWrite,
-                                         uint32_t dwAccess) {
+IFGAS_Stream* IFGAS_Stream::CreateStream(
+    const CFX_RetainPtr<IFX_SeekableWriteStream>& pFileWrite,
+    uint32_t dwAccess) {
   CFGAS_Stream* pSR = new CFGAS_Stream;
   if (!pSR->LoadFileWrite(pFileWrite, dwAccess)) {
     pSR->Release();
@@ -534,18 +540,22 @@
   m_iLength = FileLength(m_hFile);
   return bRet;
 }
+
 CFGAS_FileReadStreamImp::CFGAS_FileReadStreamImp()
     : m_pFileRead(nullptr), m_iPosition(0), m_iLength(0) {}
-bool CFGAS_FileReadStreamImp::LoadFileRead(IFX_SeekableReadStream* pFileRead,
-                                           uint32_t dwAccess) {
+
+bool CFGAS_FileReadStreamImp::LoadFileRead(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
+    uint32_t dwAccess) {
   ASSERT(!m_pFileRead && pFileRead);
-  if (dwAccess & FX_STREAMACCESS_Write) {
+  if (dwAccess & FX_STREAMACCESS_Write)
     return false;
-  }
+
   m_pFileRead = pFileRead;
   m_iLength = m_pFileRead->GetSize();
   return true;
 }
+
 int32_t CFGAS_FileReadStreamImp::GetLength() const {
   return m_iLength;
 }
@@ -600,34 +610,28 @@
   bEOS = (m_iPosition >= m_iLength) || pStr[i] == L'\0';
   return i;
 }
+
 CFGAS_BufferReadStreamImp::CFGAS_BufferReadStreamImp()
-    : m_pBufferRead(nullptr),
-      m_bReleaseBufferRead(false),
-      m_iPosition(0),
-      m_iBufferSize(0) {}
-CFGAS_BufferReadStreamImp::~CFGAS_BufferReadStreamImp() {
-  if (m_bReleaseBufferRead && m_pBufferRead) {
-    m_pBufferRead->Release();
-  }
-}
+    : m_iPosition(0), m_iBufferSize(0) {}
+
+CFGAS_BufferReadStreamImp::~CFGAS_BufferReadStreamImp() {}
+
 bool CFGAS_BufferReadStreamImp::LoadBufferRead(
-    IFX_BufferedReadStream* pBufferRead,
+    const CFX_RetainPtr<IFX_BufferedReadStream>& pBufferRead,
     int32_t iFileSize,
-    uint32_t dwAccess,
-    bool bReleaseBufferRead) {
+    uint32_t dwAccess) {
   ASSERT(!m_pBufferRead && pBufferRead);
-  if (dwAccess & FX_STREAMACCESS_Write) {
+  if (dwAccess & FX_STREAMACCESS_Write)
     return false;
-  }
-  m_bReleaseBufferRead = bReleaseBufferRead;
+
   m_pBufferRead = pBufferRead;
   m_iBufferSize = iFileSize;
-  if (m_iBufferSize >= 0) {
+  if (m_iBufferSize >= 0)
     return true;
-  }
-  if (!m_pBufferRead->ReadNextBlock(true)) {
+
+  if (!m_pBufferRead->ReadNextBlock(true))
     return false;
-  }
+
   m_iBufferSize = m_pBufferRead->GetBlockSize();
   while (!m_pBufferRead->IsEOF()) {
     m_pBufferRead->ReadNextBlock(false);
@@ -733,23 +737,25 @@
 }
 CFGAS_FileWriteStreamImp::CFGAS_FileWriteStreamImp()
     : m_pFileWrite(nullptr), m_iPosition(0) {}
+
 bool CFGAS_FileWriteStreamImp::LoadFileWrite(
-    IFX_SeekableWriteStream* pFileWrite,
+    const CFX_RetainPtr<IFX_SeekableWriteStream>& pFileWrite,
     uint32_t dwAccess) {
   ASSERT(!m_pFileWrite && pFileWrite);
-  if (dwAccess & FX_STREAMACCESS_Read) {
+  if (dwAccess & FX_STREAMACCESS_Read)
     return false;
-  }
-  if (dwAccess & FX_STREAMACCESS_Append) {
+
+  if (dwAccess & FX_STREAMACCESS_Append)
     m_iPosition = pFileWrite->GetSize();
-  }
+
   m_pFileWrite = pFileWrite;
   return true;
 }
+
 int32_t CFGAS_FileWriteStreamImp::GetLength() const {
-  if (!m_pFileWrite) {
+  if (!m_pFileWrite)
     return 0;
-  }
+
   return (int32_t)m_pFileWrite->GetSize();
 }
 int32_t CFGAS_FileWriteStreamImp::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
@@ -1159,8 +1165,9 @@
   return true;
 }
 
-bool CFGAS_Stream::LoadFileRead(IFX_SeekableReadStream* pFileRead,
-                                uint32_t dwAccess) {
+bool CFGAS_Stream::LoadFileRead(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
+    uint32_t dwAccess) {
   if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp)
     return false;
 
@@ -1178,16 +1185,16 @@
   return true;
 }
 
-bool CFGAS_Stream::LoadFileWrite(IFX_SeekableWriteStream* pFileWrite,
-                                 uint32_t dwAccess) {
+bool CFGAS_Stream::LoadFileWrite(
+    const CFX_RetainPtr<IFX_SeekableWriteStream>& pFileWrite,
+    uint32_t dwAccess) {
   if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp)
     return false;
 
   if (!pFileWrite)
     return false;
 
-  std::unique_ptr<CFGAS_FileWriteStreamImp> pImp(
-      new CFGAS_FileWriteStreamImp());
+  auto pImp = pdfium::MakeUnique<CFGAS_FileWriteStreamImp>();
   if (!pImp->LoadFileWrite(pFileWrite, dwAccess))
     return false;
 
@@ -1218,20 +1225,18 @@
   return true;
 }
 
-bool CFGAS_Stream::LoadBufferRead(IFX_BufferedReadStream* pBufferRead,
-                                  int32_t iFileSize,
-                                  uint32_t dwAccess,
-                                  bool bReleaseBufferRead) {
+bool CFGAS_Stream::LoadBufferRead(
+    const CFX_RetainPtr<IFX_BufferedReadStream>& pBufferRead,
+    int32_t iFileSize,
+    uint32_t dwAccess) {
   if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp)
     return false;
 
   if (!pBufferRead)
     return false;
 
-  std::unique_ptr<CFGAS_BufferReadStreamImp> pImp(
-      new CFGAS_BufferReadStreamImp);
-  if (!pImp->LoadBufferRead(pBufferRead, iFileSize, dwAccess,
-                            bReleaseBufferRead))
+  auto pImp = pdfium::MakeUnique<CFGAS_BufferReadStreamImp>();
+  if (!pImp->LoadBufferRead(pBufferRead, iFileSize, dwAccess))
     return false;
 
   m_pStreamImp = pImp.release();
@@ -1478,14 +1483,21 @@
   return pShared;
 }
 
-IFX_SeekableReadStream* IFGAS_Stream::MakeSeekableReadStream() {
-  return new CFGAS_FileRead(this, false);
+CFX_RetainPtr<IFX_SeekableReadStream> IFGAS_Stream::MakeSeekableReadStream() {
+  return CFGAS_FileRead::Create(this, false);
+}
+
+CFX_RetainPtr<CFGAS_FileRead> CFGAS_FileRead::Create(IFGAS_Stream* pStream,
+                                                     bool bReleaseStream) {
+  return CFX_RetainPtr<CFGAS_FileRead>(
+      new CFGAS_FileRead(pStream, bReleaseStream));
 }
 
 CFGAS_FileRead::CFGAS_FileRead(IFGAS_Stream* pStream, bool bReleaseStream)
     : m_bReleaseStream(bReleaseStream), m_pStream(pStream) {
   ASSERT(m_pStream);
 }
+
 CFGAS_FileRead::~CFGAS_FileRead() {
   if (m_bReleaseStream) {
     m_pStream->Release();
@@ -1500,7 +1512,3 @@
   int32_t iLen = m_pStream->ReadData((uint8_t*)buffer, (int32_t)size);
   return iLen == (int32_t)size;
 }
-
-void CFGAS_FileRead::Release() {
-  delete this;
-}
diff --git a/xfa/fgas/crt/fgas_stream.h b/xfa/fgas/crt/fgas_stream.h
index bd065ff..b6552d9 100644
--- a/xfa/fgas/crt/fgas_stream.h
+++ b/xfa/fgas/crt/fgas_stream.h
@@ -7,6 +7,7 @@
 #ifndef XFA_FGAS_CRT_FGAS_STREAM_H_
 #define XFA_FGAS_CRT_FGAS_STREAM_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_stream.h"
 #include "core/fxcrt/fx_system.h"
 
@@ -28,10 +29,12 @@
 
 class IFGAS_Stream {
  public:
-  static IFGAS_Stream* CreateStream(IFX_SeekableReadStream* pFileRead,
-                                    uint32_t dwAccess);
-  static IFGAS_Stream* CreateStream(IFX_SeekableWriteStream* pFileWrite,
-                                    uint32_t dwAccess);
+  static IFGAS_Stream* CreateStream(
+      const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead,
+      uint32_t dwAccess);
+  static IFGAS_Stream* CreateStream(
+      const CFX_RetainPtr<IFX_SeekableWriteStream>& pFileWrite,
+      uint32_t dwAccess);
   static IFGAS_Stream* CreateStream(uint8_t* pData,
                                     int32_t length,
                                     uint32_t dwAccess);
@@ -63,7 +66,7 @@
   virtual uint16_t GetCodePage() const = 0;
   virtual uint16_t SetCodePage(uint16_t wCodePage) = 0;
 
-  IFX_SeekableReadStream* MakeSeekableReadStream();
+  CFX_RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream();
 };
 
 
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index f211e64..060dd95 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -607,13 +607,6 @@
     delete pFonts;
   }
   m_Hash2Fonts.RemoveAll();
-  pos = m_IFXFont2FileRead.GetStartPosition();
-  while (pos) {
-    CFGAS_GEFont* pFont;
-    IFX_SeekableReadStream* pFileRead;
-    m_IFXFont2FileRead.GetNextAssoc(pos, pFont, pFileRead);
-    pFileRead->Release();
-  }
 }
 
 bool CFGAS_FontMgr::EnumFontsFromFontMapper() {
@@ -628,7 +621,7 @@
 
   pSystemFontInfo->EnumFontList(pFontMapper);
   for (int32_t i = 0; i < pFontMapper->GetFaceSize(); ++i) {
-    IFX_SeekableReadStream* pFontStream =
+    CFX_RetainPtr<IFX_SeekableReadStream> pFontStream =
         CreateFontStream(pFontMapper, pSystemFontInfo, i);
     if (!pFontStream)
       continue;
@@ -636,19 +629,15 @@
     CFX_WideString wsFaceName =
         CFX_WideString::FromLocal(pFontMapper->GetFaceName(i).c_str());
     RegisterFaces(pFontStream, &wsFaceName);
-    pFontStream->Release();
   }
-  if (m_InstalledFonts.GetSize() == 0)
-    return false;
-
-  return true;
+  return m_InstalledFonts.GetSize() != 0;
 }
 
 bool CFGAS_FontMgr::EnumFontsFromFiles() {
   CFX_GEModule::Get()->GetFontMgr()->InitFTLibrary();
   FX_POSITION pos = m_pFontSource->GetStartPosition();
   IFX_FileAccess* pFontSource = nullptr;
-  IFX_SeekableReadStream* pFontStream = nullptr;
+  CFX_RetainPtr<IFX_SeekableReadStream> pFontStream;
   while (pos) {
     pFontSource = m_pFontSource->GetNext(pos);
     pFontStream = pFontSource->CreateFileStream(FX_FILEMODE_ReadOnly);
@@ -657,12 +646,9 @@
       continue;
     }
     RegisterFaces(pFontStream, nullptr);
-    pFontStream->Release();
     pFontSource->Release();
   }
-  if (m_InstalledFonts.GetSize() == 0)
-    return false;
-  return true;
+  return m_InstalledFonts.GetSize() != 0;
 }
 
 bool CFGAS_FontMgr::EnumFonts() {
@@ -765,7 +751,7 @@
 
 bool CFGAS_FontMgr::VerifyUnicode(CFX_FontDescriptor* pDesc,
                                   FX_WCHAR wcUnicode) {
-  IFX_SeekableReadStream* pFileRead =
+  CFX_RetainPtr<IFX_SeekableReadStream> pFileRead =
       CreateFontStream(pDesc->m_wsFaceName.UTF8Encode());
   if (!pFileRead)
     return false;
@@ -773,12 +759,12 @@
   FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex);
   FT_Error retCharmap = FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE);
   FT_Error retIndex = FXFT_Get_Char_Index(pFace, wcUnicode);
-  pFileRead->Release();
   if (!pFace)
     return false;
 
   if (FXFT_Get_Face_External_Stream(pFace))
     FXFT_Clear_Face_External_Stream(pFace);
+
   FXFT_Done_Face(pFace);
   return !retCharmap && retIndex;
 }
@@ -811,24 +797,20 @@
   if (!pSystemFontInfo)
     return nullptr;
 
-  IFX_SeekableReadStream* pFontStream =
+  CFX_RetainPtr<IFX_SeekableReadStream> pFontStream =
       CreateFontStream(wsFaceName.UTF8Encode());
   if (!pFontStream)
     return nullptr;
 
-  std::unique_ptr<CFX_Font> pInternalFont(new CFX_Font());
-  if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) {
-    pFontStream->Release();
+  auto pInternalFont = pdfium::MakeUnique<CFX_Font>();
+  if (!pInternalFont->LoadFile(pFontStream, iFaceIndex))
     return nullptr;
-  }
 
   CFGAS_GEFont* pFont = CFGAS_GEFont::LoadFont(std::move(pInternalFont), this);
-  if (!pFont) {
-    pFontStream->Release();
+  if (!pFont)
     return nullptr;
-  }
 
-  m_IFXFont2FileRead.SetAt(pFont, pFontStream);
+  m_IFXFont2FileRead[pFont] = pFontStream;
   if (pFaceCount)
     *pFaceCount = pFont->GetDevFont()->GetFace()->num_faces;
 
@@ -845,24 +827,26 @@
     return 0;
 
   IFX_SeekableReadStream* pFile =
-      (IFX_SeekableReadStream*)stream->descriptor.pointer;
-  int res = pFile->ReadBlock(buffer, offset, count);
-  if (res)
-    return count;
-  return 0;
+      static_cast<IFX_SeekableReadStream*>(stream->descriptor.pointer);
+  if (!pFile->ReadBlock(buffer, offset, count))
+    return 0;
+
+  return count;
 }
 
 void _ftStreamClose(FXFT_Stream stream) {}
 
 };  // extern "C"
 
-FXFT_Face CFGAS_FontMgr::LoadFace(IFX_SeekableReadStream* pFontStream,
-                                  int32_t iFaceIndex) {
+FXFT_Face CFGAS_FontMgr::LoadFace(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFontStream,
+    int32_t iFaceIndex) {
   if (!pFontStream)
     return nullptr;
 
   CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
   pFontMgr->InitFTLibrary();
+
   FXFT_Library library = pFontMgr->GetFTLibrary();
   if (!library)
     return nullptr;
@@ -870,7 +854,7 @@
   FXFT_Stream ftStream = FX_Alloc(FXFT_StreamRec, 1);
   FXSYS_memset(ftStream, 0, sizeof(FXFT_StreamRec));
   ftStream->base = nullptr;
-  ftStream->descriptor.pointer = pFontStream;
+  ftStream->descriptor.pointer = static_cast<void*>(pFontStream.Get());
   ftStream->pos = 0;
   ftStream->size = static_cast<unsigned long>(pFontStream->GetSize());
   ftStream->read = _ftStreamRead;
@@ -891,7 +875,7 @@
   return pFace;
 }
 
-IFX_SeekableReadStream* CFGAS_FontMgr::CreateFontStream(
+CFX_RetainPtr<IFX_SeekableReadStream> CFGAS_FontMgr::CreateFontStream(
     CFX_FontMapper* pFontMapper,
     IFX_SystemFontInfo* pSystemFontInfo,
     uint32_t index) {
@@ -912,11 +896,10 @@
   return IFX_MemoryStream::Create(pBuffer, dwFileSize, true);
 }
 
-IFX_SeekableReadStream* CFGAS_FontMgr::CreateFontStream(
+CFX_RetainPtr<IFX_SeekableReadStream> CFGAS_FontMgr::CreateFontStream(
     const CFX_ByteString& bsFaceName) {
   CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
   CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
-
   if (!pFontMapper)
     return nullptr;
 
@@ -1039,11 +1022,8 @@
   if (!pEFont)
     return;
 
-  IFX_SeekableReadStream* pFileRead;
-  if (m_IFXFont2FileRead.Lookup(pEFont, pFileRead)) {
-    pFileRead->Release();
-    m_IFXFont2FileRead.RemoveKey(pEFont);
-  }
+  m_IFXFont2FileRead.erase(pEFont);
+
   FX_POSITION pos;
   pos = m_Hash2Fonts.GetStartPosition();
   while (pos) {
@@ -1096,8 +1076,9 @@
   m_InstalledFonts.Add(pFont.release());
 }
 
-void CFGAS_FontMgr::RegisterFaces(IFX_SeekableReadStream* pFontStream,
-                                  const CFX_WideString* pFaceName) {
+void CFGAS_FontMgr::RegisterFaces(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pFontStream,
+    const CFX_WideString* pFaceName) {
   int32_t index = 0;
   int32_t num_faces = 0;
   do {
diff --git a/xfa/fgas/font/cfgas_fontmgr.h b/xfa/fgas/font/cfgas_fontmgr.h
index 7b68525..28a8bb5 100644
--- a/xfa/fgas/font/cfgas_fontmgr.h
+++ b/xfa/fgas/font/cfgas_fontmgr.h
@@ -7,6 +7,7 @@
 #ifndef XFA_FGAS_FONT_CFGAS_FONTMGR_H_
 #define XFA_FGAS_FONT_CFGAS_FONTMGR_H_
 
+#include <map>
 #include <memory>
 #include <vector>
 
@@ -214,7 +215,7 @@
   bool EnumFontsFromFontMapper();
   bool EnumFontsFromFiles();
   void RegisterFace(FXFT_Face pFace, const CFX_WideString* pFaceName);
-  void RegisterFaces(IFX_SeekableReadStream* pFontStream,
+  void RegisterFaces(const CFX_RetainPtr<IFX_SeekableReadStream>& pFontStream,
                      const CFX_WideString* pFaceName);
   void GetNames(const uint8_t* name_table, CFX_WideStringArray& Names);
   std::vector<uint16_t> GetCharsets(FXFT_Face pFace) const;
@@ -236,16 +237,20 @@
   CFGAS_GEFont* LoadFont(const CFX_WideString& wsFaceName,
                          int32_t iFaceIndex,
                          int32_t* pFaceCount);
-  FXFT_Face LoadFace(IFX_SeekableReadStream* pFontStream, int32_t iFaceIndex);
-  IFX_SeekableReadStream* CreateFontStream(CFX_FontMapper* pFontMapper,
-                                           IFX_SystemFontInfo* pSystemFontInfo,
-                                           uint32_t index);
-  IFX_SeekableReadStream* CreateFontStream(const CFX_ByteString& bsFaceName);
+  FXFT_Face LoadFace(const CFX_RetainPtr<IFX_SeekableReadStream>& pFontStream,
+                     int32_t iFaceIndex);
+  CFX_RetainPtr<IFX_SeekableReadStream> CreateFontStream(
+      CFX_FontMapper* pFontMapper,
+      IFX_SystemFontInfo* pSystemFontInfo,
+      uint32_t index);
+  CFX_RetainPtr<IFX_SeekableReadStream> CreateFontStream(
+      const CFX_ByteString& bsFaceName);
 
   CFX_FontDescriptors m_InstalledFonts;
   CFX_MapPtrTemplate<uint32_t, CFX_FontDescriptorInfos*> m_Hash2CandidateList;
   CFX_MapPtrTemplate<uint32_t, CFX_ArrayTemplate<CFGAS_GEFont*>*> m_Hash2Fonts;
-  CFX_MapPtrTemplate<CFGAS_GEFont*, IFX_SeekableReadStream*> m_IFXFont2FileRead;
+  std::map<CFGAS_GEFont*, CFX_RetainPtr<IFX_SeekableReadStream> >
+      m_IFXFont2FileRead;
   CFX_MapPtrTemplate<FX_WCHAR, CFGAS_GEFont*> m_FailedUnicodes2Nullptr;
   CFX_FontSourceEnum_File* const m_pFontSource;
 };
diff --git a/xfa/fgas/font/cfgas_gefont.cpp b/xfa/fgas/font/cfgas_gefont.cpp
index 1d4624f..3bca4dc 100644
--- a/xfa/fgas/font/cfgas_gefont.cpp
+++ b/xfa/fgas/font/cfgas_gefont.cpp
@@ -210,12 +210,13 @@
   if (bSaveStream)
     m_pStream.reset(pFontStream);
 
-  m_pFileRead.reset(pFontStream->MakeSeekableReadStream());
+  m_pFileRead = pFontStream->MakeSeekableReadStream();
   m_pFont = new CFX_Font;
-  if (m_pFont->LoadFile(m_pFileRead.get()))
-    return InitFont();
-  m_pFileRead.reset();
-  return false;
+  if (!m_pFont->LoadFile(m_pFileRead)) {
+    m_pFileRead.Reset();
+    return false;
+  }
+  return InitFont();
 }
 #endif  // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
 
diff --git a/xfa/fgas/font/cfgas_gefont.h b/xfa/fgas/font/cfgas_gefont.h
index 2b4179e..b4fcf25 100644
--- a/xfa/fgas/font/cfgas_gefont.h
+++ b/xfa/fgas/font/cfgas_gefont.h
@@ -98,9 +98,7 @@
   int32_t m_iRefCount;
   bool m_bExternalFont;
   std::unique_ptr<IFGAS_Stream, ReleaseDeleter<IFGAS_Stream>> m_pStream;
-  std::unique_ptr<IFX_SeekableReadStream,
-                  ReleaseDeleter<IFX_SeekableReadStream>>
-      m_pFileRead;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFileRead;
   std::unique_ptr<CFX_UnicodeEncoding> m_pFontEncoding;
   std::unique_ptr<CFX_DiscreteArrayTemplate<uint16_t>> m_pCharWidthMap;
   std::unique_ptr<CFX_MassArrayTemplate<CFX_Rect>> m_pRectArray;
diff --git a/xfa/fxfa/app/xfa_checksum.cpp b/xfa/fxfa/app/xfa_checksum.cpp
index 01035f8..61cbe97 100644
--- a/xfa/fxfa/app/xfa_checksum.cpp
+++ b/xfa/fxfa/app/xfa_checksum.cpp
@@ -225,11 +225,13 @@
   m_pSAXReader = new CFX_SAXReader;
 }
 
-bool CXFA_ChecksumContext::UpdateChecksum(IFX_SeekableReadStream* pSrcFile,
-                                          FX_FILESIZE offset,
-                                          size_t size) {
+bool CXFA_ChecksumContext::UpdateChecksum(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pSrcFile,
+    FX_FILESIZE offset,
+    size_t size) {
   if (!m_pSAXReader || !pSrcFile)
     return false;
+
   if (size < 1)
     size = pSrcFile->GetSize();
 
diff --git a/xfa/fxfa/app/xfa_ffapp.cpp b/xfa/fxfa/app/xfa_ffapp.cpp
index 9c0411b..a0674b6 100644
--- a/xfa/fxfa/app/xfa_ffapp.cpp
+++ b/xfa/fxfa/app/xfa_ffapp.cpp
@@ -31,7 +31,6 @@
   // IFX_SeekableReadStream
   FX_FILESIZE GetSize() override;
   bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
-  void Release() override;
 
  private:
   CFX_ObjectArray<CPDF_StreamAcc> m_Data;
@@ -84,15 +83,11 @@
   return false;
 }
 
-void CXFA_FileRead::Release() {
-  delete this;
-}
-
 }  // namespace
 
-IFX_SeekableReadStream* MakeSeekableReadStream(
+CFX_RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream(
     const std::vector<CPDF_Stream*>& streams) {
-  return new CXFA_FileRead(streams);
+  return CFX_RetainPtr<IFX_SeekableReadStream>(new CXFA_FileRead(streams));
 }
 
 CXFA_FFApp::CXFA_FFApp(IXFA_AppProvider* pProvider)
@@ -108,12 +103,11 @@
   return m_pDocHandler.get();
 }
 
-CXFA_FFDoc* CXFA_FFApp::CreateDoc(IXFA_DocEnvironment* pDocEnvironment,
-                                  IFX_SeekableReadStream* pStream,
-                                  bool bTakeOverFile) {
-  std::unique_ptr<CXFA_FFDoc> pDoc(new CXFA_FFDoc(this, pDocEnvironment));
-  bool bSuccess = pDoc->OpenDoc(pStream, bTakeOverFile);
-  return bSuccess ? pDoc.release() : nullptr;
+CXFA_FFDoc* CXFA_FFApp::CreateDoc(
+    IXFA_DocEnvironment* pDocEnvironment,
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pStream) {
+  auto pDoc = pdfium::MakeUnique<CXFA_FFDoc>(this, pDocEnvironment);
+  return pDoc->OpenDoc(pStream) ? pDoc.release() : nullptr;
 }
 
 CXFA_FFDoc* CXFA_FFApp::CreateDoc(IXFA_DocEnvironment* pDocEnvironment,
diff --git a/xfa/fxfa/app/xfa_ffapp_unittest.cpp b/xfa/fxfa/app/xfa_ffapp_unittest.cpp
index 7a65dcc..b087901 100644
--- a/xfa/fxfa/app/xfa_ffapp_unittest.cpp
+++ b/xfa/fxfa/app/xfa_ffapp_unittest.cpp
@@ -13,12 +13,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/base/ptr_util.h"
 
-using UniqueFileRead = std::unique_ptr<IFX_SeekableReadStream,
-                                       ReleaseDeleter<IFX_SeekableReadStream>>;
-
 TEST(CXFAFileRead, NoStreams) {
   std::vector<CPDF_Stream*> streams;
-  UniqueFileRead fileread(MakeSeekableReadStream(streams));
+  CFX_RetainPtr<IFX_SeekableReadStream> fileread =
+      MakeSeekableReadStream(streams);
 
   uint8_t output_buffer[16];
   memset(output_buffer, 0xbd, sizeof(output_buffer));
@@ -28,9 +26,10 @@
 
 TEST(CXFAFileRead, EmptyStreams) {
   std::vector<CPDF_Stream*> streams;
-  std::unique_ptr<CPDF_Stream> stream1 = pdfium::MakeUnique<CPDF_Stream>();
+  auto stream1 = pdfium::MakeUnique<CPDF_Stream>();
   streams.push_back(stream1.get());
-  UniqueFileRead fileread(MakeSeekableReadStream(streams));
+  CFX_RetainPtr<IFX_SeekableReadStream> fileread =
+      MakeSeekableReadStream(streams);
 
   uint8_t output_buffer[16];
   memset(output_buffer, 0xbd, sizeof(output_buffer));
@@ -40,9 +39,9 @@
 
 TEST(CXFAFileRead, NormalStreams) {
   std::vector<CPDF_Stream*> streams;
-  std::unique_ptr<CPDF_Stream> stream1 = pdfium::MakeUnique<CPDF_Stream>();
-  std::unique_ptr<CPDF_Stream> stream2 = pdfium::MakeUnique<CPDF_Stream>();
-  std::unique_ptr<CPDF_Stream> stream3 = pdfium::MakeUnique<CPDF_Stream>();
+  auto stream1 = pdfium::MakeUnique<CPDF_Stream>();
+  auto stream2 = pdfium::MakeUnique<CPDF_Stream>();
+  auto stream3 = pdfium::MakeUnique<CPDF_Stream>();
 
   // 16 chars total.
   stream1->InitStream(reinterpret_cast<const uint8_t*>("one t"), 5,
@@ -55,7 +54,8 @@
   streams.push_back(stream1.get());
   streams.push_back(stream2.get());
   streams.push_back(stream3.get());
-  UniqueFileRead fileread(MakeSeekableReadStream(streams));
+  CFX_RetainPtr<IFX_SeekableReadStream> fileread =
+      MakeSeekableReadStream(streams);
 
   uint8_t output_buffer[16];
   memset(output_buffer, 0xbd, sizeof(output_buffer));
diff --git a/xfa/fxfa/app/xfa_ffdoc.cpp b/xfa/fxfa/app/xfa_ffdoc.cpp
index e719a41..917c853 100644
--- a/xfa/fxfa/app/xfa_ffdoc.cpp
+++ b/xfa/fxfa/app/xfa_ffdoc.cpp
@@ -152,12 +152,10 @@
 CXFA_FFDoc::CXFA_FFDoc(CXFA_FFApp* pApp, IXFA_DocEnvironment* pDocEnvironment)
     : m_pDocEnvironment(pDocEnvironment),
       m_pDocumentParser(nullptr),
-      m_pStream(nullptr),
       m_pApp(pApp),
       m_pNotify(nullptr),
       m_pPDFDoc(nullptr),
-      m_dwDocType(XFA_DOCTYPE_Static),
-      m_bOwnStream(true) {}
+      m_dwDocType(XFA_DOCTYPE_Static) {}
 
 CXFA_FFDoc::~CXFA_FFDoc() {
   CloseDoc();
@@ -292,8 +290,7 @@
   return it != m_TypeToDocViewMap.end() ? it->second.get() : nullptr;
 }
 
-bool CXFA_FFDoc::OpenDoc(IFX_SeekableReadStream* pStream, bool bTakeOverFile) {
-  m_bOwnStream = bTakeOverFile;
+bool CXFA_FFDoc::OpenDoc(const CFX_RetainPtr<IFX_SeekableReadStream>& pStream) {
   m_pStream = pStream;
   return true;
 }
@@ -326,14 +323,8 @@
   if (xfaStreams.empty())
     return false;
 
-  IFX_SeekableReadStream* pFileRead = MakeSeekableReadStream(xfaStreams);
   m_pPDFDoc = pPDFDoc;
-  if (m_pStream) {
-    m_pStream->Release();
-    m_pStream = nullptr;
-  }
-  m_pStream = pFileRead;
-  m_bOwnStream = true;
+  m_pStream = MakeSeekableReadStream(xfaStreams);
   return true;
 }
 
@@ -351,11 +342,6 @@
   m_pNotify.reset(nullptr);
   m_pApp->GetXFAFontMgr()->ReleaseDocFonts(this);
 
-  if (m_dwDocType != XFA_DOCTYPE_XDP && m_pStream && m_bOwnStream) {
-    m_pStream->Release();
-    m_pStream = nullptr;
-  }
-
   for (const auto& pair : m_HashToDibDpiMap)
     delete pair.second.pDibSource;
 
@@ -417,21 +403,21 @@
   CPDF_StreamAcc streamAcc;
   streamAcc.LoadAllData(pStream);
 
-  IFX_SeekableReadStream* pImageFileRead = IFX_MemoryStream::Create(
-      (uint8_t*)streamAcc.GetData(), streamAcc.GetSize());
+  CFX_RetainPtr<IFX_SeekableReadStream> pImageFileRead =
+      IFX_MemoryStream::Create((uint8_t*)streamAcc.GetData(),
+                               streamAcc.GetSize());
 
   CFX_DIBitmap* pDibSource = XFA_LoadImageFromBuffer(
       pImageFileRead, FXCODEC_IMAGE_UNKNOWN, iImageXDpi, iImageYDpi);
   m_HashToDibDpiMap[dwHash] = {pDibSource, iImageXDpi, iImageYDpi};
-  pImageFileRead->Release();
   return pDibSource;
 }
 
-bool CXFA_FFDoc::SavePackage(XFA_HashCode code,
-                             IFX_SeekableWriteStream* pFile,
-                             CXFA_ChecksumContext* pCSContext) {
+bool CXFA_FFDoc::SavePackage(
+    XFA_HashCode code,
+    const CFX_RetainPtr<IFX_SeekableWriteStream>& pFile,
+    CXFA_ChecksumContext* pCSContext) {
   CXFA_Document* doc = m_pDocumentParser->GetDocument();
-
   std::unique_ptr<CXFA_DataExporter> pExport(new CXFA_DataExporter(doc));
   CXFA_Node* pNode = code == XFA_HASHCODE_Xfa ? doc->GetRoot()
                                               : ToNode(doc->GetXFAObject(code));
@@ -446,8 +432,10 @@
       pFile, pNode, 0, bsChecksum.GetLength() ? bsChecksum.c_str() : nullptr);
 }
 
-bool CXFA_FFDoc::ImportData(IFX_SeekableReadStream* pStream, bool bXDP) {
-  std::unique_ptr<CXFA_DataImporter> importer(
-      new CXFA_DataImporter(m_pDocumentParser->GetDocument()));
+bool CXFA_FFDoc::ImportData(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pStream,
+    bool bXDP) {
+  auto importer =
+      pdfium::MakeUnique<CXFA_DataImporter>(m_pDocumentParser->GetDocument());
   return importer->ImportData(pStream);
 }
diff --git a/xfa/fxfa/app/xfa_ffwidget.cpp b/xfa/fxfa/app/xfa_ffwidget.cpp
index dfe418b..99333ba 100644
--- a/xfa/fxfa/app/xfa_ffwidget.cpp
+++ b/xfa/fxfa/app/xfa_ffwidget.cpp
@@ -1054,7 +1054,7 @@
   FXCODEC_IMAGE_TYPE type = XFA_GetImageType(wsContentType);
   CFX_ByteString bsContent;
   uint8_t* pImageBuffer = nullptr;
-  IFX_SeekableReadStream* pImageFileRead = nullptr;
+  CFX_RetainPtr<IFX_SeekableReadStream> pImageFileRead;
   if (wsImage.GetLength() > 0) {
     XFA_ATTRIBUTEENUM iEncoding =
         (XFA_ATTRIBUTEENUM)pImage->GetTransferEncoding();
@@ -1092,7 +1092,6 @@
   CFX_DIBitmap* pBitmap =
       XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
   FX_Free(pImageBuffer);
-  pImageFileRead->Release();
   return pBitmap;
 }
 static FXDIB_Format XFA_GetDIBFormat(FXCODEC_IMAGE_TYPE type,
@@ -1115,18 +1114,20 @@
   }
   return dibFormat;
 }
-CFX_DIBitmap* XFA_LoadImageFromBuffer(IFX_SeekableReadStream* pImageFileRead,
-                                      FXCODEC_IMAGE_TYPE type,
-                                      int32_t& iImageXDpi,
-                                      int32_t& iImageYDpi) {
+
+CFX_DIBitmap* XFA_LoadImageFromBuffer(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pImageFileRead,
+    FXCODEC_IMAGE_TYPE type,
+    int32_t& iImageXDpi,
+    int32_t& iImageYDpi) {
   CFX_GEModule* pGeModule = CFX_GEModule::Get();
-  if (!pGeModule) {
+  if (!pGeModule)
     return nullptr;
-  }
+
   CCodec_ModuleMgr* pCodecMgr = pGeModule->GetCodecModule();
-  if (!pCodecMgr) {
+  if (!pCodecMgr)
     return nullptr;
-  }
+
   CFX_DIBAttribute dibAttr;
   CFX_DIBitmap* pBitmap = nullptr;
   CCodec_ProgressiveDecoder* pProgressiveDecoder =
diff --git a/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp b/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp
index 8bcdcdd..01328f2 100644
--- a/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp
+++ b/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp
@@ -4924,7 +4924,7 @@
   std::unique_ptr<CFXJSE_Value> argOne = GetSimpleValue(pThis, args, 0);
   CFX_ByteString urlString;
   ValueToUTF8String(argOne.get(), urlString);
-  IFX_SeekableReadStream* pFile = pAppProvider->DownloadURL(
+  CFX_RetainPtr<IFX_SeekableReadStream> pFile = pAppProvider->DownloadURL(
       CFX_WideString::FromUTF8(urlString.AsStringC()));
   if (!pFile)
     return;
@@ -4933,7 +4933,6 @@
   std::unique_ptr<uint8_t> pData(FX_Alloc(uint8_t, size));
   pFile->ReadBlock(pData.get(), size);
   args.GetReturnValue()->SetString(CFX_ByteStringC(pData.get(), size));
-  pFile->Release();
 }
 
 // static
diff --git a/xfa/fxfa/fxfa.h b/xfa/fxfa/fxfa.h
index d3ae838..ec5282c 100644
--- a/xfa/fxfa/fxfa.h
+++ b/xfa/fxfa/fxfa.h
@@ -9,6 +9,7 @@
 
 #include <vector>
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "xfa/fxfa/fxfa_basic.h"
 #include "xfa/fxfa/fxfa_widget.h"
 
@@ -230,7 +231,8 @@
    * @param[in] wsURL - http, ftp, such as
    * "http://www.w3.org/TR/REC-xml-names/".
    */
-  virtual IFX_SeekableReadStream* DownloadURL(const CFX_WideString& wsURL) = 0;
+  virtual CFX_RetainPtr<IFX_SeekableReadStream> DownloadURL(
+      const CFX_WideString& wsURL) = 0;
 
   /**
    * POST data to the given url.
@@ -320,7 +322,7 @@
   virtual bool SetGlobalProperty(CXFA_FFDoc* hDoc,
                                  const CFX_ByteStringC& szPropName,
                                  CFXJSE_Value* pValue) = 0;
-  virtual IFX_SeekableReadStream* OpenLinkedFile(
+  virtual CFX_RetainPtr<IFX_SeekableReadStream> OpenLinkedFile(
       CXFA_FFDoc* hDoc,
       const CFX_WideString& wsLink) = 0;
 };
diff --git a/xfa/fxfa/parser/cxfa_dataexporter.cpp b/xfa/fxfa/parser/cxfa_dataexporter.cpp
index f97e8a3..9760261 100644
--- a/xfa/fxfa/parser/cxfa_dataexporter.cpp
+++ b/xfa/fxfa/parser/cxfa_dataexporter.cpp
@@ -197,17 +197,20 @@
         if (!pRichTextXML)
           break;
 
-        IFX_MemoryStream* pMemStream = IFX_MemoryStream::Create(true);
+        CFX_RetainPtr<IFX_MemoryStream> pMemStream =
+            IFX_MemoryStream::Create(true);
+
+        // Note: ambiguous without cast below.
         IFGAS_Stream* pTempStream = IFGAS_Stream::CreateStream(
-            (IFX_SeekableWriteStream*)pMemStream, FX_STREAMACCESS_Text |
-                                                      FX_STREAMACCESS_Write |
-                                                      FX_STREAMACCESS_Append);
+            CFX_RetainPtr<IFX_SeekableWriteStream>(pMemStream),
+            FX_STREAMACCESS_Text | FX_STREAMACCESS_Write |
+                FX_STREAMACCESS_Append);
+
         pTempStream->SetCodePage(FX_CODEPAGE_UTF8);
         pRichTextXML->SaveXMLNode(pTempStream);
         wsChildren += CFX_WideString::FromUTF8(
             CFX_ByteStringC(pMemStream->GetBuffer(), pMemStream->GetSize()));
         pTempStream->Release();
-        pMemStream->Release();
       } else if (pRawValueNode->GetElementType() == XFA_Element::Sharpxml &&
                  wsContentType == FX_WSTRC(L"text/xml")) {
         CFX_WideString wsRawValue;
@@ -444,18 +447,20 @@
   ASSERT(m_pDocument);
 }
 
-bool CXFA_DataExporter::Export(IFX_SeekableWriteStream* pWrite) {
+bool CXFA_DataExporter::Export(
+    const CFX_RetainPtr<IFX_SeekableWriteStream>& pWrite) {
   return Export(pWrite, m_pDocument->GetRoot(), 0, nullptr);
 }
 
-bool CXFA_DataExporter::Export(IFX_SeekableWriteStream* pWrite,
-                               CXFA_Node* pNode,
-                               uint32_t dwFlag,
-                               const FX_CHAR* pChecksum) {
-  if (!pWrite) {
-    ASSERT(false);
+bool CXFA_DataExporter::Export(
+    const CFX_RetainPtr<IFX_SeekableWriteStream>& pWrite,
+    CXFA_Node* pNode,
+    uint32_t dwFlag,
+    const FX_CHAR* pChecksum) {
+  ASSERT(pWrite);
+  if (!pWrite)
     return false;
-  }
+
   IFGAS_Stream* pStream = IFGAS_Stream::CreateStream(
       pWrite,
       FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
diff --git a/xfa/fxfa/parser/cxfa_dataexporter.h b/xfa/fxfa/parser/cxfa_dataexporter.h
index 8496e0d..f3c784a 100644
--- a/xfa/fxfa/parser/cxfa_dataexporter.h
+++ b/xfa/fxfa/parser/cxfa_dataexporter.h
@@ -7,6 +7,7 @@
 #ifndef XFA_FXFA_PARSER_CXFA_DATAEXPORTER_H_
 #define XFA_FXFA_PARSER_CXFA_DATAEXPORTER_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_string.h"
 
 class CXFA_Document;
@@ -18,8 +19,8 @@
  public:
   explicit CXFA_DataExporter(CXFA_Document* pDocument);
 
-  bool Export(IFX_SeekableWriteStream* pWrite);
-  bool Export(IFX_SeekableWriteStream* pWrite,
+  bool Export(const CFX_RetainPtr<IFX_SeekableWriteStream>& pWrite);
+  bool Export(const CFX_RetainPtr<IFX_SeekableWriteStream>& pWrite,
               CXFA_Node* pNode,
               uint32_t dwFlag,
               const FX_CHAR* pChecksum);
diff --git a/xfa/fxfa/parser/cxfa_dataimporter.cpp b/xfa/fxfa/parser/cxfa_dataimporter.cpp
index c0c798d..0199028 100644
--- a/xfa/fxfa/parser/cxfa_dataimporter.cpp
+++ b/xfa/fxfa/parser/cxfa_dataimporter.cpp
@@ -9,6 +9,7 @@
 #include <memory>
 
 #include "core/fxcrt/fx_stream.h"
+#include "third_party/base/ptr_util.h"
 #include "xfa/fde/xml/fde_xml_imp.h"
 #include "xfa/fxfa/fxfa.h"
 #include "xfa/fxfa/fxfa_basic.h"
@@ -21,9 +22,10 @@
   ASSERT(m_pDocument);
 }
 
-bool CXFA_DataImporter::ImportData(IFX_SeekableReadStream* pDataDocument) {
-  std::unique_ptr<CXFA_SimpleParser> pDataDocumentParser(
-      new CXFA_SimpleParser(m_pDocument, false));
+bool CXFA_DataImporter::ImportData(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pDataDocument) {
+  auto pDataDocumentParser =
+      pdfium::MakeUnique<CXFA_SimpleParser>(m_pDocument, false);
   if (pDataDocumentParser->StartParse(pDataDocument, XFA_XDPPACKET_Datasets) !=
       XFA_PARSESTATUS_Ready) {
     return false;
diff --git a/xfa/fxfa/parser/cxfa_dataimporter.h b/xfa/fxfa/parser/cxfa_dataimporter.h
index 86e41a8..bf04b05 100644
--- a/xfa/fxfa/parser/cxfa_dataimporter.h
+++ b/xfa/fxfa/parser/cxfa_dataimporter.h
@@ -7,6 +7,7 @@
 #ifndef XFA_FXFA_PARSER_CXFA_DATAIMPORTER_H_
 #define XFA_FXFA_PARSER_CXFA_DATAIMPORTER_H_
 
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_system.h"
 
 class CXFA_Document;
@@ -16,7 +17,7 @@
  public:
   explicit CXFA_DataImporter(CXFA_Document* pDocument);
 
-  bool ImportData(IFX_SeekableReadStream* pDataDocument);
+  bool ImportData(const CFX_RetainPtr<IFX_SeekableReadStream>& pDataDocument);
 
  protected:
   CXFA_Document* const m_pDocument;
diff --git a/xfa/fxfa/parser/cxfa_document_parser.cpp b/xfa/fxfa/parser/cxfa_document_parser.cpp
index fe3cb93..1bf327d 100644
--- a/xfa/fxfa/parser/cxfa_document_parser.cpp
+++ b/xfa/fxfa/parser/cxfa_document_parser.cpp
@@ -15,8 +15,9 @@
 CXFA_DocumentParser::~CXFA_DocumentParser() {
 }
 
-int32_t CXFA_DocumentParser::StartParse(IFX_SeekableReadStream* pStream,
-                                        XFA_XDPPACKET ePacketID) {
+int32_t CXFA_DocumentParser::StartParse(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pStream,
+    XFA_XDPPACKET ePacketID) {
   m_pDocument.reset();
   m_nodeParser.CloseParser();
 
diff --git a/xfa/fxfa/parser/cxfa_document_parser.h b/xfa/fxfa/parser/cxfa_document_parser.h
index 29aeca3..617bddf 100644
--- a/xfa/fxfa/parser/cxfa_document_parser.h
+++ b/xfa/fxfa/parser/cxfa_document_parser.h
@@ -23,7 +23,8 @@
   explicit CXFA_DocumentParser(CXFA_FFNotify* pNotify);
   ~CXFA_DocumentParser();
 
-  int32_t StartParse(IFX_SeekableReadStream* pStream, XFA_XDPPACKET ePacketID);
+  int32_t StartParse(const CFX_RetainPtr<IFX_SeekableReadStream>& pStream,
+                     XFA_XDPPACKET ePacketID);
   int32_t DoParse(IFX_Pause* pPause);
 
   CFDE_XMLDoc* GetXMLDoc() const;
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 16062f7..5dd6c52 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -1441,13 +1441,16 @@
       }
       XFA_DataExporter_DealWithDataGroupNode(this);
     }
-    std::unique_ptr<IFX_MemoryStream, ReleaseDeleter<IFX_MemoryStream>>
-        pMemoryStream(IFX_MemoryStream::Create(true));
+    CFX_RetainPtr<IFX_MemoryStream> pMemoryStream =
+        IFX_MemoryStream::Create(true);
+
+    // Note: ambiguious below without static_cast.
     std::unique_ptr<IFGAS_Stream, ReleaseDeleter<IFGAS_Stream>> pStream(
         IFGAS_Stream::CreateStream(
-            static_cast<IFX_SeekableWriteStream*>(pMemoryStream.get()),
+            CFX_RetainPtr<IFX_SeekableWriteStream>(pMemoryStream),
             FX_STREAMACCESS_Text | FX_STREAMACCESS_Write |
                 FX_STREAMACCESS_Append));
+
     if (!pStream) {
       pArguments->GetReturnValue()->SetString(bsXMLHeader);
       return;
diff --git a/xfa/fxfa/parser/cxfa_simple_parser.cpp b/xfa/fxfa/parser/cxfa_simple_parser.cpp
index a9025fa..2329e86 100644
--- a/xfa/fxfa/parser/cxfa_simple_parser.cpp
+++ b/xfa/fxfa/parser/cxfa_simple_parser.cpp
@@ -277,8 +277,9 @@
   m_pFactory = pFactory;
 }
 
-int32_t CXFA_SimpleParser::StartParse(IFX_SeekableReadStream* pStream,
-                                      XFA_XDPPACKET ePacketID) {
+int32_t CXFA_SimpleParser::StartParse(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pStream,
+    XFA_XDPPACKET ePacketID) {
   CloseParser();
   m_pFileRead = pStream;
   m_pStream.reset(IFGAS_Stream::CreateStream(
diff --git a/xfa/fxfa/parser/cxfa_simple_parser.h b/xfa/fxfa/parser/cxfa_simple_parser.h
index fa9fdb3..559df71 100644
--- a/xfa/fxfa/parser/cxfa_simple_parser.h
+++ b/xfa/fxfa/parser/cxfa_simple_parser.h
@@ -24,7 +24,8 @@
   CXFA_SimpleParser(CXFA_Document* pFactory, bool bDocumentParser);
   ~CXFA_SimpleParser();
 
-  int32_t StartParse(IFX_SeekableReadStream* pStream, XFA_XDPPACKET ePacketID);
+  int32_t StartParse(const CFX_RetainPtr<IFX_SeekableReadStream>& pStream,
+                     XFA_XDPPACKET ePacketID);
   int32_t DoParse(IFX_Pause* pPause);
   int32_t ParseXMLData(const CFX_WideString& wsXML,
                        CFDE_XMLNode*& pXMLNode,
@@ -78,7 +79,7 @@
   CXFA_XMLParser* m_pXMLParser;
   std::unique_ptr<CFDE_XMLDoc> m_pXMLDoc;
   std::unique_ptr<IFGAS_Stream, ReleaseDeleter<IFGAS_Stream>> m_pStream;
-  IFX_SeekableReadStream* m_pFileRead;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pFileRead;
   CXFA_Document* m_pFactory;
   CXFA_Node* m_pRootNode;
   XFA_XDPPACKET m_ePacketID;
diff --git a/xfa/fxfa/xfa_checksum.h b/xfa/fxfa/xfa_checksum.h
index aaa587f..32862c9 100644
--- a/xfa/fxfa/xfa_checksum.h
+++ b/xfa/fxfa/xfa_checksum.h
@@ -62,7 +62,7 @@
 
   void StartChecksum();
   void Update(const CFX_ByteStringC& bsText);
-  bool UpdateChecksum(IFX_SeekableReadStream* pSrcFile,
+  bool UpdateChecksum(const CFX_RetainPtr<IFX_SeekableReadStream>& pSrcFile,
                       FX_FILESIZE offset = 0,
                       size_t size = 0);
   void FinishChecksum();
diff --git a/xfa/fxfa/xfa_ffapp.h b/xfa/fxfa/xfa_ffapp.h
index 95013ef..5883be2 100644
--- a/xfa/fxfa/xfa_ffapp.h
+++ b/xfa/fxfa/xfa_ffapp.h
@@ -12,6 +12,7 @@
 
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
+#include "core/fxcrt/cfx_retain_ptr.h"
 #include "xfa/fgas/font/cfgas_fontmgr.h"
 #include "xfa/fwl/core/cfwl_app.h"
 #include "xfa/fxfa/fxfa.h"
@@ -26,7 +27,7 @@
 
 // Layering prevents fxcrt from knowing about CPDF_Streams; this could go
 // in fpdfsdk, but it is XFA-Only.
-IFX_SeekableReadStream* MakeSeekableReadStream(
+CFX_RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream(
     const std::vector<CPDF_Stream*>& streams);
 
 class CXFA_FFApp {
@@ -35,8 +36,7 @@
   ~CXFA_FFApp();
 
   CXFA_FFDoc* CreateDoc(IXFA_DocEnvironment* pDocEnvironment,
-                        IFX_SeekableReadStream* pStream,
-                        bool bTakeOverFile);
+                        const CFX_RetainPtr<IFX_SeekableReadStream>& pStream);
   CXFA_FFDoc* CreateDoc(IXFA_DocEnvironment* pDocEnvironment,
                         CPDF_Document* pPDFDoc);
   void SetDefaultFontMgr(std::unique_ptr<CXFA_DefFontMgr> pFontMgr);
diff --git a/xfa/fxfa/xfa_ffdoc.h b/xfa/fxfa/xfa_ffdoc.h
index a31f6d7..4407970 100644
--- a/xfa/fxfa/xfa_ffdoc.h
+++ b/xfa/fxfa/xfa_ffdoc.h
@@ -40,7 +40,7 @@
 
   CXFA_FFDocView* CreateDocView(uint32_t dwView = 0);
 
-  bool OpenDoc(IFX_SeekableReadStream* pStream, bool bTakeOverFile);
+  bool OpenDoc(const CFX_RetainPtr<IFX_SeekableReadStream>& pStream);
   bool OpenDoc(CPDF_Document* pPDFDoc);
   bool CloseDoc();
 
@@ -54,21 +54,21 @@
                                  int32_t& iImageYDpi);
 
   bool SavePackage(XFA_HashCode code,
-                   IFX_SeekableWriteStream* pFile,
+                   const CFX_RetainPtr<IFX_SeekableWriteStream>& pFile,
                    CXFA_ChecksumContext* pCSContext);
-  bool ImportData(IFX_SeekableReadStream* pStream, bool bXDP = true);
+  bool ImportData(const CFX_RetainPtr<IFX_SeekableReadStream>& pStream,
+                  bool bXDP = true);
 
  protected:
   IXFA_DocEnvironment* const m_pDocEnvironment;
   std::unique_ptr<CXFA_DocumentParser> m_pDocumentParser;
-  IFX_SeekableReadStream* m_pStream;
+  CFX_RetainPtr<IFX_SeekableReadStream> m_pStream;
   CXFA_FFApp* m_pApp;
   std::unique_ptr<CXFA_FFNotify> m_pNotify;
   CPDF_Document* m_pPDFDoc;
   std::map<uint32_t, FX_IMAGEDIB_AND_DPI> m_HashToDibDpiMap;
   std::map<uint32_t, std::unique_ptr<CXFA_FFDocView>> m_TypeToDocViewMap;
   uint32_t m_dwDocType;
-  bool m_bOwnStream;
 };
 
 #endif  // XFA_FXFA_XFA_FFDOC_H_
diff --git a/xfa/fxfa/xfa_ffwidget.h b/xfa/fxfa/xfa_ffwidget.h
index 9e02680..031c35b 100644
--- a/xfa/fxfa/xfa_ffwidget.h
+++ b/xfa/fxfa/xfa_ffwidget.h
@@ -161,15 +161,19 @@
                    int32_t iImageYDpi,
                    int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left,
                    int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top);
+
 CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc* pDoc,
                                 CXFA_Image* pImage,
                                 bool& bNameImage,
                                 int32_t& iImageXDpi,
                                 int32_t& iImageYDpi);
-CFX_DIBitmap* XFA_LoadImageFromBuffer(IFX_SeekableReadStream* pImageFileRead,
-                                      FXCODEC_IMAGE_TYPE type,
-                                      int32_t& iImageXDpi,
-                                      int32_t& iImageYDpi);
+
+CFX_DIBitmap* XFA_LoadImageFromBuffer(
+    const CFX_RetainPtr<IFX_SeekableReadStream>& pImageFileRead,
+    FXCODEC_IMAGE_TYPE type,
+    int32_t& iImageXDpi,
+    int32_t& iImageYDpi);
+
 FXCODEC_IMAGE_TYPE XFA_GetImageType(const CFX_WideString& wsType);
 FX_CHAR* XFA_Base64Encode(const uint8_t* buf, int32_t buf_len);
 void XFA_RectWidthoutMargin(CFX_RectF& rt,