Split fx_dib part 1

Move CFX_DIBSource to its own file. Also move the classes that inherit from it
to their own headers. Their cpp's will be added in followup.

Change-Id: Id2b53e124ea5445c558bfcf627bf526870cc92e8
Reviewed-on: https://pdfium-review.googlesource.com/3450
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Nicolás Peña <npm@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index dfc6d6c..f142d5f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -862,6 +862,10 @@
     "core/fxge/cfx_substfont.h",
     "core/fxge/cfx_unicodeencoding.h",
     "core/fxge/cfx_windowsdevice.h",
+    "core/fxge/dib/cfx_dibitmap.h",
+    "core/fxge/dib/cfx_dibsource.cpp",
+    "core/fxge/dib/cfx_dibsource.h",
+    "core/fxge/dib/cfx_filtereddib.h",
     "core/fxge/dib/dib_int.h",
     "core/fxge/dib/fx_dib_composite.cpp",
     "core/fxge/dib/fx_dib_convert.cpp",
diff --git a/core/fpdfapi/render/cpdf_dibtransferfunc.h b/core/fpdfapi/render/cpdf_dibtransferfunc.h
index d57ec0f..25c76ec 100644
--- a/core/fpdfapi/render/cpdf_dibtransferfunc.h
+++ b/core/fpdfapi/render/cpdf_dibtransferfunc.h
@@ -9,6 +9,7 @@
 
 #include <vector>
 
+#include "core/fxge/dib/cfx_filtereddib.h"
 #include "core/fxge/fx_dib.h"
 
 class CPDF_TransferFunc;
diff --git a/core/fxge/dib/cfx_dibitmap.h b/core/fxge/dib/cfx_dibitmap.h
new file mode 100644
index 0000000..9cb46af
--- /dev/null
+++ b/core/fxge/dib/cfx_dibitmap.h
@@ -0,0 +1,135 @@
+// Copyright 2017 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.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FXGE_DIB_CFX_DIBITMAP_H_
+#define CORE_FXGE_DIB_CFX_DIBITMAP_H_
+
+#include "core/fxcrt/cfx_retain_ptr.h"
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxge/dib/cfx_dibsource.h"
+#include "third_party/base/stl_util.h"
+
+class CFX_DIBitmap : public CFX_DIBSource {
+ public:
+  template <typename T, typename... Args>
+  friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+  ~CFX_DIBitmap() override;
+
+  bool Create(int width,
+              int height,
+              FXDIB_Format format,
+              uint8_t* pBuffer = nullptr,
+              int pitch = 0);
+
+  bool Copy(const CFX_RetainPtr<CFX_DIBSource>& pSrc);
+
+  // CFX_DIBSource
+  uint8_t* GetBuffer() const override;
+  const uint8_t* GetScanline(int line) const override;
+  void DownSampleScanline(int line,
+                          uint8_t* dest_scan,
+                          int dest_bpp,
+                          int dest_width,
+                          bool bFlipX,
+                          int clip_left,
+                          int clip_width) const override;
+
+  void TakeOver(CFX_RetainPtr<CFX_DIBitmap>&& pSrcBitmap);
+  bool ConvertFormat(FXDIB_Format format);
+  void Clear(uint32_t color);
+
+  uint32_t GetPixel(int x, int y) const;
+  void SetPixel(int x, int y, uint32_t color);
+
+  bool LoadChannel(FXDIB_Channel destChannel,
+                   const CFX_RetainPtr<CFX_DIBSource>& pSrcBitmap,
+                   FXDIB_Channel srcChannel);
+  bool LoadChannel(FXDIB_Channel destChannel, int value);
+
+  bool MultiplyAlpha(int alpha);
+  bool MultiplyAlpha(const CFX_RetainPtr<CFX_DIBSource>& pAlphaMask);
+
+  bool TransferBitmap(int dest_left,
+                      int dest_top,
+                      int width,
+                      int height,
+                      const CFX_RetainPtr<CFX_DIBSource>& pSrcBitmap,
+                      int src_left,
+                      int src_top);
+
+  bool CompositeBitmap(int dest_left,
+                       int dest_top,
+                       int width,
+                       int height,
+                       const CFX_RetainPtr<CFX_DIBSource>& pSrcBitmap,
+                       int src_left,
+                       int src_top,
+                       int blend_type = FXDIB_BLEND_NORMAL,
+                       const CFX_ClipRgn* pClipRgn = nullptr,
+                       bool bRgbByteOrder = false,
+                       void* pIccTransform = nullptr);
+
+  bool TransferMask(int dest_left,
+                    int dest_top,
+                    int width,
+                    int height,
+                    const CFX_RetainPtr<CFX_DIBSource>& pMask,
+                    uint32_t color,
+                    int src_left,
+                    int src_top,
+                    int alpha_flag = 0,
+                    void* pIccTransform = nullptr);
+
+  bool CompositeMask(int dest_left,
+                     int dest_top,
+                     int width,
+                     int height,
+                     const CFX_RetainPtr<CFX_DIBSource>& pMask,
+                     uint32_t color,
+                     int src_left,
+                     int src_top,
+                     int blend_type = FXDIB_BLEND_NORMAL,
+                     const CFX_ClipRgn* pClipRgn = nullptr,
+                     bool bRgbByteOrder = false,
+                     int alpha_flag = 0,
+                     void* pIccTransform = nullptr);
+
+  bool CompositeRect(int dest_left,
+                     int dest_top,
+                     int width,
+                     int height,
+                     uint32_t color,
+                     int alpha_flag = 0,
+                     void* pIccTransform = nullptr);
+
+  bool ConvertColorScale(uint32_t forecolor, uint32_t backcolor);
+
+#if defined _SKIA_SUPPORT_ || _SKIA_SUPPORT_PATHS_
+  void PreMultiply();
+#endif
+#if defined _SKIA_SUPPORT_PATHS_
+  void UnPreMultiply();
+#endif
+
+ protected:
+  CFX_DIBitmap();
+  CFX_DIBitmap(const CFX_DIBitmap& src);
+  bool GetGrayData(void* pIccTransform = nullptr);
+
+#if defined _SKIA_SUPPORT_PATHS_
+  enum class Format { kCleared, kPreMultiplied, kUnPreMultiplied };
+#endif
+
+  uint8_t* m_pBuffer;
+#if defined _SKIA_SUPPORT_PATHS_
+  Format m_nFormat;
+#endif
+  bool m_bExtBuf;
+};
+
+#endif  // CORE_FXGE_DIB_CFX_DIBITMAP_H_
diff --git a/core/fxge/dib/cfx_dibsource.cpp b/core/fxge/dib/cfx_dibsource.cpp
new file mode 100644
index 0000000..a3e5c30
--- /dev/null
+++ b/core/fxge/dib/cfx_dibsource.cpp
@@ -0,0 +1,530 @@
+// Copyright 2017 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.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fxge/dib/cfx_dibsource.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+#include "core/fxge/dib/cfx_dibitmap.h"
+#include "core/fxge/ge/cfx_cliprgn.h"
+#include "third_party/base/ptr_util.h"
+
+CFX_DIBSource::CFX_DIBSource()
+    : m_Width(0), m_Height(0), m_bpp(0), m_AlphaFlag(0), m_Pitch(0) {}
+
+CFX_DIBSource::~CFX_DIBSource() {}
+
+uint8_t* CFX_DIBSource::GetBuffer() const {
+  return nullptr;
+}
+
+bool CFX_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const {
+  return false;
+}
+
+CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::Clone(const FX_RECT* pClip) const {
+  FX_RECT rect(0, 0, m_Width, m_Height);
+  if (pClip) {
+    rect.Intersect(*pClip);
+    if (rect.IsEmpty())
+      return nullptr;
+  }
+  auto pNewBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+  if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat()))
+    return nullptr;
+
+  pNewBitmap->SetPalette(m_pPalette.get());
+  pNewBitmap->SetAlphaMask(m_pAlphaMask, pClip);
+  if (GetBPP() == 1 && rect.left % 8 != 0) {
+    int left_shift = rect.left % 32;
+    int right_shift = 32 - left_shift;
+    int dword_count = pNewBitmap->m_Pitch / 4;
+    for (int row = rect.top; row < rect.bottom; row++) {
+      uint32_t* src_scan = (uint32_t*)GetScanline(row) + rect.left / 32;
+      uint32_t* dest_scan = (uint32_t*)pNewBitmap->GetScanline(row - rect.top);
+      for (int i = 0; i < dword_count; i++) {
+        dest_scan[i] =
+            (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift);
+      }
+    }
+  } else {
+    int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8;
+    if (m_Pitch < (uint32_t)copy_len)
+      copy_len = m_Pitch;
+
+    for (int row = rect.top; row < rect.bottom; row++) {
+      const uint8_t* src_scan = GetScanline(row) + rect.left * m_bpp / 8;
+      uint8_t* dest_scan = (uint8_t*)pNewBitmap->GetScanline(row - rect.top);
+      FXSYS_memcpy(dest_scan, src_scan, copy_len);
+    }
+  }
+  return pNewBitmap;
+}
+
+void CFX_DIBSource::BuildPalette() {
+  if (m_pPalette)
+    return;
+
+  if (GetBPP() == 1) {
+    m_pPalette.reset(FX_Alloc(uint32_t, 2));
+    if (IsCmykImage()) {
+      m_pPalette.get()[0] = 0xff;
+      m_pPalette.get()[1] = 0;
+    } else {
+      m_pPalette.get()[0] = 0xff000000;
+      m_pPalette.get()[1] = 0xffffffff;
+    }
+  } else if (GetBPP() == 8) {
+    m_pPalette.reset(FX_Alloc(uint32_t, 256));
+    if (IsCmykImage()) {
+      for (int i = 0; i < 256; i++)
+        m_pPalette.get()[i] = 0xff - i;
+    } else {
+      for (int i = 0; i < 256; i++)
+        m_pPalette.get()[i] = 0xff000000 | (i * 0x10101);
+    }
+  }
+}
+
+bool CFX_DIBSource::BuildAlphaMask() {
+  if (m_pAlphaMask)
+    return true;
+
+  m_pAlphaMask = pdfium::MakeRetain<CFX_DIBitmap>();
+  if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
+    m_pAlphaMask = nullptr;
+    return false;
+  }
+  FXSYS_memset(m_pAlphaMask->GetBuffer(), 0xff,
+               m_pAlphaMask->GetHeight() * m_pAlphaMask->GetPitch());
+  return true;
+}
+
+uint32_t CFX_DIBSource::GetPaletteEntry(int index) const {
+  ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
+  if (m_pPalette) {
+    return m_pPalette.get()[index];
+  }
+  if (IsCmykImage()) {
+    if (GetBPP() == 1) {
+      return index ? 0 : 0xff;
+    }
+    return 0xff - index;
+  }
+  if (GetBPP() == 1) {
+    return index ? 0xffffffff : 0xff000000;
+  }
+  return index * 0x10101 | 0xff000000;
+}
+
+void CFX_DIBSource::SetPaletteEntry(int index, uint32_t color) {
+  ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
+  if (!m_pPalette) {
+    BuildPalette();
+  }
+  m_pPalette.get()[index] = color;
+}
+
+int CFX_DIBSource::FindPalette(uint32_t color) const {
+  ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
+  if (!m_pPalette) {
+    if (IsCmykImage()) {
+      if (GetBPP() == 1) {
+        return ((uint8_t)color == 0xff) ? 0 : 1;
+      }
+      return 0xff - (uint8_t)color;
+    }
+    if (GetBPP() == 1) {
+      return ((uint8_t)color == 0xff) ? 1 : 0;
+    }
+    return (uint8_t)color;
+  }
+  int palsize = (1 << GetBPP());
+  for (int i = 0; i < palsize; i++)
+    if (m_pPalette.get()[i] == color) {
+      return i;
+    }
+  return -1;
+}
+
+void CFX_DIBSource::GetOverlapRect(int& dest_left,
+                                   int& dest_top,
+                                   int& width,
+                                   int& height,
+                                   int src_width,
+                                   int src_height,
+                                   int& src_left,
+                                   int& src_top,
+                                   const CFX_ClipRgn* pClipRgn) {
+  if (width == 0 || height == 0) {
+    return;
+  }
+  ASSERT(width > 0 && height > 0);
+  if (dest_left > m_Width || dest_top > m_Height) {
+    width = 0;
+    height = 0;
+    return;
+  }
+  int x_offset = dest_left - src_left;
+  int y_offset = dest_top - src_top;
+  FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height);
+  FX_RECT src_bound(0, 0, src_width, src_height);
+  src_rect.Intersect(src_bound);
+  FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset,
+                    src_rect.right + x_offset, src_rect.bottom + y_offset);
+  FX_RECT dest_bound(0, 0, m_Width, m_Height);
+  dest_rect.Intersect(dest_bound);
+  if (pClipRgn) {
+    dest_rect.Intersect(pClipRgn->GetBox());
+  }
+  dest_left = dest_rect.left;
+  dest_top = dest_rect.top;
+  src_left = dest_left - x_offset;
+  src_top = dest_top - y_offset;
+  width = dest_rect.right - dest_rect.left;
+  height = dest_rect.bottom - dest_rect.top;
+}
+
+void CFX_DIBSource::SetPalette(const uint32_t* pSrc) {
+  static const uint32_t kPaletteSize = 256;
+  if (!pSrc || GetBPP() > 8) {
+    m_pPalette.reset();
+    return;
+  }
+  uint32_t pal_size = 1 << GetBPP();
+  if (!m_pPalette)
+    m_pPalette.reset(FX_Alloc(uint32_t, pal_size));
+  pal_size = std::min(pal_size, kPaletteSize);
+  FXSYS_memcpy(m_pPalette.get(), pSrc, pal_size * sizeof(uint32_t));
+}
+
+void CFX_DIBSource::GetPalette(uint32_t* pal, int alpha) const {
+  ASSERT(GetBPP() <= 8 && !IsCmykImage());
+  if (GetBPP() == 1) {
+    pal[0] = ((m_pPalette ? m_pPalette.get()[0] : 0xff000000) & 0xffffff) |
+             (alpha << 24);
+    pal[1] = ((m_pPalette ? m_pPalette.get()[1] : 0xffffffff) & 0xffffff) |
+             (alpha << 24);
+    return;
+  }
+  if (m_pPalette) {
+    for (int i = 0; i < 256; i++) {
+      pal[i] = (m_pPalette.get()[i] & 0x00ffffff) | (alpha << 24);
+    }
+  } else {
+    for (int i = 0; i < 256; i++) {
+      pal[i] = (i * 0x10101) | (alpha << 24);
+    }
+  }
+}
+
+CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::CloneAlphaMask(
+    const FX_RECT* pClip) const {
+  ASSERT(GetFormat() == FXDIB_Argb);
+  FX_RECT rect(0, 0, m_Width, m_Height);
+  if (pClip) {
+    rect.Intersect(*pClip);
+    if (rect.IsEmpty())
+      return nullptr;
+  }
+  auto pMask = pdfium::MakeRetain<CFX_DIBitmap>();
+  if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask))
+    return nullptr;
+
+  for (int row = rect.top; row < rect.bottom; row++) {
+    const uint8_t* src_scan = GetScanline(row) + rect.left * 4 + 3;
+    uint8_t* dest_scan =
+        const_cast<uint8_t*>(pMask->GetScanline(row - rect.top));
+    for (int col = rect.left; col < rect.right; col++) {
+      *dest_scan++ = *src_scan;
+      src_scan += 4;
+    }
+  }
+  return pMask;
+}
+
+bool CFX_DIBSource::SetAlphaMask(const CFX_RetainPtr<CFX_DIBSource>& pAlphaMask,
+                                 const FX_RECT* pClip) {
+  if (!HasAlpha() || GetFormat() == FXDIB_Argb)
+    return false;
+
+  if (!pAlphaMask) {
+    m_pAlphaMask->Clear(0xff000000);
+    return true;
+  }
+  FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height);
+  if (pClip) {
+    rect.Intersect(*pClip);
+    if (rect.IsEmpty() || rect.Width() != m_Width ||
+        rect.Height() != m_Height) {
+      return false;
+    }
+  } else {
+    if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Height)
+      return false;
+  }
+  for (int row = 0; row < m_Height; row++) {
+    FXSYS_memcpy(const_cast<uint8_t*>(m_pAlphaMask->GetScanline(row)),
+                 pAlphaMask->GetScanline(row + rect.top) + rect.left,
+                 m_pAlphaMask->m_Pitch);
+  }
+  return true;
+}
+
+CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::FlipImage(bool bXFlip,
+                                                     bool bYFlip) const {
+  auto pFlipped = pdfium::MakeRetain<CFX_DIBitmap>();
+  if (!pFlipped->Create(m_Width, m_Height, GetFormat()))
+    return nullptr;
+
+  pFlipped->SetPalette(m_pPalette.get());
+  uint8_t* pDestBuffer = pFlipped->GetBuffer();
+  int Bpp = m_bpp / 8;
+  for (int row = 0; row < m_Height; row++) {
+    const uint8_t* src_scan = GetScanline(row);
+    uint8_t* dest_scan =
+        pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row - 1) : row);
+    if (!bXFlip) {
+      FXSYS_memcpy(dest_scan, src_scan, m_Pitch);
+      continue;
+    }
+    if (m_bpp == 1) {
+      FXSYS_memset(dest_scan, 0, m_Pitch);
+      for (int col = 0; col < m_Width; col++)
+        if (src_scan[col / 8] & (1 << (7 - col % 8))) {
+          int dest_col = m_Width - col - 1;
+          dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8));
+        }
+    } else {
+      dest_scan += (m_Width - 1) * Bpp;
+      if (Bpp == 1) {
+        for (int col = 0; col < m_Width; col++) {
+          *dest_scan = *src_scan;
+          dest_scan--;
+          src_scan++;
+        }
+      } else if (Bpp == 3) {
+        for (int col = 0; col < m_Width; col++) {
+          dest_scan[0] = src_scan[0];
+          dest_scan[1] = src_scan[1];
+          dest_scan[2] = src_scan[2];
+          dest_scan -= 3;
+          src_scan += 3;
+        }
+      } else {
+        ASSERT(Bpp == 4);
+        for (int col = 0; col < m_Width; col++) {
+          *(uint32_t*)dest_scan = *(uint32_t*)src_scan;
+          dest_scan -= 4;
+          src_scan += 4;
+        }
+      }
+    }
+  }
+  if (m_pAlphaMask) {
+    pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer();
+    uint32_t dest_pitch = pFlipped->m_pAlphaMask->GetPitch();
+    for (int row = 0; row < m_Height; row++) {
+      const uint8_t* src_scan = m_pAlphaMask->GetScanline(row);
+      uint8_t* dest_scan =
+          pDestBuffer + dest_pitch * (bYFlip ? (m_Height - row - 1) : row);
+      if (!bXFlip) {
+        FXSYS_memcpy(dest_scan, src_scan, dest_pitch);
+        continue;
+      }
+      dest_scan += (m_Width - 1);
+      for (int col = 0; col < m_Width; col++) {
+        *dest_scan = *src_scan;
+        dest_scan--;
+        src_scan++;
+      }
+    }
+  }
+  return pFlipped;
+}
+
+CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::CloneConvert(
+    FXDIB_Format dest_format) {
+  if (dest_format == GetFormat())
+    return Clone(nullptr);
+
+  auto pClone = pdfium::MakeRetain<CFX_DIBitmap>();
+  if (!pClone->Create(m_Width, m_Height, dest_format))
+    return nullptr;
+
+  CFX_RetainPtr<CFX_DIBitmap> pSrcAlpha;
+  if (HasAlpha()) {
+    if (GetFormat() == FXDIB_Argb)
+      pSrcAlpha = CloneAlphaMask();
+    else
+      pSrcAlpha = m_pAlphaMask;
+
+    if (!pSrcAlpha)
+      return nullptr;
+  }
+  bool ret = true;
+  if (dest_format & 0x0200) {
+    if (dest_format == FXDIB_Argb) {
+      ret = pSrcAlpha ? pClone->LoadChannel(FXDIB_Alpha, pSrcAlpha, FXDIB_Alpha)
+                      : pClone->LoadChannel(FXDIB_Alpha, 0xff);
+    } else {
+      ret = pClone->SetAlphaMask(pSrcAlpha);
+    }
+  }
+  if (!ret)
+    return nullptr;
+
+  CFX_RetainPtr<CFX_DIBSource> holder(this);
+  std::unique_ptr<uint32_t, FxFreeDeleter> pal_8bpp;
+  if (!ConvertBuffer(dest_format, pClone->GetBuffer(), pClone->GetPitch(),
+                     m_Width, m_Height, holder, 0, 0, &pal_8bpp)) {
+    return nullptr;
+  }
+  if (pal_8bpp)
+    pClone->SetPalette(pal_8bpp.get());
+
+  return pClone;
+}
+
+CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::SwapXY(
+    bool bXFlip,
+    bool bYFlip,
+    const FX_RECT* pDestClip) const {
+  FX_RECT dest_clip(0, 0, m_Height, m_Width);
+  if (pDestClip)
+    dest_clip.Intersect(*pDestClip);
+  if (dest_clip.IsEmpty())
+    return nullptr;
+
+  auto pTransBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
+  int result_height = dest_clip.Height();
+  int result_width = dest_clip.Width();
+  if (!pTransBitmap->Create(result_width, result_height, GetFormat()))
+    return nullptr;
+
+  pTransBitmap->SetPalette(m_pPalette.get());
+  int dest_pitch = pTransBitmap->GetPitch();
+  uint8_t* dest_buf = pTransBitmap->GetBuffer();
+  int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left;
+  int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right;
+  int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top;
+  int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom;
+  if (GetBPP() == 1) {
+    FXSYS_memset(dest_buf, 0xff, dest_pitch * result_height);
+    for (int row = row_start; row < row_end; row++) {
+      const uint8_t* src_scan = GetScanline(row);
+      int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
+                     dest_clip.left;
+      uint8_t* dest_scan = dest_buf;
+      if (bYFlip) {
+        dest_scan += (result_height - 1) * dest_pitch;
+      }
+      int dest_step = bYFlip ? -dest_pitch : dest_pitch;
+      for (int col = col_start; col < col_end; col++) {
+        if (!(src_scan[col / 8] & (1 << (7 - col % 8)))) {
+          dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8));
+        }
+        dest_scan += dest_step;
+      }
+    }
+  } else {
+    int nBytes = GetBPP() / 8;
+    int dest_step = bYFlip ? -dest_pitch : dest_pitch;
+    if (nBytes == 3) {
+      dest_step -= 2;
+    }
+    for (int row = row_start; row < row_end; row++) {
+      int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
+                     dest_clip.left;
+      uint8_t* dest_scan = dest_buf + dest_col * nBytes;
+      if (bYFlip) {
+        dest_scan += (result_height - 1) * dest_pitch;
+      }
+      if (nBytes == 4) {
+        uint32_t* src_scan = (uint32_t*)GetScanline(row) + col_start;
+        for (int col = col_start; col < col_end; col++) {
+          *(uint32_t*)dest_scan = *src_scan++;
+          dest_scan += dest_step;
+        }
+      } else {
+        const uint8_t* src_scan = GetScanline(row) + col_start * nBytes;
+        if (nBytes == 1) {
+          for (int col = col_start; col < col_end; col++) {
+            *dest_scan = *src_scan++;
+            dest_scan += dest_step;
+          }
+        } else {
+          for (int col = col_start; col < col_end; col++) {
+            *dest_scan++ = *src_scan++;
+            *dest_scan++ = *src_scan++;
+            *dest_scan = *src_scan++;
+            dest_scan += dest_step;
+          }
+        }
+      }
+    }
+  }
+  if (m_pAlphaMask) {
+    dest_pitch = pTransBitmap->m_pAlphaMask->GetPitch();
+    dest_buf = pTransBitmap->m_pAlphaMask->GetBuffer();
+    int dest_step = bYFlip ? -dest_pitch : dest_pitch;
+    for (int row = row_start; row < row_end; row++) {
+      int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
+                     dest_clip.left;
+      uint8_t* dest_scan = dest_buf + dest_col;
+      if (bYFlip) {
+        dest_scan += (result_height - 1) * dest_pitch;
+      }
+      const uint8_t* src_scan = m_pAlphaMask->GetScanline(row) + col_start;
+      for (int col = col_start; col < col_end; col++) {
+        *dest_scan = *src_scan++;
+        dest_scan += dest_step;
+      }
+    }
+  }
+  return pTransBitmap;
+}
+
+CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::TransformTo(
+    const CFX_Matrix* pDestMatrix,
+    int& result_left,
+    int& result_top,
+    uint32_t flags,
+    const FX_RECT* pDestClip) {
+  CFX_RetainPtr<CFX_DIBSource> holder(this);
+  CFX_ImageTransformer transformer(holder, pDestMatrix, flags, pDestClip);
+  transformer.Start();
+  transformer.Continue(nullptr);
+  result_left = transformer.result().left;
+  result_top = transformer.result().top;
+  return transformer.DetachBitmap();
+}
+
+CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::StretchTo(int dest_width,
+                                                     int dest_height,
+                                                     uint32_t flags,
+                                                     const FX_RECT* pClip) {
+  CFX_RetainPtr<CFX_DIBSource> holder(this);
+  FX_RECT clip_rect(0, 0, FXSYS_abs(dest_width), FXSYS_abs(dest_height));
+  if (pClip)
+    clip_rect.Intersect(*pClip);
+
+  if (clip_rect.IsEmpty())
+    return nullptr;
+
+  if (dest_width == m_Width && dest_height == m_Height)
+    return Clone(&clip_rect);
+
+  CFX_BitmapStorer storer;
+  CFX_ImageStretcher stretcher(&storer, holder, dest_width, dest_height,
+                               clip_rect, flags);
+  if (stretcher.Start())
+    stretcher.Continue(nullptr);
+
+  return storer.Detach();
+}
diff --git a/core/fxge/dib/cfx_dibsource.h b/core/fxge/dib/cfx_dibsource.h
new file mode 100644
index 0000000..76f7009
--- /dev/null
+++ b/core/fxge/dib/cfx_dibsource.h
@@ -0,0 +1,176 @@
+// Copyright 2017 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.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FXGE_DIB_CFX_DIBSOURCE_H_
+#define CORE_FXGE_DIB_CFX_DIBSOURCE_H_
+
+#include <memory>
+
+#include "core/fxcrt/cfx_retain_ptr.h"
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_coordinates.h"
+
+enum FXDIB_Channel {
+  FXDIB_Red = 1,
+  FXDIB_Green,
+  FXDIB_Blue,
+  FXDIB_Cyan,
+  FXDIB_Magenta,
+  FXDIB_Yellow,
+  FXDIB_Black,
+  FXDIB_Alpha
+};
+
+enum FXDIB_Format {
+  FXDIB_Invalid = 0,
+  FXDIB_1bppMask = 0x101,
+  FXDIB_1bppRgb = 0x001,
+  FXDIB_1bppCmyk = 0x401,
+  FXDIB_8bppMask = 0x108,
+  FXDIB_8bppRgb = 0x008,
+  FXDIB_8bppRgba = 0x208,
+  FXDIB_8bppCmyk = 0x408,
+  FXDIB_8bppCmyka = 0x608,
+  FXDIB_Rgb = 0x018,
+  FXDIB_Rgba = 0x218,
+  FXDIB_Rgb32 = 0x020,
+  FXDIB_Argb = 0x220,
+  FXDIB_Cmyk = 0x420,
+  FXDIB_Cmyka = 0x620,
+};
+
+#define FXDIB_DOWNSAMPLE 0x04
+#define FXDIB_INTERPOL 0x20
+#define FXDIB_BICUBIC_INTERPOL 0x80
+#define FXDIB_NOSMOOTH 0x100
+#define FXDIB_BLEND_NORMAL 0
+#define FXDIB_BLEND_MULTIPLY 1
+#define FXDIB_BLEND_SCREEN 2
+#define FXDIB_BLEND_OVERLAY 3
+#define FXDIB_BLEND_DARKEN 4
+#define FXDIB_BLEND_LIGHTEN 5
+
+#define FXDIB_BLEND_COLORDODGE 6
+#define FXDIB_BLEND_COLORBURN 7
+#define FXDIB_BLEND_HARDLIGHT 8
+#define FXDIB_BLEND_SOFTLIGHT 9
+#define FXDIB_BLEND_DIFFERENCE 10
+#define FXDIB_BLEND_EXCLUSION 11
+#define FXDIB_BLEND_NONSEPARABLE 21
+#define FXDIB_BLEND_HUE 21
+#define FXDIB_BLEND_SATURATION 22
+#define FXDIB_BLEND_COLOR 23
+#define FXDIB_BLEND_LUMINOSITY 24
+#define FXDIB_BLEND_UNSUPPORTED -1
+
+class CFX_ClipRgn;
+class CFX_DIBitmap;
+
+class CFX_DIBSource : public CFX_Retainable {
+ public:
+  ~CFX_DIBSource() override;
+
+  virtual uint8_t* GetBuffer() const;
+  virtual const uint8_t* GetScanline(int line) const = 0;
+  virtual bool SkipToScanline(int line, IFX_Pause* pPause) const;
+  virtual void DownSampleScanline(int line,
+                                  uint8_t* dest_scan,
+                                  int dest_bpp,
+                                  int dest_width,
+                                  bool bFlipX,
+                                  int clip_left,
+                                  int clip_width) const = 0;
+
+  int GetWidth() const { return m_Width; }
+  int GetHeight() const { return m_Height; }
+
+  FXDIB_Format GetFormat() const {
+    return (FXDIB_Format)(m_AlphaFlag * 0x100 + m_bpp);
+  }
+  uint32_t GetPitch() const { return m_Pitch; }
+  uint32_t* GetPalette() const { return m_pPalette.get(); }
+  int GetBPP() const { return m_bpp; }
+
+  // TODO(thestig): Investigate this. Given the possible values of FXDIB_Format,
+  // it feels as though this should be implemented as !!(m_AlphaFlag & 1) and
+  // IsOpaqueImage() below should never be able to return true.
+  bool IsAlphaMask() const { return m_AlphaFlag == 1; }
+  bool HasAlpha() const { return !!(m_AlphaFlag & 2); }
+  bool IsOpaqueImage() const { return !(m_AlphaFlag & 3); }
+  bool IsCmykImage() const { return !!(m_AlphaFlag & 4); }
+
+  int GetPaletteSize() const {
+    return IsAlphaMask() ? 0 : (m_bpp == 1 ? 2 : (m_bpp == 8 ? 256 : 0));
+  }
+
+  uint32_t GetPaletteEntry(int index) const;
+
+  void SetPaletteEntry(int index, uint32_t color);
+  uint32_t GetPaletteArgb(int index) const { return GetPaletteEntry(index); }
+  void SetPaletteArgb(int index, uint32_t color) {
+    SetPaletteEntry(index, color);
+  }
+
+  // Copies into internally-owned palette.
+  void SetPalette(const uint32_t* pSrcPal);
+
+  CFX_RetainPtr<CFX_DIBitmap> Clone(const FX_RECT* pClip = nullptr) const;
+  CFX_RetainPtr<CFX_DIBitmap> CloneConvert(FXDIB_Format format);
+  CFX_RetainPtr<CFX_DIBitmap> StretchTo(int dest_width,
+                                        int dest_height,
+                                        uint32_t flags = 0,
+                                        const FX_RECT* pClip = nullptr);
+  CFX_RetainPtr<CFX_DIBitmap> TransformTo(const CFX_Matrix* pMatrix,
+                                          int& left,
+                                          int& top,
+                                          uint32_t flags = 0,
+                                          const FX_RECT* pClip = nullptr);
+  CFX_RetainPtr<CFX_DIBitmap> SwapXY(bool bXFlip,
+                                     bool bYFlip,
+                                     const FX_RECT* pClip = nullptr) const;
+  CFX_RetainPtr<CFX_DIBitmap> FlipImage(bool bXFlip, bool bYFlip) const;
+
+  CFX_RetainPtr<CFX_DIBitmap> CloneAlphaMask(
+      const FX_RECT* pClip = nullptr) const;
+
+  // Copies into internally-owned mask.
+  bool SetAlphaMask(const CFX_RetainPtr<CFX_DIBSource>& pAlphaMask,
+                    const FX_RECT* pClip = nullptr);
+
+  void GetOverlapRect(int& dest_left,
+                      int& dest_top,
+                      int& width,
+                      int& height,
+                      int src_width,
+                      int src_height,
+                      int& src_left,
+                      int& src_top,
+                      const CFX_ClipRgn* pClipRgn);
+
+#if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
+  void DebugVerifyBitmapIsPreMultiplied(void* buffer = nullptr) const;
+#endif
+
+  CFX_RetainPtr<CFX_DIBitmap> m_pAlphaMask;
+
+ protected:
+  CFX_DIBSource();
+
+  void BuildPalette();
+  bool BuildAlphaMask();
+  int FindPalette(uint32_t color) const;
+  void GetPalette(uint32_t* pal, int alpha) const;
+
+  int m_Width;
+  int m_Height;
+  int m_bpp;
+  uint32_t m_AlphaFlag;
+  uint32_t m_Pitch;
+  // TODO(weili): Use std::vector for this.
+  std::unique_ptr<uint32_t, FxFreeDeleter> m_pPalette;
+};
+
+#endif  // CORE_FXGE_DIB_CFX_DIBSOURCE_H_
diff --git a/core/fxge/dib/cfx_filtereddib.h b/core/fxge/dib/cfx_filtereddib.h
new file mode 100644
index 0000000..3a16bb0
--- /dev/null
+++ b/core/fxge/dib/cfx_filtereddib.h
@@ -0,0 +1,50 @@
+// Copyright 2017 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.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FXGE_DIB_CFX_FILTEREDDIB_H_
+#define CORE_FXGE_DIB_CFX_FILTEREDDIB_H_
+
+#include <vector>
+
+#include "core/fxcrt/cfx_retain_ptr.h"
+#include "core/fxge/dib/cfx_dibsource.h"
+
+class CFX_FilteredDIB : public CFX_DIBSource {
+ public:
+  template <typename T, typename... Args>
+  friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+  ~CFX_FilteredDIB() override;
+
+  virtual FXDIB_Format GetDestFormat() = 0;
+  virtual uint32_t* GetDestPalette() = 0;
+  virtual void TranslateScanline(const uint8_t* src_buf,
+                                 std::vector<uint8_t>* dest_buf) const = 0;
+  virtual void TranslateDownSamples(uint8_t* dest_buf,
+                                    const uint8_t* src_buf,
+                                    int pixels,
+                                    int Bpp) const = 0;
+
+  void LoadSrc(const CFX_RetainPtr<CFX_DIBSource>& pSrc);
+
+ protected:
+  CFX_FilteredDIB();
+
+  // CFX_DIBSource
+  const uint8_t* GetScanline(int line) const override;
+  void DownSampleScanline(int line,
+                          uint8_t* dest_scan,
+                          int dest_bpp,
+                          int dest_width,
+                          bool bFlipX,
+                          int clip_left,
+                          int clip_width) const override;
+
+  CFX_RetainPtr<CFX_DIBSource> m_pSrc;
+  mutable std::vector<uint8_t> m_Scanline;
+};
+
+#endif  // CORE_FXGE_DIB_CFX_FILTEREDDIB_H_
diff --git a/core/fxge/dib/fx_dib_convert.cpp b/core/fxge/dib/fx_dib_convert.cpp
index 624e143..419e654 100644
--- a/core/fxge/dib/fx_dib_convert.cpp
+++ b/core/fxge/dib/fx_dib_convert.cpp
@@ -787,49 +787,6 @@
   }
 }
 
-CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::CloneConvert(
-    FXDIB_Format dest_format) {
-  if (dest_format == GetFormat())
-    return Clone(nullptr);
-
-  auto pClone = pdfium::MakeRetain<CFX_DIBitmap>();
-  if (!pClone->Create(m_Width, m_Height, dest_format))
-    return nullptr;
-
-  CFX_RetainPtr<CFX_DIBitmap> pSrcAlpha;
-  if (HasAlpha()) {
-    if (GetFormat() == FXDIB_Argb)
-      pSrcAlpha = CloneAlphaMask();
-    else
-      pSrcAlpha = m_pAlphaMask;
-
-    if (!pSrcAlpha)
-      return nullptr;
-  }
-  bool ret = true;
-  if (dest_format & 0x0200) {
-    if (dest_format == FXDIB_Argb) {
-      ret = pSrcAlpha ? pClone->LoadChannel(FXDIB_Alpha, pSrcAlpha, FXDIB_Alpha)
-                      : pClone->LoadChannel(FXDIB_Alpha, 0xff);
-    } else {
-      ret = pClone->SetAlphaMask(pSrcAlpha);
-    }
-  }
-  if (!ret)
-    return nullptr;
-
-  CFX_RetainPtr<CFX_DIBSource> holder(this);
-  std::unique_ptr<uint32_t, FxFreeDeleter> pal_8bpp;
-  if (!ConvertBuffer(dest_format, pClone->GetBuffer(), pClone->GetPitch(),
-                     m_Width, m_Height, holder, 0, 0, &pal_8bpp)) {
-    return nullptr;
-  }
-  if (pal_8bpp)
-    pClone->SetPalette(pal_8bpp.get());
-
-  return pClone;
-}
-
 bool CFX_DIBitmap::ConvertFormat(FXDIB_Format dest_format) {
   FXDIB_Format src_format = GetFormat();
   if (dest_format == src_format)
diff --git a/core/fxge/dib/fx_dib_main.cpp b/core/fxge/dib/fx_dib_main.cpp
index 32b7c0b..7ee2ee5 100644
--- a/core/fxge/dib/fx_dib_main.cpp
+++ b/core/fxge/dib/fx_dib_main.cpp
@@ -15,6 +15,7 @@
 #include "core/fxcodec/fx_codec.h"
 #include "core/fxcrt/cfx_maybe_owned.h"
 #include "core/fxge/cfx_gemodule.h"
+#include "core/fxge/dib/cfx_filtereddib.h"
 #include "core/fxge/dib/dib_int.h"
 #include "core/fxge/ge/cfx_cliprgn.h"
 #include "third_party/base/ptr_util.h"
@@ -43,19 +44,6 @@
                      FXSYS_GetBValue(rgb));
 }
 
-CFX_DIBSource::CFX_DIBSource()
-    : m_Width(0), m_Height(0), m_bpp(0), m_AlphaFlag(0), m_Pitch(0) {}
-
-CFX_DIBSource::~CFX_DIBSource() {}
-
-uint8_t* CFX_DIBSource::GetBuffer() const {
-  return nullptr;
-}
-
-bool CFX_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const {
-  return false;
-}
-
 CFX_DIBitmap::CFX_DIBitmap() {
   m_bExtBuf = false;
   m_pBuffer = nullptr;
@@ -167,131 +155,6 @@
   m_Pitch = pSrcBitmap->m_Pitch;
 }
 
-CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::Clone(const FX_RECT* pClip) const {
-  FX_RECT rect(0, 0, m_Width, m_Height);
-  if (pClip) {
-    rect.Intersect(*pClip);
-    if (rect.IsEmpty())
-      return nullptr;
-  }
-  auto pNewBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
-  if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat()))
-    return nullptr;
-
-  pNewBitmap->SetPalette(m_pPalette.get());
-  pNewBitmap->SetAlphaMask(m_pAlphaMask, pClip);
-  if (GetBPP() == 1 && rect.left % 8 != 0) {
-    int left_shift = rect.left % 32;
-    int right_shift = 32 - left_shift;
-    int dword_count = pNewBitmap->m_Pitch / 4;
-    for (int row = rect.top; row < rect.bottom; row++) {
-      uint32_t* src_scan = (uint32_t*)GetScanline(row) + rect.left / 32;
-      uint32_t* dest_scan = (uint32_t*)pNewBitmap->GetScanline(row - rect.top);
-      for (int i = 0; i < dword_count; i++) {
-        dest_scan[i] =
-            (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift);
-      }
-    }
-  } else {
-    int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8;
-    if (m_Pitch < (uint32_t)copy_len)
-      copy_len = m_Pitch;
-
-    for (int row = rect.top; row < rect.bottom; row++) {
-      const uint8_t* src_scan = GetScanline(row) + rect.left * m_bpp / 8;
-      uint8_t* dest_scan = (uint8_t*)pNewBitmap->GetScanline(row - rect.top);
-      FXSYS_memcpy(dest_scan, src_scan, copy_len);
-    }
-  }
-  return pNewBitmap;
-}
-
-void CFX_DIBSource::BuildPalette() {
-  if (m_pPalette)
-    return;
-
-  if (GetBPP() == 1) {
-    m_pPalette.reset(FX_Alloc(uint32_t, 2));
-    if (IsCmykImage()) {
-      m_pPalette.get()[0] = 0xff;
-      m_pPalette.get()[1] = 0;
-    } else {
-      m_pPalette.get()[0] = 0xff000000;
-      m_pPalette.get()[1] = 0xffffffff;
-    }
-  } else if (GetBPP() == 8) {
-    m_pPalette.reset(FX_Alloc(uint32_t, 256));
-    if (IsCmykImage()) {
-      for (int i = 0; i < 256; i++)
-        m_pPalette.get()[i] = 0xff - i;
-    } else {
-      for (int i = 0; i < 256; i++)
-        m_pPalette.get()[i] = 0xff000000 | (i * 0x10101);
-    }
-  }
-}
-
-bool CFX_DIBSource::BuildAlphaMask() {
-  if (m_pAlphaMask)
-    return true;
-
-  m_pAlphaMask = pdfium::MakeRetain<CFX_DIBitmap>();
-  if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
-    m_pAlphaMask = nullptr;
-    return false;
-  }
-  FXSYS_memset(m_pAlphaMask->GetBuffer(), 0xff,
-               m_pAlphaMask->GetHeight() * m_pAlphaMask->GetPitch());
-  return true;
-}
-
-uint32_t CFX_DIBSource::GetPaletteEntry(int index) const {
-  ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
-  if (m_pPalette) {
-    return m_pPalette.get()[index];
-  }
-  if (IsCmykImage()) {
-    if (GetBPP() == 1) {
-      return index ? 0 : 0xff;
-    }
-    return 0xff - index;
-  }
-  if (GetBPP() == 1) {
-    return index ? 0xffffffff : 0xff000000;
-  }
-  return index * 0x10101 | 0xff000000;
-}
-
-void CFX_DIBSource::SetPaletteEntry(int index, uint32_t color) {
-  ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
-  if (!m_pPalette) {
-    BuildPalette();
-  }
-  m_pPalette.get()[index] = color;
-}
-
-int CFX_DIBSource::FindPalette(uint32_t color) const {
-  ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
-  if (!m_pPalette) {
-    if (IsCmykImage()) {
-      if (GetBPP() == 1) {
-        return ((uint8_t)color == 0xff) ? 0 : 1;
-      }
-      return 0xff - (uint8_t)color;
-    }
-    if (GetBPP() == 1) {
-      return ((uint8_t)color == 0xff) ? 1 : 0;
-    }
-    return (uint8_t)color;
-  }
-  int palsize = (1 << GetBPP());
-  for (int i = 0; i < palsize; i++)
-    if (m_pPalette.get()[i] == color) {
-      return i;
-    }
-  return -1;
-}
-
 void CFX_DIBitmap::Clear(uint32_t color) {
   if (!m_pBuffer) {
     return;
@@ -354,44 +217,6 @@
   }
 }
 
-void CFX_DIBSource::GetOverlapRect(int& dest_left,
-                                   int& dest_top,
-                                   int& width,
-                                   int& height,
-                                   int src_width,
-                                   int src_height,
-                                   int& src_left,
-                                   int& src_top,
-                                   const CFX_ClipRgn* pClipRgn) {
-  if (width == 0 || height == 0) {
-    return;
-  }
-  ASSERT(width > 0 && height > 0);
-  if (dest_left > m_Width || dest_top > m_Height) {
-    width = 0;
-    height = 0;
-    return;
-  }
-  int x_offset = dest_left - src_left;
-  int y_offset = dest_top - src_top;
-  FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height);
-  FX_RECT src_bound(0, 0, src_width, src_height);
-  src_rect.Intersect(src_bound);
-  FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset,
-                    src_rect.right + x_offset, src_rect.bottom + y_offset);
-  FX_RECT dest_bound(0, 0, m_Width, m_Height);
-  dest_rect.Intersect(dest_bound);
-  if (pClipRgn) {
-    dest_rect.Intersect(pClipRgn->GetBox());
-  }
-  dest_left = dest_rect.left;
-  dest_top = dest_rect.top;
-  src_left = dest_left - x_offset;
-  src_top = dest_top - y_offset;
-  width = dest_rect.right - dest_rect.left;
-  height = dest_rect.bottom - dest_rect.top;
-}
-
 bool CFX_DIBitmap::TransferBitmap(
     int dest_left,
     int dest_top,
@@ -564,92 +389,6 @@
   return true;
 }
 
-void CFX_DIBSource::SetPalette(const uint32_t* pSrc) {
-  static const uint32_t kPaletteSize = 256;
-  if (!pSrc || GetBPP() > 8) {
-    m_pPalette.reset();
-    return;
-  }
-  uint32_t pal_size = 1 << GetBPP();
-  if (!m_pPalette)
-    m_pPalette.reset(FX_Alloc(uint32_t, pal_size));
-  pal_size = std::min(pal_size, kPaletteSize);
-  FXSYS_memcpy(m_pPalette.get(), pSrc, pal_size * sizeof(uint32_t));
-}
-
-void CFX_DIBSource::GetPalette(uint32_t* pal, int alpha) const {
-  ASSERT(GetBPP() <= 8 && !IsCmykImage());
-  if (GetBPP() == 1) {
-    pal[0] = ((m_pPalette ? m_pPalette.get()[0] : 0xff000000) & 0xffffff) |
-             (alpha << 24);
-    pal[1] = ((m_pPalette ? m_pPalette.get()[1] : 0xffffffff) & 0xffffff) |
-             (alpha << 24);
-    return;
-  }
-  if (m_pPalette) {
-    for (int i = 0; i < 256; i++) {
-      pal[i] = (m_pPalette.get()[i] & 0x00ffffff) | (alpha << 24);
-    }
-  } else {
-    for (int i = 0; i < 256; i++) {
-      pal[i] = (i * 0x10101) | (alpha << 24);
-    }
-  }
-}
-
-CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::CloneAlphaMask(
-    const FX_RECT* pClip) const {
-  ASSERT(GetFormat() == FXDIB_Argb);
-  FX_RECT rect(0, 0, m_Width, m_Height);
-  if (pClip) {
-    rect.Intersect(*pClip);
-    if (rect.IsEmpty())
-      return nullptr;
-  }
-  auto pMask = pdfium::MakeRetain<CFX_DIBitmap>();
-  if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask))
-    return nullptr;
-
-  for (int row = rect.top; row < rect.bottom; row++) {
-    const uint8_t* src_scan = GetScanline(row) + rect.left * 4 + 3;
-    uint8_t* dest_scan =
-        const_cast<uint8_t*>(pMask->GetScanline(row - rect.top));
-    for (int col = rect.left; col < rect.right; col++) {
-      *dest_scan++ = *src_scan;
-      src_scan += 4;
-    }
-  }
-  return pMask;
-}
-
-bool CFX_DIBSource::SetAlphaMask(const CFX_RetainPtr<CFX_DIBSource>& pAlphaMask,
-                                 const FX_RECT* pClip) {
-  if (!HasAlpha() || GetFormat() == FXDIB_Argb)
-    return false;
-
-  if (!pAlphaMask) {
-    m_pAlphaMask->Clear(0xff000000);
-    return true;
-  }
-  FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height);
-  if (pClip) {
-    rect.Intersect(*pClip);
-    if (rect.IsEmpty() || rect.Width() != m_Width ||
-        rect.Height() != m_Height) {
-      return false;
-    }
-  } else {
-    if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Height)
-      return false;
-  }
-  for (int row = 0; row < m_Height; row++) {
-    FXSYS_memcpy(const_cast<uint8_t*>(m_pAlphaMask->GetScanline(row)),
-                 pAlphaMask->GetScanline(row + rect.top) + rect.left,
-                 m_pAlphaMask->m_Pitch);
-  }
-  return true;
-}
-
 const int g_ChannelOffset[] = {0, 2, 1, 0, 0, 1, 2, 3, 3};
 bool CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel,
                                const CFX_RetainPtr<CFX_DIBSource>& pSrcBitmap,
@@ -1326,78 +1065,6 @@
   return true;
 }
 
-CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::FlipImage(bool bXFlip,
-                                                     bool bYFlip) const {
-  auto pFlipped = pdfium::MakeRetain<CFX_DIBitmap>();
-  if (!pFlipped->Create(m_Width, m_Height, GetFormat()))
-    return nullptr;
-
-  pFlipped->SetPalette(m_pPalette.get());
-  uint8_t* pDestBuffer = pFlipped->GetBuffer();
-  int Bpp = m_bpp / 8;
-  for (int row = 0; row < m_Height; row++) {
-    const uint8_t* src_scan = GetScanline(row);
-    uint8_t* dest_scan =
-        pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row - 1) : row);
-    if (!bXFlip) {
-      FXSYS_memcpy(dest_scan, src_scan, m_Pitch);
-      continue;
-    }
-    if (m_bpp == 1) {
-      FXSYS_memset(dest_scan, 0, m_Pitch);
-      for (int col = 0; col < m_Width; col++)
-        if (src_scan[col / 8] & (1 << (7 - col % 8))) {
-          int dest_col = m_Width - col - 1;
-          dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8));
-        }
-    } else {
-      dest_scan += (m_Width - 1) * Bpp;
-      if (Bpp == 1) {
-        for (int col = 0; col < m_Width; col++) {
-          *dest_scan = *src_scan;
-          dest_scan--;
-          src_scan++;
-        }
-      } else if (Bpp == 3) {
-        for (int col = 0; col < m_Width; col++) {
-          dest_scan[0] = src_scan[0];
-          dest_scan[1] = src_scan[1];
-          dest_scan[2] = src_scan[2];
-          dest_scan -= 3;
-          src_scan += 3;
-        }
-      } else {
-        ASSERT(Bpp == 4);
-        for (int col = 0; col < m_Width; col++) {
-          *(uint32_t*)dest_scan = *(uint32_t*)src_scan;
-          dest_scan -= 4;
-          src_scan += 4;
-        }
-      }
-    }
-  }
-  if (m_pAlphaMask) {
-    pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer();
-    uint32_t dest_pitch = pFlipped->m_pAlphaMask->GetPitch();
-    for (int row = 0; row < m_Height; row++) {
-      const uint8_t* src_scan = m_pAlphaMask->GetScanline(row);
-      uint8_t* dest_scan =
-          pDestBuffer + dest_pitch * (bYFlip ? (m_Height - row - 1) : row);
-      if (!bXFlip) {
-        FXSYS_memcpy(dest_scan, src_scan, dest_pitch);
-        continue;
-      }
-      dest_scan += (m_Width - 1);
-      for (int col = 0; col < m_Width; col++) {
-        *dest_scan = *src_scan;
-        dest_scan--;
-        src_scan++;
-      }
-    }
-  }
-  return pFlipped;
-}
-
 CFX_DIBExtractor::CFX_DIBExtractor(const CFX_RetainPtr<CFX_DIBSource>& pSrc) {
   if (pSrc->GetBuffer()) {
     CFX_RetainPtr<CFX_DIBSource> pOldSrc(pSrc);
diff --git a/core/fxge/dib/fx_dib_transform.cpp b/core/fxge/dib/fx_dib_transform.cpp
index 3d8ddf8..72de148 100644
--- a/core/fxge/dib/fx_dib_transform.cpp
+++ b/core/fxge/dib/fx_dib_transform.cpp
@@ -179,105 +179,6 @@
   }
 };
 
-CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::SwapXY(
-    bool bXFlip,
-    bool bYFlip,
-    const FX_RECT* pDestClip) const {
-  FX_RECT dest_clip(0, 0, m_Height, m_Width);
-  if (pDestClip)
-    dest_clip.Intersect(*pDestClip);
-  if (dest_clip.IsEmpty())
-    return nullptr;
-
-  auto pTransBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
-  int result_height = dest_clip.Height();
-  int result_width = dest_clip.Width();
-  if (!pTransBitmap->Create(result_width, result_height, GetFormat()))
-    return nullptr;
-
-  pTransBitmap->SetPalette(m_pPalette.get());
-  int dest_pitch = pTransBitmap->GetPitch();
-  uint8_t* dest_buf = pTransBitmap->GetBuffer();
-  int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left;
-  int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right;
-  int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top;
-  int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom;
-  if (GetBPP() == 1) {
-    FXSYS_memset(dest_buf, 0xff, dest_pitch * result_height);
-    for (int row = row_start; row < row_end; row++) {
-      const uint8_t* src_scan = GetScanline(row);
-      int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
-                     dest_clip.left;
-      uint8_t* dest_scan = dest_buf;
-      if (bYFlip) {
-        dest_scan += (result_height - 1) * dest_pitch;
-      }
-      int dest_step = bYFlip ? -dest_pitch : dest_pitch;
-      for (int col = col_start; col < col_end; col++) {
-        if (!(src_scan[col / 8] & (1 << (7 - col % 8)))) {
-          dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8));
-        }
-        dest_scan += dest_step;
-      }
-    }
-  } else {
-    int nBytes = GetBPP() / 8;
-    int dest_step = bYFlip ? -dest_pitch : dest_pitch;
-    if (nBytes == 3) {
-      dest_step -= 2;
-    }
-    for (int row = row_start; row < row_end; row++) {
-      int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
-                     dest_clip.left;
-      uint8_t* dest_scan = dest_buf + dest_col * nBytes;
-      if (bYFlip) {
-        dest_scan += (result_height - 1) * dest_pitch;
-      }
-      if (nBytes == 4) {
-        uint32_t* src_scan = (uint32_t*)GetScanline(row) + col_start;
-        for (int col = col_start; col < col_end; col++) {
-          *(uint32_t*)dest_scan = *src_scan++;
-          dest_scan += dest_step;
-        }
-      } else {
-        const uint8_t* src_scan = GetScanline(row) + col_start * nBytes;
-        if (nBytes == 1) {
-          for (int col = col_start; col < col_end; col++) {
-            *dest_scan = *src_scan++;
-            dest_scan += dest_step;
-          }
-        } else {
-          for (int col = col_start; col < col_end; col++) {
-            *dest_scan++ = *src_scan++;
-            *dest_scan++ = *src_scan++;
-            *dest_scan = *src_scan++;
-            dest_scan += dest_step;
-          }
-        }
-      }
-    }
-  }
-  if (m_pAlphaMask) {
-    dest_pitch = pTransBitmap->m_pAlphaMask->GetPitch();
-    dest_buf = pTransBitmap->m_pAlphaMask->GetBuffer();
-    int dest_step = bYFlip ? -dest_pitch : dest_pitch;
-    for (int row = row_start; row < row_end; row++) {
-      int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) -
-                     dest_clip.left;
-      uint8_t* dest_scan = dest_buf + dest_col;
-      if (bYFlip) {
-        dest_scan += (result_height - 1) * dest_pitch;
-      }
-      const uint8_t* src_scan = m_pAlphaMask->GetScanline(row) + col_start;
-      for (int col = col_start; col < col_end; col++) {
-        *dest_scan = *src_scan++;
-        dest_scan += dest_step;
-      }
-    }
-  }
-  return pTransBitmap;
-}
-
 #define FIX16_005 0.05f
 FX_RECT FXDIB_SwapClipBox(FX_RECT& clip,
                           int width,
@@ -303,45 +204,6 @@
   return rect;
 }
 
-CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::TransformTo(
-    const CFX_Matrix* pDestMatrix,
-    int& result_left,
-    int& result_top,
-    uint32_t flags,
-    const FX_RECT* pDestClip) {
-  CFX_RetainPtr<CFX_DIBSource> holder(this);
-  CFX_ImageTransformer transformer(holder, pDestMatrix, flags, pDestClip);
-  transformer.Start();
-  transformer.Continue(nullptr);
-  result_left = transformer.result().left;
-  result_top = transformer.result().top;
-  return transformer.DetachBitmap();
-}
-
-CFX_RetainPtr<CFX_DIBitmap> CFX_DIBSource::StretchTo(int dest_width,
-                                                     int dest_height,
-                                                     uint32_t flags,
-                                                     const FX_RECT* pClip) {
-  CFX_RetainPtr<CFX_DIBSource> holder(this);
-  FX_RECT clip_rect(0, 0, FXSYS_abs(dest_width), FXSYS_abs(dest_height));
-  if (pClip)
-    clip_rect.Intersect(*pClip);
-
-  if (clip_rect.IsEmpty())
-    return nullptr;
-
-  if (dest_width == m_Width && dest_height == m_Height)
-    return Clone(&clip_rect);
-
-  CFX_BitmapStorer storer;
-  CFX_ImageStretcher stretcher(&storer, holder, dest_width, dest_height,
-                               clip_rect, flags);
-  if (stretcher.Start())
-    stretcher.Continue(nullptr);
-
-  return storer.Detach();
-}
-
 CFX_ImageTransformer::CFX_ImageTransformer(
     const CFX_RetainPtr<CFX_DIBSource>& pSrc,
     const CFX_Matrix* pMatrix,
diff --git a/core/fxge/fx_dib.h b/core/fxge/fx_dib.h
index 2208276..85af766 100644
--- a/core/fxge/fx_dib.h
+++ b/core/fxge/fx_dib.h
@@ -13,66 +13,14 @@
 #include "core/fxcrt/cfx_retain_ptr.h"
 #include "core/fxcrt/fx_basic.h"
 #include "core/fxcrt/fx_coordinates.h"
+#include "core/fxge/dib/cfx_dibitmap.h"
+#include "core/fxge/dib/cfx_dibsource.h"
 #include "third_party/base/stl_util.h"
 
-enum FXDIB_Format {
-  FXDIB_Invalid = 0,
-  FXDIB_1bppMask = 0x101,
-  FXDIB_1bppRgb = 0x001,
-  FXDIB_1bppCmyk = 0x401,
-  FXDIB_8bppMask = 0x108,
-  FXDIB_8bppRgb = 0x008,
-  FXDIB_8bppRgba = 0x208,
-  FXDIB_8bppCmyk = 0x408,
-  FXDIB_8bppCmyka = 0x608,
-  FXDIB_Rgb = 0x018,
-  FXDIB_Rgba = 0x218,
-  FXDIB_Rgb32 = 0x020,
-  FXDIB_Argb = 0x220,
-  FXDIB_Cmyk = 0x420,
-  FXDIB_Cmyka = 0x620,
-};
-
-enum FXDIB_Channel {
-  FXDIB_Red = 1,
-  FXDIB_Green,
-  FXDIB_Blue,
-  FXDIB_Cyan,
-  FXDIB_Magenta,
-  FXDIB_Yellow,
-  FXDIB_Black,
-  FXDIB_Alpha
-};
-
-#define FXDIB_DOWNSAMPLE 0x04
-#define FXDIB_INTERPOL 0x20
-#define FXDIB_BICUBIC_INTERPOL 0x80
-#define FXDIB_NOSMOOTH 0x100
-#define FXDIB_BLEND_NORMAL 0
-#define FXDIB_BLEND_MULTIPLY 1
-#define FXDIB_BLEND_SCREEN 2
-#define FXDIB_BLEND_OVERLAY 3
-#define FXDIB_BLEND_DARKEN 4
-#define FXDIB_BLEND_LIGHTEN 5
-
-#define FXDIB_BLEND_COLORDODGE 6
-#define FXDIB_BLEND_COLORBURN 7
-#define FXDIB_BLEND_HARDLIGHT 8
-#define FXDIB_BLEND_SOFTLIGHT 9
-#define FXDIB_BLEND_DIFFERENCE 10
-#define FXDIB_BLEND_EXCLUSION 11
-#define FXDIB_BLEND_NONSEPARABLE 21
-#define FXDIB_BLEND_HUE 21
-#define FXDIB_BLEND_SATURATION 22
-#define FXDIB_BLEND_COLOR 23
-#define FXDIB_BLEND_LUMINOSITY 24
-#define FXDIB_BLEND_UNSUPPORTED -1
 typedef uint32_t FX_ARGB;
 typedef uint32_t FX_COLORREF;
 typedef uint32_t FX_CMYK;
 class CFX_ClipRgn;
-class CFX_DIBSource;
-class CFX_DIBitmap;
 class CStretchEngine;
 
 #define FXSYS_RGB(r, g, b) ((r) | ((g) << 8) | ((b) << 16))
@@ -169,229 +117,6 @@
                    int src_top,
                    std::unique_ptr<uint32_t, FxFreeDeleter>* pal);
 
-class CFX_DIBSource : public CFX_Retainable {
- public:
-  ~CFX_DIBSource() override;
-
-  virtual uint8_t* GetBuffer() const;
-  virtual const uint8_t* GetScanline(int line) const = 0;
-  virtual bool SkipToScanline(int line, IFX_Pause* pPause) const;
-  virtual void DownSampleScanline(int line,
-                                  uint8_t* dest_scan,
-                                  int dest_bpp,
-                                  int dest_width,
-                                  bool bFlipX,
-                                  int clip_left,
-                                  int clip_width) const = 0;
-
-  int GetWidth() const { return m_Width; }
-  int GetHeight() const { return m_Height; }
-
-  FXDIB_Format GetFormat() const {
-    return (FXDIB_Format)(m_AlphaFlag * 0x100 + m_bpp);
-  }
-  uint32_t GetPitch() const { return m_Pitch; }
-  uint32_t* GetPalette() const { return m_pPalette.get(); }
-  int GetBPP() const { return m_bpp; }
-
-  // TODO(thestig): Investigate this. Given the possible values of FXDIB_Format,
-  // it feels as though this should be implemented as !!(m_AlphaFlag & 1) and
-  // IsOpaqueImage() below should never be able to return true.
-  bool IsAlphaMask() const { return m_AlphaFlag == 1; }
-  bool HasAlpha() const { return !!(m_AlphaFlag & 2); }
-  bool IsOpaqueImage() const { return !(m_AlphaFlag & 3); }
-  bool IsCmykImage() const { return !!(m_AlphaFlag & 4); }
-
-  int GetPaletteSize() const {
-    return IsAlphaMask() ? 0 : (m_bpp == 1 ? 2 : (m_bpp == 8 ? 256 : 0));
-  }
-
-  uint32_t GetPaletteEntry(int index) const;
-
-  void SetPaletteEntry(int index, uint32_t color);
-  uint32_t GetPaletteArgb(int index) const { return GetPaletteEntry(index); }
-  void SetPaletteArgb(int index, uint32_t color) {
-    SetPaletteEntry(index, color);
-  }
-
-  // Copies into internally-owned palette.
-  void SetPalette(const uint32_t* pSrcPal);
-
-  CFX_RetainPtr<CFX_DIBitmap> Clone(const FX_RECT* pClip = nullptr) const;
-  CFX_RetainPtr<CFX_DIBitmap> CloneConvert(FXDIB_Format format);
-  CFX_RetainPtr<CFX_DIBitmap> StretchTo(int dest_width,
-                                        int dest_height,
-                                        uint32_t flags = 0,
-                                        const FX_RECT* pClip = nullptr);
-  CFX_RetainPtr<CFX_DIBitmap> TransformTo(const CFX_Matrix* pMatrix,
-                                          int& left,
-                                          int& top,
-                                          uint32_t flags = 0,
-                                          const FX_RECT* pClip = nullptr);
-  CFX_RetainPtr<CFX_DIBitmap> SwapXY(bool bXFlip,
-                                     bool bYFlip,
-                                     const FX_RECT* pClip = nullptr) const;
-  CFX_RetainPtr<CFX_DIBitmap> FlipImage(bool bXFlip, bool bYFlip) const;
-
-  CFX_RetainPtr<CFX_DIBitmap> CloneAlphaMask(
-      const FX_RECT* pClip = nullptr) const;
-
-  // Copies into internally-owned mask.
-  bool SetAlphaMask(const CFX_RetainPtr<CFX_DIBSource>& pAlphaMask,
-                    const FX_RECT* pClip = nullptr);
-
-  void GetOverlapRect(int& dest_left,
-                      int& dest_top,
-                      int& width,
-                      int& height,
-                      int src_width,
-                      int src_height,
-                      int& src_left,
-                      int& src_top,
-                      const CFX_ClipRgn* pClipRgn);
-
-#if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
-  void DebugVerifyBitmapIsPreMultiplied(void* buffer = nullptr) const;
-#endif
-
-  CFX_RetainPtr<CFX_DIBitmap> m_pAlphaMask;
-
- protected:
-  CFX_DIBSource();
-
-  void BuildPalette();
-  bool BuildAlphaMask();
-  int FindPalette(uint32_t color) const;
-  void GetPalette(uint32_t* pal, int alpha) const;
-
-  int m_Width;
-  int m_Height;
-  int m_bpp;
-  uint32_t m_AlphaFlag;
-  uint32_t m_Pitch;
-  // TODO(weili): Use std::vector for this.
-  std::unique_ptr<uint32_t, FxFreeDeleter> m_pPalette;
-};
-
-class CFX_DIBitmap : public CFX_DIBSource {
- public:
-  template <typename T, typename... Args>
-  friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
-
-  ~CFX_DIBitmap() override;
-
-  bool Create(int width,
-              int height,
-              FXDIB_Format format,
-              uint8_t* pBuffer = nullptr,
-              int pitch = 0);
-
-  bool Copy(const CFX_RetainPtr<CFX_DIBSource>& pSrc);
-
-  // CFX_DIBSource
-  uint8_t* GetBuffer() const override;
-  const uint8_t* GetScanline(int line) const override;
-  void DownSampleScanline(int line,
-                          uint8_t* dest_scan,
-                          int dest_bpp,
-                          int dest_width,
-                          bool bFlipX,
-                          int clip_left,
-                          int clip_width) const override;
-
-  void TakeOver(CFX_RetainPtr<CFX_DIBitmap>&& pSrcBitmap);
-  bool ConvertFormat(FXDIB_Format format);
-  void Clear(uint32_t color);
-
-  uint32_t GetPixel(int x, int y) const;
-  void SetPixel(int x, int y, uint32_t color);
-
-  bool LoadChannel(FXDIB_Channel destChannel,
-                   const CFX_RetainPtr<CFX_DIBSource>& pSrcBitmap,
-                   FXDIB_Channel srcChannel);
-  bool LoadChannel(FXDIB_Channel destChannel, int value);
-
-  bool MultiplyAlpha(int alpha);
-  bool MultiplyAlpha(const CFX_RetainPtr<CFX_DIBSource>& pAlphaMask);
-
-  bool TransferBitmap(int dest_left,
-                      int dest_top,
-                      int width,
-                      int height,
-                      const CFX_RetainPtr<CFX_DIBSource>& pSrcBitmap,
-                      int src_left,
-                      int src_top);
-
-  bool CompositeBitmap(int dest_left,
-                       int dest_top,
-                       int width,
-                       int height,
-                       const CFX_RetainPtr<CFX_DIBSource>& pSrcBitmap,
-                       int src_left,
-                       int src_top,
-                       int blend_type = FXDIB_BLEND_NORMAL,
-                       const CFX_ClipRgn* pClipRgn = nullptr,
-                       bool bRgbByteOrder = false,
-                       void* pIccTransform = nullptr);
-
-  bool TransferMask(int dest_left,
-                    int dest_top,
-                    int width,
-                    int height,
-                    const CFX_RetainPtr<CFX_DIBSource>& pMask,
-                    uint32_t color,
-                    int src_left,
-                    int src_top,
-                    int alpha_flag = 0,
-                    void* pIccTransform = nullptr);
-
-  bool CompositeMask(int dest_left,
-                     int dest_top,
-                     int width,
-                     int height,
-                     const CFX_RetainPtr<CFX_DIBSource>& pMask,
-                     uint32_t color,
-                     int src_left,
-                     int src_top,
-                     int blend_type = FXDIB_BLEND_NORMAL,
-                     const CFX_ClipRgn* pClipRgn = nullptr,
-                     bool bRgbByteOrder = false,
-                     int alpha_flag = 0,
-                     void* pIccTransform = nullptr);
-
-  bool CompositeRect(int dest_left,
-                     int dest_top,
-                     int width,
-                     int height,
-                     uint32_t color,
-                     int alpha_flag = 0,
-                     void* pIccTransform = nullptr);
-
-  bool ConvertColorScale(uint32_t forecolor, uint32_t backcolor);
-
-#if defined _SKIA_SUPPORT_ || _SKIA_SUPPORT_PATHS_
-  void PreMultiply();
-#endif
-#if defined _SKIA_SUPPORT_PATHS_
-  void UnPreMultiply();
-#endif
-
- protected:
-  CFX_DIBitmap();
-  CFX_DIBitmap(const CFX_DIBitmap& src);
-  bool GetGrayData(void* pIccTransform = nullptr);
-
-#if defined _SKIA_SUPPORT_PATHS_
-  enum class Format { kCleared, kPreMultiplied, kUnPreMultiplied };
-#endif
-
-  uint8_t* m_pBuffer;
-#if defined _SKIA_SUPPORT_PATHS_
-  Format m_nFormat;
-#endif
-  bool m_bExtBuf;
-};
-
 class CFX_DIBExtractor {
  public:
   explicit CFX_DIBExtractor(const CFX_RetainPtr<CFX_DIBSource>& pSrc);
@@ -403,41 +128,6 @@
   CFX_RetainPtr<CFX_DIBitmap> m_pBitmap;
 };
 
-class CFX_FilteredDIB : public CFX_DIBSource {
- public:
-  template <typename T, typename... Args>
-  friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
-
-  ~CFX_FilteredDIB() override;
-
-  virtual FXDIB_Format GetDestFormat() = 0;
-  virtual uint32_t* GetDestPalette() = 0;
-  virtual void TranslateScanline(const uint8_t* src_buf,
-                                 std::vector<uint8_t>* dest_buf) const = 0;
-  virtual void TranslateDownSamples(uint8_t* dest_buf,
-                                    const uint8_t* src_buf,
-                                    int pixels,
-                                    int Bpp) const = 0;
-
-  void LoadSrc(const CFX_RetainPtr<CFX_DIBSource>& pSrc);
-
- protected:
-  CFX_FilteredDIB();
-
-  // CFX_DIBSource
-  const uint8_t* GetScanline(int line) const override;
-  void DownSampleScanline(int line,
-                          uint8_t* dest_scan,
-                          int dest_bpp,
-                          int dest_width,
-                          bool bFlipX,
-                          int clip_left,
-                          int clip_width) const override;
-
-  CFX_RetainPtr<CFX_DIBSource> m_pSrc;
-  mutable std::vector<uint8_t> m_Scanline;
-};
-
 class IFX_ScanlineComposer {
  public:
   virtual ~IFX_ScanlineComposer() {}