// Copyright 2016 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fpdfapi/fpdf_page/include/cpdf_colorspace.h"

#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_object.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
#include "core/fxcodec/include/fx_codec.h"

namespace {

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,
};

class CPDF_CalGray : public CPDF_ColorSpace {
 public:
  explicit CPDF_CalGray(CPDF_Document* pDoc);

  FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;

  FX_BOOL GetRGB(FX_FLOAT* pBuf,
                 FX_FLOAT& R,
                 FX_FLOAT& G,
                 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;
};

class CPDF_CalRGB : public CPDF_ColorSpace {
 public:
  explicit CPDF_CalRGB(CPDF_Document* pDoc);

  FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;

  FX_BOOL GetRGB(FX_FLOAT* pBuf,
                 FX_FLOAT& R,
                 FX_FLOAT& G,
                 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;
};

class CPDF_LabCS : public CPDF_ColorSpace {
 public:
  explicit CPDF_LabCS(CPDF_Document* pDoc);

  FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;

  void GetDefaultValue(int iComponent,
                       FX_FLOAT& value,
                       FX_FLOAT& min,
                       FX_FLOAT& max) const override;
  FX_BOOL 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_Ranges[4];
};

class CPDF_ICCBasedCS : public CPDF_ColorSpace {
 public:
  explicit CPDF_ICCBasedCS(CPDF_Document* pDoc);
  ~CPDF_ICCBasedCS() override;

  FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;

  FX_BOOL GetRGB(FX_FLOAT* pBuf,
                 FX_FLOAT& R,
                 FX_FLOAT& G,
                 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;
};

class CPDF_IndexedCS : public CPDF_ColorSpace {
 public:
  explicit CPDF_IndexedCS(CPDF_Document* pDoc);
  ~CPDF_IndexedCS() override;

  FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;

  FX_BOOL GetRGB(FX_FLOAT* pBuf,
                 FX_FLOAT& R,
                 FX_FLOAT& G,
                 FX_FLOAT& B) const override;
  CPDF_ColorSpace* GetBaseCS() const override;

  void EnableStdConversion(FX_BOOL bEnabled) override;

  CPDF_ColorSpace* m_pBaseCS;
  CPDF_CountedColorSpace* m_pCountedBaseCS;
  int m_nBaseComponents;
  int m_MaxIndex;
  CFX_ByteString m_Table;
  FX_FLOAT* m_pCompMinMax;
};

class CPDF_SeparationCS : public CPDF_ColorSpace {
 public:
  explicit CPDF_SeparationCS(CPDF_Document* pDoc);
  ~CPDF_SeparationCS() override;

  // CPDF_ColorSpace:
  void GetDefaultValue(int iComponent,
                       FX_FLOAT& value,
                       FX_FLOAT& min,
                       FX_FLOAT& max) const override;
  FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
  FX_BOOL GetRGB(FX_FLOAT* pBuf,
                 FX_FLOAT& R,
                 FX_FLOAT& G,
                 FX_FLOAT& B) const override;
  void EnableStdConversion(FX_BOOL bEnabled) override;

  CPDF_ColorSpace* m_pAltCS;
  CPDF_Function* m_pFunc;
  enum { None, All, Colorant } m_Type;
};

class CPDF_DeviceNCS : public CPDF_ColorSpace {
 public:
  explicit CPDF_DeviceNCS(CPDF_Document* pDoc);
  ~CPDF_DeviceNCS() override;

  // CPDF_ColorSpace:
  void GetDefaultValue(int iComponent,
                       FX_FLOAT& value,
                       FX_FLOAT& min,
                       FX_FLOAT& max) const override;
  FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
  FX_BOOL GetRGB(FX_FLOAT* pBuf,
                 FX_FLOAT& R,
                 FX_FLOAT& G,
                 FX_FLOAT& B) const override;
  void EnableStdConversion(FX_BOOL bEnabled) override;

  CPDF_ColorSpace* m_pAltCS;
  CPDF_Function* m_pFunc;
};

FX_FLOAT RGB_Conversion(FX_FLOAT colorComponent) {
  if (colorComponent > 1)
    colorComponent = 1;
  if (colorComponent < 0)
    colorComponent = 0;

  int scale = (int)(colorComponent * 1023);
  if (scale < 0)
    scale = 0;
  if (scale < 192)
    colorComponent = (g_sRGBSamples1[scale] / 255.0f);
  else
    colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
  return colorComponent;
}

void XYZ_to_sRGB(FX_FLOAT X,
                 FX_FLOAT Y,
                 FX_FLOAT Z,
                 FX_FLOAT& R,
                 FX_FLOAT& G,
                 FX_FLOAT& B) {
  FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
  FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
  FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z;

  R = RGB_Conversion(R1);
  G = RGB_Conversion(G1);
  B = RGB_Conversion(B1);
}

void XYZ_to_sRGB_WhitePoint(FX_FLOAT X,
                            FX_FLOAT Y,
                            FX_FLOAT Z,
                            FX_FLOAT& R,
                            FX_FLOAT& G,
                            FX_FLOAT& B,
                            FX_FLOAT Xw,
                            FX_FLOAT Yw,
                            FX_FLOAT Zw) {
  // The following RGB_xyz is based on
  // sRGB value {Rx,Ry}={0.64, 0.33}, {Gx,Gy}={0.30, 0.60}, {Bx,By}={0.15, 0.06}

  FX_FLOAT Rx = 0.64f, Ry = 0.33f;
  FX_FLOAT Gx = 0.30f, Gy = 0.60f;
  FX_FLOAT Bx = 0.15f, By = 0.06f;
  CFX_Matrix_3by3 RGB_xyz(Rx, Gx, Bx, Ry, Gy, By, 1 - Rx - Ry, 1 - Gx - Gy,
                          1 - Bx - By);
  CFX_Vector_3by1 whitePoint(Xw, Yw, Zw);
  CFX_Vector_3by1 XYZ(X, Y, Z);

  CFX_Vector_3by1 RGB_Sum_XYZ = RGB_xyz.Inverse().TransformVector(whitePoint);
  CFX_Matrix_3by3 RGB_SUM_XYZ_DIAG(RGB_Sum_XYZ.a, 0, 0, 0, RGB_Sum_XYZ.b, 0, 0,
                                   0, RGB_Sum_XYZ.c);
  CFX_Matrix_3by3 M = RGB_xyz.Multiply(RGB_SUM_XYZ_DIAG);
  CFX_Vector_3by1 RGB = M.Inverse().TransformVector(XYZ);

  R = RGB_Conversion(RGB.a);
  G = RGB_Conversion(RGB.b);
  B = RGB_Conversion(RGB.c);
}

}  // namespace

CPDF_ColorSpace* CPDF_ColorSpace::ColorspaceFromName(
    const CFX_ByteString& name) {
  if (name == "DeviceRGB" || name == "RGB") {
    return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
  }
  if (name == "DeviceGray" || name == "G") {
    return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
  }
  if (name == "DeviceCMYK" || name == "CMYK") {
    return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
  }
  if (name == "Pattern") {
    return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
  }
  return NULL;
}

CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) {
  return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);
}

CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj) {
  if (!pObj)
    return nullptr;
  if (pObj->IsName())
    return ColorspaceFromName(pObj->GetString());

  if (CPDF_Stream* pStream = pObj->AsStream()) {
    CPDF_Dictionary* pDict = pStream->GetDict();
    if (!pDict)
      return nullptr;

    for (const auto& it : *pDict) {
      CPDF_ColorSpace* pRet = nullptr;
      CPDF_Object* pValue = it.second;
      if (ToName(pValue))
        pRet = ColorspaceFromName(pValue->GetString());
      if (pRet)
        return pRet;
    }
    return nullptr;
  }

  CPDF_Array* pArray = pObj->AsArray();
  if (!pArray || pArray->GetCount() == 0)
    return nullptr;

  CPDF_Object* pFamilyObj = pArray->GetDirectObjectAt(0);
  if (!pFamilyObj)
    return nullptr;

  CFX_ByteString familyname = pFamilyObj->GetString();
  if (pArray->GetCount() == 1)
    return ColorspaceFromName(familyname);

  CPDF_ColorSpace* pCS = NULL;
  uint32_t id = familyname.GetID();
  if (id == FXBSTR_ID('C', 'a', 'l', 'G')) {
    pCS = new CPDF_CalGray(pDoc);
  } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) {
    pCS = new CPDF_CalRGB(pDoc);
  } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) {
    pCS = new CPDF_LabCS(pDoc);
  } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) {
    pCS = new CPDF_ICCBasedCS(pDoc);
  } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') ||
             id == FXBSTR_ID('I', 0, 0, 0)) {
    pCS = new CPDF_IndexedCS(pDoc);
  } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) {
    pCS = new CPDF_SeparationCS(pDoc);
  } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) {
    pCS = new CPDF_DeviceNCS(pDoc);
  } else if (id == FXBSTR_ID('P', 'a', 't', 't')) {
    pCS = new CPDF_PatternCS(pDoc);
  } else {
    return NULL;
  }
  pCS->m_pArray = pArray;
  if (!pCS->v_Load(pDoc, pArray)) {
    pCS->ReleaseCS();
    return NULL;
  }
  return pCS;
}

void CPDF_ColorSpace::ReleaseCS() {
  if (this == GetStockCS(PDFCS_DEVICERGB)) {
    return;
  }
  if (this == GetStockCS(PDFCS_DEVICEGRAY)) {
    return;
  }
  if (this == GetStockCS(PDFCS_DEVICECMYK)) {
    return;
  }
  if (this == GetStockCS(PDFCS_PATTERN)) {
    return;
  }
  delete this;
}

int CPDF_ColorSpace::GetBufSize() const {
  if (m_Family == PDFCS_PATTERN) {
    return sizeof(PatternValue);
  }
  return m_nComponents * sizeof(FX_FLOAT);
}

FX_FLOAT* CPDF_ColorSpace::CreateBuf() {
  int size = GetBufSize();
  uint8_t* pBuf = FX_Alloc(uint8_t, size);
  return (FX_FLOAT*)pBuf;
}

FX_BOOL CPDF_ColorSpace::sRGB() const {
  if (m_Family == PDFCS_DEVICERGB) {
    return TRUE;
  }
  if (m_Family != PDFCS_ICCBASED) {
    return FALSE;
  }
  CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this;
  return pCS->m_pProfile->m_bsRGB;
}

FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf,
                                 FX_FLOAT& c,
                                 FX_FLOAT& m,
                                 FX_FLOAT& y,
                                 FX_FLOAT& k) const {
  if (v_GetCMYK(pBuf, c, m, y, k)) {
    return TRUE;
  }
  FX_FLOAT R, G, B;
  if (!GetRGB(pBuf, R, G, B)) {
    return FALSE;
  }
  sRGB_to_AdobeCMYK(R, G, B, c, m, y, k);
  return TRUE;
}

FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf,
                                 FX_FLOAT c,
                                 FX_FLOAT m,
                                 FX_FLOAT y,
                                 FX_FLOAT k) const {
  if (v_SetCMYK(pBuf, c, m, y, k)) {
    return TRUE;
  }
  FX_FLOAT R, G, B;
  AdobeCMYK_to_sRGB(c, m, y, k, R, G, B);
  return SetRGB(pBuf, R, G, B);
}

void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const {
  if (!buf || m_Family == PDFCS_PATTERN) {
    return;
  }
  FX_FLOAT min, max;
  for (uint32_t 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 (uint32_t j = 0; j < m_nComponents; j++)
      if (m_Family == PDFCS_INDEXED) {
        src[j] = (FX_FLOAT)(*src_buf++);
      } else {
        src[j] = (FX_FLOAT)(*src_buf++) / 255;
      }
    GetRGB(src, R, G, B);
    *dest_buf++ = (int32_t)(B * 255);
    *dest_buf++ = (int32_t)(G * 255);
    *dest_buf++ = (int32_t)(R * 255);
  }
}

void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) {
  if (bEnabled)
    m_dwStdConversion++;
  else if (m_dwStdConversion)
    m_dwStdConversion--;
}

CPDF_CalGray::CPDF_CalGray(CPDF_Document* pDoc)
    : CPDF_ColorSpace(pDoc, PDFCS_CALGRAY, 1) {}

FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  CPDF_Dictionary* pDict = pArray->GetDictAt(1);
  if (!pDict)
    return FALSE;

  CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
  int i;
  for (i = 0; i < 3; i++)
    m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;

  pParam = pDict->GetArrayBy("BlackPoint");
  for (i = 0; i < 3; i++)
    m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;

  m_Gamma = pDict->GetNumberBy("Gamma");
  if (m_Gamma == 0)
    m_Gamma = 1.0f;
  return TRUE;
}

FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf,
                             FX_FLOAT& R,
                             FX_FLOAT& G,
                             FX_FLOAT& B) const {
  R = G = B = *pBuf;
  return TRUE;
}

FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf,
                             FX_FLOAT R,
                             FX_FLOAT G,
                             FX_FLOAT B) const {
  if (R == G && R == B) {
    *pBuf = R;
    return TRUE;
  }
  return FALSE;
}

void CPDF_CalGray::TranslateImageLine(uint8_t* pDestBuf,
                                      const uint8_t* pSrcBuf,
                                      int pixels,
                                      int image_width,
                                      int image_height,
                                      FX_BOOL bTransMask) const {
  for (int i = 0; i < pixels; i++) {
    *pDestBuf++ = pSrcBuf[i];
    *pDestBuf++ = pSrcBuf[i];
    *pDestBuf++ = pSrcBuf[i];
  }
}

CPDF_CalRGB::CPDF_CalRGB(CPDF_Document* pDoc)
    : CPDF_ColorSpace(pDoc, PDFCS_CALRGB, 3) {}

FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  CPDF_Dictionary* pDict = pArray->GetDictAt(1);
  if (!pDict)
    return FALSE;

  CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
  int i;
  for (i = 0; i < 3; i++)
    m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;

  pParam = pDict->GetArrayBy("BlackPoint");
  for (i = 0; i < 3; i++)
    m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;

  pParam = pDict->GetArrayBy("Gamma");
  if (pParam) {
    m_bGamma = TRUE;
    for (i = 0; i < 3; i++)
      m_Gamma[i] = pParam->GetNumberAt(i);
  } else {
    m_bGamma = FALSE;
  }

  pParam = pDict->GetArrayBy("Matrix");
  if (pParam) {
    m_bMatrix = TRUE;
    for (i = 0; i < 9; i++)
      m_Matrix[i] = pParam->GetNumberAt(i);
  } else {
    m_bMatrix = FALSE;
  }
  return TRUE;
}

FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf,
                            FX_FLOAT& R,
                            FX_FLOAT& G,
                            FX_FLOAT& B) const {
  FX_FLOAT A_ = pBuf[0];
  FX_FLOAT B_ = pBuf[1];
  FX_FLOAT C_ = pBuf[2];
  if (m_bGamma) {
    A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]);
    B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]);
    C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]);
  }

  FX_FLOAT X;
  FX_FLOAT Y;
  FX_FLOAT Z;
  if (m_bMatrix) {
    X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_;
    Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_;
    Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_;
  } else {
    X = A_;
    Y = B_;
    Z = C_;
  }
  XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1],
                         m_WhitePoint[2]);
  return TRUE;
}

FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf,
                            FX_FLOAT R,
                            FX_FLOAT G,
                            FX_FLOAT B) const {
  pBuf[0] = R;
  pBuf[1] = G;
  pBuf[2] = B;
  return TRUE;
}

void CPDF_CalRGB::TranslateImageLine(uint8_t* pDestBuf,
                                     const uint8_t* pSrcBuf,
                                     int pixels,
                                     int image_width,
                                     int image_height,
                                     FX_BOOL bTransMask) const {
  if (bTransMask) {
    FX_FLOAT Cal[3];
    FX_FLOAT R;
    FX_FLOAT G;
    FX_FLOAT B;
    for (int i = 0; i < pixels; i++) {
      Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255;
      Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255;
      Cal[2] = ((FX_FLOAT)pSrcBuf[0]) / 255;
      GetRGB(Cal, R, G, B);
      pDestBuf[0] = FXSYS_round(B * 255);
      pDestBuf[1] = FXSYS_round(G * 255);
      pDestBuf[2] = FXSYS_round(R * 255);
      pSrcBuf += 3;
      pDestBuf += 3;
    }
  }
  ReverseRGB(pDestBuf, pSrcBuf, pixels);
}

CPDF_LabCS::CPDF_LabCS(CPDF_Document* pDoc)
    : CPDF_ColorSpace(pDoc, PDFCS_LAB, 3) {}

void CPDF_LabCS::GetDefaultValue(int iComponent,
                                 FX_FLOAT& value,
                                 FX_FLOAT& min,
                                 FX_FLOAT& max) const {
  assert(iComponent < 3);
  value = 0;
  if (iComponent == 0) {
    min = 0;
    max = 100 * 1.0f;
  } else {
    min = m_Ranges[iComponent * 2 - 2];
    max = m_Ranges[iComponent * 2 - 1];
    if (value < min)
      value = min;
    else if (value > max)
      value = max;
  }
}

FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  CPDF_Dictionary* pDict = pArray->GetDictAt(1);
  if (!pDict)
    return FALSE;

  CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
  int i;
  for (i = 0; i < 3; i++)
    m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;

  pParam = pDict->GetArrayBy("BlackPoint");
  for (i = 0; i < 3; i++)
    m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;

  pParam = pDict->GetArrayBy("Range");
  const FX_FLOAT def_ranges[4] = {-100 * 1.0f, 100 * 1.0f, -100 * 1.0f,
                                  100 * 1.0f};
  for (i = 0; i < 4; i++)
    m_Ranges[i] = pParam ? pParam->GetNumberAt(i) : def_ranges[i];
  return TRUE;
}

FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf,
                           FX_FLOAT& R,
                           FX_FLOAT& G,
                           FX_FLOAT& B) const {
  FX_FLOAT Lstar = pBuf[0];
  FX_FLOAT astar = pBuf[1];
  FX_FLOAT bstar = pBuf[2];
  FX_FLOAT M = (Lstar + 16.0f) / 116.0f;
  FX_FLOAT L = M + astar / 500.0f;
  FX_FLOAT N = M - bstar / 200.0f;
  FX_FLOAT X, Y, Z;
  if (L < 0.2069f)
    X = 0.957f * 0.12842f * (L - 0.1379f);
  else
    X = 0.957f * L * L * L;

  if (M < 0.2069f)
    Y = 0.12842f * (M - 0.1379f);
  else
    Y = M * M * M;

  if (N < 0.2069f)
    Z = 1.0889f * 0.12842f * (N - 0.1379f);
  else
    Z = 1.0889f * N * N * N;

  XYZ_to_sRGB(X, Y, Z, R, G, B);
  return TRUE;
}

FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf,
                           FX_FLOAT R,
                           FX_FLOAT G,
                           FX_FLOAT B) const {
  return FALSE;
}

void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf,
                                    const uint8_t* pSrcBuf,
                                    int pixels,
                                    int image_width,
                                    int image_height,
                                    FX_BOOL bTransMask) const {
  for (int i = 0; i < pixels; i++) {
    FX_FLOAT lab[3];
    FX_FLOAT R, G, B;
    lab[0] = (pSrcBuf[0] * 100 / 255.0f);
    lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128);
    lab[2] = (FX_FLOAT)(pSrcBuf[2] - 128);
    GetRGB(lab, R, G, B);
    pDestBuf[0] = (int32_t)(B * 255);
    pDestBuf[1] = (int32_t)(G * 255);
    pDestBuf[2] = (int32_t)(R * 255);
    pDestBuf += 3;
    pSrcBuf += 3;
  }
}

CPDF_ICCBasedCS::CPDF_ICCBasedCS(CPDF_Document* pDoc)
    : CPDF_ColorSpace(pDoc, PDFCS_ICCBASED, 0),
      m_pAlterCS(nullptr),
      m_pProfile(nullptr),
      m_pCache(nullptr),
      m_pRanges(nullptr),
      m_bOwn(FALSE) {}

CPDF_ICCBasedCS::~CPDF_ICCBasedCS() {
  FX_Free(m_pCache);
  FX_Free(m_pRanges);
  if (m_pAlterCS && m_bOwn)
    m_pAlterCS->ReleaseCS();
  if (m_pProfile && m_pDocument)
    m_pDocument->GetPageData()->ReleaseIccProfile(m_pProfile);
}

FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  CPDF_Stream* pStream = pArray->GetStreamAt(1);
  if (!pStream)
    return FALSE;

  m_pProfile = pDoc->LoadIccProfile(pStream);
  if (!m_pProfile)
    return FALSE;

  m_nComponents =
      m_pProfile
          ->GetComponents();  // Try using the nComponents from ICC profile
  CPDF_Dictionary* pDict = pStream->GetDict();
  if (!m_pProfile->m_pTransform) {  // No valid ICC profile or using sRGB
    CPDF_Object* pAlterCSObj =
        pDict ? pDict->GetDirectObjectBy("Alternate") : nullptr;
    if (pAlterCSObj) {
      CPDF_ColorSpace* pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj);
      if (pAlterCS) {
        if (m_nComponents == 0) {                 // NO valid ICC profile
          if (pAlterCS->CountComponents() > 0) {  // Use Alternative colorspace
            m_nComponents = pAlterCS->CountComponents();
            m_pAlterCS = pAlterCS;
            m_bOwn = TRUE;
          } else {  // No valid alternative colorspace
            pAlterCS->ReleaseCS();
            int32_t nDictComponents = pDict ? pDict->GetIntegerBy("N") : 0;
            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->GetArrayBy("Range");
  m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2);
  for (uint32_t i = 0; i < m_nComponents * 2; i++) {
    if (pRanges)
      m_pRanges[i] = pRanges->GetNumberAt(i);
    else if (i % 2)
      m_pRanges[i] = 1.0f;
    else
      m_pRanges[i] = 0;
  }
  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;
  }
  CCodec_IccModule* pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
  if (!m_pProfile->m_pTransform || !pIccModule) {
    if (m_pAlterCS)
      return m_pAlterCS->GetRGB(pBuf, R, G, B);

    R = 0.0f;
    G = 0.0f;
    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::SetRGB(FX_FLOAT* pBuf,
                                FX_FLOAT R,
                                FX_FLOAT G,
                                FX_FLOAT B) const {
  return FALSE;
}

FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf,
                                   FX_FLOAT& c,
                                   FX_FLOAT& m,
                                   FX_FLOAT& y,
                                   FX_FLOAT& k) const {
  if (m_nComponents != 4)
    return FALSE;

  c = pBuf[0];
  m = pBuf[1];
  y = pBuf[2];
  k = pBuf[3];
  return TRUE;
}

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 (uint32_t 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) {
        ((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++) {
          uint32_t color = i;
          uint32_t order = nMaxColors / 52;
          for (uint32_t 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 (uint32_t 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);
  }
}

CPDF_IndexedCS::CPDF_IndexedCS(CPDF_Document* pDoc)
    : CPDF_ColorSpace(pDoc, PDFCS_INDEXED, 1),
      m_pBaseCS(nullptr),
      m_pCountedBaseCS(nullptr),
      m_pCompMinMax(nullptr) {}

CPDF_IndexedCS::~CPDF_IndexedCS() {
  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->GetDirectObjectAt(1);
  if (pBaseObj == m_pArray) {
    return FALSE;
  }
  CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
  m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL);
  if (!m_pBaseCS) {
    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->GetIntegerAt(2);

  CPDF_Object* pTableObj = pArray->GetDirectObjectAt(3);
  if (!pTableObj)
    return FALSE;

  if (CPDF_String* pString = pTableObj->AsString()) {
    m_Table = pString->GetString();
  } else if (CPDF_Stream* pStream = pTableObj->AsStream()) {
    CPDF_StreamAcc acc;
    acc.LoadAllData(pStream, 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.raw_str();
  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;
  }
  return m_pBaseCS->GetRGB(comps, R, G, B);
}

CPDF_ColorSpace* CPDF_IndexedCS::GetBaseCS() const {
  return m_pBaseCS;
}

void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled) {
  CPDF_ColorSpace::EnableStdConversion(bEnabled);
  if (m_pBaseCS) {
    m_pBaseCS->EnableStdConversion(bEnabled);
  }
}

CPDF_PatternCS::CPDF_PatternCS(CPDF_Document* pDoc)
    : CPDF_ColorSpace(pDoc, PDFCS_PATTERN, 1),
      m_pBaseCS(nullptr),
      m_pCountedBaseCS(nullptr) {}

CPDF_PatternCS::~CPDF_PatternCS() {
  CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
  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->GetDirectObjectAt(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;
}

CPDF_SeparationCS::CPDF_SeparationCS(CPDF_Document* pDoc)
    : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1),
      m_pAltCS(nullptr),
      m_pFunc(nullptr) {}

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->GetStringAt(1);
  if (name == "None") {
    m_Type = None;
  } else {
    m_Type = Colorant;
    CPDF_Object* pAltCS = pArray->GetDirectObjectAt(2);
    if (pAltCS == m_pArray) {
      return FALSE;
    }
    m_pAltCS = Load(pDoc, pAltCS);
    if (!m_pAltCS) {
      return FALSE;
    }
    CPDF_Object* pFuncObj = pArray->GetDirectObjectAt(3);
    if (pFuncObj && !pFuncObj->IsName())
      m_pFunc = CPDF_Function::Load(pFuncObj);

    if (m_pFunc && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
      delete m_pFunc;
      m_pFunc = NULL;
    }
  }
  return TRUE;
}

FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf,
                                  FX_FLOAT& R,
                                  FX_FLOAT& G,
                                  FX_FLOAT& B) const {
  if (m_Type == None) {
    return FALSE;
  }
  if (!m_pFunc) {
    if (!m_pAltCS) {
      return FALSE;
    }
    int nComps = m_pAltCS->CountComponents();
    CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps);
    for (int i = 0; i < nComps; i++) {
      results[i] = *pBuf;
    }
    return m_pAltCS->GetRGB(results, R, G, B);
  }
  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) {
    return m_pAltCS->GetRGB(results, R, G, B);
  }
  R = G = B = 0;
  return FALSE;
}

void CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled) {
  CPDF_ColorSpace::EnableStdConversion(bEnabled);
  if (m_pAltCS) {
    m_pAltCS->EnableStdConversion(bEnabled);
  }
}

CPDF_DeviceNCS::CPDF_DeviceNCS(CPDF_Document* pDoc)
    : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN, 0),
      m_pAltCS(nullptr),
      m_pFunc(nullptr) {}

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_Array* pObj = ToArray(pArray->GetDirectObjectAt(1));
  if (!pObj)
    return FALSE;

  m_nComponents = pObj->GetCount();
  CPDF_Object* pAltCS = pArray->GetDirectObjectAt(2);
  if (!pAltCS || pAltCS == m_pArray) {
    return FALSE;
  }
  m_pAltCS = Load(pDoc, pAltCS);
  m_pFunc = CPDF_Function::Load(pArray->GetDirectObjectAt(3));
  if (!m_pAltCS || !m_pFunc) {
    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) {
    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;
  }
  return m_pAltCS->GetRGB(results, R, G, B);
}

void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) {
  CPDF_ColorSpace::EnableStdConversion(bEnabled);
  if (m_pAltCS) {
    m_pAltCS->EnableStdConversion(bEnabled);
  }
}
