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,