Track depth of palettes in CFX_ScanlineCompositor.
Because every reinterpret_cast<> is a bug of some sort, to some
way of thinking. So introduce a class to track these properly.
-- add some more const while at it.
-- be consistent in one spot about hex literals.
Change-Id: Ib7aae6a2652d8416ecb003718c11db3ba5a1c731
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/75190
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxge/dib/cfx_scanlinecompositor.cpp b/core/fxge/dib/cfx_scanlinecompositor.cpp
index 16035ed..175ed4b 100644
--- a/core/fxge/dib/cfx_scanlinecompositor.cpp
+++ b/core/fxge/dib/cfx_scanlinecompositor.cpp
@@ -10,6 +10,7 @@
#include "core/fxge/dib/cfx_cmyk_to_srgb.h"
#include "core/fxge/fx_dib.h"
+#include "third_party/base/check.h"
#define FX_CCOLOR(val) (255 - (val))
#define FXDIB_ALPHA_UNION(dest, src) ((dest) + (src) - (dest) * (src) / 255)
@@ -1203,7 +1204,7 @@
void CompositeRow_8bppRgb2Rgb_NoBlend(uint8_t* dest_scan,
const uint8_t* src_scan,
- uint32_t* pPalette,
+ const uint32_t* pPalette,
int pixel_count,
int DestBpp,
const uint8_t* clip_scan,
@@ -1272,7 +1273,7 @@
void CompositeRow_1bppRgb2Rgb_NoBlend(uint8_t* dest_scan,
const uint8_t* src_scan,
int src_left,
- uint32_t* pPalette,
+ const uint32_t* pPalette,
int pixel_count,
int DestBpp,
const uint8_t* clip_scan) {
@@ -1316,7 +1317,7 @@
void CompositeRow_8bppRgb2Argb_NoBlend(uint8_t* dest_scan,
const uint8_t* src_scan,
int width,
- uint32_t* pPalette,
+ const uint32_t* pPalette,
const uint8_t* clip_scan,
const uint8_t* src_alpha_scan) {
if (src_alpha_scan) {
@@ -1398,7 +1399,7 @@
const uint8_t* src_scan,
int src_left,
int width,
- uint32_t* pPalette,
+ const uint32_t* pPalette,
const uint8_t* clip_scan) {
int reset_r, reset_g, reset_b;
int set_r, set_g, set_b;
@@ -1449,7 +1450,7 @@
const uint8_t* src_scan,
int src_left,
int width,
- uint32_t* pPalette,
+ const uint32_t* pPalette,
const uint8_t* clip_scan,
uint8_t* dest_alpha_scan) {
int reset_r, reset_g, reset_b;
@@ -2316,7 +2317,7 @@
void CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(uint8_t* dest_scan,
const uint8_t* src_scan,
- FX_ARGB* pPalette,
+ const FX_ARGB* pPalette,
int pixel_count,
int DestBpp,
const uint8_t* clip_scan) {
@@ -2342,7 +2343,7 @@
void CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(uint8_t* dest_scan,
const uint8_t* src_scan,
int src_left,
- FX_ARGB* pPalette,
+ const FX_ARGB* pPalette,
int pixel_count,
int DestBpp,
const uint8_t* clip_scan) {
@@ -2386,7 +2387,7 @@
void CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(uint8_t* dest_scan,
const uint8_t* src_scan,
int width,
- FX_ARGB* pPalette,
+ const FX_ARGB* pPalette,
const uint8_t* clip_scan) {
for (int col = 0; col < width; col++) {
int src_r, src_g, src_b;
@@ -2429,7 +2430,7 @@
const uint8_t* src_scan,
int src_left,
int width,
- FX_ARGB* pPalette,
+ const FX_ARGB* pPalette,
const uint8_t* clip_scan) {
int reset_r, reset_g, reset_b;
int set_r, set_g, set_b;
@@ -2781,17 +2782,18 @@
void CFX_ScanlineCompositor::InitSourcePalette(FXDIB_Format src_format,
FXDIB_Format dest_format,
const uint32_t* pSrcPalette) {
- bool bIsSrcCmyk = GetIsCmykFromFormat(src_format);
- bool bIsDstCmyk = GetIsCmykFromFormat(dest_format);
- bool bIsDestBpp8 = GetBppFromFormat(dest_format) == 8;
- int pal_count = 1 << GetBppFromFormat(src_format);
- m_pSrcPalette = nullptr;
+ m_SrcPalette.Reset();
+ const bool bIsSrcCmyk = GetIsCmykFromFormat(src_format);
+ const bool bIsDstCmyk = GetIsCmykFromFormat(dest_format);
+ const bool bIsDestBpp8 = GetBppFromFormat(dest_format) == 8;
+ const size_t pal_count = static_cast<size_t>(1)
+ << GetBppFromFormat(src_format);
+
if (pSrcPalette) {
if (bIsDestBpp8) {
- uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count);
- m_pSrcPalette.reset(reinterpret_cast<uint32_t*>(gray_pal));
+ pdfium::span<uint8_t> gray_pal = m_SrcPalette.Make8BitPalette(pal_count);
if (bIsSrcCmyk) {
- for (int i = 0; i < pal_count; ++i) {
+ for (size_t i = 0; i < pal_count; ++i) {
FX_CMYK cmyk = pSrcPalette[i];
uint8_t r;
uint8_t g;
@@ -2799,23 +2801,22 @@
std::tie(r, g, b) =
AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk),
FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk));
- *gray_pal++ = FXRGB2GRAY(r, g, b);
+ gray_pal[i] = FXRGB2GRAY(r, g, b);
}
} else {
- for (int i = 0; i < pal_count; ++i) {
+ for (size_t i = 0; i < pal_count; ++i) {
FX_ARGB argb = pSrcPalette[i];
- *gray_pal++ =
+ gray_pal[i] =
FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
}
}
return;
}
- m_pSrcPalette.reset(FX_Alloc(uint32_t, pal_count));
- uint32_t* pPalette = m_pSrcPalette.get();
+ pdfium::span<uint32_t> pPalette = m_SrcPalette.Make32BitPalette(pal_count);
if (bIsDstCmyk == bIsSrcCmyk) {
- memcpy(pPalette, pSrcPalette, pal_count * sizeof(uint32_t));
+ memcpy(pPalette.data(), pSrcPalette, pal_count * sizeof(uint32_t));
} else {
- for (int i = 0; i < pal_count; ++i) {
+ for (size_t i = 0; i < pal_count; ++i) {
FX_CMYK cmyk = pSrcPalette[i];
uint8_t r;
uint8_t g;
@@ -2829,28 +2830,26 @@
return;
}
if (bIsDestBpp8) {
- uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count);
+ pdfium::span<uint8_t> gray_pal = m_SrcPalette.Make8BitPalette(pal_count);
if (pal_count == 2) {
gray_pal[0] = 0;
gray_pal[1] = 255;
} else {
- for (int i = 0; i < pal_count; ++i)
+ for (size_t i = 0; i < pal_count; ++i)
gray_pal[i] = i;
}
- m_pSrcPalette.reset(reinterpret_cast<uint32_t*>(gray_pal));
return;
}
- m_pSrcPalette.reset(FX_Alloc(uint32_t, pal_count));
- uint32_t* pPalette = m_pSrcPalette.get();
+ pdfium::span<uint32_t> pPalette = m_SrcPalette.Make32BitPalette(pal_count);
if (pal_count == 2) {
- pPalette[0] = bIsSrcCmyk ? 255 : 0xff000000;
- pPalette[1] = bIsSrcCmyk ? 0 : 0xffffffff;
+ pPalette[0] = bIsSrcCmyk ? 0xff : 0xff000000;
+ pPalette[1] = bIsSrcCmyk ? 0x00 : 0xffffffff;
} else {
- for (int i = 0; i < pal_count; ++i)
+ for (size_t i = 0; i < pal_count; ++i)
pPalette[i] = bIsSrcCmyk ? FX_CCOLOR(i) : (i * 0x10101);
}
if (bIsSrcCmyk != bIsDstCmyk) {
- for (int i = 0; i < pal_count; ++i) {
+ for (size_t i = 0; i < pal_count; ++i) {
FX_CMYK cmyk = pPalette[i];
uint8_t r;
uint8_t g;
@@ -3039,11 +3038,12 @@
}
if (m_DestFormat == FXDIB_Argb) {
CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(
- dest_scan, src_scan, src_left, width, m_pSrcPalette.get(),
- clip_scan);
+ dest_scan, src_scan, src_left, width,
+ m_SrcPalette.Get32BitPalette().data(), clip_scan);
} else {
CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(
- dest_scan, src_scan, src_left, m_pSrcPalette.get(), width,
+ dest_scan, src_scan, src_left,
+ m_SrcPalette.Get32BitPalette().data(), width,
GetCompsFromFormat(m_DestFormat), clip_scan);
}
} else {
@@ -3052,10 +3052,11 @@
}
if (m_DestFormat == FXDIB_Argb) {
CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(
- dest_scan, src_scan, width, m_pSrcPalette.get(), clip_scan);
+ dest_scan, src_scan, width, m_SrcPalette.Get32BitPalette().data(),
+ clip_scan);
} else {
CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(
- dest_scan, src_scan, m_pSrcPalette.get(), width,
+ dest_scan, src_scan, m_SrcPalette.Get32BitPalette().data(), width,
GetCompsFromFormat(m_DestFormat), clip_scan);
}
}
@@ -3068,59 +3069,57 @@
if (GetBppFromFormat(m_DestFormat) == 8) {
if (m_iTransparency & 8) {
if (GetIsAlphaFromFormat(m_DestFormat)) {
- CompositeRow_1bppPal2Graya(
- dest_scan, src_scan, src_left,
- reinterpret_cast<const uint8_t*>(m_pSrcPalette.get()), width,
- m_BlendType, clip_scan, dst_extra_alpha);
+ CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left,
+ m_SrcPalette.Get8BitPalette().data(), width,
+ m_BlendType, clip_scan, dst_extra_alpha);
} else {
- CompositeRow_1bppPal2Gray(
- dest_scan, src_scan, src_left,
- reinterpret_cast<const uint8_t*>(m_pSrcPalette.get()), width,
- m_BlendType, clip_scan);
+ CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left,
+ m_SrcPalette.Get8BitPalette().data(), width,
+ m_BlendType, clip_scan);
}
} else {
if (GetIsAlphaFromFormat(m_DestFormat)) {
CompositeRow_8bppPal2Graya(
- dest_scan, src_scan,
- reinterpret_cast<const uint8_t*>(m_pSrcPalette.get()), width,
+ dest_scan, src_scan, m_SrcPalette.Get8BitPalette().data(), width,
m_BlendType, clip_scan, dst_extra_alpha, src_extra_alpha);
} else {
- CompositeRow_8bppPal2Gray(
- dest_scan, src_scan,
- reinterpret_cast<const uint8_t*>(m_pSrcPalette.get()), width,
- m_BlendType, clip_scan, src_extra_alpha);
+ CompositeRow_8bppPal2Gray(dest_scan, src_scan,
+ m_SrcPalette.Get8BitPalette().data(), width,
+ m_BlendType, clip_scan, src_extra_alpha);
}
}
} else {
switch (m_iTransparency) {
case 1 + 2:
CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width,
- m_pSrcPalette.get(), clip_scan,
- src_extra_alpha);
+ m_SrcPalette.Get32BitPalette().data(),
+ clip_scan, src_extra_alpha);
break;
case 1 + 2 + 8:
CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width,
- m_pSrcPalette.get(), clip_scan);
+ m_SrcPalette.Get32BitPalette().data(),
+ clip_scan);
break;
case 0:
CompositeRow_8bppRgb2Rgb_NoBlend(
- dest_scan, src_scan, m_pSrcPalette.get(), width,
+ dest_scan, src_scan, m_SrcPalette.Get32BitPalette().data(), width,
GetCompsFromFormat(m_DestFormat), clip_scan, src_extra_alpha);
break;
case 0 + 8:
CompositeRow_1bppRgb2Rgb_NoBlend(
- dest_scan, src_scan, src_left, m_pSrcPalette.get(), width,
+ dest_scan, src_scan, src_left,
+ m_SrcPalette.Get32BitPalette().data(), width,
GetCompsFromFormat(m_DestFormat), clip_scan);
break;
case 0 + 2:
CompositeRow_8bppRgb2Rgb_NoBlend(
- dest_scan, src_scan, m_pSrcPalette.get(), width,
+ dest_scan, src_scan, m_SrcPalette.Get32BitPalette().data(), width,
GetCompsFromFormat(m_DestFormat), clip_scan, src_extra_alpha);
break;
case 0 + 2 + 8:
CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width,
- m_pSrcPalette.get(), clip_scan,
- dst_extra_alpha);
+ m_SrcPalette.Get32BitPalette().data(),
+ clip_scan, dst_extra_alpha);
break;
}
}
@@ -3206,3 +3205,41 @@
clip_scan);
}
}
+
+CFX_ScanlineCompositor::Palette::Palette() = default;
+
+CFX_ScanlineCompositor::Palette::~Palette() = default;
+
+void CFX_ScanlineCompositor::Palette::Reset() {
+ m_Width = 0;
+ m_nElements = 0;
+ m_pData.reset();
+}
+
+pdfium::span<uint8_t> CFX_ScanlineCompositor::Palette::Make8BitPalette(
+ size_t nElements) {
+ m_Width = sizeof(uint8_t);
+ m_nElements = nElements;
+ m_pData.reset(reinterpret_cast<uint32_t*>(FX_Alloc(uint8_t, m_nElements)));
+ return {reinterpret_cast<uint8_t*>(m_pData.get()), m_nElements};
+}
+
+pdfium::span<uint32_t> CFX_ScanlineCompositor::Palette::Make32BitPalette(
+ size_t nElements) {
+ m_Width = sizeof(uint32_t);
+ m_nElements = nElements;
+ m_pData.reset(FX_Alloc(uint32_t, m_nElements));
+ return {m_pData.get(), m_nElements};
+}
+
+pdfium::span<const uint8_t> CFX_ScanlineCompositor::Palette::Get8BitPalette()
+ const {
+ CHECK(!m_pData || m_Width == sizeof(uint8_t));
+ return {reinterpret_cast<const uint8_t*>(m_pData.get()), m_nElements};
+}
+
+pdfium::span<const uint32_t> CFX_ScanlineCompositor::Palette::Get32BitPalette()
+ const {
+ CHECK(!m_pData || m_Width == sizeof(uint32_t));
+ return {m_pData.get(), m_nElements};
+}
diff --git a/core/fxge/dib/cfx_scanlinecompositor.h b/core/fxge/dib/cfx_scanlinecompositor.h
index 3448609..ec2ee8f 100644
--- a/core/fxge/dib/cfx_scanlinecompositor.h
+++ b/core/fxge/dib/cfx_scanlinecompositor.h
@@ -11,6 +11,7 @@
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxge/fx_dib.h"
+#include "third_party/base/span.h"
class CFX_ScanlineCompositor {
public:
@@ -55,6 +56,28 @@
uint8_t* dst_extra_alpha);
private:
+ class Palette {
+ public:
+ Palette();
+ ~Palette();
+
+ void Reset();
+ pdfium::span<uint8_t> Make8BitPalette(size_t nElements);
+ pdfium::span<uint32_t> Make32BitPalette(size_t nElements);
+
+ // Hard CHECK() if mismatch between created and requested widths.
+ pdfium::span<const uint8_t> Get8BitPalette() const;
+ pdfium::span<const uint32_t> Get32BitPalette() const;
+
+ private:
+ // If 0, then no |m_pData|.
+ // If 1, then |m_pData| is really uint8_t* instead.
+ // If 4, then |m_pData| is uint32_t* as expected.
+ size_t m_Width = 0;
+ size_t m_nElements = 0;
+ std::unique_ptr<uint32_t, FxFreeDeleter> m_pData;
+ };
+
void InitSourcePalette(FXDIB_Format src_format,
FXDIB_Format dest_format,
const uint32_t* pSrcPalette);
@@ -64,7 +87,7 @@
int m_iTransparency;
FXDIB_Format m_SrcFormat;
FXDIB_Format m_DestFormat;
- std::unique_ptr<uint32_t, FxFreeDeleter> m_pSrcPalette;
+ Palette m_SrcPalette;
int m_MaskAlpha;
int m_MaskRed;
int m_MaskGreen;