Get rid of CCodec_ModuleMgr::GetBasicModule().

The CCodec_BasicModule class consists of a set of methods that can all
be static. Make the methods static, and make sure CCodec_BasicModule
cannot be instantiated. Then CCodec_ModuleMgr::GetBasicModule() becomes
pointless and all the callers can just call CCodec_BasicModule directly.

While making the above changes, move the CCodec_BasicModule code into
its own separate file.

Change-Id: I11981544f304dbd98ec8cc9e94506209758a338e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/55030
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/render/cpdf_dibbase.cpp b/core/fpdfapi/render/cpdf_dibbase.cpp
index 9ca9833..6fc101d 100644
--- a/core/fpdfapi/render/cpdf_dibbase.cpp
+++ b/core/fpdfapi/render/cpdf_dibbase.cpp
@@ -487,8 +487,7 @@
     m_pDecoder = CreateFlateDecoder(src_span, m_Width, m_Height, m_nComponents,
                                     m_bpc, pParams);
   } else if (decoder == "RunLengthDecode") {
-    CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
-    m_pDecoder = pEncoders->GetBasicModule()->CreateRunLengthDecoder(
+    m_pDecoder = CCodec_BasicModule::CreateRunLengthDecoder(
         src_span, m_Width, m_Height, m_nComponents, m_bpc);
   } else if (decoder == "DCTDecode") {
     if (!CreateDCTDecoder(src_span, pParams))
diff --git a/core/fxcodec/BUILD.gn b/core/fxcodec/BUILD.gn
index 5d49f82..0617ef8 100644
--- a/core/fxcodec/BUILD.gn
+++ b/core/fxcodec/BUILD.gn
@@ -9,6 +9,7 @@
 jumbo_source_set("fxcodec") {
   sources = [
     "JBig2_DocumentContext.h",
+    "codec/ccodec_basicmodule.cpp",
     "codec/ccodec_basicmodule.h",
     "codec/ccodec_faxmodule.cpp",
     "codec/ccodec_faxmodule.h",
diff --git a/core/fxcodec/codec/ccodec_basicmodule.cpp b/core/fxcodec/codec/ccodec_basicmodule.cpp
new file mode 100644
index 0000000..ff3824d
--- /dev/null
+++ b/core/fxcodec/codec/ccodec_basicmodule.cpp
@@ -0,0 +1,372 @@
+// Copyright 2019 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fxcodec/codec/ccodec_basicmodule.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "core/fxcodec/codec/ccodec_scanlinedecoder.h"
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+class CCodec_RLScanlineDecoder final : public CCodec_ScanlineDecoder {
+ public:
+  CCodec_RLScanlineDecoder();
+  ~CCodec_RLScanlineDecoder() override;
+
+  bool Create(pdfium::span<const uint8_t> src_buf,
+              int width,
+              int height,
+              int nComps,
+              int bpc);
+
+  // CCodec_ScanlineDecoder
+  bool v_Rewind() override;
+  uint8_t* v_GetNextLine() override;
+  uint32_t GetSrcOffset() override { return m_SrcOffset; }
+
+ private:
+  bool CheckDestSize();
+  void GetNextOperator();
+  void UpdateOperator(uint8_t used_bytes);
+
+  std::unique_ptr<uint8_t, FxFreeDeleter> m_pScanline;
+  pdfium::span<const uint8_t> m_SrcBuf;
+  size_t m_dwLineBytes = 0;
+  size_t m_SrcOffset = 0;
+  bool m_bEOD = false;
+  uint8_t m_Operator = 0;
+};
+
+CCodec_RLScanlineDecoder::CCodec_RLScanlineDecoder() = default;
+
+CCodec_RLScanlineDecoder::~CCodec_RLScanlineDecoder() = default;
+
+bool CCodec_RLScanlineDecoder::CheckDestSize() {
+  size_t i = 0;
+  uint32_t old_size = 0;
+  uint32_t dest_size = 0;
+  while (i < m_SrcBuf.size()) {
+    if (m_SrcBuf[i] < 128) {
+      old_size = dest_size;
+      dest_size += m_SrcBuf[i] + 1;
+      if (dest_size < old_size) {
+        return false;
+      }
+      i += m_SrcBuf[i] + 2;
+    } else if (m_SrcBuf[i] > 128) {
+      old_size = dest_size;
+      dest_size += 257 - m_SrcBuf[i];
+      if (dest_size < old_size) {
+        return false;
+      }
+      i += 2;
+    } else {
+      break;
+    }
+  }
+  if (((uint32_t)m_OrigWidth * m_nComps * m_bpc * m_OrigHeight + 7) / 8 >
+      dest_size) {
+    return false;
+  }
+  return true;
+}
+
+bool CCodec_RLScanlineDecoder::Create(pdfium::span<const uint8_t> src_buf,
+                                      int width,
+                                      int height,
+                                      int nComps,
+                                      int bpc) {
+  m_SrcBuf = src_buf;
+  m_OutputWidth = m_OrigWidth = width;
+  m_OutputHeight = m_OrigHeight = height;
+  m_nComps = nComps;
+  m_bpc = bpc;
+  // Aligning the pitch to 4 bytes requires an integer overflow check.
+  FX_SAFE_UINT32 pitch = width;
+  pitch *= nComps;
+  pitch *= bpc;
+  pitch += 31;
+  pitch /= 32;
+  pitch *= 4;
+  if (!pitch.IsValid()) {
+    return false;
+  }
+  m_Pitch = pitch.ValueOrDie();
+  // Overflow should already have been checked before this is called.
+  m_dwLineBytes = (static_cast<uint32_t>(width) * nComps * bpc + 7) / 8;
+  m_pScanline.reset(FX_Alloc(uint8_t, m_Pitch));
+  return CheckDestSize();
+}
+
+bool CCodec_RLScanlineDecoder::v_Rewind() {
+  memset(m_pScanline.get(), 0, m_Pitch);
+  m_SrcOffset = 0;
+  m_bEOD = false;
+  m_Operator = 0;
+  return true;
+}
+
+uint8_t* CCodec_RLScanlineDecoder::v_GetNextLine() {
+  if (m_SrcOffset == 0) {
+    GetNextOperator();
+  } else if (m_bEOD) {
+    return nullptr;
+  }
+  memset(m_pScanline.get(), 0, m_Pitch);
+  uint32_t col_pos = 0;
+  bool eol = false;
+  while (m_SrcOffset < m_SrcBuf.size() && !eol) {
+    if (m_Operator < 128) {
+      uint32_t copy_len = m_Operator + 1;
+      if (col_pos + copy_len >= m_dwLineBytes) {
+        copy_len = m_dwLineBytes - col_pos;
+        eol = true;
+      }
+      if (copy_len >= m_SrcBuf.size() - m_SrcOffset) {
+        copy_len = m_SrcBuf.size() - m_SrcOffset;
+        m_bEOD = true;
+      }
+      auto copy_span = m_SrcBuf.subspan(m_SrcOffset, copy_len);
+      memcpy(m_pScanline.get() + col_pos, copy_span.data(), copy_span.size());
+      col_pos += copy_len;
+      UpdateOperator((uint8_t)copy_len);
+    } else if (m_Operator > 128) {
+      int fill = 0;
+      if (m_SrcOffset - 1 < m_SrcBuf.size() - 1) {
+        fill = m_SrcBuf[m_SrcOffset];
+      }
+      uint32_t duplicate_len = 257 - m_Operator;
+      if (col_pos + duplicate_len >= m_dwLineBytes) {
+        duplicate_len = m_dwLineBytes - col_pos;
+        eol = true;
+      }
+      memset(m_pScanline.get() + col_pos, fill, duplicate_len);
+      col_pos += duplicate_len;
+      UpdateOperator((uint8_t)duplicate_len);
+    } else {
+      m_bEOD = true;
+      break;
+    }
+  }
+  return m_pScanline.get();
+}
+
+void CCodec_RLScanlineDecoder::GetNextOperator() {
+  if (m_SrcOffset >= m_SrcBuf.size()) {
+    m_Operator = 128;
+    return;
+  }
+  m_Operator = m_SrcBuf[m_SrcOffset];
+  m_SrcOffset++;
+}
+void CCodec_RLScanlineDecoder::UpdateOperator(uint8_t used_bytes) {
+  if (used_bytes == 0) {
+    return;
+  }
+  if (m_Operator < 128) {
+    ASSERT((uint32_t)m_Operator + 1 >= used_bytes);
+    if (used_bytes == m_Operator + 1) {
+      m_SrcOffset += used_bytes;
+      GetNextOperator();
+      return;
+    }
+    m_Operator -= used_bytes;
+    m_SrcOffset += used_bytes;
+    if (m_SrcOffset >= m_SrcBuf.size()) {
+      m_Operator = 128;
+    }
+    return;
+  }
+  uint8_t count = 257 - m_Operator;
+  ASSERT((uint32_t)count >= used_bytes);
+  if (used_bytes == count) {
+    m_SrcOffset++;
+    GetNextOperator();
+    return;
+  }
+  count -= used_bytes;
+  m_Operator = 257 - count;
+}
+
+}  // namespace
+
+// static
+std::unique_ptr<CCodec_ScanlineDecoder>
+CCodec_BasicModule::CreateRunLengthDecoder(pdfium::span<const uint8_t> src_buf,
+                                           int width,
+                                           int height,
+                                           int nComps,
+                                           int bpc) {
+  auto pDecoder = pdfium::MakeUnique<CCodec_RLScanlineDecoder>();
+  if (!pDecoder->Create(src_buf, width, height, nComps, bpc))
+    return nullptr;
+
+  return std::move(pDecoder);
+}
+
+// static
+bool CCodec_BasicModule::RunLengthEncode(
+    pdfium::span<const uint8_t> src_span,
+    std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+    uint32_t* dest_size) {
+  // Check inputs
+  if (src_span.empty() || !dest_buf || !dest_size)
+    return false;
+
+  // Edge case
+  if (src_span.size() == 1) {
+    *dest_size = 3;
+    dest_buf->reset(FX_Alloc(uint8_t, *dest_size));
+    auto dest_buf_span = pdfium::make_span(dest_buf->get(), *dest_size);
+    dest_buf_span[0] = 0;
+    dest_buf_span[1] = src_span[0];
+    dest_buf_span[2] = 128;
+    return true;
+  }
+
+  // Worst case: 1 nonmatch, 2 match, 1 nonmatch, 2 match, etc. This becomes
+  // 4 output chars for every 3 input, plus up to 4 more for the 1-2 chars
+  // rounded off plus the terminating character.
+  FX_SAFE_SIZE_T estimated_size = src_span.size();
+  estimated_size += 2;
+  estimated_size /= 3;
+  estimated_size *= 4;
+  estimated_size += 1;
+  dest_buf->reset(FX_Alloc(uint8_t, estimated_size.ValueOrDie()));
+
+  // Set up pointers.
+  uint8_t* out = dest_buf->get();
+  uint32_t run_start = 0;
+  uint32_t run_end = 1;
+  uint8_t x = src_span[run_start];
+  uint8_t y = src_span[run_end];
+  while (run_end < src_span.size()) {
+    size_t max_len = std::min<size_t>(128, src_span.size() - run_start);
+    while (x == y && (run_end - run_start < max_len - 1))
+      y = src_span[++run_end];
+
+    // Reached end with matched run. Update variables to expected values.
+    if (x == y) {
+      run_end++;
+      if (run_end < src_span.size())
+        y = src_span[run_end];
+    }
+    if (run_end - run_start > 1) {  // Matched run but not at end of input.
+      out[0] = 257 - (run_end - run_start);
+      out[1] = x;
+      x = y;
+      run_start = run_end;
+      run_end++;
+      if (run_end < src_span.size())
+        y = src_span[run_end];
+      out += 2;
+      continue;
+    }
+    // Mismatched run
+    while (x != y && run_end <= run_start + max_len) {
+      out[run_end - run_start] = x;
+      x = y;
+      run_end++;
+      if (run_end == src_span.size()) {
+        if (run_end <= run_start + max_len) {
+          out[run_end - run_start] = x;
+          run_end++;
+        }
+        break;
+      }
+      y = src_span[run_end];
+    }
+    out[0] = run_end - run_start - 2;
+    out += run_end - run_start;
+    run_start = run_end - 1;
+  }
+  if (run_start < src_span.size()) {  // 1 leftover character
+    out[0] = 0;
+    out[1] = x;
+    out += 2;
+  }
+  *out = 128;
+  *dest_size = out + 1 - dest_buf->get();
+  return true;
+}
+
+// static
+bool CCodec_BasicModule::A85Encode(
+    pdfium::span<const uint8_t> src_span,
+    std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+    uint32_t* dest_size) {
+  // Check inputs.
+  if (!dest_buf || !dest_size)
+    return false;
+
+  if (src_span.empty()) {
+    *dest_size = 0;
+    return false;
+  }
+
+  // Worst case: 5 output for each 4 input (plus up to 4 from leftover), plus
+  // 2 character new lines each 75 output chars plus 2 termination chars. May
+  // have fewer if there are special "z" chars.
+  FX_SAFE_SIZE_T estimated_size = src_span.size();
+  estimated_size /= 4;
+  estimated_size *= 5;
+  estimated_size += 4;
+  estimated_size += src_span.size() / 30;
+  estimated_size += 2;
+  dest_buf->reset(FX_Alloc(uint8_t, estimated_size.ValueOrDie()));
+
+  // Set up pointers.
+  uint8_t* out = dest_buf->get();
+  uint32_t pos = 0;
+  uint32_t line_length = 0;
+  while (src_span.size() >= 4 && pos < src_span.size() - 3) {
+    uint32_t val = ((uint32_t)(src_span[pos]) << 24) +
+                   ((uint32_t)(src_span[pos + 1]) << 16) +
+                   ((uint32_t)(src_span[pos + 2]) << 8) +
+                   (uint32_t)(src_span[pos + 3]);
+    pos += 4;
+    if (val == 0) {  // All zero special case
+      *out = 'z';
+      out++;
+      line_length++;
+    } else {  // Compute base 85 characters and add 33.
+      for (int i = 4; i >= 0; i--) {
+        out[i] = (uint8_t)(val % 85) + 33;
+        val = val / 85;
+      }
+      out += 5;
+      line_length += 5;
+    }
+    if (line_length >= 75) {  // Add a return.
+      *out++ = '\r';
+      *out++ = '\n';
+      line_length = 0;
+    }
+  }
+  if (pos < src_span.size()) {  // Leftover bytes
+    uint32_t val = 0;
+    int count = 0;
+    while (pos < src_span.size()) {
+      val += (uint32_t)(src_span[pos]) << (8 * (3 - count));
+      count++;
+      pos++;
+    }
+    for (int i = 4; i >= 0; i--) {
+      if (i <= count)
+        out[i] = (uint8_t)(val % 85) + 33;
+      val = val / 85;
+    }
+    out += count + 1;
+  }
+
+  // Terminating characters.
+  out[0] = '~';
+  out[1] = '>';
+  out += 2;
+  *dest_size = out - dest_buf->get();
+  return true;
+}
diff --git a/core/fxcodec/codec/ccodec_basicmodule.h b/core/fxcodec/codec/ccodec_basicmodule.h
index 72dd016..8f55901 100644
--- a/core/fxcodec/codec/ccodec_basicmodule.h
+++ b/core/fxcodec/codec/ccodec_basicmodule.h
@@ -17,20 +17,24 @@
 
 class CCodec_BasicModule {
  public:
-  std::unique_ptr<CCodec_ScanlineDecoder> CreateRunLengthDecoder(
+  static std::unique_ptr<CCodec_ScanlineDecoder> CreateRunLengthDecoder(
       pdfium::span<const uint8_t> src_buf,
       int width,
       int height,
       int nComps,
       int bpc);
 
-  bool RunLengthEncode(pdfium::span<const uint8_t> src_buf,
-                       std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
-                       uint32_t* dest_size);
+  static bool RunLengthEncode(pdfium::span<const uint8_t> src_buf,
+                              std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+                              uint32_t* dest_size);
 
-  bool A85Encode(pdfium::span<const uint8_t> src_buf,
-                 std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
-                 uint32_t* dest_size);
+  static bool A85Encode(pdfium::span<const uint8_t> src_buf,
+                        std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+                        uint32_t* dest_size);
+
+  CCodec_BasicModule() = delete;
+  CCodec_BasicModule(const CCodec_BasicModule&) = delete;
+  CCodec_BasicModule& operator=(const CCodec_BasicModule&) = delete;
 };
 
 #endif  // CORE_FXCODEC_CODEC_CCODEC_BASICMODULE_H_
diff --git a/core/fxcodec/codec/fx_codec.cpp b/core/fxcodec/codec/fx_codec.cpp
index 0a34a1d..e2ba733 100644
--- a/core/fxcodec/codec/fx_codec.cpp
+++ b/core/fxcodec/codec/fx_codec.cpp
@@ -11,13 +11,11 @@
 #include <memory>
 #include <utility>
 
-#include "core/fxcodec/codec/ccodec_basicmodule.h"
 #include "core/fxcodec/codec/ccodec_faxmodule.h"
 #include "core/fxcodec/codec/ccodec_iccmodule.h"
 #include "core/fxcodec/codec/ccodec_jbig2module.h"
 #include "core/fxcodec/codec/ccodec_jpegmodule.h"
 #include "core/fxcodec/codec/ccodec_jpxmodule.h"
-#include "core/fxcodec/codec/ccodec_scanlinedecoder.h"
 #include "core/fxcodec/codec/codec_int.h"
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_safe_types.h"
@@ -25,8 +23,7 @@
 #include "third_party/base/ptr_util.h"
 
 CCodec_ModuleMgr::CCodec_ModuleMgr()
-    : m_pBasicModule(pdfium::MakeUnique<CCodec_BasicModule>()),
-      m_pFaxModule(pdfium::MakeUnique<CCodec_FaxModule>()),
+    : m_pFaxModule(pdfium::MakeUnique<CCodec_FaxModule>()),
       m_pJpegModule(pdfium::MakeUnique<CCodec_JpegModule>()),
       m_pJpxModule(pdfium::MakeUnique<CCodec_JpxModule>()),
       m_pJbig2Module(pdfium::MakeUnique<CCodec_Jbig2Module>()),
@@ -34,167 +31,6 @@
 
 CCodec_ModuleMgr::~CCodec_ModuleMgr() = default;
 
-bool CCodec_BasicModule::RunLengthEncode(
-    pdfium::span<const uint8_t> src_span,
-    std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
-    uint32_t* dest_size) {
-  // Check inputs
-  if (src_span.empty() || !dest_buf || !dest_size)
-    return false;
-
-  // Edge case
-  if (src_span.size() == 1) {
-    *dest_size = 3;
-    dest_buf->reset(FX_Alloc(uint8_t, *dest_size));
-    auto dest_buf_span = pdfium::make_span(dest_buf->get(), *dest_size);
-    dest_buf_span[0] = 0;
-    dest_buf_span[1] = src_span[0];
-    dest_buf_span[2] = 128;
-    return true;
-  }
-
-  // Worst case: 1 nonmatch, 2 match, 1 nonmatch, 2 match, etc. This becomes
-  // 4 output chars for every 3 input, plus up to 4 more for the 1-2 chars
-  // rounded off plus the terminating character.
-  FX_SAFE_SIZE_T estimated_size = src_span.size();
-  estimated_size += 2;
-  estimated_size /= 3;
-  estimated_size *= 4;
-  estimated_size += 1;
-  dest_buf->reset(FX_Alloc(uint8_t, estimated_size.ValueOrDie()));
-
-  // Set up pointers.
-  uint8_t* out = dest_buf->get();
-  uint32_t run_start = 0;
-  uint32_t run_end = 1;
-  uint8_t x = src_span[run_start];
-  uint8_t y = src_span[run_end];
-  while (run_end < src_span.size()) {
-    size_t max_len = std::min<size_t>(128, src_span.size() - run_start);
-    while (x == y && (run_end - run_start < max_len - 1))
-      y = src_span[++run_end];
-
-    // Reached end with matched run. Update variables to expected values.
-    if (x == y) {
-      run_end++;
-      if (run_end < src_span.size())
-        y = src_span[run_end];
-    }
-    if (run_end - run_start > 1) {  // Matched run but not at end of input.
-      out[0] = 257 - (run_end - run_start);
-      out[1] = x;
-      x = y;
-      run_start = run_end;
-      run_end++;
-      if (run_end < src_span.size())
-        y = src_span[run_end];
-      out += 2;
-      continue;
-    }
-    // Mismatched run
-    while (x != y && run_end <= run_start + max_len) {
-      out[run_end - run_start] = x;
-      x = y;
-      run_end++;
-      if (run_end == src_span.size()) {
-        if (run_end <= run_start + max_len) {
-          out[run_end - run_start] = x;
-          run_end++;
-        }
-        break;
-      }
-      y = src_span[run_end];
-    }
-    out[0] = run_end - run_start - 2;
-    out += run_end - run_start;
-    run_start = run_end - 1;
-  }
-  if (run_start < src_span.size()) {  // 1 leftover character
-    out[0] = 0;
-    out[1] = x;
-    out += 2;
-  }
-  *out = 128;
-  *dest_size = out + 1 - dest_buf->get();
-  return true;
-}
-
-bool CCodec_BasicModule::A85Encode(
-    pdfium::span<const uint8_t> src_span,
-    std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
-    uint32_t* dest_size) {
-  // Check inputs.
-  if (!dest_buf || !dest_size)
-    return false;
-
-  if (src_span.empty()) {
-    *dest_size = 0;
-    return false;
-  }
-
-  // Worst case: 5 output for each 4 input (plus up to 4 from leftover), plus
-  // 2 character new lines each 75 output chars plus 2 termination chars. May
-  // have fewer if there are special "z" chars.
-  FX_SAFE_SIZE_T estimated_size = src_span.size();
-  estimated_size /= 4;
-  estimated_size *= 5;
-  estimated_size += 4;
-  estimated_size += src_span.size() / 30;
-  estimated_size += 2;
-  dest_buf->reset(FX_Alloc(uint8_t, estimated_size.ValueOrDie()));
-
-  // Set up pointers.
-  uint8_t* out = dest_buf->get();
-  uint32_t pos = 0;
-  uint32_t line_length = 0;
-  while (src_span.size() >= 4 && pos < src_span.size() - 3) {
-    uint32_t val = ((uint32_t)(src_span[pos]) << 24) +
-                   ((uint32_t)(src_span[pos + 1]) << 16) +
-                   ((uint32_t)(src_span[pos + 2]) << 8) +
-                   (uint32_t)(src_span[pos + 3]);
-    pos += 4;
-    if (val == 0) {  // All zero special case
-      *out = 'z';
-      out++;
-      line_length++;
-    } else {  // Compute base 85 characters and add 33.
-      for (int i = 4; i >= 0; i--) {
-        out[i] = (uint8_t)(val % 85) + 33;
-        val = val / 85;
-      }
-      out += 5;
-      line_length += 5;
-    }
-    if (line_length >= 75) {  // Add a return.
-      *out++ = '\r';
-      *out++ = '\n';
-      line_length = 0;
-    }
-  }
-  if (pos < src_span.size()) {  // Leftover bytes
-    uint32_t val = 0;
-    int count = 0;
-    while (pos < src_span.size()) {
-      val += (uint32_t)(src_span[pos]) << (8 * (3 - count));
-      count++;
-      pos++;
-    }
-    for (int i = 4; i >= 0; i--) {
-      if (i <= count)
-        out[i] = (uint8_t)(val % 85) + 33;
-      val = val / 85;
-    }
-    out += count + 1;
-  }
-
-  // Terminating characters.
-  out[0] = '~';
-  out[1] = '>';
-  out += 2;
-  *dest_size = out - dest_buf->get();
-  return true;
-}
-
 #ifdef PDF_ENABLE_XFA
 CFX_DIBAttribute::CFX_DIBAttribute() {}
 
@@ -204,199 +40,6 @@
 }
 #endif  // PDF_ENABLE_XFA
 
-class CCodec_RLScanlineDecoder final : public CCodec_ScanlineDecoder {
- public:
-  CCodec_RLScanlineDecoder();
-  ~CCodec_RLScanlineDecoder() override;
-
-  bool Create(pdfium::span<const uint8_t> src_buf,
-              int width,
-              int height,
-              int nComps,
-              int bpc);
-
-  // CCodec_ScanlineDecoder
-  bool v_Rewind() override;
-  uint8_t* v_GetNextLine() override;
-  uint32_t GetSrcOffset() override { return m_SrcOffset; }
-
- private:
-  bool CheckDestSize();
-  void GetNextOperator();
-  void UpdateOperator(uint8_t used_bytes);
-
-  std::unique_ptr<uint8_t, FxFreeDeleter> m_pScanline;
-  pdfium::span<const uint8_t> m_SrcBuf;
-  size_t m_dwLineBytes = 0;
-  size_t m_SrcOffset = 0;
-  bool m_bEOD = false;
-  uint8_t m_Operator = 0;
-};
-
-CCodec_RLScanlineDecoder::CCodec_RLScanlineDecoder() = default;
-
-CCodec_RLScanlineDecoder::~CCodec_RLScanlineDecoder() = default;
-
-bool CCodec_RLScanlineDecoder::CheckDestSize() {
-  size_t i = 0;
-  uint32_t old_size = 0;
-  uint32_t dest_size = 0;
-  while (i < m_SrcBuf.size()) {
-    if (m_SrcBuf[i] < 128) {
-      old_size = dest_size;
-      dest_size += m_SrcBuf[i] + 1;
-      if (dest_size < old_size) {
-        return false;
-      }
-      i += m_SrcBuf[i] + 2;
-    } else if (m_SrcBuf[i] > 128) {
-      old_size = dest_size;
-      dest_size += 257 - m_SrcBuf[i];
-      if (dest_size < old_size) {
-        return false;
-      }
-      i += 2;
-    } else {
-      break;
-    }
-  }
-  if (((uint32_t)m_OrigWidth * m_nComps * m_bpc * m_OrigHeight + 7) / 8 >
-      dest_size) {
-    return false;
-  }
-  return true;
-}
-
-bool CCodec_RLScanlineDecoder::Create(pdfium::span<const uint8_t> src_buf,
-                                      int width,
-                                      int height,
-                                      int nComps,
-                                      int bpc) {
-  m_SrcBuf = src_buf;
-  m_OutputWidth = m_OrigWidth = width;
-  m_OutputHeight = m_OrigHeight = height;
-  m_nComps = nComps;
-  m_bpc = bpc;
-  // Aligning the pitch to 4 bytes requires an integer overflow check.
-  FX_SAFE_UINT32 pitch = width;
-  pitch *= nComps;
-  pitch *= bpc;
-  pitch += 31;
-  pitch /= 32;
-  pitch *= 4;
-  if (!pitch.IsValid()) {
-    return false;
-  }
-  m_Pitch = pitch.ValueOrDie();
-  // Overflow should already have been checked before this is called.
-  m_dwLineBytes = (static_cast<uint32_t>(width) * nComps * bpc + 7) / 8;
-  m_pScanline.reset(FX_Alloc(uint8_t, m_Pitch));
-  return CheckDestSize();
-}
-
-bool CCodec_RLScanlineDecoder::v_Rewind() {
-  memset(m_pScanline.get(), 0, m_Pitch);
-  m_SrcOffset = 0;
-  m_bEOD = false;
-  m_Operator = 0;
-  return true;
-}
-
-uint8_t* CCodec_RLScanlineDecoder::v_GetNextLine() {
-  if (m_SrcOffset == 0) {
-    GetNextOperator();
-  } else if (m_bEOD) {
-    return nullptr;
-  }
-  memset(m_pScanline.get(), 0, m_Pitch);
-  uint32_t col_pos = 0;
-  bool eol = false;
-  while (m_SrcOffset < m_SrcBuf.size() && !eol) {
-    if (m_Operator < 128) {
-      uint32_t copy_len = m_Operator + 1;
-      if (col_pos + copy_len >= m_dwLineBytes) {
-        copy_len = m_dwLineBytes - col_pos;
-        eol = true;
-      }
-      if (copy_len >= m_SrcBuf.size() - m_SrcOffset) {
-        copy_len = m_SrcBuf.size() - m_SrcOffset;
-        m_bEOD = true;
-      }
-      auto copy_span = m_SrcBuf.subspan(m_SrcOffset, copy_len);
-      memcpy(m_pScanline.get() + col_pos, copy_span.data(), copy_span.size());
-      col_pos += copy_len;
-      UpdateOperator((uint8_t)copy_len);
-    } else if (m_Operator > 128) {
-      int fill = 0;
-      if (m_SrcOffset - 1 < m_SrcBuf.size() - 1) {
-        fill = m_SrcBuf[m_SrcOffset];
-      }
-      uint32_t duplicate_len = 257 - m_Operator;
-      if (col_pos + duplicate_len >= m_dwLineBytes) {
-        duplicate_len = m_dwLineBytes - col_pos;
-        eol = true;
-      }
-      memset(m_pScanline.get() + col_pos, fill, duplicate_len);
-      col_pos += duplicate_len;
-      UpdateOperator((uint8_t)duplicate_len);
-    } else {
-      m_bEOD = true;
-      break;
-    }
-  }
-  return m_pScanline.get();
-}
-
-void CCodec_RLScanlineDecoder::GetNextOperator() {
-  if (m_SrcOffset >= m_SrcBuf.size()) {
-    m_Operator = 128;
-    return;
-  }
-  m_Operator = m_SrcBuf[m_SrcOffset];
-  m_SrcOffset++;
-}
-void CCodec_RLScanlineDecoder::UpdateOperator(uint8_t used_bytes) {
-  if (used_bytes == 0) {
-    return;
-  }
-  if (m_Operator < 128) {
-    ASSERT((uint32_t)m_Operator + 1 >= used_bytes);
-    if (used_bytes == m_Operator + 1) {
-      m_SrcOffset += used_bytes;
-      GetNextOperator();
-      return;
-    }
-    m_Operator -= used_bytes;
-    m_SrcOffset += used_bytes;
-    if (m_SrcOffset >= m_SrcBuf.size()) {
-      m_Operator = 128;
-    }
-    return;
-  }
-  uint8_t count = 257 - m_Operator;
-  ASSERT((uint32_t)count >= used_bytes);
-  if (used_bytes == count) {
-    m_SrcOffset++;
-    GetNextOperator();
-    return;
-  }
-  count -= used_bytes;
-  m_Operator = 257 - count;
-}
-
-std::unique_ptr<CCodec_ScanlineDecoder>
-CCodec_BasicModule::CreateRunLengthDecoder(pdfium::span<const uint8_t> src_buf,
-                                           int width,
-                                           int height,
-                                           int nComps,
-                                           int bpc) {
-  auto pDecoder = pdfium::MakeUnique<CCodec_RLScanlineDecoder>();
-  if (!pDecoder->Create(src_buf, width, height, nComps, bpc))
-    return nullptr;
-
-  return std::move(pDecoder);
-}
-
 FX_SAFE_UINT32 CalculatePitch8(uint32_t bpc, uint32_t components, int width) {
   FX_SAFE_UINT32 pitch = bpc;
   pitch *= components;
diff --git a/core/fxcodec/codec/fx_codec_a85_unittest.cpp b/core/fxcodec/codec/fx_codec_a85_unittest.cpp
index 1372858..c6eb34d 100644
--- a/core/fxcodec/codec/fx_codec_a85_unittest.cpp
+++ b/core/fxcodec/codec/fx_codec_a85_unittest.cpp
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "core/fxcodec/codec/ccodec_basicmodule.h"
-#include "core/fxcodec/fx_codec.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 TEST(fxcodec, A85TestBadInputs) {
@@ -16,25 +15,19 @@
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
 
-  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
-  EXPECT_TRUE(pEncoders);
-
   // Error codes, not segvs, should callers pass us a nullptr pointer.
-  EXPECT_FALSE(pEncoders->A85Encode(src_buf, &dest_buf, nullptr));
-  EXPECT_FALSE(pEncoders->A85Encode(src_buf, nullptr, &dest_size));
-  EXPECT_FALSE(pEncoders->A85Encode({}, &dest_buf, &dest_size));
+  EXPECT_FALSE(CCodec_BasicModule::A85Encode(src_buf, &dest_buf, nullptr));
+  EXPECT_FALSE(CCodec_BasicModule::A85Encode(src_buf, nullptr, &dest_size));
+  EXPECT_FALSE(CCodec_BasicModule::A85Encode({}, &dest_buf, &dest_size));
 }
 
 // No leftover bytes, just translate 2 sets of symbols.
 TEST(fxcodec, A85TestBasic) {
-  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
-  EXPECT_TRUE(pEncoders);
-
   // Make sure really big values don't break.
   const uint8_t src_buf[] = {1, 2, 3, 4, 255, 255, 255, 255};
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
-  EXPECT_TRUE(pEncoders->A85Encode(src_buf, &dest_buf, &dest_size));
+  EXPECT_TRUE(CCodec_BasicModule::A85Encode(src_buf, &dest_buf, &dest_size));
 
   // Should have 5 chars for each set of 4 and 2 terminators.
   const uint8_t expected_out[] = {33, 60, 78, 63, 43,  115,
@@ -49,16 +42,14 @@
 
 // Leftover bytes.
 TEST(fxcodec, A85TestLeftoverBytes) {
-  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
-  EXPECT_TRUE(pEncoders);
-
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
 
   {
     // 1 Leftover Byte:
     const uint8_t src_buf_1leftover[] = {1, 2, 3, 4, 255};
-    EXPECT_TRUE(pEncoders->A85Encode(src_buf_1leftover, &dest_buf, &dest_size));
+    EXPECT_TRUE(CCodec_BasicModule::A85Encode(src_buf_1leftover, &dest_buf,
+                                              &dest_size));
 
     // 5 chars for first symbol + 2 + 2 terminators.
     uint8_t expected_out_1leftover[] = {33, 60, 78, 63, 43, 114, 114, 126, 62};
@@ -75,7 +66,8 @@
     const uint8_t src_buf_2leftover[] = {1, 2, 3, 4, 255, 254};
     dest_buf.reset();
     dest_size = 0;
-    EXPECT_TRUE(pEncoders->A85Encode(src_buf_2leftover, &dest_buf, &dest_size));
+    EXPECT_TRUE(CCodec_BasicModule::A85Encode(src_buf_2leftover, &dest_buf,
+                                              &dest_size));
     // 5 chars for first symbol + 3 + 2 terminators.
     const uint8_t expected_out_2leftover[] = {33,  60, 78, 63,  43,
                                               115, 56, 68, 126, 62};
@@ -92,7 +84,8 @@
     const uint8_t src_buf_3leftover[] = {1, 2, 3, 4, 255, 254, 253};
     dest_buf.reset();
     dest_size = 0;
-    EXPECT_TRUE(pEncoders->A85Encode(src_buf_3leftover, &dest_buf, &dest_size));
+    EXPECT_TRUE(CCodec_BasicModule::A85Encode(src_buf_3leftover, &dest_buf,
+                                              &dest_size));
     // 5 chars for first symbol + 4 + 2 terminators.
     const uint8_t expected_out_3leftover[] = {33, 60, 78,  63,  43, 115,
                                               56, 77, 114, 126, 62};
@@ -107,16 +100,13 @@
 
 // Test all zeros comes through as "z".
 TEST(fxcodec, A85TestZeros) {
-  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
-  EXPECT_TRUE(pEncoders);
-
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
 
   {
     // Make sure really big values don't break.
     const uint8_t src_buf[] = {1, 2, 3, 4, 0, 0, 0, 0};
-    EXPECT_TRUE(pEncoders->A85Encode(src_buf, &dest_buf, &dest_size));
+    EXPECT_TRUE(CCodec_BasicModule::A85Encode(src_buf, &dest_buf, &dest_size));
 
     // Should have 5 chars for first set of 4 + 1 for z + 2 terminators.
     const uint8_t expected_out[] = {33, 60, 78, 63, 43, 122, 126, 62};
@@ -133,7 +123,8 @@
     const uint8_t src_buf_2[] = {0, 0, 0, 0, 1, 2, 3, 4};
     dest_buf.reset();
     dest_size = 0;
-    EXPECT_TRUE(pEncoders->A85Encode(src_buf_2, &dest_buf, &dest_size));
+    EXPECT_TRUE(
+        CCodec_BasicModule::A85Encode(src_buf_2, &dest_buf, &dest_size));
 
     // Should have 5 chars for set of 4 + 1 for z + 2 terminators.
     const uint8_t expected_out_2[] = {122, 33, 60, 78, 63, 43, 126, 62};
@@ -150,7 +141,8 @@
     const uint8_t src_buf_3[] = {1, 2, 3, 4, 0, 0};
     dest_buf.reset();
     dest_size = 0;
-    EXPECT_TRUE(pEncoders->A85Encode(src_buf_3, &dest_buf, &dest_size));
+    EXPECT_TRUE(
+        CCodec_BasicModule::A85Encode(src_buf_3, &dest_buf, &dest_size));
 
     // Should have 5 chars for set of 4 + 3 for last 2 + 2 terminators.
     const uint8_t expected_out_leftover[] = {33, 60, 78, 63,  43,
@@ -185,11 +177,8 @@
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
 
-  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
-  EXPECT_TRUE(pEncoders);
-
   // Should succeed.
-  EXPECT_TRUE(pEncoders->A85Encode(src_buf, &dest_buf, &dest_size));
+  EXPECT_TRUE(CCodec_BasicModule::A85Encode(src_buf, &dest_buf, &dest_size));
 
   // Should have 75 chars in the first row plus 2 char return,
   // 76 chars in the second row plus 2 char return,
diff --git a/core/fxcodec/codec/fx_codec_rle_unittest.cpp b/core/fxcodec/codec/fx_codec_rle_unittest.cpp
index 433d96d..b0323c1 100644
--- a/core/fxcodec/codec/fx_codec_rle_unittest.cpp
+++ b/core/fxcodec/codec/fx_codec_rle_unittest.cpp
@@ -9,7 +9,6 @@
 
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fxcodec/codec/ccodec_basicmodule.h"
-#include "core/fxcodec/fx_codec.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 TEST(fxcodec, RLETestBadInputs) {
@@ -17,25 +16,22 @@
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
 
-  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
-  EXPECT_TRUE(pEncoders);
-
   // Error codes, not segvs, should callers pass us a nullptr pointer.
-  EXPECT_FALSE(pEncoders->RunLengthEncode(src_buf, &dest_buf, nullptr));
-  EXPECT_FALSE(pEncoders->RunLengthEncode(src_buf, nullptr, &dest_size));
-  EXPECT_FALSE(pEncoders->RunLengthEncode({}, &dest_buf, &dest_size));
+  EXPECT_FALSE(
+      CCodec_BasicModule::RunLengthEncode(src_buf, &dest_buf, nullptr));
+  EXPECT_FALSE(
+      CCodec_BasicModule::RunLengthEncode(src_buf, nullptr, &dest_size));
+  EXPECT_FALSE(CCodec_BasicModule::RunLengthEncode({}, &dest_buf, &dest_size));
 }
 
 // Check length 1 input works. Check terminating character is applied.
 TEST(fxcodec, RLETestShortInput) {
-  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
-  EXPECT_TRUE(pEncoders);
-
   const uint8_t src_buf[] = {1};
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
 
-  EXPECT_TRUE(pEncoders->RunLengthEncode(src_buf, &dest_buf, &dest_size));
+  EXPECT_TRUE(
+      CCodec_BasicModule::RunLengthEncode(src_buf, &dest_buf, &dest_size));
   ASSERT_EQ(3u, dest_size);
   auto dest_buf_span = pdfium::make_span(dest_buf.get(), dest_size);
   EXPECT_EQ(0, dest_buf_span[0]);
@@ -46,9 +42,6 @@
 // Check a few basic cases (2 matching runs in a row, matching run followed
 // by a non-matching run, and non-matching run followed by a matching run).
 TEST(fxcodec, RLETestNormalInputs) {
-  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
-  EXPECT_TRUE(pEncoders);
-
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
   std::unique_ptr<uint8_t, FxFreeDeleter> decoded_buf;
@@ -57,7 +50,8 @@
   {
     // Case 1: Match, match
     const uint8_t src_buf_1[] = {2, 2, 2, 2, 4, 4, 4, 4, 4, 4};
-    EXPECT_TRUE(pEncoders->RunLengthEncode(src_buf_1, &dest_buf, &dest_size));
+    EXPECT_TRUE(
+        CCodec_BasicModule::RunLengthEncode(src_buf_1, &dest_buf, &dest_size));
     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
     ASSERT_EQ(sizeof(src_buf_1), decoded_size);
     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
@@ -70,7 +64,8 @@
     const uint8_t src_buf_2[] = {2, 2, 2, 2, 1, 2, 3, 4, 5, 6};
     dest_buf.reset();
     dest_size = 0;
-    EXPECT_TRUE(pEncoders->RunLengthEncode(src_buf_2, &dest_buf, &dest_size));
+    EXPECT_TRUE(
+        CCodec_BasicModule::RunLengthEncode(src_buf_2, &dest_buf, &dest_size));
     decoded_buf.reset();
     decoded_size = 0;
     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
@@ -85,7 +80,8 @@
     const uint8_t src_buf_3[] = {1, 2, 3, 4, 5, 3, 3, 3, 3, 3};
     dest_buf.reset();
     dest_size = 0;
-    EXPECT_TRUE(pEncoders->RunLengthEncode(src_buf_3, &dest_buf, &dest_size));
+    EXPECT_TRUE(
+        CCodec_BasicModule::RunLengthEncode(src_buf_3, &dest_buf, &dest_size));
     decoded_buf.reset();
     decoded_size = 0;
     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
@@ -99,9 +95,6 @@
 // Check that runs longer than 128 are broken up properly, both matched and
 // non-matched.
 TEST(fxcodec, RLETestFullLengthInputs) {
-  CCodec_BasicModule* pEncoders = CCodec_ModuleMgr().GetBasicModule();
-  EXPECT_TRUE(pEncoders);
-
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
   std::unique_ptr<uint8_t, FxFreeDeleter> decoded_buf;
@@ -110,7 +103,8 @@
   {
     // Case 1: Match, match
     const uint8_t src_buf_1[260] = {1};
-    EXPECT_TRUE(pEncoders->RunLengthEncode(src_buf_1, &dest_buf, &dest_size));
+    EXPECT_TRUE(
+        CCodec_BasicModule::RunLengthEncode(src_buf_1, &dest_buf, &dest_size));
     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
     ASSERT_EQ(sizeof(src_buf_1), decoded_size);
     auto decoded_buf_span = pdfium::make_span(decoded_buf.get(), decoded_size);
@@ -125,7 +119,8 @@
       src_buf_2[i] = static_cast<uint8_t>(i - 125);
     dest_buf.reset();
     dest_size = 0;
-    EXPECT_TRUE(pEncoders->RunLengthEncode(src_buf_2, &dest_buf, &dest_size));
+    EXPECT_TRUE(
+        CCodec_BasicModule::RunLengthEncode(src_buf_2, &dest_buf, &dest_size));
     decoded_buf.reset();
     decoded_size = 0;
     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
@@ -142,7 +137,8 @@
       src_buf_3[i] = i;
     dest_buf.reset();
     dest_size = 0;
-    EXPECT_TRUE(pEncoders->RunLengthEncode(src_buf_3, &dest_buf, &dest_size));
+    EXPECT_TRUE(
+        CCodec_BasicModule::RunLengthEncode(src_buf_3, &dest_buf, &dest_size));
     decoded_buf.reset();
     decoded_size = 0;
     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
@@ -159,7 +155,8 @@
       src_buf_4[i] = static_cast<uint8_t>(i);
     dest_buf.reset();
     dest_size = 0;
-    EXPECT_TRUE(pEncoders->RunLengthEncode(src_buf_4, &dest_buf, &dest_size));
+    EXPECT_TRUE(
+        CCodec_BasicModule::RunLengthEncode(src_buf_4, &dest_buf, &dest_size));
     decoded_buf.reset();
     decoded_size = 0;
     RunLengthDecode({dest_buf.get(), dest_size}, &decoded_buf, &decoded_size);
diff --git a/core/fxcodec/fx_codec.h b/core/fxcodec/fx_codec.h
index bb332e9..2ab6fae 100644
--- a/core/fxcodec/fx_codec.h
+++ b/core/fxcodec/fx_codec.h
@@ -34,7 +34,6 @@
 #endif  // PDF_ENABLE_XFA_TIFF
 #endif  // PDF_ENABLE_XFA
 
-class CCodec_BasicModule;
 class CCodec_FaxModule;
 class CCodec_IccModule;
 class CCodec_Jbig2Module;
@@ -64,7 +63,6 @@
   CCodec_ModuleMgr();
   ~CCodec_ModuleMgr();
 
-  CCodec_BasicModule* GetBasicModule() const { return m_pBasicModule.get(); }
   CCodec_FaxModule* GetFaxModule() const { return m_pFaxModule.get(); }
   CCodec_JpegModule* GetJpegModule() const { return m_pJpegModule.get(); }
   CCodec_JpxModule* GetJpxModule() const { return m_pJpxModule.get(); }
@@ -104,7 +102,6 @@
 #endif  // PDF_ENABLE_XFA
 
  protected:
-  std::unique_ptr<CCodec_BasicModule> m_pBasicModule;
   std::unique_ptr<CCodec_FaxModule> m_pFaxModule;
   std::unique_ptr<CCodec_JpegModule> m_pJpegModule;
   std::unique_ptr<CCodec_JpxModule> m_pJpxModule;
diff --git a/core/fxge/cfx_windowsrenderdevice.h b/core/fxge/cfx_windowsrenderdevice.h
index a52f4ee..454f448 100644
--- a/core/fxge/cfx_windowsrenderdevice.h
+++ b/core/fxge/cfx_windowsrenderdevice.h
@@ -23,7 +23,6 @@
   kModePostScript3PassThrough = 5,
 };
 
-class CCodec_ModuleMgr;
 class RenderDeviceDriverIface;
 
 #if defined(PDFIUM_PRINT_TEXT_WITH_GDI)
@@ -39,11 +38,11 @@
 
 class CFX_WindowsRenderDevice final : public CFX_RenderDevice {
  public:
-  static RenderDeviceDriverIface* CreateDriver(CCodec_ModuleMgr* pModuleMgr,
-                                               HDC hDC);
-
-  CFX_WindowsRenderDevice(CCodec_ModuleMgr* pModuleMgr, HDC hDC);
+  explicit CFX_WindowsRenderDevice(HDC hDC);
   ~CFX_WindowsRenderDevice() override;
+
+ private:
+  static RenderDeviceDriverIface* CreateDriver(HDC hDC);
 };
 
 #endif  // _WIN32
diff --git a/core/fxge/win32/cfx_psrenderer.cpp b/core/fxge/win32/cfx_psrenderer.cpp
index d1aedf2..15efa25 100644
--- a/core/fxge/win32/cfx_psrenderer.cpp
+++ b/core/fxge/win32/cfx_psrenderer.cpp
@@ -15,7 +15,6 @@
 #include "core/fxcodec/codec/ccodec_faxmodule.h"
 #include "core/fxcodec/codec/ccodec_flatemodule.h"
 #include "core/fxcodec/codec/ccodec_jpegmodule.h"
-#include "core/fxcodec/fx_codec.h"
 #include "core/fxcrt/maybe_owned.h"
 #include "core/fxge/cfx_fontcache.h"
 #include "core/fxge/cfx_gemodule.h"
@@ -46,8 +45,7 @@
   return true;
 }
 
-void PSCompressData(CCodec_ModuleMgr* pEncoders,
-                    int PSLevel,
+void PSCompressData(int PSLevel,
                     uint8_t* src_buf,
                     uint32_t src_size,
                     uint8_t** output_buf,
@@ -70,8 +68,8 @@
     }
   } else {
     std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf_unique;
-    if (pEncoders->GetBasicModule()->RunLengthEncode(
-            {src_buf, src_size}, &dest_buf_unique, &dest_size)) {
+    if (CCodec_BasicModule::RunLengthEncode({src_buf, src_size},
+                                            &dest_buf_unique, &dest_size)) {
       dest_buf = dest_buf_unique.release();
       *filter = "/RunLengthDecode filter ";
     }
@@ -100,8 +98,7 @@
   PSGlyph m_Glyphs[256];
 };
 
-CFX_PSRenderer::CFX_PSRenderer(CCodec_ModuleMgr* pModuleMgr)
-    : m_pModuleMgr(pModuleMgr) {}
+CFX_PSRenderer::CFX_PSRenderer() = default;
 
 CFX_PSRenderer::~CFX_PSRenderer() = default;
 
@@ -480,8 +477,8 @@
       }
       uint8_t* compressed_buf;
       uint32_t compressed_size;
-      PSCompressData(m_pModuleMgr.Get(), m_PSLevel, output_buf, output_size,
-                     &compressed_buf, &compressed_size, &filter);
+      PSCompressData(m_PSLevel, output_buf, output_size, &compressed_buf,
+                     &compressed_size, &filter);
       if (output_buf != compressed_buf)
         FX_Free(output_buf);
 
@@ -686,8 +683,8 @@
 void CFX_PSRenderer::WritePSBinary(const uint8_t* data, int len) {
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size;
-  if (m_pModuleMgr->GetBasicModule()->A85Encode(
-          {data, static_cast<size_t>(len)}, &dest_buf, &dest_size)) {
+  if (CCodec_BasicModule::A85Encode({data, static_cast<size_t>(len)}, &dest_buf,
+                                    &dest_size)) {
     m_pStream->WriteBlock(dest_buf.get(), dest_size);
   } else {
     m_pStream->WriteBlock(data, len);
diff --git a/core/fxge/win32/cfx_psrenderer.h b/core/fxge/win32/cfx_psrenderer.h
index 91888df..a9b9f10 100644
--- a/core/fxge/win32/cfx_psrenderer.h
+++ b/core/fxge/win32/cfx_psrenderer.h
@@ -14,15 +14,11 @@
 #include "core/fxcrt/fx_stream.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/cfx_graphstatedata.h"
 
-class CCodec_ModuleMgr;
 class CFX_DIBBase;
 class CFX_GlyphCache;
 class CFX_Font;
-class CFX_FontCache;
-class CFX_Matrix;
 class CFX_PathData;
 class CPSFont;
 class TextCharPos;
@@ -30,7 +26,7 @@
 
 class CFX_PSRenderer {
  public:
-  explicit CFX_PSRenderer(CCodec_ModuleMgr* pModuleMgr);
+  CFX_PSRenderer();
   ~CFX_PSRenderer();
 
   void Init(const RetainPtr<IFX_RetainableWriteStream>& stream,
@@ -98,7 +94,6 @@
   uint32_t m_LastColor = 0;
   FX_RECT m_ClipBox;
   CFX_GraphStateData m_CurGraphState;
-  UnownedPtr<CCodec_ModuleMgr> m_pModuleMgr;
   RetainPtr<IFX_RetainableWriteStream> m_pStream;
   std::vector<std::unique_ptr<CPSFont>> m_PSFontList;
   std::vector<FX_RECT> m_ClipBoxStack;
diff --git a/core/fxge/win32/fx_win32_device.cpp b/core/fxge/win32/fx_win32_device.cpp
index c4e4576..2b53b61 100644
--- a/core/fxge/win32/fx_win32_device.cpp
+++ b/core/fxge/win32/fx_win32_device.cpp
@@ -1337,16 +1337,14 @@
   return false;
 }
 
-CFX_WindowsRenderDevice::CFX_WindowsRenderDevice(CCodec_ModuleMgr* pModuleMgr,
-                                                 HDC hDC) {
-  SetDeviceDriver(pdfium::WrapUnique(CreateDriver(pModuleMgr, hDC)));
+CFX_WindowsRenderDevice::CFX_WindowsRenderDevice(HDC hDC) {
+  SetDeviceDriver(pdfium::WrapUnique(CreateDriver(hDC)));
 }
 
-CFX_WindowsRenderDevice::~CFX_WindowsRenderDevice() {}
+CFX_WindowsRenderDevice::~CFX_WindowsRenderDevice() = default;
 
 // static
 RenderDeviceDriverIface* CFX_WindowsRenderDevice::CreateDriver(
-    CCodec_ModuleMgr* pModuleMgr,
     HDC hDC) {
   int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
   int obj_type = ::GetObjectType(hDC);
@@ -1363,5 +1361,5 @@
   if (g_pdfium_print_mode == WindowsPrintMode::kModeTextOnly)
     return new CTextOnlyPrinterDriver(hDC);
 
-  return new CPSPrinterDriver(pModuleMgr, hDC, g_pdfium_print_mode, false);
+  return new CPSPrinterDriver(hDC, g_pdfium_print_mode, false);
 }
diff --git a/core/fxge/win32/fx_win32_print.cpp b/core/fxge/win32/fx_win32_print.cpp
index 57cacdf..b6dd416 100644
--- a/core/fxge/win32/fx_win32_print.cpp
+++ b/core/fxge/win32/fx_win32_print.cpp
@@ -330,11 +330,10 @@
 #endif
 }
 
-CPSPrinterDriver::CPSPrinterDriver(CCodec_ModuleMgr* pModuleMgr,
-                                   HDC hDC,
+CPSPrinterDriver::CPSPrinterDriver(HDC hDC,
                                    WindowsPrintMode mode,
                                    bool bCmykOutput)
-    : m_hDC(hDC), m_bCmykOutput(bCmykOutput), m_PSRenderer(pModuleMgr) {
+    : m_hDC(hDC), m_bCmykOutput(bCmykOutput) {
   // |mode| should be PostScript.
   ASSERT(mode == WindowsPrintMode::kModePostScript2 ||
          mode == WindowsPrintMode::kModePostScript3 ||
diff --git a/core/fxge/win32/win32_int.h b/core/fxge/win32/win32_int.h
index d0a4588..444c1dd 100644
--- a/core/fxge/win32/win32_int.h
+++ b/core/fxge/win32/win32_int.h
@@ -20,7 +20,6 @@
 #include "core/fxge/win32/cfx_psrenderer.h"
 #include "core/fxge/win32/cpsoutput.h"
 
-class CCodec_ModuleMgr;
 class CFX_ImageRenderer;
 class TextCharPos;
 struct WINDIB_Open_Args_;
@@ -214,10 +213,7 @@
 
 class CPSPrinterDriver final : public RenderDeviceDriverIface {
  public:
-  CPSPrinterDriver(CCodec_ModuleMgr* pModuleMgr,
-                   HDC hDC,
-                   WindowsPrintMode mode,
-                   bool bCmykOutput);
+  CPSPrinterDriver(HDC hDC, WindowsPrintMode mode, bool bCmykOutput);
   ~CPSPrinterDriver() override;
 
  private:
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 1aa6943..63374d2 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -545,8 +545,7 @@
       pContext->m_pOptions->GetOptions().bBreakForMasks = true;
     }
   } else {
-    pContext->m_pDevice = pdfium::MakeUnique<CFX_WindowsRenderDevice>(
-        CPDF_ModuleMgr::Get()->GetCodecModule(), dc);
+    pContext->m_pDevice = pdfium::MakeUnique<CFX_WindowsRenderDevice>(dc);
   }
 
   RenderPageWithContext(pContext, page, start_x, start_y, size_x, size_y,
@@ -573,8 +572,7 @@
     // pause after each image mask.
     pPage->SetRenderContext(pdfium::MakeUnique<CPDF_PageRenderContext>());
     pContext = pPage->GetRenderContext();
-    pContext->m_pDevice = pdfium::MakeUnique<CFX_WindowsRenderDevice>(
-        CPDF_ModuleMgr::Get()->GetCodecModule(), dc);
+    pContext->m_pDevice = pdfium::MakeUnique<CFX_WindowsRenderDevice>(dc);
     pContext->m_pOptions = pdfium::MakeUnique<CPDF_RenderOptions>();
     pContext->m_pOptions->GetOptions().bBreakForMasks = true;
 
@@ -591,7 +589,7 @@
       pContext->m_pRenderer->Continue(nullptr);
     }
   } else if (bNewBitmap) {
-    CFX_WindowsRenderDevice WinDC(CPDF_ModuleMgr::Get()->GetCodecModule(), dc);
+    CFX_WindowsRenderDevice WinDC(dc);
     bool bitsStretched = false;
     if (WinDC.GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) {
       auto pDst = pdfium::MakeRetain<CFX_DIBitmap>();
diff --git a/testing/fuzzers/pdf_codec_a85_fuzzer.cc b/testing/fuzzers/pdf_codec_a85_fuzzer.cc
index e45b81f..5740003 100644
--- a/testing/fuzzers/pdf_codec_a85_fuzzer.cc
+++ b/testing/fuzzers/pdf_codec_a85_fuzzer.cc
@@ -11,7 +11,6 @@
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
-  CCodec_BasicModule encoder_module;
-  encoder_module.A85Encode({data, size}, &dest_buf, &dest_size);
+  CCodec_BasicModule::A85Encode({data, size}, &dest_buf, &dest_size);
   return 0;
 }
diff --git a/testing/fuzzers/pdf_codec_rle_fuzzer.cc b/testing/fuzzers/pdf_codec_rle_fuzzer.cc
index 13c4a48..34702cb 100644
--- a/testing/fuzzers/pdf_codec_rle_fuzzer.cc
+++ b/testing/fuzzers/pdf_codec_rle_fuzzer.cc
@@ -11,7 +11,6 @@
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   std::unique_ptr<uint8_t, FxFreeDeleter> dest_buf;
   uint32_t dest_size = 0;
-  CCodec_BasicModule encoder_module;
-  encoder_module.RunLengthEncode({data, size}, &dest_buf, &dest_size);
+  CCodec_BasicModule::RunLengthEncode({data, size}, &dest_buf, &dest_size);
   return 0;
 }