// 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);
        CPDF_Object* pFuncObj = pArray->GetElementValue(3);
        if (pFuncObj && pFuncObj->GetType() != PDFOBJ_NAME) {
            m_pFunc = CPDF_Function::Load(pFuncObj);
        }
        if (m_pFunc && m_pAltCS && 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;
}
