// Copyright 2014 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 "../../../include/fpdfapi/fpdf_page.h"
#include "../../../include/fpdfapi/fpdf_module.h"
#include "../../../include/fxcodec/fx_codec.h"
#include "pageint.h"
#include <limits.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;
    }
}

int ComponentsForFamily(int family) {
    if (family == PDFCS_DEVICERGB)
        return 3;
    if (family == PDFCS_DEVICEGRAY)
        return 1;
    return 4;
}

}  // 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 - FX_MIN(1.0f, pBuf[0] + k);
            G = 1.0f - FX_MIN(1.0f, pBuf[1] + k);
            B = 1.0f - FX_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;
    } else if (m_Family == PDFCS_DEVICEGRAY) {
        if (R == G && R == B) {
            *pBuf = R;
            return TRUE;
        } else {
            return FALSE;
        }
    } else 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;
    } else if (m_Family == PDFCS_DEVICEGRAY) {
        return FALSE;
    } else if (m_Family == PDFCS_DEVICECMYK) {
        pBuf[0] = c;
        pBuf[1] = m;
        pBuf[2] = y;
        pBuf[3] = k;
        return TRUE;
    }
    return FALSE;
}
static 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;
        }
}
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 - FX_MIN(255, pSrcBuf[0] + k);
                pDestBuf[1] = 255 - FX_MIN(255, pSrcBuf[1] + k);
                pDestBuf[0] = 255 - FX_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,  48,  49,
    49,  50,  51,  52,  53,  53,  54,  55,  56,  56,  57,  58,  58,  59,  60,  61,
    61,  62,  62,  63,  64,  64,  65,  66,  66,  67,  67,  68,  68,  69,  70,  70,
    71,  71,  72,  72,  73,  73,  74,  74,  75,  76,  76,  77,  77,  78,  78,  79,
    79,  79,  80,  80,  81,  81,  82,  82,  83,  83,  84,  84,  85,  85,  85,  86,
    86,  87,  87,  88,  88,  88,  89,  89,  90,  90,  91,  91,  91,  92,  92,  93,
    93,  93,  94,  94,  95,  95,  95,  96,  96,  97,  97,  97,  98,  98,  98,  99,
    99,  99, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104,
    105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110,
    110, 110, 111, 111, 111, 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, 150, 151,
    152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164,
    165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 176,
    177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 187,
    188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197,
    198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207,
    208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216,
    216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
    225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
    233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240,
    241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248,
    248, 249, 249, 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) {
    }
    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;
    FX_BOOL	SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const override;
    void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width,
                            int image_height, FX_BOOL bTransMask = FALSE) const override;

private:
    FX_FLOAT m_WhitePoint[3];
    FX_FLOAT m_BlackPoint[3];
    FX_FLOAT m_Gamma;
};

FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
{
    CPDF_Dictionary* pDict = pArray->GetDict(1);
    CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
    int i;
    for (i = 0; i < 3; i ++) {
        m_WhitePoint[i] = pParam ? pParam->GetNumber(i) : 0;
    }
    pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
    for (i = 0; i < 3; i ++) {
        m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
    }
    m_Gamma = pDict->GetNumber(FX_BSTRC("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;
    } else {
        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) {
    }
    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;
    FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const override;
    void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width,
                            int image_height, FX_BOOL bTransMask = FALSE) const override;

    FX_FLOAT m_WhitePoint[3];
    FX_FLOAT m_BlackPoint[3];
    FX_FLOAT m_Gamma[3];
    FX_FLOAT m_Matrix[9];
    FX_BOOL m_bGamma;
    FX_BOOL m_bMatrix;
};
FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
{
    CPDF_Dictionary* pDict = pArray->GetDict(1);
    CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
    int i;
    for (i = 0; i < 3; i ++) {
        m_WhitePoint[i] = pParam ? pParam->GetNumber(i) : 0;
    }
    pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
    for (i = 0; i < 3; i ++) {
        m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
    }
    pParam = pDict->GetArray(FX_BSTRC("Gamma"));
    if (pParam) {
        m_bGamma = TRUE;
        for (i = 0; i < 3; i ++) {
            m_Gamma[i] = pParam->GetNumber(i);
        }
    } else {
        m_bGamma = FALSE;
    }
    pParam = pDict->GetArray(FX_BSTRC("Matrix"));
    if (pParam) {
        m_bMatrix = TRUE;
        for (i = 0; i < 9; i ++) {
            m_Matrix[i] = pParam->GetNumber(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) {
    }
    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;
    FX_BOOL	SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const override;
    void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width,
                            int image_height, FX_BOOL bTransMask = FALSE) const;

    FX_FLOAT m_WhitePoint[3];
    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->GetDict(1);
    if (!pDict) {
        return FALSE;
    }
    CPDF_Array* pParam = pDict->GetArray(FX_BSTRC("WhitePoint"));
    int i;
    for (i = 0; i < 3; i ++) {
        m_WhitePoint[i] = pParam ? pParam->GetNumber(i) : 0;
    }
    pParam = pDict->GetArray(FX_BSTRC("BlackPoint"));
    for (i = 0; i < 3; i ++) {
        m_BlackPoint[i] = pParam ? pParam->GetNumber(i) : 0;
    }
    pParam = pDict->GetArray(FX_BSTRC("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->GetNumber(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) {
    }
    ~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, FX_FLOAT& B) const override;
    FX_BOOL	SetRGB(FX_FLOAT* pBuf, 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, int pixels, int image_width,
                            int image_height, FX_BOOL bTransMask = FALSE) const override;

    CPDF_ColorSpace* m_pAlterCS;
    CPDF_IccProfile* m_pProfile;
    uint8_t* m_pCache;
    FX_FLOAT* m_pRanges;
    FX_BOOL	m_bOwn;
};

CPDF_ICCBasedCS::~CPDF_ICCBasedCS()
{
    if (m_pCache) {
        FX_Free(m_pCache);
    }
    if (m_pRanges) {
        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->GetStream(1);
    if (pStream == NULL) {
        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 == NULL) { // No valid ICC profile or using sRGB
        CPDF_Object* pAlterCSObj = pDict ? pDict->GetElementValue(FX_BSTRC("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;
                    }
                    else { // No valid alternative colorspace
                        pAlterCS->ReleaseCS();
                        int32_t nDictComponents = pDict ? pDict->GetInteger(FX_BSTRC("N")) : 0;
                        if (nDictComponents != 1 && nDictComponents != 3 && nDictComponents != 4) {
                            return FALSE;
                        }
                        m_nComponents = nDictComponents;
                    }

                }
                else { // Using sRGB
                    if (pAlterCS->CountComponents() != m_nComponents) {
                        pAlterCS->ReleaseCS();
                    }
                    else {
                        m_pAlterCS = pAlterCS;
                        m_bOwn = TRUE;
                    }
                }
            }
        }
        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->GetArray(FX_BSTRC("Range"));
    m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2);
    for (int i = 0; i < m_nComponents * 2; i ++) {
        if (pRanges) {
            m_pRanges[i] = pRanges->GetNumber(i);
        } else if (i % 2) {
            m_pRanges[i] = 1.0f;
        } else {
            m_pRanges[i] = 0;
        }
    }
    return TRUE;
}
FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
{
    if (m_pProfile && m_pProfile->m_bsRGB) {
        R = pBuf[0];
        G = pBuf[1];
        B = pBuf[2];
        return TRUE;
    }
    ICodec_IccModule *pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
    if (m_pProfile->m_pTransform == NULL || pIccModule == NULL) {
        if (m_pAlterCS) {
            m_pAlterCS->GetRGB(pBuf, R, G, B);
        } else {
            R = G = B = 0.0f;
        }
        return TRUE;
    }
    FX_FLOAT rgb[3];
    pIccModule->SetComponents(m_nComponents);
    pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb);
    R = rgb[0];
    G = rgb[1];
    B = rgb[2];
    return TRUE;
}
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) {
        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) {
        m_pAlterCS->EnableStdConversion(bEnabled);
    }
}
void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask) const
{
    if (m_pProfile->m_bsRGB) {
        ReverseRGB(pDestBuf, pSrcBuf, pixels);
    } else if (m_pProfile->m_pTransform) {
        int nMaxColors = 1;
        for (int i = 0; i < m_nComponents; i ++) {
            nMaxColors *= 52;
        }
        if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2) {
            CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(m_pProfile->m_pTransform, pDestBuf, pSrcBuf, pixels);
        } else {
            if (m_pCache == NULL) {
                ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc2D(uint8_t, nMaxColors, 3);
                uint8_t* temp_src = FX_Alloc2D(uint8_t, nMaxColors, m_nComponents);
                uint8_t* pSrc = temp_src;
                for (int i = 0; i < nMaxColors; i ++) {
                    FX_DWORD color = i;
                    FX_DWORD order = nMaxColors / 52;
                    for (int c = 0; c < m_nComponents; c ++) {
                        *pSrc++ = (uint8_t)(color / order * 5);
                        color %= order;
                        order /= 52;
                    }
                }
                CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(m_pProfile->m_pTransform, m_pCache, temp_src, nMaxColors);
                FX_Free(temp_src);
            }
            for (int i = 0; i < pixels; i ++) {
                int index = 0;
                for (int c = 0; c < m_nComponents; c ++) {
                    index = index * 52 + (*pSrcBuf) / 5;
                    pSrcBuf ++;
                }
                index *= 3;
                *pDestBuf++ = m_pCache[index];
                *pDestBuf++ = m_pCache[index + 1];
                *pDestBuf++ = m_pCache[index + 2];
            }
        }
    } else if (m_pAlterCS) {
        m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width, 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_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()
{
    if (m_pCompMinMax) {
        FX_Free(m_pCompMinMax);
    }
    CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
    if (pCS && m_pDocument) {
        m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
    }
}
FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
{
    if (pArray->GetCount() < 4) {
        return FALSE;
    }
    CPDF_Object* pBaseObj = pArray->GetElementValue(1);
    if (pBaseObj == m_pArray) {
        return FALSE;
    }
    CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
    m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL);
    if (m_pBaseCS == NULL) {
        return FALSE;
    }
    m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
    m_nBaseComponents = m_pBaseCS->CountComponents();
    m_pCompMinMax = FX_Alloc2D(FX_FLOAT, m_nBaseComponents, 2);
    FX_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_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2];
    }
    m_MaxIndex = pArray->GetInteger(2);
    CPDF_Object* pTableObj = pArray->GetElementValue(3);
    if (pTableObj == NULL) {
        return FALSE;
    }
    if (pTableObj->GetType() == PDFOBJ_STRING) {
        m_Table = ((CPDF_String*)pTableObj)->GetString();
    } else if (pTableObj->GetType() == PDFOBJ_STREAM) {
        CPDF_StreamAcc acc;
        acc.LoadAllData((CPDF_Stream*)pTableObj, FALSE);
        m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize());
    }
    return TRUE;
}

FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
{
    int index = (int32_t)(*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()) {
            R = G = B = 0;
            return FALSE;
        }
    }
    CFX_FixedBufGrow<FX_FLOAT, 16> Comps(m_nBaseComponents);
    FX_FLOAT* comps = Comps;
    const uint8_t* pTable = m_Table;
    for (int i = 0; i < m_nBaseComponents; i ++) {
        comps[i] = m_pCompMinMax[i * 2] + m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255;
    }
    m_pBaseCS->GetRGB(comps, R, G, B);
    return TRUE;
}
CPDF_ColorSpace*CPDF_IndexedCS::GetBaseCS() const
{
    return m_pBaseCS;
}
void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled)
{
    CPDF_ColorSpace::EnableStdConversion(bEnabled);
    if (m_pBaseCS) {
        m_pBaseCS->EnableStdConversion(bEnabled);
    }
}
#define MAX_PATTERN_COLORCOMPS	16
typedef struct _PatternValue {
    CPDF_Pattern*	m_pPattern;
    CPDF_CountedPattern*	m_pCountedPattern;
    int				m_nComps;
    FX_FLOAT		m_Comps[MAX_PATTERN_COLORCOMPS];
} PatternValue;
CPDF_PatternCS::~CPDF_PatternCS()
{
    CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
    if (pCS && m_pDocument) {
	    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) {
        return FALSE;
    }
    CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
    m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, NULL);
    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 {
        m_nComponents = 1;
    }
    return TRUE;
}
FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_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)) {
            return TRUE;
        }
    }
    R = G = B = 0.75f;
    return FALSE;
}
CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const
{
    return m_pBaseCS;
}
class CPDF_SeparationCS : public CPDF_ColorSpace
{
public:
    CPDF_SeparationCS(CPDF_Document* pDoc)
            : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1),
              m_pAltCS(nullptr),
              m_pFunc(nullptr) {
    }
    ~CPDF_SeparationCS() 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, 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;
};
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, FX_FLOAT& max) const
{
    value = 1.0f;
    min = 0;
    max = 1.0f;
}
FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
{
    CFX_ByteString name = pArray->GetString(1);
    if (name == FX_BSTRC("None")) {
        m_Type = None;
    } else {
        m_Type = Colorant;
        CPDF_Object* pAltCS = pArray->GetElementValue(2);
        if (pAltCS == m_pArray) {
            return FALSE;
        }
        m_pAltCS = Load(pDoc, pAltCS);
        if (!m_pAltCS) {
            return FALSE;
        }
        CPDF_Object* pFuncObj = pArray->GetElementValue(3);
        if (pFuncObj && pFuncObj->GetType() != PDFOBJ_NAME) {
            m_pFunc = CPDF_Function::Load(pFuncObj);
        }
        if (m_pFunc && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
            delete m_pFunc;
            m_pFunc = NULL;
        }
    }
    return TRUE;
}
FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
{
    if (m_Type == None) {
        return FALSE;
    }
    if (m_pFunc == NULL) {
        if (m_pAltCS == NULL) {
            return FALSE;
        }
        int nComps = m_pAltCS->CountComponents();
        CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps);
        for (int i = 0; i < nComps; i ++) {
            results[i] = *pBuf;
        }
        m_pAltCS->GetRGB(results, R, G, B);
        return TRUE;
    }
    CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
    int nresults = 0;
    m_pFunc->Call(pBuf, 1, results, nresults);
    if (nresults == 0) {
        return FALSE;
    }
    if (m_pAltCS) {
        m_pAltCS->GetRGB(results, R, G, B);
        return TRUE;
    } else {
        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:
    CPDF_DeviceNCS(CPDF_Document* pDoc)
            : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN, 0),
              m_pAltCS(nullptr),
              m_pFunc(nullptr) {
    }
    ~CPDF_DeviceNCS() 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, FX_FLOAT& B) const override;
    void EnableStdConversion(FX_BOOL bEnabled) override;

    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, FX_FLOAT& max) const
{
    value = 1.0f;
    min = 0;
    max = 1.0f;
}
FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray)
{
    CPDF_Object* pObj = pArray->GetElementValue(1);
    if (!pObj) {
        return FALSE;
    }
    if (pObj->GetType() != PDFOBJ_ARRAY) {
        return FALSE;
    }
    m_nComponents = ((CPDF_Array*)pObj)->GetCount();
    CPDF_Object* pAltCS = pArray->GetElementValue(2);
    if (!pAltCS || pAltCS == m_pArray) {
        return FALSE;
    }
    m_pAltCS = Load(pDoc, pAltCS);
    m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3));
    if (m_pAltCS == NULL || m_pFunc == NULL) {
        return FALSE;
    }
    if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
        return FALSE;
    }
    return TRUE;
}
FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
{
    if (m_pFunc == NULL) {
        return FALSE;
    }
    CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
    int nresults = 0;
    m_pFunc->Call(pBuf, m_nComponents, results, nresults);
    if (nresults == 0) {
        return FALSE;
    }
    m_pAltCS->GetRGB(results, R, G, B);
    return TRUE;
}
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 == FX_BSTRC("DeviceRGB") || name == FX_BSTRC("RGB")) {
        return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
    }
    if (name == FX_BSTRC("DeviceGray") || name == FX_BSTRC("G")) {
        return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
    }
    if (name == FX_BSTRC("DeviceCMYK") || name == FX_BSTRC("CMYK")) {
        return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
    }
    if (name == FX_BSTRC("Pattern")) {
        return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
    }
    return NULL;
}
CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj)
{
    if (pObj == NULL) {
        return NULL;
    }
    if (pObj->GetType() == PDFOBJ_NAME) {
        return _CSFromName(pObj->GetString());
    }
    if (pObj->GetType() == PDFOBJ_STREAM) {
        CPDF_Dictionary *pDict = ((CPDF_Stream *)pObj)->GetDict();
        if (!pDict) {
            return NULL;
        }
        CPDF_ColorSpace *pRet = NULL;
        FX_POSITION pos = pDict->GetStartPos();
        while (pos) {
            CFX_ByteString bsKey;
            CPDF_Object *pValue = pDict->GetNextElement(pos, bsKey);
            if (pValue && pValue->GetType() == PDFOBJ_NAME) {
                pRet = _CSFromName(pValue->GetString());
            }
            if (pRet) {
                return pRet;
            }
        }
        return NULL;
    }
    if (pObj->GetType() != PDFOBJ_ARRAY) {
        return NULL;
    }
    CPDF_Array* pArray = (CPDF_Array*)pObj;
    if (pArray->GetCount() == 0) {
        return NULL;
    }
    CPDF_Object *pFamilyObj = pArray->GetElementValue(0);
    if (!pFamilyObj) {
        return NULL;
    }
    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 == NULL || 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 == NULL) {
            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 == NULL) {
        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 == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
        if (m_pBuffer) {
            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 == NULL) {
        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 == NULL || m_pBuffer == NULL) {
        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 == NULL || 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 == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
        return NULL;
    }
    return m_pCS->GetBaseCS();
}
FX_FLOAT* CPDF_Color::GetPatternColor() const
{
    if (m_pBuffer == NULL || 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
{
    if (m_pCS != other.m_pCS || m_pCS == NULL) {
        return FALSE;
    }
    return FXSYS_memcmp(m_pBuffer, other.m_pBuffer, m_pCS->GetBufSize()) == 0;
}
