| Index: core/fpdfapi/fpdf_page/cpdf_colorspace.cpp
|
| diff --git a/core/fpdfapi/fpdf_page/fpdf_page_colors.cpp b/core/fpdfapi/fpdf_page/cpdf_colorspace.cpp
|
| similarity index 71%
|
| copy from core/fpdfapi/fpdf_page/fpdf_page_colors.cpp
|
| copy to core/fpdfapi/fpdf_page/cpdf_colorspace.cpp
|
| index d4b69f2d3fe0b863cf5d53c6cdd6eb39cfc5f4c8..b1b464471d3fb82d58023284981280e2bec64830 100644
|
| --- a/core/fpdfapi/fpdf_page/fpdf_page_colors.cpp
|
| +++ b/core/fpdfapi/fpdf_page/cpdf_colorspace.cpp
|
| @@ -1,218 +1,24 @@
|
| -// Copyright 2014 PDFium Authors. All rights reserved.
|
| +// Copyright 2016 PDFium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
|
|
|
| -#include "core/fpdfapi/fpdf_page/pageint.h"
|
| -
|
| -#include <limits.h>
|
| -
|
| -#include <algorithm>
|
| +#include "core/fpdfapi/fpdf_page/include/cpdf_colorspace.h"
|
|
|
| +#include "core/fpdfapi/fpdf_page/pageint.h"
|
| #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
|
| #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
|
| #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
|
| +#include "core/fpdfapi/fpdf_parser/include/cpdf_object.h"
|
| +#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
|
| +#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
|
| #include "core/fpdfapi/fpdf_parser/include/cpdf_string.h"
|
| #include "core/fpdfapi/include/cpdf_modulemgr.h"
|
| #include "core/include/fxcodec/fx_codec.h"
|
|
|
| namespace {
|
|
|
| -void sRGB_to_AdobeCMYK(FX_FLOAT R,
|
| - FX_FLOAT G,
|
| - FX_FLOAT B,
|
| - FX_FLOAT& c,
|
| - FX_FLOAT& m,
|
| - FX_FLOAT& y,
|
| - FX_FLOAT& k) {
|
| - c = 1.0f - R;
|
| - m = 1.0f - G;
|
| - y = 1.0f - B;
|
| - k = c;
|
| - if (m < k) {
|
| - k = m;
|
| - }
|
| - if (y < k) {
|
| - k = y;
|
| - }
|
| -}
|
| -
|
| -FX_DWORD ComponentsForFamily(int family) {
|
| - if (family == PDFCS_DEVICERGB)
|
| - return 3;
|
| - if (family == PDFCS_DEVICEGRAY)
|
| - return 1;
|
| - return 4;
|
| -}
|
| -
|
| -void ReverseRGB(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels) {
|
| - if (pDestBuf == pSrcBuf) {
|
| - for (int i = 0; i < pixels; i++) {
|
| - uint8_t temp = pDestBuf[2];
|
| - pDestBuf[2] = pDestBuf[0];
|
| - pDestBuf[0] = temp;
|
| - pDestBuf += 3;
|
| - }
|
| - } else {
|
| - for (int i = 0; i < pixels; i++) {
|
| - *pDestBuf++ = pSrcBuf[2];
|
| - *pDestBuf++ = pSrcBuf[1];
|
| - *pDestBuf++ = pSrcBuf[0];
|
| - pSrcBuf += 3;
|
| - }
|
| - }
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -CPDF_DeviceCS::CPDF_DeviceCS(CPDF_Document* pDoc, int family)
|
| - : CPDF_ColorSpace(pDoc, family, ComponentsForFamily(family)) {}
|
| -
|
| -FX_BOOL CPDF_DeviceCS::GetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT& R,
|
| - FX_FLOAT& G,
|
| - FX_FLOAT& B) const {
|
| - if (m_Family == PDFCS_DEVICERGB) {
|
| - R = pBuf[0];
|
| - if (R < 0) {
|
| - R = 0;
|
| - } else if (R > 1) {
|
| - R = 1;
|
| - }
|
| - G = pBuf[1];
|
| - if (G < 0) {
|
| - G = 0;
|
| - } else if (G > 1) {
|
| - G = 1;
|
| - }
|
| - B = pBuf[2];
|
| - if (B < 0) {
|
| - B = 0;
|
| - } else if (B > 1) {
|
| - B = 1;
|
| - }
|
| - } else if (m_Family == PDFCS_DEVICEGRAY) {
|
| - R = *pBuf;
|
| - if (R < 0) {
|
| - R = 0;
|
| - } else if (R > 1) {
|
| - R = 1;
|
| - }
|
| - G = B = R;
|
| - } else if (m_Family == PDFCS_DEVICECMYK) {
|
| - if (!m_dwStdConversion) {
|
| - AdobeCMYK_to_sRGB(pBuf[0], pBuf[1], pBuf[2], pBuf[3], R, G, B);
|
| - } else {
|
| - FX_FLOAT k = pBuf[3];
|
| - R = 1.0f - std::min(1.0f, pBuf[0] + k);
|
| - G = 1.0f - std::min(1.0f, pBuf[1] + k);
|
| - B = 1.0f - std::min(1.0f, pBuf[2] + k);
|
| - }
|
| - } else {
|
| - ASSERT(m_Family == PDFCS_PATTERN);
|
| - R = G = B = 0;
|
| - return FALSE;
|
| - }
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CPDF_DeviceCS::v_GetCMYK(FX_FLOAT* pBuf,
|
| - FX_FLOAT& c,
|
| - FX_FLOAT& m,
|
| - FX_FLOAT& y,
|
| - FX_FLOAT& k) const {
|
| - if (m_Family != PDFCS_DEVICECMYK) {
|
| - return FALSE;
|
| - }
|
| - c = pBuf[0];
|
| - m = pBuf[1];
|
| - y = pBuf[2];
|
| - k = pBuf[3];
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CPDF_DeviceCS::SetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT R,
|
| - FX_FLOAT G,
|
| - FX_FLOAT B) const {
|
| - if (m_Family == PDFCS_DEVICERGB) {
|
| - pBuf[0] = R;
|
| - pBuf[1] = G;
|
| - pBuf[2] = B;
|
| - return TRUE;
|
| - }
|
| - if (m_Family == PDFCS_DEVICEGRAY) {
|
| - if (R == G && R == B) {
|
| - *pBuf = R;
|
| - return TRUE;
|
| - }
|
| - return FALSE;
|
| - }
|
| - if (m_Family == PDFCS_DEVICECMYK) {
|
| - sRGB_to_AdobeCMYK(R, G, B, pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
|
| - return TRUE;
|
| - }
|
| - return FALSE;
|
| -}
|
| -FX_BOOL CPDF_DeviceCS::v_SetCMYK(FX_FLOAT* pBuf,
|
| - FX_FLOAT c,
|
| - FX_FLOAT m,
|
| - FX_FLOAT y,
|
| - FX_FLOAT k) const {
|
| - if (m_Family == PDFCS_DEVICERGB) {
|
| - AdobeCMYK_to_sRGB(c, m, y, k, pBuf[0], pBuf[1], pBuf[2]);
|
| - return TRUE;
|
| - }
|
| - if (m_Family == PDFCS_DEVICECMYK) {
|
| - pBuf[0] = c;
|
| - pBuf[1] = m;
|
| - pBuf[2] = y;
|
| - pBuf[3] = k;
|
| - return TRUE;
|
| - }
|
| - return FALSE;
|
| -}
|
| -
|
| -void CPDF_DeviceCS::TranslateImageLine(uint8_t* pDestBuf,
|
| - const uint8_t* pSrcBuf,
|
| - int pixels,
|
| - int image_width,
|
| - int image_height,
|
| - FX_BOOL bTransMask) const {
|
| - if (bTransMask && m_Family == PDFCS_DEVICECMYK) {
|
| - for (int i = 0; i < pixels; i++) {
|
| - int k = 255 - pSrcBuf[3];
|
| - pDestBuf[0] = ((255 - pSrcBuf[0]) * k) / 255;
|
| - pDestBuf[1] = ((255 - pSrcBuf[1]) * k) / 255;
|
| - pDestBuf[2] = ((255 - pSrcBuf[2]) * k) / 255;
|
| - pDestBuf += 3;
|
| - pSrcBuf += 4;
|
| - }
|
| - return;
|
| - }
|
| - if (m_Family == PDFCS_DEVICERGB) {
|
| - ReverseRGB(pDestBuf, pSrcBuf, pixels);
|
| - } else if (m_Family == PDFCS_DEVICEGRAY) {
|
| - for (int i = 0; i < pixels; i++) {
|
| - *pDestBuf++ = pSrcBuf[i];
|
| - *pDestBuf++ = pSrcBuf[i];
|
| - *pDestBuf++ = pSrcBuf[i];
|
| - }
|
| - } else {
|
| - for (int i = 0; i < pixels; i++) {
|
| - if (!m_dwStdConversion) {
|
| - AdobeCMYK_to_sRGB1(pSrcBuf[0], pSrcBuf[1], pSrcBuf[2], pSrcBuf[3],
|
| - pDestBuf[2], pDestBuf[1], pDestBuf[0]);
|
| - } else {
|
| - uint8_t k = pSrcBuf[3];
|
| - pDestBuf[2] = 255 - std::min(255, pSrcBuf[0] + k);
|
| - pDestBuf[1] = 255 - std::min(255, pSrcBuf[1] + k);
|
| - pDestBuf[0] = 255 - std::min(255, pSrcBuf[2] + k);
|
| - }
|
| - pSrcBuf += 4;
|
| - pDestBuf += 3;
|
| - }
|
| - }
|
| -}
|
| const uint8_t g_sRGBSamples1[] = {
|
| 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 31,
|
| 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
| @@ -228,6 +34,7 @@ const uint8_t g_sRGBSamples1[] = {
|
| 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 115, 116, 116,
|
| 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120,
|
| };
|
| +
|
| const uint8_t g_sRGBSamples2[] = {
|
| 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
|
| 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149,
|
| @@ -245,75 +52,12 @@ const uint8_t g_sRGBSamples2[] = {
|
| 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
|
| };
|
|
|
| -static FX_FLOAT RGB_Conversion(FX_FLOAT colorComponent) {
|
| - if (colorComponent > 1) {
|
| - colorComponent = 1;
|
| - }
|
| - if (colorComponent < 0) {
|
| - colorComponent = 0;
|
| - }
|
| - int scale = (int)(colorComponent * 1023);
|
| - if (scale < 0) {
|
| - scale = 0;
|
| - }
|
| - if (scale < 192) {
|
| - colorComponent = (g_sRGBSamples1[scale] / 255.0f);
|
| - } else {
|
| - colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
|
| - }
|
| - return colorComponent;
|
| -}
|
| -
|
| -static void XYZ_to_sRGB(FX_FLOAT X,
|
| - FX_FLOAT Y,
|
| - FX_FLOAT Z,
|
| - FX_FLOAT& R,
|
| - FX_FLOAT& G,
|
| - FX_FLOAT& B) {
|
| - FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
|
| - FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
|
| - FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z;
|
| -
|
| - R = RGB_Conversion(R1);
|
| - G = RGB_Conversion(G1);
|
| - B = RGB_Conversion(B1);
|
| -}
|
| -
|
| -static void XYZ_to_sRGB_WhitePoint(FX_FLOAT X,
|
| - FX_FLOAT Y,
|
| - FX_FLOAT Z,
|
| - FX_FLOAT& R,
|
| - FX_FLOAT& G,
|
| - FX_FLOAT& B,
|
| - FX_FLOAT Xw,
|
| - FX_FLOAT Yw,
|
| - FX_FLOAT Zw) {
|
| - // 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}
|
| -
|
| - FX_FLOAT Rx = 0.64f, Ry = 0.33f;
|
| - FX_FLOAT Gx = 0.30f, Gy = 0.60f;
|
| - FX_FLOAT Bx = 0.15f, By = 0.06f;
|
| - CFX_Matrix_3by3 RGB_xyz(Rx, Gx, Bx, Ry, Gy, By, 1 - Rx - Ry, 1 - Gx - Gy,
|
| - 1 - Bx - By);
|
| - CFX_Vector_3by1 whitePoint(Xw, Yw, Zw);
|
| - CFX_Vector_3by1 XYZ(X, Y, Z);
|
| -
|
| - CFX_Vector_3by1 RGB_Sum_XYZ = RGB_xyz.Inverse().TransformVector(whitePoint);
|
| - CFX_Matrix_3by3 RGB_SUM_XYZ_DIAG(RGB_Sum_XYZ.a, 0, 0, 0, RGB_Sum_XYZ.b, 0, 0,
|
| - 0, RGB_Sum_XYZ.c);
|
| - 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);
|
| -}
|
| class CPDF_CalGray : public CPDF_ColorSpace {
|
| public:
|
| - explicit CPDF_CalGray(CPDF_Document* pDoc)
|
| - : CPDF_ColorSpace(pDoc, PDFCS_CALGRAY, 1) {}
|
| + explicit CPDF_CalGray(CPDF_Document* pDoc);
|
| +
|
| FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| +
|
| FX_BOOL GetRGB(FX_FLOAT* pBuf,
|
| FX_FLOAT& R,
|
| FX_FLOAT& G,
|
| @@ -322,6 +66,7 @@ class CPDF_CalGray : public CPDF_ColorSpace {
|
| FX_FLOAT R,
|
| FX_FLOAT G,
|
| FX_FLOAT B) const override;
|
| +
|
| void TranslateImageLine(uint8_t* pDestBuf,
|
| const uint8_t* pSrcBuf,
|
| int pixels,
|
| @@ -335,60 +80,12 @@ class CPDF_CalGray : public CPDF_ColorSpace {
|
| FX_FLOAT m_Gamma;
|
| };
|
|
|
| -FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| - CPDF_Dictionary* pDict = pArray->GetDictAt(1);
|
| - if (!pDict)
|
| - return FALSE;
|
| -
|
| - CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
|
| - int i;
|
| - for (i = 0; i < 3; i++) {
|
| - m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| - }
|
| - pParam = pDict->GetArrayBy("BlackPoint");
|
| - for (i = 0; i < 3; i++) {
|
| - m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| - }
|
| - m_Gamma = pDict->GetNumberBy("Gamma");
|
| - if (m_Gamma == 0) {
|
| - m_Gamma = 1.0f;
|
| - }
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT& R,
|
| - FX_FLOAT& G,
|
| - FX_FLOAT& B) const {
|
| - R = G = B = *pBuf;
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT R,
|
| - FX_FLOAT G,
|
| - FX_FLOAT B) const {
|
| - if (R == G && R == B) {
|
| - *pBuf = R;
|
| - return TRUE;
|
| - }
|
| - return FALSE;
|
| -}
|
| -void CPDF_CalGray::TranslateImageLine(uint8_t* pDestBuf,
|
| - const uint8_t* pSrcBuf,
|
| - int pixels,
|
| - int image_width,
|
| - int image_height,
|
| - FX_BOOL bTransMask) const {
|
| - for (int i = 0; i < pixels; i++) {
|
| - *pDestBuf++ = pSrcBuf[i];
|
| - *pDestBuf++ = pSrcBuf[i];
|
| - *pDestBuf++ = pSrcBuf[i];
|
| - }
|
| -}
|
| class CPDF_CalRGB : public CPDF_ColorSpace {
|
| public:
|
| - explicit CPDF_CalRGB(CPDF_Document* pDoc)
|
| - : CPDF_ColorSpace(pDoc, PDFCS_CALRGB, 3) {}
|
| + explicit CPDF_CalRGB(CPDF_Document* pDoc);
|
| +
|
| FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| +
|
| FX_BOOL GetRGB(FX_FLOAT* pBuf,
|
| FX_FLOAT& R,
|
| FX_FLOAT& G,
|
| @@ -397,6 +94,7 @@ class CPDF_CalRGB : public CPDF_ColorSpace {
|
| FX_FLOAT R,
|
| FX_FLOAT G,
|
| FX_FLOAT B) const override;
|
| +
|
| void TranslateImageLine(uint8_t* pDestBuf,
|
| const uint8_t* pSrcBuf,
|
| int pixels,
|
| @@ -411,107 +109,17 @@ class CPDF_CalRGB : public CPDF_ColorSpace {
|
| FX_BOOL m_bGamma;
|
| FX_BOOL m_bMatrix;
|
| };
|
| -FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| - CPDF_Dictionary* pDict = pArray->GetDictAt(1);
|
| - if (!pDict)
|
| - return FALSE;
|
|
|
| - CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
|
| - int i;
|
| - for (i = 0; i < 3; i++) {
|
| - m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| - }
|
| - pParam = pDict->GetArrayBy("BlackPoint");
|
| - for (i = 0; i < 3; i++) {
|
| - m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| - }
|
| - pParam = pDict->GetArrayBy("Gamma");
|
| - if (pParam) {
|
| - m_bGamma = TRUE;
|
| - for (i = 0; i < 3; i++) {
|
| - m_Gamma[i] = pParam->GetNumberAt(i);
|
| - }
|
| - } else {
|
| - m_bGamma = FALSE;
|
| - }
|
| - pParam = pDict->GetArrayBy("Matrix");
|
| - if (pParam) {
|
| - m_bMatrix = TRUE;
|
| - for (i = 0; i < 9; i++) {
|
| - m_Matrix[i] = pParam->GetNumberAt(i);
|
| - }
|
| - } else {
|
| - m_bMatrix = FALSE;
|
| - }
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT& R,
|
| - FX_FLOAT& G,
|
| - FX_FLOAT& B) const {
|
| - FX_FLOAT A_ = pBuf[0];
|
| - FX_FLOAT B_ = pBuf[1];
|
| - FX_FLOAT C_ = pBuf[2];
|
| - if (m_bGamma) {
|
| - A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]);
|
| - B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]);
|
| - C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]);
|
| - }
|
| - FX_FLOAT X, Y, Z;
|
| - if (m_bMatrix) {
|
| - X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_;
|
| - Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_;
|
| - Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_;
|
| - } else {
|
| - X = A_;
|
| - Y = B_;
|
| - Z = C_;
|
| - }
|
| - XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1],
|
| - m_WhitePoint[2]);
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT R,
|
| - FX_FLOAT G,
|
| - FX_FLOAT B) const {
|
| - pBuf[0] = R;
|
| - pBuf[1] = G;
|
| - pBuf[2] = B;
|
| - return TRUE;
|
| -}
|
| -void CPDF_CalRGB::TranslateImageLine(uint8_t* pDestBuf,
|
| - const uint8_t* pSrcBuf,
|
| - int pixels,
|
| - int image_width,
|
| - int image_height,
|
| - FX_BOOL bTransMask) const {
|
| - if (bTransMask) {
|
| - FX_FLOAT Cal[3];
|
| - FX_FLOAT R, G, B;
|
| - for (int i = 0; i < pixels; i++) {
|
| - Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255;
|
| - Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255;
|
| - Cal[2] = ((FX_FLOAT)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);
|
| - pSrcBuf += 3;
|
| - pDestBuf += 3;
|
| - }
|
| - }
|
| - ReverseRGB(pDestBuf, pSrcBuf, pixels);
|
| -}
|
| class CPDF_LabCS : public CPDF_ColorSpace {
|
| public:
|
| - explicit CPDF_LabCS(CPDF_Document* pDoc)
|
| - : CPDF_ColorSpace(pDoc, PDFCS_LAB, 3) {}
|
| + explicit CPDF_LabCS(CPDF_Document* pDoc);
|
| +
|
| + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| +
|
| void GetDefaultValue(int iComponent,
|
| FX_FLOAT& value,
|
| FX_FLOAT& min,
|
| FX_FLOAT& max) const override;
|
| - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| FX_BOOL GetRGB(FX_FLOAT* pBuf,
|
| FX_FLOAT& R,
|
| FX_FLOAT& G,
|
| @@ -520,6 +128,7 @@ class CPDF_LabCS : public CPDF_ColorSpace {
|
| FX_FLOAT R,
|
| FX_FLOAT G,
|
| FX_FLOAT B) const override;
|
| +
|
| void TranslateImageLine(uint8_t* pDestBuf,
|
| const uint8_t* pSrcBuf,
|
| int pixels,
|
| @@ -531,130 +140,14 @@ class CPDF_LabCS : public CPDF_ColorSpace {
|
| FX_FLOAT m_BlackPoint[3];
|
| FX_FLOAT m_Ranges[4];
|
| };
|
| -FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| - CPDF_Dictionary* pDict = pArray->GetDictAt(1);
|
| - if (!pDict) {
|
| - return FALSE;
|
| - }
|
| - CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
|
| - int i;
|
| - for (i = 0; i < 3; i++) {
|
| - m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| - }
|
| - pParam = pDict->GetArrayBy("BlackPoint");
|
| - for (i = 0; i < 3; i++) {
|
| - m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| - }
|
| - pParam = pDict->GetArrayBy("Range");
|
| - const FX_FLOAT def_ranges[4] = {-100 * 1.0f, 100 * 1.0f, -100 * 1.0f,
|
| - 100 * 1.0f};
|
| - for (i = 0; i < 4; i++) {
|
| - m_Ranges[i] = pParam ? pParam->GetNumberAt(i) : def_ranges[i];
|
| - }
|
| - return TRUE;
|
| -}
|
| -void CPDF_LabCS::GetDefaultValue(int iComponent,
|
| - FX_FLOAT& value,
|
| - FX_FLOAT& min,
|
| - FX_FLOAT& max) const {
|
| - assert(iComponent < 3);
|
| - value = 0;
|
| - if (iComponent == 0) {
|
| - min = 0;
|
| - max = 100 * 1.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;
|
| - }
|
| - }
|
| -}
|
| -FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT& R,
|
| - FX_FLOAT& G,
|
| - FX_FLOAT& B) const {
|
| - FX_FLOAT Lstar = pBuf[0];
|
| - FX_FLOAT astar = pBuf[1];
|
| - FX_FLOAT bstar = pBuf[2];
|
| - FX_FLOAT M = (Lstar + 16.0f) / 116.0f;
|
| - FX_FLOAT L = M + astar / 500.0f;
|
| - FX_FLOAT N = M - bstar / 200.0f;
|
| - FX_FLOAT X, Y, Z;
|
| - if (L < 0.2069f) {
|
| - X = 0.957f * 0.12842f * (L - 0.1379f);
|
| - } else {
|
| - X = 0.957f * L * L * L;
|
| - }
|
| - if (M < 0.2069f) {
|
| - Y = 0.12842f * (M - 0.1379f);
|
| - } else {
|
| - Y = M * M * M;
|
| - }
|
| - if (N < 0.2069f) {
|
| - Z = 1.0889f * 0.12842f * (N - 0.1379f);
|
| - } else {
|
| - Z = 1.0889f * N * N * N;
|
| - }
|
| - XYZ_to_sRGB(X, Y, Z, R, G, B);
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT R,
|
| - FX_FLOAT G,
|
| - FX_FLOAT B) const {
|
| - return FALSE;
|
| -}
|
| -void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf,
|
| - const uint8_t* pSrcBuf,
|
| - int pixels,
|
| - int image_width,
|
| - int image_height,
|
| - FX_BOOL bTransMask) const {
|
| - for (int i = 0; i < pixels; i++) {
|
| - FX_FLOAT lab[3];
|
| - FX_FLOAT R, G, B;
|
| - lab[0] = (pSrcBuf[0] * 100 / 255.0f);
|
| - lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128);
|
| - lab[2] = (FX_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);
|
| - pDestBuf += 3;
|
| - pSrcBuf += 3;
|
| - }
|
| -}
|
| -CPDF_IccProfile::CPDF_IccProfile(const uint8_t* pData, FX_DWORD dwSize)
|
| - : m_bsRGB(FALSE), m_pTransform(NULL), m_nSrcComponents(0) {
|
| - if (dwSize == 3144 &&
|
| - FXSYS_memcmp(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0) {
|
| - m_bsRGB = TRUE;
|
| - m_nSrcComponents = 3;
|
| - } else if (CPDF_ModuleMgr::Get()->GetIccModule()) {
|
| - m_pTransform = CPDF_ModuleMgr::Get()->GetIccModule()->CreateTransform_sRGB(
|
| - pData, dwSize, m_nSrcComponents);
|
| - }
|
| -}
|
| -CPDF_IccProfile::~CPDF_IccProfile() {
|
| - if (m_pTransform) {
|
| - CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform);
|
| - }
|
| -}
|
| +
|
| class CPDF_ICCBasedCS : public CPDF_ColorSpace {
|
| public:
|
| - explicit CPDF_ICCBasedCS(CPDF_Document* pDoc)
|
| - : CPDF_ColorSpace(pDoc, PDFCS_ICCBASED, 0),
|
| - m_pAlterCS(nullptr),
|
| - m_pProfile(nullptr),
|
| - m_pCache(nullptr),
|
| - m_pRanges(nullptr),
|
| - m_bOwn(FALSE) {}
|
| + explicit CPDF_ICCBasedCS(CPDF_Document* pDoc);
|
| ~CPDF_ICCBasedCS() override;
|
|
|
| FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| +
|
| FX_BOOL GetRGB(FX_FLOAT* pBuf,
|
| FX_FLOAT& R,
|
| FX_FLOAT& G,
|
| @@ -663,11 +156,13 @@ class CPDF_ICCBasedCS : public CPDF_ColorSpace {
|
| FX_FLOAT R,
|
| FX_FLOAT G,
|
| FX_FLOAT B) const override;
|
| +
|
| FX_BOOL v_GetCMYK(FX_FLOAT* pBuf,
|
| FX_FLOAT& c,
|
| FX_FLOAT& m,
|
| FX_FLOAT& y,
|
| FX_FLOAT& k) const override;
|
| +
|
| void EnableStdConversion(FX_BOOL bEnabled) override;
|
| void TranslateImageLine(uint8_t* pDestBuf,
|
| const uint8_t* pSrcBuf,
|
| @@ -683,41 +178,639 @@ class CPDF_ICCBasedCS : public CPDF_ColorSpace {
|
| FX_BOOL m_bOwn;
|
| };
|
|
|
| -CPDF_ICCBasedCS::~CPDF_ICCBasedCS() {
|
| - FX_Free(m_pCache);
|
| - FX_Free(m_pRanges);
|
| - if (m_pAlterCS && m_bOwn) {
|
| - m_pAlterCS->ReleaseCS();
|
| - }
|
| - if (m_pProfile && m_pDocument) {
|
| - m_pDocument->GetPageData()->ReleaseIccProfile(m_pProfile);
|
| - }
|
| +class CPDF_IndexedCS : public CPDF_ColorSpace {
|
| + public:
|
| + explicit CPDF_IndexedCS(CPDF_Document* pDoc);
|
| + ~CPDF_IndexedCS() override;
|
| +
|
| + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| +
|
| + FX_BOOL GetRGB(FX_FLOAT* pBuf,
|
| + FX_FLOAT& R,
|
| + FX_FLOAT& G,
|
| + FX_FLOAT& B) const override;
|
| + CPDF_ColorSpace* GetBaseCS() const override;
|
| +
|
| + void EnableStdConversion(FX_BOOL bEnabled) override;
|
| +
|
| + CPDF_ColorSpace* m_pBaseCS;
|
| + CPDF_CountedColorSpace* m_pCountedBaseCS;
|
| + int m_nBaseComponents;
|
| + int m_MaxIndex;
|
| + CFX_ByteString m_Table;
|
| + FX_FLOAT* m_pCompMinMax;
|
| +};
|
| +
|
| +class CPDF_SeparationCS : public CPDF_ColorSpace {
|
| + public:
|
| + explicit CPDF_SeparationCS(CPDF_Document* pDoc);
|
| + ~CPDF_SeparationCS() override;
|
| +
|
| + // CPDF_ColorSpace:
|
| + void GetDefaultValue(int iComponent,
|
| + FX_FLOAT& value,
|
| + FX_FLOAT& min,
|
| + FX_FLOAT& max) const override;
|
| + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| + FX_BOOL GetRGB(FX_FLOAT* pBuf,
|
| + FX_FLOAT& R,
|
| + FX_FLOAT& G,
|
| + FX_FLOAT& B) const override;
|
| + void EnableStdConversion(FX_BOOL bEnabled) override;
|
| +
|
| + CPDF_ColorSpace* m_pAltCS;
|
| + CPDF_Function* m_pFunc;
|
| + enum { None, All, Colorant } m_Type;
|
| +};
|
| +
|
| +class CPDF_DeviceNCS : public CPDF_ColorSpace {
|
| + public:
|
| + explicit CPDF_DeviceNCS(CPDF_Document* pDoc);
|
| + ~CPDF_DeviceNCS() override;
|
| +
|
| + // CPDF_ColorSpace:
|
| + void GetDefaultValue(int iComponent,
|
| + FX_FLOAT& value,
|
| + FX_FLOAT& min,
|
| + FX_FLOAT& max) const override;
|
| + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| + FX_BOOL GetRGB(FX_FLOAT* pBuf,
|
| + FX_FLOAT& R,
|
| + FX_FLOAT& G,
|
| + FX_FLOAT& B) const override;
|
| + void EnableStdConversion(FX_BOOL bEnabled) override;
|
| +
|
| + CPDF_ColorSpace* m_pAltCS;
|
| + CPDF_Function* m_pFunc;
|
| +};
|
| +
|
| +FX_FLOAT RGB_Conversion(FX_FLOAT colorComponent) {
|
| + if (colorComponent > 1)
|
| + colorComponent = 1;
|
| + if (colorComponent < 0)
|
| + colorComponent = 0;
|
| +
|
| + int scale = (int)(colorComponent * 1023);
|
| + if (scale < 0)
|
| + scale = 0;
|
| + if (scale < 192)
|
| + colorComponent = (g_sRGBSamples1[scale] / 255.0f);
|
| + else
|
| + colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
|
| + return colorComponent;
|
| }
|
|
|
| -FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| - CPDF_Stream* pStream = pArray->GetStreamAt(1);
|
| - if (!pStream) {
|
| - return FALSE;
|
| +void XYZ_to_sRGB(FX_FLOAT X,
|
| + FX_FLOAT Y,
|
| + FX_FLOAT Z,
|
| + FX_FLOAT& R,
|
| + FX_FLOAT& G,
|
| + FX_FLOAT& B) {
|
| + FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
|
| + FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
|
| + FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z;
|
| +
|
| + R = RGB_Conversion(R1);
|
| + G = RGB_Conversion(G1);
|
| + B = RGB_Conversion(B1);
|
| +}
|
| +
|
| +void XYZ_to_sRGB_WhitePoint(FX_FLOAT X,
|
| + FX_FLOAT Y,
|
| + FX_FLOAT Z,
|
| + FX_FLOAT& R,
|
| + FX_FLOAT& G,
|
| + FX_FLOAT& B,
|
| + FX_FLOAT Xw,
|
| + FX_FLOAT Yw,
|
| + FX_FLOAT Zw) {
|
| + // 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}
|
| +
|
| + FX_FLOAT Rx = 0.64f, Ry = 0.33f;
|
| + FX_FLOAT Gx = 0.30f, Gy = 0.60f;
|
| + FX_FLOAT Bx = 0.15f, By = 0.06f;
|
| + CFX_Matrix_3by3 RGB_xyz(Rx, Gx, Bx, Ry, Gy, By, 1 - Rx - Ry, 1 - Gx - Gy,
|
| + 1 - Bx - By);
|
| + CFX_Vector_3by1 whitePoint(Xw, Yw, Zw);
|
| + CFX_Vector_3by1 XYZ(X, Y, Z);
|
| +
|
| + CFX_Vector_3by1 RGB_Sum_XYZ = RGB_xyz.Inverse().TransformVector(whitePoint);
|
| + CFX_Matrix_3by3 RGB_SUM_XYZ_DIAG(RGB_Sum_XYZ.a, 0, 0, 0, RGB_Sum_XYZ.b, 0, 0,
|
| + 0, RGB_Sum_XYZ.c);
|
| + 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);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +CPDF_ColorSpace* CPDF_ColorSpace::ColorspaceFromName(
|
| + const CFX_ByteString& name) {
|
| + if (name == "DeviceRGB" || name == "RGB") {
|
| + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
|
| }
|
| - m_pProfile = pDoc->LoadIccProfile(pStream);
|
| - if (!m_pProfile) {
|
| - return FALSE;
|
| + if (name == "DeviceGray" || name == "G") {
|
| + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
|
| }
|
| - m_nComponents =
|
| - m_pProfile
|
| - ->GetComponents(); // Try using the nComponents from ICC profile
|
| - CPDF_Dictionary* pDict = pStream->GetDict();
|
| - if (!m_pProfile->m_pTransform) { // No valid ICC profile or using sRGB
|
| - CPDF_Object* pAlterCSObj =
|
| - pDict ? pDict->GetElementValue("Alternate") : NULL;
|
| - if (pAlterCSObj) {
|
| - CPDF_ColorSpace* 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 = pAlterCS;
|
| - m_bOwn = TRUE;
|
| + if (name == "DeviceCMYK" || name == "CMYK") {
|
| + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
|
| + }
|
| + if (name == "Pattern") {
|
| + return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) {
|
| + return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);
|
| +}
|
| +
|
| +CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj) {
|
| + if (!pObj)
|
| + return nullptr;
|
| + if (pObj->IsName())
|
| + return ColorspaceFromName(pObj->GetString());
|
| +
|
| + if (CPDF_Stream* pStream = pObj->AsStream()) {
|
| + CPDF_Dictionary* pDict = pStream->GetDict();
|
| + if (!pDict)
|
| + return nullptr;
|
| +
|
| + for (const auto& it : *pDict) {
|
| + CPDF_ColorSpace* pRet = nullptr;
|
| + CPDF_Object* pValue = it.second;
|
| + if (ToName(pValue))
|
| + pRet = ColorspaceFromName(pValue->GetString());
|
| + if (pRet)
|
| + return pRet;
|
| + }
|
| + return nullptr;
|
| + }
|
| +
|
| + CPDF_Array* pArray = pObj->AsArray();
|
| + if (!pArray || pArray->GetCount() == 0)
|
| + return nullptr;
|
| +
|
| + CPDF_Object* pFamilyObj = pArray->GetElementValue(0);
|
| + if (!pFamilyObj)
|
| + return nullptr;
|
| +
|
| + CFX_ByteString familyname = pFamilyObj->GetString();
|
| + if (pArray->GetCount() == 1)
|
| + return ColorspaceFromName(familyname);
|
| +
|
| + CPDF_ColorSpace* pCS = NULL;
|
| + FX_DWORD id = familyname.GetID();
|
| + if (id == FXBSTR_ID('C', 'a', 'l', 'G')) {
|
| + pCS = new CPDF_CalGray(pDoc);
|
| + } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) {
|
| + pCS = new CPDF_CalRGB(pDoc);
|
| + } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) {
|
| + pCS = new CPDF_LabCS(pDoc);
|
| + } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) {
|
| + pCS = new CPDF_ICCBasedCS(pDoc);
|
| + } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') ||
|
| + id == FXBSTR_ID('I', 0, 0, 0)) {
|
| + pCS = new CPDF_IndexedCS(pDoc);
|
| + } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) {
|
| + pCS = new CPDF_SeparationCS(pDoc);
|
| + } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) {
|
| + pCS = new CPDF_DeviceNCS(pDoc);
|
| + } else if (id == FXBSTR_ID('P', 'a', 't', 't')) {
|
| + pCS = new CPDF_PatternCS(pDoc);
|
| + } else {
|
| + return NULL;
|
| + }
|
| + pCS->m_pArray = pArray;
|
| + if (!pCS->v_Load(pDoc, pArray)) {
|
| + pCS->ReleaseCS();
|
| + return NULL;
|
| + }
|
| + return pCS;
|
| +}
|
| +
|
| +void CPDF_ColorSpace::ReleaseCS() {
|
| + if (this == GetStockCS(PDFCS_DEVICERGB)) {
|
| + return;
|
| + }
|
| + if (this == GetStockCS(PDFCS_DEVICEGRAY)) {
|
| + return;
|
| + }
|
| + if (this == GetStockCS(PDFCS_DEVICECMYK)) {
|
| + return;
|
| + }
|
| + if (this == GetStockCS(PDFCS_PATTERN)) {
|
| + return;
|
| + }
|
| + delete this;
|
| +}
|
| +
|
| +int CPDF_ColorSpace::GetBufSize() const {
|
| + if (m_Family == PDFCS_PATTERN) {
|
| + return sizeof(PatternValue);
|
| + }
|
| + return m_nComponents * sizeof(FX_FLOAT);
|
| +}
|
| +
|
| +FX_FLOAT* CPDF_ColorSpace::CreateBuf() {
|
| + int size = GetBufSize();
|
| + uint8_t* pBuf = FX_Alloc(uint8_t, size);
|
| + return (FX_FLOAT*)pBuf;
|
| +}
|
| +
|
| +FX_BOOL CPDF_ColorSpace::sRGB() const {
|
| + if (m_Family == PDFCS_DEVICERGB) {
|
| + return TRUE;
|
| + }
|
| + if (m_Family != PDFCS_ICCBASED) {
|
| + return FALSE;
|
| + }
|
| + CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this;
|
| + return pCS->m_pProfile->m_bsRGB;
|
| +}
|
| +
|
| +FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf,
|
| + FX_FLOAT& c,
|
| + FX_FLOAT& m,
|
| + FX_FLOAT& y,
|
| + FX_FLOAT& k) const {
|
| + if (v_GetCMYK(pBuf, c, m, y, k)) {
|
| + return TRUE;
|
| + }
|
| + FX_FLOAT R, G, B;
|
| + if (!GetRGB(pBuf, R, G, B)) {
|
| + return FALSE;
|
| + }
|
| + sRGB_to_AdobeCMYK(R, G, B, c, m, y, k);
|
| + return TRUE;
|
| +}
|
| +
|
| +FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf,
|
| + FX_FLOAT c,
|
| + FX_FLOAT m,
|
| + FX_FLOAT y,
|
| + FX_FLOAT k) const {
|
| + if (v_SetCMYK(pBuf, c, m, y, k)) {
|
| + return TRUE;
|
| + }
|
| + FX_FLOAT R, G, B;
|
| + AdobeCMYK_to_sRGB(c, m, y, k, R, G, B);
|
| + return SetRGB(pBuf, R, G, B);
|
| +}
|
| +
|
| +void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const {
|
| + if (!buf || m_Family == PDFCS_PATTERN) {
|
| + return;
|
| + }
|
| + FX_FLOAT min, max;
|
| + for (int i = 0; i < m_nComponents; i++) {
|
| + GetDefaultValue(i, buf[i], min, max);
|
| + }
|
| +}
|
| +
|
| +int CPDF_ColorSpace::GetMaxIndex() const {
|
| + if (m_Family != PDFCS_INDEXED) {
|
| + return 0;
|
| + }
|
| + CPDF_IndexedCS* pCS = (CPDF_IndexedCS*)this;
|
| + return pCS->m_MaxIndex;
|
| +}
|
| +
|
| +void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf,
|
| + const uint8_t* src_buf,
|
| + int pixels,
|
| + int image_width,
|
| + int image_height,
|
| + FX_BOOL bTransMask) const {
|
| + CFX_FixedBufGrow<FX_FLOAT, 16> srcbuf(m_nComponents);
|
| + FX_FLOAT* src = srcbuf;
|
| + FX_FLOAT R, G, B;
|
| + for (int i = 0; i < pixels; i++) {
|
| + for (int j = 0; j < m_nComponents; j++)
|
| + if (m_Family == PDFCS_INDEXED) {
|
| + src[j] = (FX_FLOAT)(*src_buf++);
|
| + } else {
|
| + src[j] = (FX_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);
|
| + }
|
| +}
|
| +
|
| +void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) {
|
| + if (bEnabled)
|
| + m_dwStdConversion++;
|
| + else if (m_dwStdConversion)
|
| + m_dwStdConversion--;
|
| +}
|
| +
|
| +CPDF_CalGray::CPDF_CalGray(CPDF_Document* pDoc)
|
| + : CPDF_ColorSpace(pDoc, PDFCS_CALGRAY, 1) {}
|
| +
|
| +FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| + CPDF_Dictionary* pDict = pArray->GetDictAt(1);
|
| + if (!pDict)
|
| + return FALSE;
|
| +
|
| + CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
|
| + int i;
|
| + for (i = 0; i < 3; i++)
|
| + m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| +
|
| + pParam = pDict->GetArrayBy("BlackPoint");
|
| + for (i = 0; i < 3; i++)
|
| + m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| +
|
| + m_Gamma = pDict->GetNumberBy("Gamma");
|
| + if (m_Gamma == 0)
|
| + m_Gamma = 1.0f;
|
| + return TRUE;
|
| +}
|
| +
|
| +FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf,
|
| + FX_FLOAT& R,
|
| + FX_FLOAT& G,
|
| + FX_FLOAT& B) const {
|
| + R = G = B = *pBuf;
|
| + return TRUE;
|
| +}
|
| +
|
| +FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf,
|
| + FX_FLOAT R,
|
| + FX_FLOAT G,
|
| + FX_FLOAT B) const {
|
| + if (R == G && R == B) {
|
| + *pBuf = R;
|
| + return TRUE;
|
| + }
|
| + return FALSE;
|
| +}
|
| +
|
| +void CPDF_CalGray::TranslateImageLine(uint8_t* pDestBuf,
|
| + const uint8_t* pSrcBuf,
|
| + int pixels,
|
| + int image_width,
|
| + int image_height,
|
| + FX_BOOL bTransMask) const {
|
| + for (int i = 0; i < pixels; i++) {
|
| + *pDestBuf++ = pSrcBuf[i];
|
| + *pDestBuf++ = pSrcBuf[i];
|
| + *pDestBuf++ = pSrcBuf[i];
|
| + }
|
| +}
|
| +
|
| +CPDF_CalRGB::CPDF_CalRGB(CPDF_Document* pDoc)
|
| + : CPDF_ColorSpace(pDoc, PDFCS_CALRGB, 3) {}
|
| +
|
| +FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| + CPDF_Dictionary* pDict = pArray->GetDictAt(1);
|
| + if (!pDict)
|
| + return FALSE;
|
| +
|
| + CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
|
| + int i;
|
| + for (i = 0; i < 3; i++)
|
| + m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| +
|
| + pParam = pDict->GetArrayBy("BlackPoint");
|
| + for (i = 0; i < 3; i++)
|
| + m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| +
|
| + pParam = pDict->GetArrayBy("Gamma");
|
| + if (pParam) {
|
| + m_bGamma = TRUE;
|
| + for (i = 0; i < 3; i++)
|
| + m_Gamma[i] = pParam->GetNumberAt(i);
|
| + } else {
|
| + m_bGamma = FALSE;
|
| + }
|
| +
|
| + pParam = pDict->GetArrayBy("Matrix");
|
| + if (pParam) {
|
| + m_bMatrix = TRUE;
|
| + for (i = 0; i < 9; i++)
|
| + m_Matrix[i] = pParam->GetNumberAt(i);
|
| + } else {
|
| + m_bMatrix = FALSE;
|
| + }
|
| + return TRUE;
|
| +}
|
| +
|
| +FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf,
|
| + FX_FLOAT& R,
|
| + FX_FLOAT& G,
|
| + FX_FLOAT& B) const {
|
| + FX_FLOAT A_ = pBuf[0];
|
| + FX_FLOAT B_ = pBuf[1];
|
| + FX_FLOAT C_ = pBuf[2];
|
| + if (m_bGamma) {
|
| + A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]);
|
| + B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]);
|
| + C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]);
|
| + }
|
| +
|
| + FX_FLOAT X;
|
| + FX_FLOAT Y;
|
| + FX_FLOAT Z;
|
| + if (m_bMatrix) {
|
| + X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_;
|
| + Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_;
|
| + Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_;
|
| + } else {
|
| + X = A_;
|
| + Y = B_;
|
| + Z = C_;
|
| + }
|
| + XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1],
|
| + m_WhitePoint[2]);
|
| + return TRUE;
|
| +}
|
| +
|
| +FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf,
|
| + FX_FLOAT R,
|
| + FX_FLOAT G,
|
| + FX_FLOAT B) const {
|
| + pBuf[0] = R;
|
| + pBuf[1] = G;
|
| + pBuf[2] = B;
|
| + return TRUE;
|
| +}
|
| +
|
| +void CPDF_CalRGB::TranslateImageLine(uint8_t* pDestBuf,
|
| + const uint8_t* pSrcBuf,
|
| + int pixels,
|
| + int image_width,
|
| + int image_height,
|
| + FX_BOOL bTransMask) const {
|
| + if (bTransMask) {
|
| + FX_FLOAT Cal[3];
|
| + FX_FLOAT R;
|
| + FX_FLOAT G;
|
| + FX_FLOAT B;
|
| + for (int i = 0; i < pixels; i++) {
|
| + Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255;
|
| + Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255;
|
| + Cal[2] = ((FX_FLOAT)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);
|
| + pSrcBuf += 3;
|
| + pDestBuf += 3;
|
| + }
|
| + }
|
| + ReverseRGB(pDestBuf, pSrcBuf, pixels);
|
| +}
|
| +
|
| +CPDF_LabCS::CPDF_LabCS(CPDF_Document* pDoc)
|
| + : CPDF_ColorSpace(pDoc, PDFCS_LAB, 3) {}
|
| +
|
| +void CPDF_LabCS::GetDefaultValue(int iComponent,
|
| + FX_FLOAT& value,
|
| + FX_FLOAT& min,
|
| + FX_FLOAT& max) const {
|
| + assert(iComponent < 3);
|
| + value = 0;
|
| + if (iComponent == 0) {
|
| + min = 0;
|
| + max = 100 * 1.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;
|
| + }
|
| +}
|
| +
|
| +FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| + CPDF_Dictionary* pDict = pArray->GetDictAt(1);
|
| + if (!pDict)
|
| + return FALSE;
|
| +
|
| + CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
|
| + int i;
|
| + for (i = 0; i < 3; i++)
|
| + m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| +
|
| + pParam = pDict->GetArrayBy("BlackPoint");
|
| + for (i = 0; i < 3; i++)
|
| + m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
|
| +
|
| + pParam = pDict->GetArrayBy("Range");
|
| + const FX_FLOAT def_ranges[4] = {-100 * 1.0f, 100 * 1.0f, -100 * 1.0f,
|
| + 100 * 1.0f};
|
| + for (i = 0; i < 4; i++)
|
| + m_Ranges[i] = pParam ? pParam->GetNumberAt(i) : def_ranges[i];
|
| + return TRUE;
|
| +}
|
| +
|
| +FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf,
|
| + FX_FLOAT& R,
|
| + FX_FLOAT& G,
|
| + FX_FLOAT& B) const {
|
| + FX_FLOAT Lstar = pBuf[0];
|
| + FX_FLOAT astar = pBuf[1];
|
| + FX_FLOAT bstar = pBuf[2];
|
| + FX_FLOAT M = (Lstar + 16.0f) / 116.0f;
|
| + FX_FLOAT L = M + astar / 500.0f;
|
| + FX_FLOAT N = M - bstar / 200.0f;
|
| + FX_FLOAT X, Y, Z;
|
| + if (L < 0.2069f)
|
| + X = 0.957f * 0.12842f * (L - 0.1379f);
|
| + else
|
| + X = 0.957f * L * L * L;
|
| +
|
| + if (M < 0.2069f)
|
| + Y = 0.12842f * (M - 0.1379f);
|
| + else
|
| + Y = M * M * M;
|
| +
|
| + if (N < 0.2069f)
|
| + Z = 1.0889f * 0.12842f * (N - 0.1379f);
|
| + else
|
| + Z = 1.0889f * N * N * N;
|
| +
|
| + XYZ_to_sRGB(X, Y, Z, R, G, B);
|
| + return TRUE;
|
| +}
|
| +
|
| +FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf,
|
| + FX_FLOAT R,
|
| + FX_FLOAT G,
|
| + FX_FLOAT B) const {
|
| + return FALSE;
|
| +}
|
| +
|
| +void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf,
|
| + const uint8_t* pSrcBuf,
|
| + int pixels,
|
| + int image_width,
|
| + int image_height,
|
| + FX_BOOL bTransMask) const {
|
| + for (int i = 0; i < pixels; i++) {
|
| + FX_FLOAT lab[3];
|
| + FX_FLOAT R, G, B;
|
| + lab[0] = (pSrcBuf[0] * 100 / 255.0f);
|
| + lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128);
|
| + lab[2] = (FX_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);
|
| + pDestBuf += 3;
|
| + pSrcBuf += 3;
|
| + }
|
| +}
|
| +
|
| +CPDF_ICCBasedCS::CPDF_ICCBasedCS(CPDF_Document* pDoc)
|
| + : CPDF_ColorSpace(pDoc, PDFCS_ICCBASED, 0),
|
| + m_pAlterCS(nullptr),
|
| + m_pProfile(nullptr),
|
| + m_pCache(nullptr),
|
| + m_pRanges(nullptr),
|
| + m_bOwn(FALSE) {}
|
| +
|
| +CPDF_ICCBasedCS::~CPDF_ICCBasedCS() {
|
| + FX_Free(m_pCache);
|
| + FX_Free(m_pRanges);
|
| + if (m_pAlterCS && m_bOwn)
|
| + m_pAlterCS->ReleaseCS();
|
| + if (m_pProfile && m_pDocument)
|
| + m_pDocument->GetPageData()->ReleaseIccProfile(m_pProfile);
|
| +}
|
| +
|
| +FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| + CPDF_Stream* pStream = pArray->GetStreamAt(1);
|
| + if (!pStream)
|
| + return FALSE;
|
| +
|
| + m_pProfile = pDoc->LoadIccProfile(pStream);
|
| + if (!m_pProfile)
|
| + return FALSE;
|
| +
|
| + m_nComponents =
|
| + m_pProfile
|
| + ->GetComponents(); // Try using the nComponents from ICC profile
|
| + CPDF_Dictionary* pDict = pStream->GetDict();
|
| + if (!m_pProfile->m_pTransform) { // No valid ICC profile or using sRGB
|
| + CPDF_Object* pAlterCSObj =
|
| + pDict ? pDict->GetElementValue("Alternate") : nullptr;
|
| + if (pAlterCSObj) {
|
| + CPDF_ColorSpace* 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 = pAlterCS;
|
| + m_bOwn = TRUE;
|
| } else { // No valid alternative colorspace
|
| pAlterCS->ReleaseCS();
|
| int32_t nDictComponents = pDict ? pDict->GetIntegerBy("N") : 0;
|
| @@ -739,28 +832,27 @@ FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| }
|
| }
|
| if (!m_pAlterCS) {
|
| - if (m_nComponents == 1) {
|
| + if (m_nComponents == 1)
|
| m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY);
|
| - } else if (m_nComponents == 3) {
|
| + else if (m_nComponents == 3)
|
| m_pAlterCS = GetStockCS(PDFCS_DEVICERGB);
|
| - } else if (m_nComponents == 4) {
|
| + else if (m_nComponents == 4)
|
| m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK);
|
| - }
|
| }
|
| }
|
| CPDF_Array* pRanges = pDict->GetArrayBy("Range");
|
| m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2);
|
| for (int i = 0; i < m_nComponents * 2; i++) {
|
| - if (pRanges) {
|
| + if (pRanges)
|
| m_pRanges[i] = pRanges->GetNumberAt(i);
|
| - } else if (i % 2) {
|
| + else if (i % 2)
|
| m_pRanges[i] = 1.0f;
|
| - } else {
|
| + else
|
| m_pRanges[i] = 0;
|
| - }
|
| }
|
| return TRUE;
|
| }
|
| +
|
| FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf,
|
| FX_FLOAT& R,
|
| FX_FLOAT& G,
|
| @@ -787,32 +879,35 @@ FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf,
|
| B = rgb[2];
|
| return TRUE;
|
| }
|
| +
|
| +FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf,
|
| + FX_FLOAT R,
|
| + FX_FLOAT G,
|
| + FX_FLOAT B) const {
|
| + return FALSE;
|
| +}
|
| +
|
| FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf,
|
| FX_FLOAT& c,
|
| FX_FLOAT& m,
|
| FX_FLOAT& y,
|
| FX_FLOAT& k) const {
|
| - if (m_nComponents != 4) {
|
| + if (m_nComponents != 4)
|
| return FALSE;
|
| - }
|
| +
|
| c = pBuf[0];
|
| m = pBuf[1];
|
| y = pBuf[2];
|
| k = pBuf[3];
|
| return TRUE;
|
| }
|
| -FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT R,
|
| - FX_FLOAT G,
|
| - FX_FLOAT B) const {
|
| - return FALSE;
|
| -}
|
| +
|
| void CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled) {
|
| CPDF_ColorSpace::EnableStdConversion(bEnabled);
|
| - if (m_pAlterCS) {
|
| + if (m_pAlterCS)
|
| m_pAlterCS->EnableStdConversion(bEnabled);
|
| - }
|
| }
|
| +
|
| void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf,
|
| const uint8_t* pSrcBuf,
|
| int pixels,
|
| @@ -864,30 +959,13 @@ void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf,
|
| image_height);
|
| }
|
| }
|
| -class CPDF_IndexedCS : public CPDF_ColorSpace {
|
| - public:
|
| - explicit CPDF_IndexedCS(CPDF_Document* pDoc)
|
| - : CPDF_ColorSpace(pDoc, PDFCS_INDEXED, 1),
|
| - m_pBaseCS(nullptr),
|
| - m_pCountedBaseCS(nullptr),
|
| - m_pCompMinMax(nullptr) {}
|
| - ~CPDF_IndexedCS() override;
|
|
|
| - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| - FX_BOOL GetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT& R,
|
| - FX_FLOAT& G,
|
| - FX_FLOAT& B) const override;
|
| - CPDF_ColorSpace* GetBaseCS() const override;
|
| - void EnableStdConversion(FX_BOOL bEnabled) override;
|
| +CPDF_IndexedCS::CPDF_IndexedCS(CPDF_Document* pDoc)
|
| + : CPDF_ColorSpace(pDoc, PDFCS_INDEXED, 1),
|
| + m_pBaseCS(nullptr),
|
| + m_pCountedBaseCS(nullptr),
|
| + m_pCompMinMax(nullptr) {}
|
|
|
| - CPDF_ColorSpace* m_pBaseCS;
|
| - CPDF_CountedColorSpace* m_pCountedBaseCS;
|
| - int m_nBaseComponents;
|
| - int m_MaxIndex;
|
| - CFX_ByteString m_Table;
|
| - FX_FLOAT* m_pCompMinMax;
|
| -};
|
| CPDF_IndexedCS::~CPDF_IndexedCS() {
|
| FX_Free(m_pCompMinMax);
|
| CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
|
| @@ -895,6 +973,7 @@ CPDF_IndexedCS::~CPDF_IndexedCS() {
|
| m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
|
| }
|
| }
|
| +
|
| FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| if (pArray->GetCount() < 4) {
|
| return FALSE;
|
| @@ -958,9 +1037,11 @@ FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf,
|
| }
|
| return m_pBaseCS->GetRGB(comps, R, G, B);
|
| }
|
| +
|
| CPDF_ColorSpace* CPDF_IndexedCS::GetBaseCS() const {
|
| return m_pBaseCS;
|
| }
|
| +
|
| void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled) {
|
| CPDF_ColorSpace::EnableStdConversion(bEnabled);
|
| if (m_pBaseCS) {
|
| @@ -968,13 +1049,10 @@ void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled) {
|
| }
|
| }
|
|
|
| -#define MAX_PATTERN_COLORCOMPS 16
|
| -struct PatternValue {
|
| - CPDF_Pattern* m_pPattern;
|
| - CPDF_CountedPattern* m_pCountedPattern;
|
| - int m_nComps;
|
| - FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS];
|
| -};
|
| +CPDF_PatternCS::CPDF_PatternCS(CPDF_Document* pDoc)
|
| + : CPDF_ColorSpace(pDoc, PDFCS_PATTERN, 1),
|
| + m_pBaseCS(nullptr),
|
| + m_pCountedBaseCS(nullptr) {}
|
|
|
| CPDF_PatternCS::~CPDF_PatternCS() {
|
| CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
|
| @@ -982,6 +1060,7 @@ CPDF_PatternCS::~CPDF_PatternCS() {
|
| m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
|
| }
|
| }
|
| +
|
| FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| CPDF_Object* pBaseCS = pArray->GetElementValue(1);
|
| if (pBaseCS == m_pArray) {
|
| @@ -1003,6 +1082,7 @@ FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| }
|
| return TRUE;
|
| }
|
| +
|
| FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf,
|
| FX_FLOAT& R,
|
| FX_FLOAT& G,
|
| @@ -1017,39 +1097,23 @@ FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf,
|
| R = G = B = 0.75f;
|
| return FALSE;
|
| }
|
| +
|
| CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const {
|
| return m_pBaseCS;
|
| }
|
| -class CPDF_SeparationCS : public CPDF_ColorSpace {
|
| - public:
|
| - explicit CPDF_SeparationCS(CPDF_Document* pDoc)
|
| - : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1),
|
| - m_pAltCS(nullptr),
|
| - m_pFunc(nullptr) {}
|
| - ~CPDF_SeparationCS() override;
|
|
|
| - // CPDF_ColorSpace:
|
| - void GetDefaultValue(int iComponent,
|
| - FX_FLOAT& value,
|
| - FX_FLOAT& min,
|
| - FX_FLOAT& max) const override;
|
| - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| - FX_BOOL GetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT& R,
|
| - FX_FLOAT& G,
|
| - FX_FLOAT& B) const override;
|
| - void EnableStdConversion(FX_BOOL bEnabled) override;
|
| +CPDF_SeparationCS::CPDF_SeparationCS(CPDF_Document* pDoc)
|
| + : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1),
|
| + m_pAltCS(nullptr),
|
| + m_pFunc(nullptr) {}
|
|
|
| - CPDF_ColorSpace* m_pAltCS;
|
| - CPDF_Function* m_pFunc;
|
| - enum { None, All, Colorant } m_Type;
|
| -};
|
| CPDF_SeparationCS::~CPDF_SeparationCS() {
|
| if (m_pAltCS) {
|
| m_pAltCS->ReleaseCS();
|
| }
|
| delete m_pFunc;
|
| }
|
| +
|
| void CPDF_SeparationCS::GetDefaultValue(int iComponent,
|
| FX_FLOAT& value,
|
| FX_FLOAT& min,
|
| @@ -1058,6 +1122,7 @@ void CPDF_SeparationCS::GetDefaultValue(int iComponent,
|
| min = 0;
|
| max = 1.0f;
|
| }
|
| +
|
| FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| CFX_ByteString name = pArray->GetStringAt(1);
|
| if (name == "None") {
|
| @@ -1083,6 +1148,7 @@ FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| }
|
| return TRUE;
|
| }
|
| +
|
| FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf,
|
| FX_FLOAT& R,
|
| FX_FLOAT& G,
|
| @@ -1113,41 +1179,26 @@ FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf,
|
| R = G = B = 0;
|
| return FALSE;
|
| }
|
| +
|
| void CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled) {
|
| CPDF_ColorSpace::EnableStdConversion(bEnabled);
|
| if (m_pAltCS) {
|
| m_pAltCS->EnableStdConversion(bEnabled);
|
| }
|
| }
|
| -class CPDF_DeviceNCS : public CPDF_ColorSpace {
|
| - public:
|
| - explicit CPDF_DeviceNCS(CPDF_Document* pDoc)
|
| - : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN, 0),
|
| - m_pAltCS(nullptr),
|
| - m_pFunc(nullptr) {}
|
| - ~CPDF_DeviceNCS() override;
|
|
|
| - // CPDF_ColorSpace:
|
| - void GetDefaultValue(int iComponent,
|
| - FX_FLOAT& value,
|
| - FX_FLOAT& min,
|
| - FX_FLOAT& max) const override;
|
| - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
|
| - FX_BOOL GetRGB(FX_FLOAT* pBuf,
|
| - FX_FLOAT& R,
|
| - FX_FLOAT& G,
|
| - FX_FLOAT& B) const override;
|
| - void EnableStdConversion(FX_BOOL bEnabled) override;
|
| +CPDF_DeviceNCS::CPDF_DeviceNCS(CPDF_Document* pDoc)
|
| + : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN, 0),
|
| + m_pAltCS(nullptr),
|
| + m_pFunc(nullptr) {}
|
|
|
| - CPDF_ColorSpace* m_pAltCS;
|
| - CPDF_Function* m_pFunc;
|
| -};
|
| CPDF_DeviceNCS::~CPDF_DeviceNCS() {
|
| delete m_pFunc;
|
| if (m_pAltCS) {
|
| m_pAltCS->ReleaseCS();
|
| }
|
| }
|
| +
|
| void CPDF_DeviceNCS::GetDefaultValue(int iComponent,
|
| FX_FLOAT& value,
|
| FX_FLOAT& min,
|
| @@ -1156,6 +1207,7 @@ void CPDF_DeviceNCS::GetDefaultValue(int iComponent,
|
| min = 0;
|
| max = 1.0f;
|
| }
|
| +
|
| FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| CPDF_Array* pObj = ToArray(pArray->GetElementValue(1));
|
| if (!pObj)
|
| @@ -1176,6 +1228,7 @@ FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
|
| }
|
| return TRUE;
|
| }
|
| +
|
| FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf,
|
| FX_FLOAT& R,
|
| FX_FLOAT& G,
|
| @@ -1191,359 +1244,10 @@ FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf,
|
| }
|
| return m_pAltCS->GetRGB(results, R, G, B);
|
| }
|
| +
|
| void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) {
|
| CPDF_ColorSpace::EnableStdConversion(bEnabled);
|
| if (m_pAltCS) {
|
| m_pAltCS->EnableStdConversion(bEnabled);
|
| }
|
| }
|
| -
|
| -CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) {
|
| - return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);
|
| -}
|
| -
|
| -CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name) {
|
| - if (name == "DeviceRGB" || name == "RGB") {
|
| - return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
|
| - }
|
| - if (name == "DeviceGray" || name == "G") {
|
| - return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
|
| - }
|
| - if (name == "DeviceCMYK" || name == "CMYK") {
|
| - return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
|
| - }
|
| - if (name == "Pattern") {
|
| - return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
|
| - }
|
| - return NULL;
|
| -}
|
| -CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj) {
|
| - if (!pObj)
|
| - return nullptr;
|
| - if (pObj->IsName())
|
| - return _CSFromName(pObj->GetString());
|
| -
|
| - if (CPDF_Stream* pStream = pObj->AsStream()) {
|
| - CPDF_Dictionary* pDict = pStream->GetDict();
|
| - if (!pDict)
|
| - return nullptr;
|
| -
|
| - for (const auto& it : *pDict) {
|
| - CPDF_ColorSpace* pRet = nullptr;
|
| - CPDF_Object* pValue = it.second;
|
| - if (ToName(pValue))
|
| - pRet = _CSFromName(pValue->GetString());
|
| - if (pRet)
|
| - return pRet;
|
| - }
|
| - return nullptr;
|
| - }
|
| -
|
| - CPDF_Array* pArray = pObj->AsArray();
|
| - if (!pArray || pArray->GetCount() == 0)
|
| - return nullptr;
|
| -
|
| - CPDF_Object* pFamilyObj = pArray->GetElementValue(0);
|
| - if (!pFamilyObj)
|
| - return nullptr;
|
| -
|
| - CFX_ByteString familyname = pFamilyObj->GetString();
|
| - if (pArray->GetCount() == 1)
|
| - return _CSFromName(familyname);
|
| -
|
| - CPDF_ColorSpace* pCS = NULL;
|
| - FX_DWORD id = familyname.GetID();
|
| - if (id == FXBSTR_ID('C', 'a', 'l', 'G')) {
|
| - pCS = new CPDF_CalGray(pDoc);
|
| - } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) {
|
| - pCS = new CPDF_CalRGB(pDoc);
|
| - } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) {
|
| - pCS = new CPDF_LabCS(pDoc);
|
| - } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) {
|
| - pCS = new CPDF_ICCBasedCS(pDoc);
|
| - } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') ||
|
| - id == FXBSTR_ID('I', 0, 0, 0)) {
|
| - pCS = new CPDF_IndexedCS(pDoc);
|
| - } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) {
|
| - pCS = new CPDF_SeparationCS(pDoc);
|
| - } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) {
|
| - pCS = new CPDF_DeviceNCS(pDoc);
|
| - } else if (id == FXBSTR_ID('P', 'a', 't', 't')) {
|
| - pCS = new CPDF_PatternCS(pDoc);
|
| - } else {
|
| - return NULL;
|
| - }
|
| - pCS->m_pArray = pArray;
|
| - if (!pCS->v_Load(pDoc, pArray)) {
|
| - pCS->ReleaseCS();
|
| - return NULL;
|
| - }
|
| - return pCS;
|
| -}
|
| -void CPDF_ColorSpace::ReleaseCS() {
|
| - if (this == GetStockCS(PDFCS_DEVICERGB)) {
|
| - return;
|
| - }
|
| - if (this == GetStockCS(PDFCS_DEVICEGRAY)) {
|
| - return;
|
| - }
|
| - if (this == GetStockCS(PDFCS_DEVICECMYK)) {
|
| - return;
|
| - }
|
| - if (this == GetStockCS(PDFCS_PATTERN)) {
|
| - return;
|
| - }
|
| - delete this;
|
| -}
|
| -int CPDF_ColorSpace::GetBufSize() const {
|
| - if (m_Family == PDFCS_PATTERN) {
|
| - return sizeof(PatternValue);
|
| - }
|
| - return m_nComponents * sizeof(FX_FLOAT);
|
| -}
|
| -FX_FLOAT* CPDF_ColorSpace::CreateBuf() {
|
| - int size = GetBufSize();
|
| - uint8_t* pBuf = FX_Alloc(uint8_t, size);
|
| - return (FX_FLOAT*)pBuf;
|
| -}
|
| -FX_BOOL CPDF_ColorSpace::sRGB() const {
|
| - if (m_Family == PDFCS_DEVICERGB) {
|
| - return TRUE;
|
| - }
|
| - if (m_Family != PDFCS_ICCBASED) {
|
| - return FALSE;
|
| - }
|
| - CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this;
|
| - return pCS->m_pProfile->m_bsRGB;
|
| -}
|
| -FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf,
|
| - FX_FLOAT& c,
|
| - FX_FLOAT& m,
|
| - FX_FLOAT& y,
|
| - FX_FLOAT& k) const {
|
| - if (v_GetCMYK(pBuf, c, m, y, k)) {
|
| - return TRUE;
|
| - }
|
| - FX_FLOAT R, G, B;
|
| - if (!GetRGB(pBuf, R, G, B)) {
|
| - return FALSE;
|
| - }
|
| - sRGB_to_AdobeCMYK(R, G, B, c, m, y, k);
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf,
|
| - FX_FLOAT c,
|
| - FX_FLOAT m,
|
| - FX_FLOAT y,
|
| - FX_FLOAT k) const {
|
| - if (v_SetCMYK(pBuf, c, m, y, k)) {
|
| - return TRUE;
|
| - }
|
| - FX_FLOAT R, G, B;
|
| - AdobeCMYK_to_sRGB(c, m, y, k, R, G, B);
|
| - return SetRGB(pBuf, R, G, B);
|
| -}
|
| -void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const {
|
| - if (!buf || m_Family == PDFCS_PATTERN) {
|
| - return;
|
| - }
|
| - FX_FLOAT min, max;
|
| - for (int i = 0; i < m_nComponents; i++) {
|
| - GetDefaultValue(i, buf[i], min, max);
|
| - }
|
| -}
|
| -int CPDF_ColorSpace::GetMaxIndex() const {
|
| - if (m_Family != PDFCS_INDEXED) {
|
| - return 0;
|
| - }
|
| - CPDF_IndexedCS* pCS = (CPDF_IndexedCS*)this;
|
| - return pCS->m_MaxIndex;
|
| -}
|
| -void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf,
|
| - const uint8_t* src_buf,
|
| - int pixels,
|
| - int image_width,
|
| - int image_height,
|
| - FX_BOOL bTransMask) const {
|
| - CFX_FixedBufGrow<FX_FLOAT, 16> srcbuf(m_nComponents);
|
| - FX_FLOAT* src = srcbuf;
|
| - FX_FLOAT R, G, B;
|
| - for (int i = 0; i < pixels; i++) {
|
| - for (int j = 0; j < m_nComponents; j++)
|
| - if (m_Family == PDFCS_INDEXED) {
|
| - src[j] = (FX_FLOAT)(*src_buf++);
|
| - } else {
|
| - src[j] = (FX_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);
|
| - }
|
| -}
|
| -void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) {
|
| - if (bEnabled) {
|
| - m_dwStdConversion++;
|
| - } else if (m_dwStdConversion) {
|
| - m_dwStdConversion--;
|
| - }
|
| -}
|
| -CPDF_Color::CPDF_Color(int family) {
|
| - m_pCS = CPDF_ColorSpace::GetStockCS(family);
|
| - int nComps = 3;
|
| - if (family == PDFCS_DEVICEGRAY) {
|
| - nComps = 1;
|
| - } else if (family == PDFCS_DEVICECMYK) {
|
| - nComps = 4;
|
| - }
|
| - m_pBuffer = FX_Alloc(FX_FLOAT, nComps);
|
| - for (int i = 0; i < nComps; i++) {
|
| - m_pBuffer[i] = 0;
|
| - }
|
| -}
|
| -CPDF_Color::~CPDF_Color() {
|
| - ReleaseBuffer();
|
| - ReleaseColorSpace();
|
| -}
|
| -void CPDF_Color::ReleaseBuffer() {
|
| - if (!m_pBuffer) {
|
| - return;
|
| - }
|
| - if (m_pCS->GetFamily() == PDFCS_PATTERN) {
|
| - PatternValue* pvalue = (PatternValue*)m_pBuffer;
|
| - CPDF_Pattern* pPattern =
|
| - pvalue->m_pCountedPattern ? pvalue->m_pCountedPattern->get() : NULL;
|
| - if (pPattern && pPattern->m_pDocument) {
|
| - CPDF_DocPageData* pPageData = pPattern->m_pDocument->GetPageData();
|
| - if (pPageData) {
|
| - pPageData->ReleasePattern(pPattern->m_pPatternObj);
|
| - }
|
| - }
|
| - }
|
| - FX_Free(m_pBuffer);
|
| - m_pBuffer = NULL;
|
| -}
|
| -void CPDF_Color::ReleaseColorSpace() {
|
| - if (m_pCS && m_pCS->m_pDocument && m_pCS->GetArray()) {
|
| - m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray());
|
| - m_pCS = NULL;
|
| - }
|
| -}
|
| -void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) {
|
| - if (m_pCS == pCS) {
|
| - if (!m_pBuffer) {
|
| - m_pBuffer = pCS->CreateBuf();
|
| - }
|
| - ReleaseColorSpace();
|
| - m_pCS = pCS;
|
| - return;
|
| - }
|
| - ReleaseBuffer();
|
| - ReleaseColorSpace();
|
| - m_pCS = pCS;
|
| - if (m_pCS) {
|
| - m_pBuffer = pCS->CreateBuf();
|
| - pCS->GetDefaultColor(m_pBuffer);
|
| - }
|
| -}
|
| -void CPDF_Color::SetValue(FX_FLOAT* comps) {
|
| - if (!m_pBuffer) {
|
| - return;
|
| - }
|
| - if (m_pCS->GetFamily() != PDFCS_PATTERN) {
|
| - FXSYS_memcpy(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT));
|
| - }
|
| -}
|
| -void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps) {
|
| - if (ncomps > MAX_PATTERN_COLORCOMPS) {
|
| - return;
|
| - }
|
| - if (!m_pCS || m_pCS->GetFamily() != PDFCS_PATTERN) {
|
| - FX_Free(m_pBuffer);
|
| - m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
|
| - m_pBuffer = m_pCS->CreateBuf();
|
| - }
|
| - CPDF_DocPageData* pDocPageData = NULL;
|
| - PatternValue* pvalue = (PatternValue*)m_pBuffer;
|
| - if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
|
| - pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData();
|
| - if (pDocPageData) {
|
| - pDocPageData->ReleasePattern(pvalue->m_pPattern->m_pPatternObj);
|
| - }
|
| - }
|
| - pvalue->m_nComps = ncomps;
|
| - pvalue->m_pPattern = pPattern;
|
| - if (ncomps) {
|
| - FXSYS_memcpy(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT));
|
| - }
|
| - pvalue->m_pCountedPattern = NULL;
|
| - if (pPattern && pPattern->m_pDocument) {
|
| - if (!pDocPageData) {
|
| - pDocPageData = pPattern->m_pDocument->GetPageData();
|
| - }
|
| - pvalue->m_pCountedPattern =
|
| - pDocPageData->FindPatternPtr(pPattern->m_pPatternObj);
|
| - }
|
| -}
|
| -void CPDF_Color::Copy(const CPDF_Color* pSrc) {
|
| - ReleaseBuffer();
|
| - ReleaseColorSpace();
|
| - m_pCS = pSrc->m_pCS;
|
| - if (m_pCS && m_pCS->m_pDocument) {
|
| - CPDF_Array* pArray = m_pCS->GetArray();
|
| - if (pArray) {
|
| - m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray);
|
| - }
|
| - }
|
| - if (!m_pCS) {
|
| - return;
|
| - }
|
| - m_pBuffer = m_pCS->CreateBuf();
|
| - FXSYS_memcpy(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize());
|
| - if (m_pCS->GetFamily() == PDFCS_PATTERN) {
|
| - PatternValue* pvalue = (PatternValue*)m_pBuffer;
|
| - if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
|
| - pvalue->m_pPattern =
|
| - pvalue->m_pPattern->m_pDocument->GetPageData()->GetPattern(
|
| - pvalue->m_pPattern->m_pPatternObj, FALSE,
|
| - &pvalue->m_pPattern->m_ParentMatrix);
|
| - }
|
| - }
|
| -}
|
| -FX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const {
|
| - if (!m_pCS || !m_pBuffer) {
|
| - return FALSE;
|
| - }
|
| - FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f;
|
| - if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) {
|
| - return FALSE;
|
| - }
|
| - R = (int32_t)(r * 255 + 0.5f);
|
| - G = (int32_t)(g * 255 + 0.5f);
|
| - B = (int32_t)(b * 255 + 0.5f);
|
| - return TRUE;
|
| -}
|
| -CPDF_Pattern* CPDF_Color::GetPattern() const {
|
| - if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN) {
|
| - return NULL;
|
| - }
|
| - PatternValue* pvalue = (PatternValue*)m_pBuffer;
|
| - return pvalue->m_pPattern;
|
| -}
|
| -CPDF_ColorSpace* CPDF_Color::GetPatternCS() const {
|
| - if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN) {
|
| - return NULL;
|
| - }
|
| - return m_pCS->GetBaseCS();
|
| -}
|
| -FX_FLOAT* CPDF_Color::GetPatternColor() const {
|
| - if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN) {
|
| - return NULL;
|
| - }
|
| - PatternValue* pvalue = (PatternValue*)m_pBuffer;
|
| - return pvalue->m_nComps ? pvalue->m_Comps : NULL;
|
| -}
|
| -FX_BOOL CPDF_Color::IsEqual(const CPDF_Color& other) const {
|
| - return m_pCS && m_pCS == other.m_pCS &&
|
| - FXSYS_memcmp(m_pBuffer, other.m_pBuffer, m_pCS->GetBufSize()) == 0;
|
| -}
|
|
|