// 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;
  }
  if (m_Family == PDFCS_DEVICEGRAY) {
    if (R == G && R == B) {
      *pBuf = R;
      return TRUE;
    }
    return FALSE;
  }
  if (m_Family == PDFCS_DEVICECMYK) {
    sRGB_to_AdobeCMYK(R, G, B, pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CPDF_DeviceCS::v_SetCMYK(FX_FLOAT* pBuf,
                                 FX_FLOAT c,
                                 FX_FLOAT m,
                                 FX_FLOAT y,
                                 FX_FLOAT k) const {
  if (m_Family == PDFCS_DEVICERGB) {
    AdobeCMYK_to_sRGB(c, m, y, k, pBuf[0], pBuf[1], pBuf[2]);
    return TRUE;
  }
  if (m_Family == PDFCS_DEVICECMYK) {
    pBuf[0] = c;
    pBuf[1] = m;
    pBuf[2] = y;
    pBuf[3] = k;
    return TRUE;
  }
  return FALSE;
}
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;
  }
  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);
  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;
}
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 override;

  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() {
  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->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) {
      return m_pAlterCS->GetRGB(pBuf, R, G, B);
    }
    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() {
  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;
  }
  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);
  }
}
#define MAX_PATTERN_COLORCOMPS 16
typedef struct _PatternValue {
  CPDF_Pattern* m_pPattern;
  CPDF_CountedPattern* m_pCountedPattern;
  int m_nComps;
  FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS];
} PatternValue;
CPDF_PatternCS::~CPDF_PatternCS() {
  CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
  if (pCS && m_pDocument) {
    m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
  }
}
FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  CPDF_Object* pBaseCS = pArray->GetElementValue(1);
  if (pBaseCS == m_pArray) {
    return FALSE;
  }
  CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
  m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, NULL);
  if (m_pBaseCS) {
    if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) {
      return FALSE;
    }
    m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
    m_nComponents = m_pBaseCS->CountComponents() + 1;
    if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) {
      return FALSE;
    }
  } else {
    m_nComponents = 1;
  }
  return TRUE;
}
FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf,
                               FX_FLOAT& R,
                               FX_FLOAT& G,
                               FX_FLOAT& B) const {
  if (m_pBaseCS) {
    ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN);
    PatternValue* pvalue = (PatternValue*)pBuf;
    if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B)) {
      return TRUE;
    }
  }
  R = G = B = 0.75f;
  return FALSE;
}
CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const {
  return m_pBaseCS;
}
class CPDF_SeparationCS : public CPDF_ColorSpace {
 public:
  CPDF_SeparationCS(CPDF_Document* pDoc)
      : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1),
        m_pAltCS(nullptr),
        m_pFunc(nullptr) {}
  ~CPDF_SeparationCS() override;
  void GetDefaultValue(int iComponent,
                       FX_FLOAT& value,
                       FX_FLOAT& min,
                       FX_FLOAT& max) const override;
  FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
  FX_BOOL GetRGB(FX_FLOAT* pBuf,
                 FX_FLOAT& R,
                 FX_FLOAT& G,
                 FX_FLOAT& B) const override;
  void EnableStdConversion(FX_BOOL bEnabled) override;

  CPDF_ColorSpace* m_pAltCS;
  CPDF_Function* m_pFunc;
  enum { None, All, Colorant } m_Type;
};
CPDF_SeparationCS::~CPDF_SeparationCS() {
  if (m_pAltCS) {
    m_pAltCS->ReleaseCS();
  }
  delete m_pFunc;
}
void CPDF_SeparationCS::GetDefaultValue(int iComponent,
                                        FX_FLOAT& value,
                                        FX_FLOAT& min,
                                        FX_FLOAT& max) const {
  value = 1.0f;
  min = 0;
  max = 1.0f;
}
FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  CFX_ByteString name = pArray->GetString(1);
  if (name == FX_BSTRC("None")) {
    m_Type = None;
  } else {
    m_Type = Colorant;
    CPDF_Object* pAltCS = pArray->GetElementValue(2);
    if (pAltCS == m_pArray) {
      return FALSE;
    }
    m_pAltCS = Load(pDoc, pAltCS);
    if (!m_pAltCS) {
      return FALSE;
    }
    CPDF_Object* pFuncObj = pArray->GetElementValue(3);
    if (pFuncObj && pFuncObj->GetType() != PDFOBJ_NAME) {
      m_pFunc = CPDF_Function::Load(pFuncObj);
    }
    if (m_pFunc && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
      delete m_pFunc;
      m_pFunc = NULL;
    }
  }
  return TRUE;
}
FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf,
                                  FX_FLOAT& R,
                                  FX_FLOAT& G,
                                  FX_FLOAT& B) const {
  if (m_Type == None) {
    return FALSE;
  }
  if (m_pFunc == NULL) {
    if (m_pAltCS == NULL) {
      return FALSE;
    }
    int nComps = m_pAltCS->CountComponents();
    CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps);
    for (int i = 0; i < nComps; i++) {
      results[i] = *pBuf;
    }
    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);
  }
}
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;
  }
  return m_pAltCS->GetRGB(results, R, G, B);
}
void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) {
  CPDF_ColorSpace::EnableStdConversion(bEnabled);
  if (m_pAltCS) {
    m_pAltCS->EnableStdConversion(bEnabled);
  }
}
CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) {
  return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);
  ;
}
CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name) {
  if (name == 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) {
    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;
}
