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/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);