// 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)) {
}

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;
}
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;
}
bool CPDF_DeviceCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
{
    if (m_Family == PDFCS_DEVICERGB) {
        pBuf[0] = R;
        pBuf[1] = G;
        pBuf[2] = B;
        return true;
    }
    if (m_Family == PDFCS_DEVICEGRAY) {
        if (R == G && R == B) {
            *pBuf = R;
            return true;
        }
        return false;
    }
    if (m_Family == PDFCS_DEVICECMYK) {
        sRGB_to_AdobeCMYK(R, G, B, pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
        return true;
    }
    return false;
}
bool CPDF_DeviceCS::v_SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k) const
{
    if (m_Family == PDFCS_DEVICERGB) {
        AdobeCMYK_to_sRGB(c, m, y, k, pBuf[0], pBuf[1], pBuf[2]);
        return true;
    }
    if (m_Family == PDFCS_DEVICECMYK) {
        pBuf[0] = c;
        pBuf[1] = m;
        pBuf[2] = y;
        pBuf[3] = k;
        return true;
    }
    return false;
}
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, 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) {
    }
    bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
    bool GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
    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, bool bTransMask = false) const override;

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

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;
}
bool CPDF_CalGray::GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const
{
    R = G = B = *pBuf;
    return true;
}
bool CPDF_CalGray::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
{
    if (R == G && R == B) {
        *pBuf = R;
        return true;
    }
    return false;
}
void CPDF_CalGray::TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width, int image_height, 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) {
    }
    bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
    bool GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
    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, 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];
    bool m_bGamma;
    bool m_bMatrix;
};
bool CPDF_CalRGB::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("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;
}
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;
}
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, 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;
    bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
    bool	GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
    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, bool bTransMask = false) const;

    FX_FLOAT m_WhitePoint[3];
    FX_FLOAT m_BlackPoint[3];
    FX_FLOAT m_Ranges[4];
};
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;
        }
    }
}
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;
}
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, 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;

    bool	v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
    bool GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
    bool	SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const override;
    bool	v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const override;
    void EnableStdConversion(bool bEnabled) override;
    void TranslateImageLine(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels, int image_width,
                            int image_height, bool bTransMask = false) const override;

    CPDF_ColorSpace* m_pAlterCS;
    CPDF_IccProfile* m_pProfile;
    uint8_t* m_pCache;
    FX_FLOAT* m_pRanges;
    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);
    }
}

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;
}
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;
}
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;
}
bool CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const
{
    return false;
}
void CPDF_ICCBasedCS::EnableStdConversion(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, 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;

    bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
    bool	GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
    CPDF_ColorSpace* GetBaseCS() const override;
    void EnableStdConversion(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());
    }
}
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;
}

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(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());
    }
}
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;
}
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;
    bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
    bool GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
    void EnableStdConversion(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;
}
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;
}
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;
    }
    R = G = B = 0;
    return false;
}
void CPDF_SeparationCS::EnableStdConversion(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;
    bool v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
    bool GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const override;
    void EnableStdConversion(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;
}
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;
}
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(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;
}
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;
}
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;
}
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, 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(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);
        }
    }
}
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;
}
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;
}
