Unshare CFX_DIBitmap::SetChannelFromBitmap()

Stop using SetChannelFromBitmap() as a common method shared by
SetAlphaFromBitmap() and SetRedFromBitmap(). This is in preparation for
simplifying the 2 caller methods based on their unique input
constraints. Along the way, rename the 2 callers to better describe
their roles, encapsulate them if appropriate, and remove the input
parameter if it is not useful.

Change-Id: I0b78522bc75edf4d275298fa19076aef4aabd924
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/115890
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/render/cpdf_rendershading.cpp b/core/fpdfapi/render/cpdf_rendershading.cpp
index 3c01d55..99cdf50 100644
--- a/core/fpdfapi/render/cpdf_rendershading.cpp
+++ b/core/fpdfapi/render/cpdf_rendershading.cpp
@@ -980,8 +980,9 @@
       break;
     }
   }
-  if (bAlphaMode)
-    pBitmap->SetRedFromBitmap(pBitmap);
+  if (bAlphaMode) {
+    pBitmap->SetRedFromAlpha();
+  }
 
   if (options.ColorModeIs(CPDF_RenderOptions::kGray))
     pBitmap->ConvertColorScale(0, 0xffffff);
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index 91178f4..e8d3e0b 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -294,11 +294,62 @@
   }
 }
 
-bool CFX_DIBitmap::SetChannelFromBitmap(Channel dest_channel,
-                                        RetainPtr<const CFX_DIBBase> source) {
+bool CFX_DIBitmap::SetAlphaFromMask(RetainPtr<const CFX_DIBitmap> mask) {
   if (!m_pBuffer)
     return false;
 
+  if (!mask->IsAlphaFormat() && !mask->IsMaskFormat()) {
+    return false;
+  }
+
+  if (mask->GetBPP() == 1) {
+    mask = mask->ConvertTo(FXDIB_Format::k8bppMask);
+    if (!mask) {
+      return false;
+    }
+  }
+  const int mask_offset = mask->GetFormat() == FXDIB_Format::kArgb ? 3 : 0;
+  int dest_offset = 0;
+  if (IsMaskFormat()) {
+    if (!ConvertFormat(FXDIB_Format::k8bppMask)) {
+      return false;
+    }
+  } else {
+    if (!ConvertFormat(FXDIB_Format::kArgb)) {
+      return false;
+    }
+
+    dest_offset = 3;
+  }
+  if (mask->GetWidth() != m_Width || mask->GetHeight() != m_Height) {
+    mask = mask->StretchTo(m_Width, m_Height, FXDIB_ResampleOptions(), nullptr);
+    if (!mask) {
+      return false;
+    }
+  }
+  RetainPtr<CFX_DIBitmap> dest_bitmap(this);
+  int mask_bytes = mask->GetBPP() / 8;
+  int dest_bytes = dest_bitmap->GetBPP() / 8;
+  for (int row = 0; row < m_Height; row++) {
+    uint8_t* dest_pos =
+        dest_bitmap->GetWritableScanline(row).subspan(dest_offset).data();
+    const uint8_t* mask_pos =
+        mask->GetScanline(row).subspan(mask_offset).data();
+    for (int col = 0; col < m_Width; col++) {
+      *dest_pos = *mask_pos;
+      dest_pos += dest_bytes;
+      mask_pos += mask_bytes;
+    }
+  }
+  return true;
+}
+
+bool CFX_DIBitmap::SetRedFromAlpha() {
+  if (!m_pBuffer) {
+    return false;
+  }
+
+  RetainPtr<CFX_DIBitmap> source(this);
   if (!source->IsAlphaFormat() && !source->IsMaskFormat()) {
     return false;
   }
@@ -310,33 +361,22 @@
     }
   }
   const int src_offset = source->GetFormat() == FXDIB_Format::kArgb ? 3 : 0;
-  int dest_offset = 0;
-  if (dest_channel == Channel::kAlpha) {
-    if (IsMaskFormat()) {
-      if (!ConvertFormat(FXDIB_Format::k8bppMask))
+  if (IsMaskFormat()) {
+    return false;
+  }
+
+  if (GetBPP() < 24) {
+    if (IsAlphaFormat()) {
+      if (!ConvertFormat(FXDIB_Format::kArgb)) {
         return false;
+      }
     } else {
-      if (!ConvertFormat(FXDIB_Format::kArgb))
+      if (!ConvertFormat(kPlatformRGBFormat)) {
         return false;
-
-      dest_offset = 3;
-    }
-  } else {
-    DCHECK_EQ(dest_channel, Channel::kRed);
-    if (IsMaskFormat())
-      return false;
-
-    if (GetBPP() < 24) {
-      if (IsAlphaFormat()) {
-        if (!ConvertFormat(FXDIB_Format::kArgb))
-          return false;
-      } else {
-        if (!ConvertFormat(kPlatformRGBFormat))
-          return false;
       }
     }
-    dest_offset = 2;
   }
+  int dest_offset = 2;
   if (source->GetWidth() != m_Width || source->GetHeight() != m_Height) {
     source =
         source->StretchTo(m_Width, m_Height, FXDIB_ResampleOptions(), nullptr);
@@ -361,14 +401,6 @@
   return true;
 }
 
-bool CFX_DIBitmap::SetAlphaFromBitmap(RetainPtr<const CFX_DIBBase> source) {
-  return SetChannelFromBitmap(Channel::kAlpha, std::move(source));
-}
-
-bool CFX_DIBitmap::SetRedFromBitmap(RetainPtr<const CFX_DIBBase> source) {
-  return SetChannelFromBitmap(Channel::kRed, std::move(source));
-}
-
 bool CFX_DIBitmap::SetUniformOpaqueAlpha() {
   if (!m_pBuffer)
     return false;
@@ -404,7 +436,7 @@
   }
 
   if (IsOpaqueImage()) {
-    return SetAlphaFromBitmap(std::move(mask));
+    return SetAlphaFromMask(std::move(mask));
   }
 
   if (mask->GetWidth() != m_Width || mask->GetHeight() != m_Height) {
diff --git a/core/fxge/dib/cfx_dibitmap.h b/core/fxge/dib/cfx_dibitmap.h
index 089d475..c79a366 100644
--- a/core/fxge/dib/cfx_dibitmap.h
+++ b/core/fxge/dib/cfx_dibitmap.h
@@ -59,8 +59,7 @@
   uint32_t GetPixelForTesting(int x, int y) const;
 #endif  // defined(PDF_USE_SKIA)
 
-  bool SetRedFromBitmap(RetainPtr<const CFX_DIBBase> source);
-  bool SetAlphaFromBitmap(RetainPtr<const CFX_DIBBase> source);
+  bool SetRedFromAlpha();
   bool SetUniformOpaqueAlpha();
 
   // TODO(crbug.com/pdfium/2007): Migrate callers to `CFX_RenderDevice`.
@@ -151,8 +150,7 @@
   CFX_DIBitmap(const CFX_DIBitmap& src);
   ~CFX_DIBitmap() override;
 
-  bool SetChannelFromBitmap(Channel dest_channel,
-                            RetainPtr<const CFX_DIBBase> source);
+  bool SetAlphaFromMask(RetainPtr<const CFX_DIBitmap> mask);
   void ConvertBGRColorScale(uint32_t forecolor, uint32_t backcolor);
   bool TransferWithUnequalFormats(FXDIB_Format dest_format,
                                   int dest_left,