Remove more dead code in CFX_DIBitmap

Set more constraints on CFX_DIBitmap methods based on current usage.
Then delete dead code, like those that assume the CFX_DIBitmap can be a
mask format, or the mask is of a different size.

Document the new constraints and side effects.

Along the way, use GetWritableScanline() and GetScanline() instead of
manually calculating row offsets.

Change-Id: If273ce40f20ef6e937f0be63b04bb853396cd109
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/115893
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index bb06115..01a3351 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -294,12 +294,9 @@
   }
 }
 
-bool CFX_DIBitmap::SetRedFromAlpha() {
+void CFX_DIBitmap::SetRedFromAlpha() {
   CHECK_EQ(FXDIB_Format::kArgb, GetFormat());
-
-  if (!m_pBuffer) {
-    return false;
-  }
+  CHECK(m_pBuffer);
 
   for (int row = 0; row < m_Height; row++) {
     constexpr int kSrcOffset = 3;
@@ -313,98 +310,59 @@
       src_pos += kBytes;
     }
   }
-  return true;
 }
 
 bool CFX_DIBitmap::SetUniformOpaqueAlpha() {
+  CHECK_EQ(FXDIB_Format::kArgb, GetFormat());
+
   if (!m_pBuffer)
     return false;
 
-  if (IsMaskFormat()) {
-    if (!ConvertFormat(FXDIB_Format::k8bppMask))
-      return false;
-  } else {
-    if (!ConvertFormat(FXDIB_Format::kArgb))
-      return false;
-  }
-  const int Bpp = GetBPP() / 8;
-  if (Bpp == 1) {
-    memset(m_pBuffer.Get(), 0xff, m_Height * m_Pitch);
-    return true;
-  }
-  const int dest_offset = GetFormat() == FXDIB_Format::kArgb ? 3 : 0;
   for (int row = 0; row < m_Height; row++) {
-    uint8_t* scan_line = m_pBuffer.Get() + row * m_Pitch + dest_offset;
+    constexpr int kDestOffset = 3;
+    constexpr int kDestBytes = 4;
+    uint8_t* dest_pos = GetWritableScanline(row).subspan(kDestOffset).data();
     for (int col = 0; col < m_Width; col++) {
-      *scan_line = 0xff;
-      scan_line += Bpp;
+      *dest_pos = 0xff;
+      dest_pos += kDestBytes;
     }
   }
   return true;
 }
 
 bool CFX_DIBitmap::MultiplyAlphaMask(RetainPtr<const CFX_DIBitmap> mask) {
+  CHECK_EQ(m_Width, mask->GetWidth());
+  CHECK_EQ(m_Height, mask->GetHeight());
   CHECK_EQ(FXDIB_Format::k8bppMask, mask->GetFormat());
+  CHECK(m_pBuffer);
 
-  if (!m_pBuffer) {
-    return false;
-  }
-
-  if (IsOpaqueImage()) {
+  constexpr int kDestOffset = 3;
+  constexpr int kDestBytes = 4;
+  if (GetFormat() == FXDIB_Format::kRgb32) {
     if (!ConvertFormat(FXDIB_Format::kArgb)) {
       return false;
     }
 
-    if (mask->GetWidth() != m_Width || mask->GetHeight() != m_Height) {
-      mask =
-          mask->StretchTo(m_Width, m_Height, FXDIB_ResampleOptions(), nullptr);
-      if (!mask) {
-        return false;
-      }
-    }
-    const int dest_bytes = GetBPP() / 8;
     for (int row = 0; row < m_Height; row++) {
-      constexpr int kMaskBytes = 1;
-      constexpr int kDestOffset = 3;
       uint8_t* dest_pos = GetWritableScanline(row).subspan(kDestOffset).data();
-      const uint8_t* mask_pos = mask->GetScanline(row).data();
+      const uint8_t* mask_scan = mask->GetScanline(row).data();
       for (int col = 0; col < m_Width; col++) {
-        *dest_pos = *mask_pos;
-        dest_pos += dest_bytes;
-        mask_pos += kMaskBytes;
+        // Since the `dest_pos` value always starts out as 255 in this case,
+        // simplify 255 * x / 255.
+        *dest_pos = mask_scan[col];
+        dest_pos += kDestBytes;
       }
     }
     return true;
   }
 
-  if (mask->GetWidth() != m_Width || mask->GetHeight() != m_Height) {
-    mask = mask->StretchTo(m_Width, m_Height, FXDIB_ResampleOptions(), nullptr);
-    if (!mask) {
-      return false;
-    }
-  }
-  if (IsMaskFormat()) {
-    if (!ConvertFormat(FXDIB_Format::k8bppMask))
-      return false;
-
-    for (int row = 0; row < m_Height; row++) {
-      uint8_t* dest_scan = m_pBuffer.Get() + m_Pitch * row;
-      const uint8_t* mask_scan = mask->m_pBuffer.Get() + mask->m_Pitch * row;
-      for (int col = 0; col < m_Width; col++) {
-        *dest_scan = (*dest_scan) * mask_scan[col] / 255;
-        dest_scan++;
-      }
-    }
-    return true;
-  }
-
-  DCHECK_EQ(GetFormat(), FXDIB_Format::kArgb);
+  CHECK_EQ(GetFormat(), FXDIB_Format::kArgb);
   for (int row = 0; row < m_Height; row++) {
-    uint8_t* dest_scan = m_pBuffer.Get() + m_Pitch * row + 3;
-    const uint8_t* mask_scan = mask->m_pBuffer.Get() + mask->m_Pitch * row;
+    uint8_t* dest_pos = GetWritableScanline(row).subspan(kDestOffset).data();
+    const uint8_t* mask_scan = mask->GetScanline(row).data();
     for (int col = 0; col < m_Width; col++) {
-      *dest_scan = (*dest_scan) * mask_scan[col] / 255;
-      dest_scan += 4;
+      *dest_pos = (*dest_pos) * mask_scan[col] / 255;
+      dest_pos += kDestBytes;
     }
   }
   return true;
@@ -413,6 +371,7 @@
 bool CFX_DIBitmap::MultiplyAlpha(float alpha) {
   CHECK_GE(alpha, 0.0f);
   CHECK_LE(alpha, 1.0f);
+  CHECK(!IsMaskFormat());
 
   if (alpha == 1.0f) {
     return true;
@@ -422,41 +381,19 @@
     return false;
   }
 
-  switch (GetFormat()) {
-    case FXDIB_Format::k1bppMask:
-      if (!ConvertFormat(FXDIB_Format::k8bppMask)) {
-        return false;
-      }
-      MultiplyAlpha(alpha);
-      break;
-    case FXDIB_Format::k8bppMask: {
-      const int bitmap_alpha = static_cast<int>(alpha * 255);
-      for (int row = 0; row < m_Height; row++) {
-        uint8_t* scan_line = m_pBuffer.Get() + row * m_Pitch;
-        for (int col = 0; col < m_Width; col++) {
-          scan_line[col] = scan_line[col] * bitmap_alpha / 255;
-        }
-      }
-      break;
+  if (!ConvertFormat(FXDIB_Format::kArgb)) {
+    return false;
+  }
+
+  const int bitmap_alpha = static_cast<int>(alpha * 255.0f);
+  for (int row = 0; row < m_Height; row++) {
+    constexpr int kDestOffset = 3;
+    constexpr int kDestBytes = 4;
+    uint8_t* dest_pos = GetWritableScanline(row).subspan(kDestOffset).data();
+    for (int col = 0; col < m_Width; col++) {
+      *dest_pos = (*dest_pos) * bitmap_alpha / 255;
+      dest_pos += kDestBytes;
     }
-    case FXDIB_Format::kArgb: {
-      const int bitmap_alpha = static_cast<int>(alpha * 255);
-      for (int row = 0; row < m_Height; row++) {
-        uint8_t* scan_line = m_pBuffer.Get() + row * m_Pitch + 3;
-        for (int col = 0; col < m_Width; col++) {
-          *scan_line = (*scan_line) * bitmap_alpha / 255;
-          scan_line += 4;
-        }
-      }
-      break;
-    }
-    default:
-      DCHECK(!IsAlphaFormat());
-      if (!ConvertFormat(FXDIB_Format::kArgb)) {
-        return false;
-      }
-      MultiplyAlpha(alpha);
-      break;
   }
   return true;
 }
diff --git a/core/fxge/dib/cfx_dibitmap.h b/core/fxge/dib/cfx_dibitmap.h
index 5ac3b8c..3651432 100644
--- a/core/fxge/dib/cfx_dibitmap.h
+++ b/core/fxge/dib/cfx_dibitmap.h
@@ -60,8 +60,9 @@
 #endif  // defined(PDF_USE_SKIA)
 
   // Requires `this` to be of format `FXDIB_Format::kArgb`.
-  bool SetRedFromAlpha();
+  void SetRedFromAlpha();
 
+  // Requires `this` to be of format `FXDIB_Format::kArgb`.
   bool SetUniformOpaqueAlpha();
 
   // TODO(crbug.com/pdfium/2007): Migrate callers to `CFX_RenderDevice`.
diff --git a/core/fxge/renderdevicedriver_iface.h b/core/fxge/renderdevicedriver_iface.h
index ff680c5..134d869 100644
--- a/core/fxge/renderdevicedriver_iface.h
+++ b/core/fxge/renderdevicedriver_iface.h
@@ -124,11 +124,22 @@
 #endif
 
   // Multiplies the device by a constant alpha, returning `true` on success.
+  // Implementations CHECK the following conditions:
+  // - `this` is bitmap-based and `this` is not of a mask format.
+  //
+  // The backing bitmap for `this` will be converted to format
+  // `FXDIB_Format::kArgb` on success when `alpha` is not 1.
   virtual bool MultiplyAlpha(float alpha) = 0;
 
   // Multiplies the device by an alpha mask, returning `true` on success.
   // Implementations CHECK the following conditions:
+  // - `this` is bitmap-based and of format `FXDIB_Format::kArgb` or
+  //   `FXDIB_Format::kRgb32`.
   // - `mask` must be of format `FXDIB_Format::k8bppMask`.
+  // - `mask` must have the same dimensions as `this`.
+  //
+  // The backing bitmap for `this` will be converted to format
+  // `FXDIB_Format::kArgb` on success.
   virtual bool MultiplyAlphaMask(RetainPtr<const CFX_DIBitmap> mask) = 0;
 };