From 2895880fa8354b273b4e2b72e61a5b78d1985fa8 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Fri, 29 Jun 2018 18:39:50 +0000 Subject: Better determine if ICC colorspaces can be used for blending. Implement CPDF_ColorSpace::IsNormal() and check it when rendering. While IsNormal() is trivial for most colorspaces, it needs to be implemented separately for ICC colorspaces. This fixes a rendering regression from commit 1c0de38c. BUG=chromium:847346 Change-Id: Iaafed3f8ee40b26ac2cbfbdf2251407f7935311b Reviewed-on: https://pdfium-review.googlesource.com/36571 Reviewed-by: Henrique Nakashima Commit-Queue: Lei Zhang --- core/fpdfapi/page/cpdf_colorspace.cpp | 23 +++++++++++++++++++---- core/fpdfapi/page/cpdf_colorspace.h | 2 ++ core/fpdfapi/render/cpdf_renderstatus.cpp | 4 +++- core/fxcodec/codec/ccodec_iccmodule.h | 6 +++++- core/fxcodec/codec/fx_codec_icc.cpp | 20 +++++++++++++++----- 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp index cf1f25063f..b78fe9acfc 100644 --- a/core/fpdfapi/page/cpdf_colorspace.cpp +++ b/core/fpdfapi/page/cpdf_colorspace.cpp @@ -207,8 +207,7 @@ class CPDF_ICCBasedCS : public CPDF_ColorSpace { int image_width, int image_height, bool bTransMask) const override; - - bool IsSRGB() const { return m_pProfile->IsSRGB(); } + bool IsNormal() const override; private: // If no valid ICC profile or using sRGB, try looking for an alternate. @@ -595,6 +594,12 @@ void CPDF_ColorSpace::EnableStdConversion(bool bEnabled) { m_dwStdConversion--; } +bool CPDF_ColorSpace::IsNormal() const { + return GetFamily() == PDFCS_DEVICEGRAY || GetFamily() == PDFCS_DEVICERGB || + GetFamily() == PDFCS_DEVICECMYK || GetFamily() == PDFCS_CALGRAY || + GetFamily() == PDFCS_CALRGB; +} + CPDF_PatternCS* CPDF_ColorSpace::AsPatternCS() { NOTREACHED(); return nullptr; @@ -909,7 +914,7 @@ bool CPDF_ICCBasedCS::GetRGB(const float* pBuf, float* G, float* B) const { ASSERT(m_pProfile); - if (IsSRGB()) { + if (m_pProfile->IsSRGB()) { *R = pBuf[0]; *G = pBuf[1]; *B = pBuf[2]; @@ -947,7 +952,7 @@ void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf, int image_width, int image_height, bool bTransMask) const { - if (IsSRGB()) { + if (m_pProfile->IsSRGB()) { ReverseRGB(pDestBuf, pSrcBuf, pixels); return; } @@ -1010,6 +1015,16 @@ void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf, } } +bool CPDF_ICCBasedCS::IsNormal() const { + if (m_pProfile->IsSRGB()) + return true; + if (m_pProfile->transform()) + return m_pProfile->transform()->m_bNormal; + if (m_pAlterCS) + return m_pAlterCS->IsNormal(); + return false; +} + bool CPDF_ICCBasedCS::FindAlternateProfile( CPDF_Document* pDoc, const CPDF_Dictionary* pDict, diff --git a/core/fpdfapi/page/cpdf_colorspace.h b/core/fpdfapi/page/cpdf_colorspace.h index fba63917f7..1789e21c58 100644 --- a/core/fpdfapi/page/cpdf_colorspace.h +++ b/core/fpdfapi/page/cpdf_colorspace.h @@ -85,6 +85,8 @@ class CPDF_ColorSpace { bool bTransMask) const; virtual void EnableStdConversion(bool bEnabled); + virtual bool IsNormal() const; + // Only call these 3 methods below if GetFamily() returns |PDFCS_PATTERN|. // Returns |this| as a CPDF_PatternCS* if |this| is a pattern. diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 8b58295ab4..29a30157df 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -2638,8 +2638,10 @@ FX_ARGB CPDF_RenderStatus::GetBackColor(const CPDF_Dictionary* pSMaskDict, return kDefaultColor; int family = pCS->GetFamily(); - if (family == PDFCS_LAB || family == PDFCS_ICCBASED || pCS->IsSpecial()) + if (family == PDFCS_LAB || pCS->IsSpecial() || + (family == PDFCS_ICCBASED && !pCS->IsNormal())) { return kDefaultColor; + } // Store Color Space Family to use in CPDF_RenderStatus::Initialize(). *pCSFamily = family; diff --git a/core/fxcodec/codec/ccodec_iccmodule.h b/core/fxcodec/codec/ccodec_iccmodule.h index c304b4bb8e..0d60c3fd4a 100644 --- a/core/fxcodec/codec/ccodec_iccmodule.h +++ b/core/fxcodec/codec/ccodec_iccmodule.h @@ -22,12 +22,16 @@ class CLcmsCmm { public: - CLcmsCmm(int srcComponents, cmsHTRANSFORM transform, bool isLab); + CLcmsCmm(int srcComponents, + cmsHTRANSFORM transform, + bool isLab, + bool bNormal); ~CLcmsCmm(); cmsHTRANSFORM m_hTransform; int m_nSrcComponents; bool m_bLab; + const bool m_bNormal; }; class CCodec_IccModule { diff --git a/core/fxcodec/codec/fx_codec_icc.cpp b/core/fxcodec/codec/fx_codec_icc.cpp index bd98a6efab..0aaaf98075 100644 --- a/core/fxcodec/codec/fx_codec_icc.cpp +++ b/core/fxcodec/codec/fx_codec_icc.cpp @@ -31,10 +31,14 @@ bool Check3Components(cmsColorSpaceSignature cs, bool bDst) { } // namespace -CLcmsCmm::CLcmsCmm(int srcComponents, cmsHTRANSFORM hTransform, bool isLab) +CLcmsCmm::CLcmsCmm(int srcComponents, + cmsHTRANSFORM hTransform, + bool isLab, + bool bNormal) : m_hTransform(hTransform), m_nSrcComponents(srcComponents), - m_bLab(isLab) {} + m_bLab(isLab), + m_bNormal(bNormal) {} CLcmsCmm::~CLcmsCmm() { cmsDeleteTransform(m_hTransform); @@ -60,8 +64,6 @@ std::unique_ptr CCodec_IccModule::CreateTransform_sRGB( cmsCloseProfile(srcProfile); return nullptr; } - int srcFormat; - bool bLab = false; cmsColorSpaceSignature srcCS = cmsGetColorSpace(srcProfile); *nSrcComponents = cmsChannelsOf(srcCS); @@ -72,6 +74,9 @@ std::unique_ptr CCodec_IccModule::CreateTransform_sRGB( return nullptr; } + int srcFormat; + bool bLab = false; + bool bNormal = false; if (srcCS == cmsSigLabData) { srcFormat = COLORSPACE_SH(PT_Lab) | CHANNELS_SH(*nSrcComponents) | BYTES_SH(0); @@ -79,6 +84,10 @@ std::unique_ptr CCodec_IccModule::CreateTransform_sRGB( } else { srcFormat = COLORSPACE_SH(PT_ANY) | CHANNELS_SH(*nSrcComponents) | BYTES_SH(1); + // TODO(thestig): Check to see if lcms2 supports more colorspaces that can + // be considered normal. + bNormal = srcCS == cmsSigGrayData || srcCS == cmsSigRgbData || + srcCS == cmsSigCmykData; } cmsColorSpaceSignature dstCS = cmsGetColorSpace(dstProfile); if (!Check3Components(dstCS, true)) { @@ -110,7 +119,8 @@ std::unique_ptr CCodec_IccModule::CreateTransform_sRGB( cmsCloseProfile(dstProfile); return nullptr; } - auto pCmm = pdfium::MakeUnique(*nSrcComponents, hTransform, bLab); + auto pCmm = + pdfium::MakeUnique(*nSrcComponents, hTransform, bLab, bNormal); cmsCloseProfile(srcProfile); cmsCloseProfile(dstProfile); return pCmm; -- cgit v1.2.3