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;