From a12159b17085796e2b72d2b49e850092e0b4e8b7 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 15 Mar 2017 13:26:37 -0700 Subject: Refactor some CPDF_ColorSpace code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1e30d68dae3bf70cf3c426f6126d593b7f1c3ba4 Reviewed-on: https://pdfium-review.googlesource.com/2991 Commit-Queue: Lei Zhang Reviewed-by: Nicolás Peña --- core/fpdfapi/page/cpdf_colorspace.cpp | 564 ++++++++++++++++++---------------- 1 file changed, 297 insertions(+), 267 deletions(-) (limited to 'core/fpdfapi/page/cpdf_colorspace.cpp') diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp index a88edb1828..7a85284ca7 100644 --- a/core/fpdfapi/page/cpdf_colorspace.cpp +++ b/core/fpdfapi/page/cpdf_colorspace.cpp @@ -6,6 +6,7 @@ #include "core/fpdfapi/page/cpdf_colorspace.h" +#include #include #include @@ -62,18 +63,18 @@ const uint8_t g_sRGBSamples2[] = { class CPDF_CalGray : public CPDF_ColorSpace { public: explicit CPDF_CalGray(CPDF_Document* pDoc); + ~CPDF_CalGray() override {} + // CPDF_ColorSpace: bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - - bool GetRGB(float* pBuf, float& R, float& G, float& B) const override; + bool GetRGB(float* pBuf, float* R, float* G, float* B) const override; bool SetRGB(float* pBuf, float R, float G, float B) const override; - void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width, int image_height, - bool bTransMask = false) const override; + bool bTransMask) const override; private: float m_WhitePoint[3]; @@ -84,10 +85,11 @@ class CPDF_CalGray : public CPDF_ColorSpace { class CPDF_CalRGB : public CPDF_ColorSpace { public: explicit CPDF_CalRGB(CPDF_Document* pDoc); + ~CPDF_CalRGB() override {} bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - bool GetRGB(float* pBuf, float& R, float& G, float& B) const override; + bool GetRGB(float* pBuf, float* R, float* G, float* B) const override; bool SetRGB(float* pBuf, float R, float G, float B) const override; void TranslateImageLine(uint8_t* pDestBuf, @@ -95,7 +97,7 @@ class CPDF_CalRGB : public CPDF_ColorSpace { int pixels, int image_width, int image_height, - bool bTransMask = false) const override; + bool bTransMask) const override; float m_WhitePoint[3]; float m_BlackPoint[3]; @@ -108,22 +110,22 @@ class CPDF_CalRGB : public CPDF_ColorSpace { class CPDF_LabCS : public CPDF_ColorSpace { public: explicit CPDF_LabCS(CPDF_Document* pDoc); + ~CPDF_LabCS() override {} bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; void GetDefaultValue(int iComponent, - float& value, - float& min, - float& max) const override; - bool GetRGB(float* pBuf, float& R, float& G, float& B) const override; - bool SetRGB(float* pBuf, float R, float G, float B) const override; + float* value, + float* min, + float* max) const override; + bool GetRGB(float* pBuf, float* R, float* G, float* B) const override; void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width, int image_height, - bool bTransMask = false) const override; + bool bTransMask) const override; float m_WhitePoint[3]; float m_BlackPoint[3]; @@ -135,24 +137,30 @@ class CPDF_ICCBasedCS : public CPDF_ColorSpace { explicit CPDF_ICCBasedCS(CPDF_Document* pDoc); ~CPDF_ICCBasedCS() override; + // CPDF_ColorSpace: bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - - bool GetRGB(float* pBuf, float& R, float& G, float& B) const override; - bool SetRGB(float* pBuf, float R, float G, float B) const override; - + bool GetRGB(float* pBuf, float* R, float* G, float* B) const override; bool v_GetCMYK(float* pBuf, - float& c, - float& m, - float& y, - float& k) const override; - + float* c, + float* m, + float* y, + float* k) const override; void EnableStdConversion(bool bEnabled) override; void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width, int image_height, - bool bTransMask = false) const override; + bool bTransMask) const override; + + bool IsSRGB() const { return m_pProfile->m_bsRGB; } + + private: + // If no valid ICC profile or using sRGB, try looking for an alternate. + bool FindAlternateProfile(CPDF_Document* pDoc, CPDF_Dictionary* pDict); + + void UseStockAlternateProfile(); + void PopulateRanges(CPDF_Dictionary* pDict); CFX_MaybeOwned m_pAlterCS; CPDF_IccProfile* m_pProfile; @@ -167,7 +175,7 @@ class CPDF_IndexedCS : public CPDF_ColorSpace { bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - bool GetRGB(float* pBuf, float& R, float& G, float& B) const override; + bool GetRGB(float* pBuf, float* R, float* G, float* B) const override; CPDF_ColorSpace* GetBaseCS() const override; void EnableStdConversion(bool bEnabled) override; @@ -187,11 +195,11 @@ class CPDF_SeparationCS : public CPDF_ColorSpace { // CPDF_ColorSpace: void GetDefaultValue(int iComponent, - float& value, - float& min, - float& max) const override; + float* value, + float* min, + float* max) const override; bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - bool GetRGB(float* pBuf, float& R, float& G, float& B) const override; + bool GetRGB(float* pBuf, float* R, float* G, float* B) const override; void EnableStdConversion(bool bEnabled) override; std::unique_ptr m_pAltCS; @@ -206,11 +214,11 @@ class CPDF_DeviceNCS : public CPDF_ColorSpace { // CPDF_ColorSpace: void GetDefaultValue(int iComponent, - float& value, - float& min, - float& max) const override; + float* value, + float* min, + float* max) const override; bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - bool GetRGB(float* pBuf, float& R, float& G, float& B) const override; + bool GetRGB(float* pBuf, float* R, float* G, float* B) const override; void EnableStdConversion(bool bEnabled) override; std::unique_ptr m_pAltCS; @@ -218,40 +226,32 @@ class CPDF_DeviceNCS : public CPDF_ColorSpace { }; float RGB_Conversion(float colorComponent) { - if (colorComponent > 1) - colorComponent = 1; - if (colorComponent < 0) - colorComponent = 0; - - int scale = (int)(colorComponent * 1023); - if (scale < 0) - scale = 0; + colorComponent = std::min(std::max(colorComponent, 0.0f), 1.0f); + int scale = std::max(static_cast(colorComponent * 1023), 0); if (scale < 192) - colorComponent = (g_sRGBSamples1[scale] / 255.0f); - else - colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f); - return colorComponent; + return g_sRGBSamples1[scale] / 255.0f; + return g_sRGBSamples2[scale / 4 - 48] / 255.0f; } -void XYZ_to_sRGB(float X, float Y, float Z, float& R, float& G, float& B) { +void XYZ_to_sRGB(float X, float Y, float Z, float* R, float* G, float* B) { float R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z; float G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z; float B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z; - R = RGB_Conversion(R1); - G = RGB_Conversion(G1); - B = RGB_Conversion(B1); + *R = RGB_Conversion(R1); + *G = RGB_Conversion(G1); + *B = RGB_Conversion(B1); } void XYZ_to_sRGB_WhitePoint(float X, float Y, float Z, - float& R, - float& G, - float& B, float Xw, float Yw, - float Zw) { + float Zw, + float* R, + float* G, + float* B) { // The following RGB_xyz is based on // sRGB value {Rx,Ry}={0.64, 0.33}, {Gx,Gy}={0.30, 0.60}, {Bx,By}={0.15, 0.06} @@ -269,9 +269,9 @@ void XYZ_to_sRGB_WhitePoint(float X, CFX_Matrix_3by3 M = RGB_xyz.Multiply(RGB_SUM_XYZ_DIAG); CFX_Vector_3by1 RGB = M.Inverse().TransformVector(XYZ); - R = RGB_Conversion(RGB.a); - G = RGB_Conversion(RGB.b); - B = RGB_Conversion(RGB.c); + *R = RGB_Conversion(RGB.a); + *G = RGB_Conversion(RGB.b); + *B = RGB_Conversion(RGB.c); } } // namespace @@ -331,26 +331,34 @@ std::unique_ptr CPDF_ColorSpace::Load(CPDF_Document* pDoc, return std::unique_ptr(ColorspaceFromName(familyname)); std::unique_ptr pCS; - uint32_t id = familyname.GetID(); - if (id == FXBSTR_ID('C', 'a', 'l', 'G')) { - pCS.reset(new CPDF_CalGray(pDoc)); - } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) { - pCS.reset(new CPDF_CalRGB(pDoc)); - } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) { - pCS.reset(new CPDF_LabCS(pDoc)); - } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) { - pCS.reset(new CPDF_ICCBasedCS(pDoc)); - } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') || - id == FXBSTR_ID('I', 0, 0, 0)) { - pCS.reset(new CPDF_IndexedCS(pDoc)); - } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) { - pCS.reset(new CPDF_SeparationCS(pDoc)); - } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) { - pCS.reset(new CPDF_DeviceNCS(pDoc)); - } else if (id == FXBSTR_ID('P', 'a', 't', 't')) { - pCS.reset(new CPDF_PatternCS(pDoc)); - } else { - return nullptr; + switch (familyname.GetID()) { + case FXBSTR_ID('C', 'a', 'l', 'G'): + pCS.reset(new CPDF_CalGray(pDoc)); + break; + case FXBSTR_ID('C', 'a', 'l', 'R'): + pCS.reset(new CPDF_CalRGB(pDoc)); + break; + case FXBSTR_ID('L', 'a', 'b', 0): + pCS.reset(new CPDF_LabCS(pDoc)); + break; + case FXBSTR_ID('I', 'C', 'C', 'B'): + pCS.reset(new CPDF_ICCBasedCS(pDoc)); + break; + case FXBSTR_ID('I', 'n', 'd', 'e'): + case FXBSTR_ID('I', 0, 0, 0): + pCS.reset(new CPDF_IndexedCS(pDoc)); + break; + case FXBSTR_ID('S', 'e', 'p', 'a'): + pCS.reset(new CPDF_SeparationCS(pDoc)); + break; + case FXBSTR_ID('D', 'e', 'v', 'i'): + pCS.reset(new CPDF_DeviceNCS(pDoc)); + break; + case FXBSTR_ID('P', 'a', 't', 't'): + pCS.reset(new CPDF_PatternCS(pDoc)); + break; + default: + return nullptr; } pCS->m_pArray = pArray; if (!pCS->v_Load(pDoc, pArray)) @@ -383,14 +391,14 @@ float* CPDF_ColorSpace::CreateBuf() { } bool CPDF_ColorSpace::sRGB() const { - if (m_Family == PDFCS_DEVICERGB) { + if (m_Family == PDFCS_DEVICERGB) return true; - } - if (m_Family != PDFCS_ICCBASED) { + + if (m_Family != PDFCS_ICCBASED) return false; - } - CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this; - return pCS->m_pProfile->m_bsRGB; + + const CPDF_ICCBasedCS* pCS = static_cast(this); + return pCS->IsSRGB(); } bool CPDF_ColorSpace::SetRGB(float* pBuf, float R, float G, float B) const { @@ -398,18 +406,20 @@ bool CPDF_ColorSpace::SetRGB(float* pBuf, float R, float G, float B) const { } bool CPDF_ColorSpace::GetCMYK(float* pBuf, - float& c, - float& m, - float& y, - float& k) const { - if (v_GetCMYK(pBuf, c, m, y, k)) { + float* c, + float* m, + float* y, + float* k) const { + if (v_GetCMYK(pBuf, c, m, y, k)) return true; - } - float R, G, B; - if (!GetRGB(pBuf, R, G, B)) { + + float R; + float G; + float B; + if (!GetRGB(pBuf, &R, &G, &B)) return false; - } - sRGB_to_AdobeCMYK(R, G, B, c, m, y, k); + + sRGB_to_AdobeCMYK(R, G, B, *c, *m, *y, *k); return true; } @@ -418,22 +428,24 @@ bool CPDF_ColorSpace::SetCMYK(float* pBuf, float m, float y, float k) const { - if (v_SetCMYK(pBuf, c, m, y, k)) { + if (v_SetCMYK(pBuf, c, m, y, k)) return true; - } - float R, G, B; + + float R; + float G; + float B; AdobeCMYK_to_sRGB(c, m, y, k, R, G, B); return SetRGB(pBuf, R, G, B); } void CPDF_ColorSpace::GetDefaultColor(float* buf) const { - if (!buf || m_Family == PDFCS_PATTERN) { + if (!buf || m_Family == PDFCS_PATTERN) return; - } - float min, max; - for (uint32_t i = 0; i < m_nComponents; i++) { - GetDefaultValue(i, buf[i], min, max); - } + + float min; + float max; + for (uint32_t i = 0; i < m_nComponents; i++) + GetDefaultValue(i, &buf[i], &min, &max); } uint32_t CPDF_ColorSpace::CountComponents() const { @@ -441,12 +453,12 @@ uint32_t CPDF_ColorSpace::CountComponents() const { } void CPDF_ColorSpace::GetDefaultValue(int iComponent, - float& value, - float& min, - float& max) const { - value = 0; - min = 0; - max = 1.0f; + float* value, + float* min, + float* max) const { + *value = 0.0f; + *min = 0.0f; + *max = 1.0f; } void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf, @@ -457,18 +469,17 @@ void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf, bool bTransMask) const { CFX_FixedBufGrow srcbuf(m_nComponents); float* src = srcbuf; - float R, G, B; + float R; + float G; + float B; + const int divisor = m_Family != PDFCS_INDEXED ? 255 : 1; for (int i = 0; i < pixels; i++) { for (uint32_t j = 0; j < m_nComponents; j++) - if (m_Family == PDFCS_INDEXED) { - src[j] = (float)(*src_buf++); - } else { - src[j] = (float)(*src_buf++) / 255; - } - GetRGB(src, R, G, B); - *dest_buf++ = (int32_t)(B * 255); - *dest_buf++ = (int32_t)(G * 255); - *dest_buf++ = (int32_t)(R * 255); + src[j] = static_cast(*src_buf++) / divisor; + GetRGB(src, &R, &G, &B); + *dest_buf++ = static_cast(B * 255); + *dest_buf++ = static_cast(G * 255); + *dest_buf++ = static_cast(R * 255); } } @@ -499,10 +510,10 @@ bool CPDF_ColorSpace::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { } bool CPDF_ColorSpace::v_GetCMYK(float* pBuf, - float& c, - float& m, - float& y, - float& k) const { + float* c, + float* m, + float* y, + float* k) const { return false; } @@ -537,8 +548,10 @@ bool CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { return true; } -bool CPDF_CalGray::GetRGB(float* pBuf, float& R, float& G, float& B) const { - R = G = B = *pBuf; +bool CPDF_CalGray::GetRGB(float* pBuf, float* R, float* G, float* B) const { + *R = *pBuf; + *G = *pBuf; + *B = *pBuf; return true; } @@ -600,7 +613,7 @@ bool CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { return true; } -bool CPDF_CalRGB::GetRGB(float* pBuf, float& R, float& G, float& B) const { +bool CPDF_CalRGB::GetRGB(float* pBuf, float* R, float* G, float* B) const { float A_ = pBuf[0]; float B_ = pBuf[1]; float C_ = pBuf[2]; @@ -622,8 +635,8 @@ bool CPDF_CalRGB::GetRGB(float* pBuf, float& R, float& G, float& B) const { Y = B_; Z = C_; } - XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1], - m_WhitePoint[2]); + XYZ_to_sRGB_WhitePoint(X, Y, Z, m_WhitePoint[0], m_WhitePoint[1], + m_WhitePoint[2], R, G, B); return true; } @@ -646,10 +659,10 @@ void CPDF_CalRGB::TranslateImageLine(uint8_t* pDestBuf, float G; float B; for (int i = 0; i < pixels; i++) { - Cal[0] = ((float)pSrcBuf[2]) / 255; - Cal[1] = ((float)pSrcBuf[1]) / 255; - Cal[2] = ((float)pSrcBuf[0]) / 255; - GetRGB(Cal, R, G, B); + Cal[0] = static_cast(pSrcBuf[2]) / 255; + Cal[1] = static_cast(pSrcBuf[1]) / 255; + Cal[2] = static_cast(pSrcBuf[0]) / 255; + GetRGB(Cal, &R, &G, &B); pDestBuf[0] = FXSYS_round(B * 255); pDestBuf[1] = FXSYS_round(G * 255); pDestBuf[2] = FXSYS_round(R * 255); @@ -664,21 +677,18 @@ CPDF_LabCS::CPDF_LabCS(CPDF_Document* pDoc) : CPDF_ColorSpace(pDoc, PDFCS_LAB, 3) {} void CPDF_LabCS::GetDefaultValue(int iComponent, - float& value, - float& min, - float& max) const { + float* value, + float* min, + float* max) const { ASSERT(iComponent < 3); - value = 0; if (iComponent == 0) { - min = 0; - max = 100 * 1.0f; + *min = 0.0f; + *max = 100 * 1.0f; + *value = 0.0f; } else { - min = m_Ranges[iComponent * 2 - 2]; - max = m_Ranges[iComponent * 2 - 1]; - if (value < min) - value = min; - else if (value > max) - value = max; + *min = m_Ranges[iComponent * 2 - 2]; + *max = m_Ranges[iComponent * 2 - 1]; + *value = std::min(std::max(0.0f, *min), *max); } } @@ -704,14 +714,16 @@ bool CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { return true; } -bool CPDF_LabCS::GetRGB(float* pBuf, float& R, float& G, float& B) const { +bool CPDF_LabCS::GetRGB(float* pBuf, float* R, float* G, float* B) const { float Lstar = pBuf[0]; float astar = pBuf[1]; float bstar = pBuf[2]; float M = (Lstar + 16.0f) / 116.0f; float L = M + astar / 500.0f; float N = M - bstar / 200.0f; - float X, Y, Z; + float X; + float Y; + float Z; if (L < 0.2069f) X = 0.957f * 0.12842f * (L - 0.1379f); else @@ -731,10 +743,6 @@ bool CPDF_LabCS::GetRGB(float* pBuf, float& R, float& G, float& B) const { return true; } -bool CPDF_LabCS::SetRGB(float* pBuf, float R, float G, float B) const { - return false; -} - void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, @@ -743,14 +751,16 @@ void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf, bool bTransMask) const { for (int i = 0; i < pixels; i++) { float lab[3]; - float R, G, B; + float R; + float G; + float B; lab[0] = (pSrcBuf[0] * 100 / 255.0f); lab[1] = (float)(pSrcBuf[1] - 128); lab[2] = (float)(pSrcBuf[2] - 128); - GetRGB(lab, R, G, B); - pDestBuf[0] = (int32_t)(B * 255); - pDestBuf[1] = (int32_t)(G * 255); - pDestBuf[2] = (int32_t)(R * 255); + GetRGB(lab, &R, &G, &B); + pDestBuf[0] = static_cast(B * 255); + pDestBuf[1] = static_cast(G * 255); + pDestBuf[2] = static_cast(R * 255); pDestBuf += 3; pSrcBuf += 3; } @@ -781,58 +791,18 @@ bool CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { // Try using the |nComponents| from ICC profile m_nComponents = m_pProfile->GetComponents(); CPDF_Dictionary* pDict = pStream->GetDict(); - if (!m_pProfile->m_pTransform) { // No valid ICC profile or using sRGB - CPDF_Object* pAlterCSObj = - pDict ? pDict->GetDirectObjectFor("Alternate") : nullptr; - if (pAlterCSObj) { - std::unique_ptr pAlterCS = - CPDF_ColorSpace::Load(pDoc, pAlterCSObj); - if (pAlterCS) { - if (m_nComponents == 0) { // NO valid ICC profile - if (pAlterCS->CountComponents() > 0) { // Use Alternative colorspace - m_nComponents = pAlterCS->CountComponents(); - m_pAlterCS = std::move(pAlterCS); - } else { // No valid alternative colorspace - int32_t nDictComponents = pDict ? pDict->GetIntegerFor("N") : 0; - if (nDictComponents != 1 && nDictComponents != 3 && - nDictComponents != 4) { - return false; - } - m_nComponents = nDictComponents; - } - } else { // Using sRGB - if (pAlterCS->CountComponents() == m_nComponents) - m_pAlterCS = std::move(pAlterCS); - } - } - } - if (!m_pAlterCS) { - if (m_nComponents == 1) - m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY); - else if (m_nComponents == 3) - m_pAlterCS = GetStockCS(PDFCS_DEVICERGB); - else if (m_nComponents == 4) - m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK); - } - } - CPDF_Array* pRanges = pDict->GetArrayFor("Range"); - m_pRanges = FX_Alloc2D(float, m_nComponents, 2); - for (uint32_t i = 0; i < m_nComponents * 2; i++) { - if (pRanges) - m_pRanges[i] = pRanges->GetNumberAt(i); - else if (i % 2) - m_pRanges[i] = 1.0f; - else - m_pRanges[i] = 0; - } + if (!m_pProfile->m_pTransform && !FindAlternateProfile(pDoc, pDict)) + return false; + + PopulateRanges(pDict); return true; } -bool CPDF_ICCBasedCS::GetRGB(float* pBuf, float& R, float& G, float& B) const { +bool CPDF_ICCBasedCS::GetRGB(float* pBuf, float* R, float* G, float* B) const { if (m_pProfile && m_pProfile->m_bsRGB) { - R = pBuf[0]; - G = pBuf[1]; - B = pBuf[2]; + *R = pBuf[0]; + *G = pBuf[1]; + *B = pBuf[2]; return true; } CCodec_IccModule* pIccModule = CPDF_ModuleMgr::Get()->GetIccModule(); @@ -840,36 +810,32 @@ bool CPDF_ICCBasedCS::GetRGB(float* pBuf, float& R, float& G, float& B) const { if (m_pAlterCS) return m_pAlterCS->GetRGB(pBuf, R, G, B); - R = 0.0f; - G = 0.0f; - B = 0.0f; + *R = 0.0f; + *G = 0.0f; + *B = 0.0f; return true; } float rgb[3]; pIccModule->SetComponents(m_nComponents); pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb); - R = rgb[0]; - G = rgb[1]; - B = rgb[2]; + *R = rgb[0]; + *G = rgb[1]; + *B = rgb[2]; return true; } -bool CPDF_ICCBasedCS::SetRGB(float* pBuf, float R, float G, float B) const { - return false; -} - bool CPDF_ICCBasedCS::v_GetCMYK(float* pBuf, - float& c, - float& m, - float& y, - float& k) const { + float* c, + float* m, + float* y, + float* k) const { if (m_nComponents != 4) return false; - c = pBuf[0]; - m = pBuf[1]; - y = pBuf[2]; - k = pBuf[3]; + *c = pBuf[0]; + *m = pBuf[1]; + *y = pBuf[2]; + *k = pBuf[3]; return true; } @@ -927,7 +893,73 @@ void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf, } } else if (m_pAlterCS) { m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width, - image_height); + image_height, false); + } +} + +bool CPDF_ICCBasedCS::FindAlternateProfile(CPDF_Document* pDoc, + CPDF_Dictionary* pDict) { + CPDF_Object* pAlterCSObj = + pDict ? pDict->GetDirectObjectFor("Alternate") : nullptr; + if (!pAlterCSObj) { + UseStockAlternateProfile(); + return true; + } + + auto pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj); + if (!pAlterCS) { + UseStockAlternateProfile(); + return true; + } + + if (m_nComponents) { + ASSERT(IsSRGB()); // Using sRGB case. + if (pAlterCS->CountComponents() == m_nComponents) + m_pAlterCS = std::move(pAlterCS); + else + UseStockAlternateProfile(); + return true; + } + + // NO valid ICC profile + if (pAlterCS->CountComponents() > 0) { + // Use Alternative colorspace + m_nComponents = pAlterCS->CountComponents(); + m_pAlterCS = std::move(pAlterCS); + return true; + } + + int32_t nDictComponents = pDict ? pDict->GetIntegerFor("N") : 0; + if (nDictComponents == 1 || nDictComponents == 3 || nDictComponents == 4) { + m_nComponents = nDictComponents; + UseStockAlternateProfile(); + return true; + } + + // No valid alternative colorspace + return false; +} + +void CPDF_ICCBasedCS::UseStockAlternateProfile() { + ASSERT(!m_pAlterCS); + if (m_nComponents == 1) + m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY); + else if (m_nComponents == 3) + m_pAlterCS = GetStockCS(PDFCS_DEVICERGB); + else if (m_nComponents == 4) + m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK); +} + +void CPDF_ICCBasedCS::PopulateRanges(CPDF_Dictionary* pDict) { + CPDF_Array* pRanges = pDict->GetArrayFor("Range"); + m_pRanges = FX_Alloc2D(float, m_nComponents, 2); + for (uint32_t i = 0; i < m_nComponents * 2; i++) { + if (pRanges) + m_pRanges[i] = pRanges->GetNumberAt(i); + else if (i % 2) + m_pRanges[i] = 1.0f; + else + m_pRanges[i] = 0.0f; } } @@ -946,25 +978,25 @@ CPDF_IndexedCS::~CPDF_IndexedCS() { } bool CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { - if (pArray->GetCount() < 4) { + if (pArray->GetCount() < 4) return false; - } + CPDF_Object* pBaseObj = pArray->GetDirectObjectAt(1); - if (pBaseObj == m_pArray) { + if (pBaseObj == m_pArray) return false; - } + CPDF_DocPageData* pDocPageData = pDoc->GetPageData(); m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, nullptr); - if (!m_pBaseCS) { + if (!m_pBaseCS) return false; - } + m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray()); m_nBaseComponents = m_pBaseCS->CountComponents(); m_pCompMinMax = FX_Alloc2D(float, m_nBaseComponents, 2); float defvalue; for (int i = 0; i < m_nBaseComponents; i++) { - m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2], - m_pCompMinMax[i * 2 + 1]); + m_pBaseCS->GetDefaultValue(i, &defvalue, &m_pCompMinMax[i * 2], + &m_pCompMinMax[i * 2 + 1]); m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2]; } m_MaxIndex = pArray->GetIntegerAt(2); @@ -983,11 +1015,11 @@ bool CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { return true; } -bool CPDF_IndexedCS::GetRGB(float* pBuf, float& R, float& G, float& B) const { - int index = (int32_t)(*pBuf); - if (index < 0 || index > m_MaxIndex) { +bool CPDF_IndexedCS::GetRGB(float* pBuf, float* R, float* G, float* B) const { + int index = static_cast(*pBuf); + if (index < 0 || index > m_MaxIndex) return false; - } + if (m_nBaseComponents) { if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents || (index + 1) * m_nBaseComponents > (int)m_Table.GetLength()) { @@ -1012,9 +1044,8 @@ CPDF_ColorSpace* CPDF_IndexedCS::GetBaseCS() const { void CPDF_IndexedCS::EnableStdConversion(bool bEnabled) { CPDF_ColorSpace::EnableStdConversion(bEnabled); - if (m_pBaseCS) { + if (m_pBaseCS) m_pBaseCS->EnableStdConversion(bEnabled); - } } CPDF_PatternCS::CPDF_PatternCS(CPDF_Document* pDoc) @@ -1031,35 +1062,34 @@ CPDF_PatternCS::~CPDF_PatternCS() { bool CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { CPDF_Object* pBaseCS = pArray->GetDirectObjectAt(1); - if (pBaseCS == m_pArray) { + if (pBaseCS == m_pArray) return false; - } + CPDF_DocPageData* pDocPageData = pDoc->GetPageData(); m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, nullptr); - if (m_pBaseCS) { - if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) { - return false; - } - m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray()); - m_nComponents = m_pBaseCS->CountComponents() + 1; - if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) { - return false; - } - } else { + if (!m_pBaseCS) { m_nComponents = 1; + return true; } - return true; + + if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) + return false; + + m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray()); + m_nComponents = m_pBaseCS->CountComponents() + 1; + return m_pBaseCS->CountComponents() <= MAX_PATTERN_COLORCOMPS; } -bool CPDF_PatternCS::GetRGB(float* pBuf, float& R, float& G, float& B) const { +bool CPDF_PatternCS::GetRGB(float* pBuf, float* R, float* G, float* B) const { if (m_pBaseCS) { ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN); PatternValue* pvalue = (PatternValue*)pBuf; - if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B)) { + if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B)) return true; - } } - R = G = B = 0.75f; + *R = 0.75f; + *G = 0.75f; + *B = 0.75f; return false; } @@ -1073,12 +1103,12 @@ CPDF_SeparationCS::CPDF_SeparationCS(CPDF_Document* pDoc) CPDF_SeparationCS::~CPDF_SeparationCS() {} void CPDF_SeparationCS::GetDefaultValue(int iComponent, - float& value, - float& min, - float& max) const { - value = 1.0f; - min = 0; - max = 1.0f; + float* value, + float* min, + float* max) const { + *value = 1.0f; + *min = 0; + *max = 1.0f; } bool CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { @@ -1107,9 +1137,9 @@ bool CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { } bool CPDF_SeparationCS::GetRGB(float* pBuf, - float& R, - float& G, - float& B) const { + float* R, + float* G, + float* B) const { if (m_Type == None) return false; @@ -1126,7 +1156,7 @@ bool CPDF_SeparationCS::GetRGB(float* pBuf, CFX_FixedBufGrow results(m_pFunc->CountOutputs()); int nresults = 0; - m_pFunc->Call(pBuf, 1, results, nresults); + m_pFunc->Call(pBuf, 1, results, &nresults); if (nresults == 0) return false; @@ -1151,12 +1181,12 @@ CPDF_DeviceNCS::CPDF_DeviceNCS(CPDF_Document* pDoc) CPDF_DeviceNCS::~CPDF_DeviceNCS() {} void CPDF_DeviceNCS::GetDefaultValue(int iComponent, - float& value, - float& min, - float& max) const { - value = 1.0f; - min = 0; - max = 1.0f; + float* value, + float* min, + float* max) const { + *value = 1.0f; + *min = 0; + *max = 1.0f; } bool CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { @@ -1177,13 +1207,13 @@ bool CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { return m_pFunc->CountOutputs() >= m_pAltCS->CountComponents(); } -bool CPDF_DeviceNCS::GetRGB(float* pBuf, float& R, float& G, float& B) const { +bool CPDF_DeviceNCS::GetRGB(float* pBuf, float* R, float* G, float* B) const { if (!m_pFunc) return false; CFX_FixedBufGrow results(m_pFunc->CountOutputs()); int nresults = 0; - m_pFunc->Call(pBuf, m_nComponents, results, nresults); + m_pFunc->Call(pBuf, m_nComponents, results, &nresults); if (nresults == 0) return false; -- cgit v1.2.3