Remove CFX_DIBExtractor

Removes the CFX_DIBExtractor class, which is only used to convert
CFX_DIBBase to CFX_DIBitmap for use with certain Windows APIs. As it
turns out, the APIs only require CFX_DIBBase.

Bug: pdfium:2034
Change-Id: I383c3987c375187694eaba976dbfb1f7eefb29a7
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/108371
Reviewed-by: Nigi <nigi@chromium.org>
Commit-Queue: K. Moon <kmoon@chromium.org>
diff --git a/core/fxge/BUILD.gn b/core/fxge/BUILD.gn
index dcb17d4..a771bfe 100644
--- a/core/fxge/BUILD.gn
+++ b/core/fxge/BUILD.gn
@@ -173,8 +173,6 @@
     sources += [
       "cfx_windowsrenderdevice.cpp",
       "cfx_windowsrenderdevice.h",
-      "dib/cfx_dibextractor.cpp",
-      "dib/cfx_dibextractor.h",
       "win32/cfx_psfonttracker.cpp",
       "win32/cfx_psfonttracker.h",
       "win32/cfx_psrenderer.cpp",
diff --git a/core/fxge/dib/cfx_dibextractor.cpp b/core/fxge/dib/cfx_dibextractor.cpp
deleted file mode 100644
index e9fded9..0000000
--- a/core/fxge/dib/cfx_dibextractor.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 The PDFium Authors
-// 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_dibextractor.h"
-
-#include "core/fxge/dib/cfx_dibbase.h"
-#include "core/fxge/dib/cfx_dibitmap.h"
-
-CFX_DIBExtractor::CFX_DIBExtractor(const RetainPtr<CFX_DIBBase>& pSrc) {
-  if (pSrc->GetBuffer().empty()) {
-    m_pBitmap = pSrc->Realize();
-    return;
-  }
-  m_pBitmap = pdfium::MakeRetain<CFX_DIBitmap>();
-  if (!m_pBitmap->Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat(),
-                         pSrc->GetWritableBuffer().data(),
-                         /*pitch=*/0)) {
-    m_pBitmap.Reset();
-    return;
-  }
-
-  m_pBitmap->SetPalette(pSrc->GetPaletteSpan());
-}
-
-CFX_DIBExtractor::~CFX_DIBExtractor() = default;
diff --git a/core/fxge/dib/cfx_dibextractor.h b/core/fxge/dib/cfx_dibextractor.h
deleted file mode 100644
index 455eca1..0000000
--- a/core/fxge/dib/cfx_dibextractor.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The PDFium Authors
-// 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_DIBEXTRACTOR_H_
-#define CORE_FXGE_DIB_CFX_DIBEXTRACTOR_H_
-
-#include "core/fxcrt/retain_ptr.h"
-
-class CFX_DIBBase;
-class CFX_DIBitmap;
-
-class CFX_DIBExtractor {
- public:
-  explicit CFX_DIBExtractor(const RetainPtr<CFX_DIBBase>& pSrc);
-  ~CFX_DIBExtractor();
-
-  RetainPtr<CFX_DIBitmap> GetBitmap() { return m_pBitmap; }
-
- private:
-  RetainPtr<CFX_DIBitmap> m_pBitmap;
-};
-
-#endif  // CORE_FXGE_DIB_CFX_DIBEXTRACTOR_H_
diff --git a/core/fxge/win32/cfx_psrenderer.cpp b/core/fxge/win32/cfx_psrenderer.cpp
index ae168f4..c2da036 100644
--- a/core/fxge/win32/cfx_psrenderer.cpp
+++ b/core/fxge/win32/cfx_psrenderer.cpp
@@ -29,7 +29,7 @@
 #include "core/fxge/cfx_glyphcache.h"
 #include "core/fxge/cfx_path.h"
 #include "core/fxge/cfx_renderdevice.h"
-#include "core/fxge/dib/cfx_dibextractor.h"
+#include "core/fxge/dib/cfx_dibbase.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "core/fxge/dib/fx_dib.h"
 #include "core/fxge/freetype/fx_freetype.h"
@@ -555,10 +555,7 @@
     WriteStream(buf);
     WritePSBinary(compress_result.data);
   } else {
-    CFX_DIBExtractor source_extractor(pSource);
-    RetainPtr<CFX_DIBBase> pConverted = source_extractor.GetBitmap();
-    if (!pConverted)
-      return false;
+    RetainPtr<CFX_DIBBase> pConverted = pSource;
     switch (pSource->GetFormat()) {
       case FXDIB_Format::k1bppRgb:
       case FXDIB_Format::kRgb32:
diff --git a/core/fxge/win32/cgdi_device_driver.cpp b/core/fxge/win32/cgdi_device_driver.cpp
index efd8a10..b794a49 100644
--- a/core/fxge/win32/cgdi_device_driver.cpp
+++ b/core/fxge/win32/cgdi_device_driver.cpp
@@ -18,6 +18,7 @@
 #include "core/fxge/cfx_fillrenderoptions.h"
 #include "core/fxge/cfx_graphstatedata.h"
 #include "core/fxge/cfx_path.h"
+#include "core/fxge/dib/cfx_dibbase.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "core/fxge/render_defines.h"
 #include "core/fxge/win32/cwin32_platform.h"
@@ -152,10 +153,11 @@
   EndPath(hDC);
 }
 
-ByteString GetBitmapInfo(const RetainPtr<CFX_DIBitmap>& pBitmap) {
+ByteString GetBitmapInfo(const RetainPtr<CFX_DIBBase>& source) {
   int len = sizeof(BITMAPINFOHEADER);
-  if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8)
-    len += sizeof(DWORD) * (int)(1 << pBitmap->GetBPP());
+  if (source->GetBPP() == 1 || source->GetBPP() == 8) {
+    len += sizeof(DWORD) * (int)(1 << source->GetBPP());
+  }
 
   ByteString result;
   {
@@ -164,30 +166,33 @@
     BITMAPINFOHEADER* pbmih = reinterpret_cast<BITMAPINFOHEADER*>(cspan.data());
     memset(pbmih, 0, sizeof(BITMAPINFOHEADER));
     pbmih->biSize = sizeof(BITMAPINFOHEADER);
-    pbmih->biBitCount = pBitmap->GetBPP();
+    pbmih->biBitCount = source->GetBPP();
     pbmih->biCompression = BI_RGB;
-    pbmih->biHeight = -(int)pBitmap->GetHeight();
+    pbmih->biHeight = -(int)source->GetHeight();
     pbmih->biPlanes = 1;
-    pbmih->biWidth = pBitmap->GetWidth();
-    if (pBitmap->GetBPP() == 8) {
-      uint32_t* pPalette = (uint32_t*)(pbmih + 1);
-      if (pBitmap->HasPalette()) {
-        pdfium::span<const uint32_t> palette = pBitmap->GetPaletteSpan();
-        for (int i = 0; i < 256; i++)
-          pPalette[i] = palette[i];
+    pbmih->biWidth = source->GetWidth();
+    if (source->GetBPP() == 8) {
+      uint32_t* palette = (uint32_t*)(pbmih + 1);
+      if (source->HasPalette()) {
+        pdfium::span<const uint32_t> palette_span = source->GetPaletteSpan();
+        for (int i = 0; i < 256; i++) {
+          palette[i] = palette_span[i];
+        }
       } else {
-        for (int i = 0; i < 256; i++)
-          pPalette[i] = ArgbEncode(0, i, i, i);
+        for (int i = 0; i < 256; i++) {
+          palette[i] = ArgbEncode(0, i, i, i);
+        }
       }
     }
-    if (pBitmap->GetBPP() == 1) {
-      uint32_t* pPalette = (uint32_t*)(pbmih + 1);
-      if (pBitmap->HasPalette()) {
-        pPalette[0] = pBitmap->GetPaletteSpan()[0];
-        pPalette[1] = pBitmap->GetPaletteSpan()[1];
+    if (source->GetBPP() == 1) {
+      uint32_t* palette = (uint32_t*)(pbmih + 1);
+      if (source->HasPalette()) {
+        pdfium::span<const uint32_t> palette_span = source->GetPaletteSpan();
+        palette[0] = palette_span[0];
+        palette[1] = palette_span[1];
       } else {
-        pPalette[0] = 0;
-        pPalette[1] = 0xffffff;
+        palette[0] = 0;
+        palette[1] = 0xffffff;
       }
     }
   }
@@ -384,84 +389,82 @@
     SaveDC(m_hDC);
 }
 
-bool CGdiDeviceDriver::GDI_SetDIBits(const RetainPtr<CFX_DIBitmap>& pBitmap1,
+bool CGdiDeviceDriver::GDI_SetDIBits(const RetainPtr<CFX_DIBBase>& source,
                                      const FX_RECT& src_rect,
                                      int left,
                                      int top) {
   if (m_DeviceType == DeviceType::kPrinter) {
-    RetainPtr<CFX_DIBitmap> pBitmap = pBitmap1->FlipImage(false, true);
-    if (!pBitmap)
+    RetainPtr<CFX_DIBBase> flipped_source = source->FlipImage(false, true);
+    if (!flipped_source) {
       return false;
+    }
 
-    LPBYTE pBuffer = pBitmap->GetWritableBuffer().data();
-    ByteString info = GetBitmapInfo(pBitmap);
+    ByteString info = GetBitmapInfo(flipped_source);
     ((BITMAPINFOHEADER*)info.c_str())->biHeight *= -1;
     FX_RECT dst_rect(0, 0, src_rect.Width(), src_rect.Height());
-    dst_rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
+    dst_rect.Intersect(0, 0, flipped_source->GetWidth(),
+                       flipped_source->GetHeight());
     int dst_width = dst_rect.Width();
     int dst_height = dst_rect.Height();
     ::StretchDIBits(m_hDC, left, top, dst_width, dst_height, 0, 0, dst_width,
-                    dst_height, pBuffer, (BITMAPINFO*)info.c_str(),
-                    DIB_RGB_COLORS, SRCCOPY);
+                    dst_height, flipped_source->GetBuffer().data(),
+                    (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS, SRCCOPY);
     return true;
   }
 
-  RetainPtr<CFX_DIBitmap> pBitmap = pBitmap1;
-  ByteString info = GetBitmapInfo(pBitmap);
+  ByteString info = GetBitmapInfo(source);
   ::SetDIBitsToDevice(m_hDC, left, top, src_rect.Width(), src_rect.Height(),
-                      src_rect.left, pBitmap->GetHeight() - src_rect.bottom, 0,
-                      pBitmap->GetHeight(), pBitmap->GetBuffer().data(),
+                      src_rect.left, source->GetHeight() - src_rect.bottom, 0,
+                      source->GetHeight(), source->GetBuffer().data(),
                       (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS);
   return true;
 }
 
-bool CGdiDeviceDriver::GDI_StretchDIBits(
-    const RetainPtr<CFX_DIBitmap>& pBitmap1,
-    int dest_left,
-    int dest_top,
-    int dest_width,
-    int dest_height,
-    const FXDIB_ResampleOptions& options) {
-  RetainPtr<CFX_DIBitmap> pBitmap = pBitmap1;
-  if (!pBitmap || dest_width == 0 || dest_height == 0)
+bool CGdiDeviceDriver::GDI_StretchDIBits(const RetainPtr<CFX_DIBBase>& source,
+                                         int dest_left,
+                                         int dest_top,
+                                         int dest_width,
+                                         int dest_height,
+                                         const FXDIB_ResampleOptions& options) {
+  if (!source || dest_width == 0 || dest_height == 0) {
     return false;
+  }
 
-  ByteString info = GetBitmapInfo(pBitmap);
+  ByteString info = GetBitmapInfo(source);
   if ((int64_t)abs(dest_width) * abs(dest_height) <
-          (int64_t)pBitmap1->GetWidth() * pBitmap1->GetHeight() * 4 ||
+          (int64_t)source->GetWidth() * source->GetHeight() * 4 ||
       options.bInterpolateBilinear) {
     SetStretchBltMode(m_hDC, HALFTONE);
   } else {
     SetStretchBltMode(m_hDC, COLORONCOLOR);
   }
-  RetainPtr<CFX_DIBitmap> pToStrechBitmap = pBitmap;
+  RetainPtr<CFX_DIBBase> stretch_source = source;
   if (m_DeviceType == DeviceType::kPrinter &&
-      ((int64_t)pBitmap->GetWidth() * pBitmap->GetHeight() >
+      ((int64_t)source->GetWidth() * source->GetHeight() >
        (int64_t)abs(dest_width) * abs(dest_height))) {
-    pToStrechBitmap = pBitmap->StretchTo(dest_width, dest_height,
-                                         FXDIB_ResampleOptions(), nullptr);
+    stretch_source = source->StretchTo(dest_width, dest_height,
+                                       FXDIB_ResampleOptions(), nullptr);
+    info = GetBitmapInfo(stretch_source);
   }
-  ByteString toStrechBitmapInfo = GetBitmapInfo(pToStrechBitmap);
   ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height, 0, 0,
-                  pToStrechBitmap->GetWidth(), pToStrechBitmap->GetHeight(),
-                  pToStrechBitmap->GetBuffer().data(),
-                  (BITMAPINFO*)toStrechBitmapInfo.c_str(), DIB_RGB_COLORS,
-                  SRCCOPY);
+                  stretch_source->GetWidth(), stretch_source->GetHeight(),
+                  stretch_source->GetBuffer().data(), (BITMAPINFO*)info.c_str(),
+                  DIB_RGB_COLORS, SRCCOPY);
   return true;
 }
 
-bool CGdiDeviceDriver::GDI_StretchBitMask(
-    const RetainPtr<CFX_DIBitmap>& pBitmap1,
-    int dest_left,
-    int dest_top,
-    int dest_width,
-    int dest_height,
-    uint32_t bitmap_color) {
-  RetainPtr<CFX_DIBitmap> pBitmap = pBitmap1;
-  if (!pBitmap || dest_width == 0 || dest_height == 0)
+bool CGdiDeviceDriver::GDI_StretchBitMask(const RetainPtr<CFX_DIBBase>& source,
+                                          int dest_left,
+                                          int dest_top,
+                                          int dest_width,
+                                          int dest_height,
+                                          uint32_t bitmap_color) {
+  if (!source || dest_width == 0 || dest_height == 0) {
     return false;
+  }
 
-  int width = pBitmap->GetWidth(), height = pBitmap->GetHeight();
+  int width = source->GetWidth();
+  int height = source->GetHeight();
   struct {
     BITMAPINFOHEADER bmiHeader;
     uint32_t bmiColors[2];
@@ -501,7 +504,7 @@
   // 0xB8074A
 
   ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height, 0, 0,
-                  width, height, pBitmap->GetBuffer().data(), (BITMAPINFO*)&bmi,
+                  width, height, source->GetBuffer().data(), (BITMAPINFO*)&bmi,
                   DIB_RGB_COLORS, 0xB8074A);
 
   SelectObject(m_hDC, hOld);
diff --git a/core/fxge/win32/cgdi_device_driver.h b/core/fxge/win32/cgdi_device_driver.h
index 59f24c0..de8c41e 100644
--- a/core/fxge/win32/cgdi_device_driver.h
+++ b/core/fxge/win32/cgdi_device_driver.h
@@ -13,6 +13,8 @@
 #include "core/fxge/renderdevicedriver_iface.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
+class CFX_DIBBase;
+
 class CGdiDeviceDriver : public RenderDeviceDriverIface {
  protected:
   CGdiDeviceDriver(HDC hDC, DeviceType device_type);
@@ -50,17 +52,17 @@
 
   void DrawLine(float x1, float y1, float x2, float y2);
 
-  bool GDI_SetDIBits(const RetainPtr<CFX_DIBitmap>& pBitmap,
+  bool GDI_SetDIBits(const RetainPtr<CFX_DIBBase>& source,
                      const FX_RECT& src_rect,
                      int left,
                      int top);
-  bool GDI_StretchDIBits(const RetainPtr<CFX_DIBitmap>& pBitmap,
+  bool GDI_StretchDIBits(const RetainPtr<CFX_DIBBase>& source,
                          int dest_left,
                          int dest_top,
                          int dest_width,
                          int dest_height,
                          const FXDIB_ResampleOptions& options);
-  bool GDI_StretchBitMask(const RetainPtr<CFX_DIBitmap>& pBitmap,
+  bool GDI_StretchBitMask(const RetainPtr<CFX_DIBBase>& source,
                           int dest_left,
                           int dest_top,
                           int dest_width,
diff --git a/core/fxge/win32/cgdi_display_driver.cpp b/core/fxge/win32/cgdi_display_driver.cpp
index cb1ac48..763e300 100644
--- a/core/fxge/win32/cgdi_display_driver.cpp
+++ b/core/fxge/win32/cgdi_display_driver.cpp
@@ -8,7 +8,7 @@
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
-#include "core/fxge/dib/cfx_dibextractor.h"
+#include "core/fxge/dib/cfx_dibbase.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "core/fxge/render_defines.h"
 #include "core/fxge/win32/cwin32_platform.h"
@@ -115,11 +115,7 @@
     FX_RECT alpha_src_rect(0, 0, width, height);
     return SetDIBits(bitmap, 0, alpha_src_rect, left, top, BlendMode::kNormal);
   }
-  CFX_DIBExtractor temp(pSource);
-  RetainPtr<CFX_DIBitmap> pBitmap = temp.GetBitmap();
-  if (!pBitmap)
-    return false;
-  return GDI_SetDIBits(pBitmap, src_rect, left, top);
+  return GDI_SetDIBits(pSource, src_rect, left, top);
 }
 
 bool CGdiDisplayDriver::UseFoxitStretchEngine(
@@ -139,7 +135,7 @@
     dest_top += dest_height;
 
   bitmap_clip.Offset(-dest_left, -dest_top);
-  RetainPtr<CFX_DIBitmap> pStretched =
+  RetainPtr<CFX_DIBBase> pStretched =
       pSource->StretchTo(dest_width, dest_height, options, &bitmap_clip);
   if (!pStretched)
     return true;
@@ -199,23 +195,15 @@
     auto* pPlatform =
         static_cast<CWin32Platform*>(CFX_GEModule::Get()->GetPlatform());
     if (pPlatform->m_GdiplusExt.IsAvailable()) {
-      CFX_DIBExtractor temp(pSource);
-      RetainPtr<CFX_DIBitmap> pBitmap = temp.GetBitmap();
-      if (!pBitmap)
-        return false;
       return pPlatform->m_GdiplusExt.StretchDIBits(
-          m_hDC, pBitmap, dest_left, dest_top, dest_width, dest_height,
+          m_hDC, pSource, dest_left, dest_top, dest_width, dest_height,
           pClipRect, FXDIB_ResampleOptions());
     }
     return UseFoxitStretchEngine(pSource, color, dest_left, dest_top,
                                  dest_width, dest_height, pClipRect,
                                  FXDIB_ResampleOptions());
   }
-  CFX_DIBExtractor temp(pSource);
-  RetainPtr<CFX_DIBitmap> pBitmap = temp.GetBitmap();
-  if (!pBitmap)
-    return false;
-  return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width,
+  return GDI_StretchDIBits(pSource, dest_left, dest_top, dest_width,
                            dest_height, FXDIB_ResampleOptions());
 }
 
diff --git a/core/fxge/win32/cgdi_plus_ext.cpp b/core/fxge/win32/cgdi_plus_ext.cpp
index e4442c0..7fa02be 100644
--- a/core/fxge/win32/cgdi_plus_ext.cpp
+++ b/core/fxge/win32/cgdi_plus_ext.cpp
@@ -23,6 +23,7 @@
 #include "core/fxge/cfx_gemodule.h"
 #include "core/fxge/cfx_graphstatedata.h"
 #include "core/fxge/cfx_path.h"
+#include "core/fxge/dib/cfx_dibbase.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "core/fxge/win32/cwin32_platform.h"
 #include "third_party/base/notreached.h"
@@ -203,7 +204,7 @@
 }
 
 void OutputImage(Gdiplus::GpGraphics* pGraphics,
-                 const RetainPtr<CFX_DIBitmap>& pBitmap,
+                 const RetainPtr<CFX_DIBBase>& source,
                  const FX_RECT& src_rect,
                  int dest_left,
                  int dest_top,
@@ -212,22 +213,27 @@
   int src_width = src_rect.Width();
   int src_height = src_rect.Height();
   const CGdiplusExt& GdiplusExt = GetGdiplusExt();
-  if (pBitmap->GetBPP() == 1 && (src_rect.left % 8)) {
+  if (source->GetBPP() == 1 && (src_rect.left % 8)) {
     FX_RECT new_rect(0, 0, src_width, src_height);
-    RetainPtr<CFX_DIBitmap> pCloned = pBitmap->ClipTo(src_rect);
+    RetainPtr<CFX_DIBBase> pCloned = source->ClipTo(src_rect);
     if (!pCloned)
       return;
     OutputImage(pGraphics, pCloned, new_rect, dest_left, dest_top, dest_width,
                 dest_height);
     return;
   }
-  int src_pitch = pBitmap->GetPitch();
-  uint8_t* scan0 = pBitmap->GetWritableBuffer()
-                       .subspan(src_rect.top * src_pitch +
-                                pBitmap->GetBPP() * src_rect.left / 8)
-                       .data();
+  int src_pitch = source->GetPitch();
+
+  // `GdipCreateBitmapFromScan0()` requires a `BYTE*` scanline buffer, but in
+  // this case, the bitmap only gets read by `GdipDrawImagePointsI()`, then
+  // disposed of, so it's safe to cast away `const` here.
+  uint8_t* scan0 =
+      const_cast<uint8_t*>(source->GetBuffer()
+                               .subspan(src_rect.top * src_pitch +
+                                        source->GetBPP() * src_rect.left / 8)
+                               .data());
   Gdiplus::GpBitmap* bitmap = nullptr;
-  switch (pBitmap->GetFormat()) {
+  switch (source->GetFormat()) {
     case FXDIB_Format::kArgb:
       CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
                                           PixelFormat32bppARGB, scan0, &bitmap);
@@ -248,7 +254,7 @@
       pal[0] = 0;
       pal[1] = 256;
       for (int i = 0; i < 256; i++)
-        pal[i + 2] = pBitmap->GetPaletteArgb(i);
+        pal[i + 2] = source->GetPaletteArgb(i);
       CallFunc(GdipSetImagePalette)(bitmap, (Gdiplus::ColorPalette*)pal);
       break;
     }
@@ -575,7 +581,7 @@
 }
 
 bool CGdiplusExt::StretchDIBits(HDC hDC,
-                                const RetainPtr<CFX_DIBitmap>& pBitmap,
+                                const RetainPtr<CFX_DIBBase>& source,
                                 int dest_left,
                                 int dest_top,
                                 int dest_width,
@@ -589,16 +595,16 @@
   if (options.bNoSmoothing) {
     CallFunc(GdipSetInterpolationMode)(
         pGraphics, Gdiplus::InterpolationModeNearestNeighbor);
-  } else if (pBitmap->GetWidth() > abs(dest_width) / 2 ||
-             pBitmap->GetHeight() > abs(dest_height) / 2) {
+  } else if (source->GetWidth() > abs(dest_width) / 2 ||
+             source->GetHeight() > abs(dest_height) / 2) {
     CallFunc(GdipSetInterpolationMode)(pGraphics,
                                        Gdiplus::InterpolationModeHighQuality);
   } else {
     CallFunc(GdipSetInterpolationMode)(pGraphics,
                                        Gdiplus::InterpolationModeBilinear);
   }
-  FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
-  OutputImage(pGraphics, pBitmap, src_rect, dest_left, dest_top, dest_width,
+  FX_RECT src_rect(0, 0, source->GetWidth(), source->GetHeight());
+  OutputImage(pGraphics, source, src_rect, dest_left, dest_top, dest_width,
               dest_height);
   CallFunc(GdipDeleteGraphics)(pGraphics);
   CallFunc(GdipDeleteGraphics)(pGraphics);
diff --git a/core/fxge/win32/cgdi_plus_ext.h b/core/fxge/win32/cgdi_plus_ext.h
index ff6f165..ced36c9 100644
--- a/core/fxge/win32/cgdi_plus_ext.h
+++ b/core/fxge/win32/cgdi_plus_ext.h
@@ -14,7 +14,7 @@
 
 #include "core/fxcrt/retain_ptr.h"
 
-class CFX_DIBitmap;
+class CFX_DIBBase;
 class CFX_GraphStateData;
 class CFX_Matrix;
 class CFX_Path;
@@ -30,7 +30,7 @@
   void Load();
   bool IsAvailable() { return !!m_hModule; }
   bool StretchDIBits(HDC hDC,
-                     const RetainPtr<CFX_DIBitmap>& pBitmap,
+                     const RetainPtr<CFX_DIBBase>& source,
                      int dest_left,
                      int dest_top,
                      int dest_width,
diff --git a/core/fxge/win32/cgdi_printer_driver.cpp b/core/fxge/win32/cgdi_printer_driver.cpp
index 8286685..28bc516 100644
--- a/core/fxge/win32/cgdi_printer_driver.cpp
+++ b/core/fxge/win32/cgdi_printer_driver.cpp
@@ -17,7 +17,7 @@
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/cfx_font.h"
 #include "core/fxge/cfx_windowsrenderdevice.h"
-#include "core/fxge/dib/cfx_dibextractor.h"
+#include "core/fxge/dib/cfx_dibbase.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 #include "core/fxge/render_defines.h"
 #include "core/fxge/text_char_pos.h"
@@ -59,12 +59,7 @@
   if (pSource->IsAlphaFormat())
     return false;
 
-  CFX_DIBExtractor temp(pSource);
-  RetainPtr<CFX_DIBitmap> pBitmap = temp.GetBitmap();
-  if (!pBitmap)
-    return false;
-
-  return GDI_SetDIBits(pBitmap, src_rect, left, top);
+  return GDI_SetDIBits(pSource, src_rect, left, top);
 }
 
 bool CGdiPrinterDriver::StretchDIBits(const RetainPtr<CFX_DIBBase>& pSource,
@@ -82,7 +77,7 @@
       return false;
 
     if (dest_width < 0 || dest_height < 0) {
-      RetainPtr<CFX_DIBitmap> pFlipped =
+      RetainPtr<CFX_DIBBase> pFlipped =
           pSource->FlipImage(dest_width < 0, dest_height < 0);
       if (!pFlipped)
         return false;
@@ -96,11 +91,7 @@
                                 abs(dest_height), color);
     }
 
-    CFX_DIBExtractor temp(pSource);
-    RetainPtr<CFX_DIBitmap> pBitmap = temp.GetBitmap();
-    if (!pBitmap)
-      return false;
-    return GDI_StretchBitMask(pBitmap, dest_left, dest_top, dest_width,
+    return GDI_StretchBitMask(pSource, dest_left, dest_top, dest_width,
                               dest_height, color);
   }
 
@@ -108,7 +99,7 @@
     return false;
 
   if (dest_width < 0 || dest_height < 0) {
-    RetainPtr<CFX_DIBitmap> pFlipped =
+    RetainPtr<CFX_DIBBase> pFlipped =
         pSource->FlipImage(dest_width < 0, dest_height < 0);
     if (!pFlipped)
       return false;
@@ -122,11 +113,7 @@
                              abs(dest_height), options);
   }
 
-  CFX_DIBExtractor temp(pSource);
-  RetainPtr<CFX_DIBitmap> pBitmap = temp.GetBitmap();
-  if (!pBitmap)
-    return false;
-  return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width,
+  return GDI_StretchDIBits(pSource, dest_left, dest_top, dest_width,
                            dest_height, options);
 }
 
@@ -157,7 +144,7 @@
   if (fabs(matrix.a) >= 0.5f || fabs(matrix.d) >= 0.5f)
     return false;
 
-  RetainPtr<CFX_DIBitmap> pTransformed =
+  RetainPtr<CFX_DIBBase> pTransformed =
       pSource->SwapXY(matrix.c > 0, matrix.b < 0);
   if (!pTransformed)
     return false;